/* Minification failed. Returning unminified contents.
(9343,21-22): run-time warning JS1004: Expected ';': i
(9644,29-30): run-time warning JS1004: Expected ';': i
(10052,13-14): run-time warning JS1004: Expected ';': e
(10263,17-18): run-time warning JS1004: Expected ';': i
(10466,17-18): run-time warning JS1004: Expected ';': u
(10467,17-18): run-time warning JS1004: Expected ';': f
(10677,57-58): run-time warning JS1195: Expected expression: >
(10683,10-11): run-time warning JS1195: Expected expression: )
(10684,56-57): run-time warning JS1195: Expected expression: >
(10687,10-11): run-time warning JS1195: Expected expression: )
(10688,5-6): run-time warning JS1002: Syntax error: }
(10691,39-40): run-time warning JS1004: Expected ';': :
(10693,46-47): run-time warning JS1002: Syntax error: }
(10695,43-44): run-time warning JS1195: Expected expression: )
(10865,1-2): run-time warning JS1002: Syntax error: }
(10865,46-47): run-time warning JS1002: Syntax error: }
(10867,39-40): run-time warning JS1195: Expected expression: )
(10881,1-2): run-time warning JS1002: Syntax error: }
(10884,42-44): run-time warning JS1197: Too many errors. The file might not be a JavaScript file: ||
(10131,26-32): run-time error JS1137: 'delete' is a new reserved word and should not be used as an identifier: delete
(10862,5,10864,7): run-time warning JS1018: 'return' statement outside of function: return {
        initialize: initialize
    };
(10878,5,10880,7): run-time warning JS1018: 'return' statement outside of function: return {
        initialize: initialize
    };
 */
/*! jQuery UI - v1.10.4 - 2014-06-10
* http://jqueryui.com
* Includes: jquery.ui.core.js, jquery.ui.widget.js, jquery.ui.position.js, jquery.ui.autocomplete.js, jquery.ui.menu.js
* Copyright 2014 jQuery Foundation and other contributors; Licensed MIT */
 
(function( $, undefined ) {

var uuid = 0,
	runiqueId = /^ui-id-\d+$/;

// $.ui might exist from components with no dependencies, e.g., $.ui.position
$.ui = $.ui || {};

$.extend( $.ui, {
	version: "1.10.4",

	keyCode: {
		BACKSPACE: 8,
		COMMA: 188,
		DELETE: 46,
		DOWN: 40,
		END: 35,
		ENTER: 13,
		ESCAPE: 27,
		HOME: 36,
		LEFT: 37,
		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,
		SPACE: 32,
		TAB: 9,
		UP: 38
	}
});

// plugins
$.fn.extend({
	focus: (function( orig ) {
		return function( delay, fn ) {
			return typeof delay === "number" ?
				this.each(function() {
					var elem = this;
					setTimeout(function() {
						$( elem ).focus();
						if ( fn ) {
							fn.call( elem );
						}
					}, delay );
				}) :
				orig.apply( this, arguments );
		};
	})( $.fn.focus ),

	scrollParent: function() {
		var scrollParent;
		if (($.ui.ie && (/(static|relative)/).test(this.css("position"))) || (/absolute/).test(this.css("position"))) {
			scrollParent = this.parents().filter(function() {
				return (/(relative|absolute|fixed)/).test($.css(this,"position")) && (/(auto|scroll)/).test($.css(this,"overflow")+$.css(this,"overflow-y")+$.css(this,"overflow-x"));
			}).eq(0);
		} else {
			scrollParent = this.parents().filter(function() {
				return (/(auto|scroll)/).test($.css(this,"overflow")+$.css(this,"overflow-y")+$.css(this,"overflow-x"));
			}).eq(0);
		}

		return (/fixed/).test(this.css("position")) || !scrollParent.length ? $(document) : scrollParent;
	},

	zIndex: function( zIndex ) {
		if ( zIndex !== undefined ) {
			return this.css( "zIndex", zIndex );
		}

		if ( this.length ) {
			var elem = $( this[ 0 ] ), position, value;
			while ( elem.length && elem[ 0 ] !== document ) {
				// Ignore z-index if position is set to a value where z-index is ignored by the browser
				// This makes behavior of this function consistent across browsers
				// WebKit always returns auto if the element is positioned
				position = elem.css( "position" );
				if ( position === "absolute" || position === "relative" || position === "fixed" ) {
					// IE returns 0 when zIndex is not specified
					// other browsers return a string
					// we ignore the case of nested elements with an explicit value of 0
					// <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
					value = parseInt( elem.css( "zIndex" ), 10 );
					if ( !isNaN( value ) && value !== 0 ) {
						return value;
					}
				}
				elem = elem.parent();
			}
		}

		return 0;
	},

	uniqueId: function() {
		return this.each(function() {
			if ( !this.id ) {
				this.id = "ui-id-" + (++uuid);
			}
		});
	},

	removeUniqueId: function() {
		return this.each(function() {
			if ( runiqueId.test( this.id ) ) {
				$( this ).removeAttr( "id" );
			}
		});
	}
});

// selectors
function focusable( element, isTabIndexNotNaN ) {
	var map, mapName, img,
		nodeName = element.nodeName.toLowerCase();
	if ( "area" === nodeName ) {
		map = element.parentNode;
		mapName = map.name;
		if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) {
			return false;
		}
		img = $( "img[usemap=#" + mapName + "]" )[0];
		return !!img && visible( img );
	}
	return ( /input|select|textarea|button|object/.test( nodeName ) ?
		!element.disabled :
		"a" === nodeName ?
			element.href || isTabIndexNotNaN :
			isTabIndexNotNaN) &&
		// the element and all of its ancestors must be visible
		visible( element );
}

function visible( element ) {
	return $.expr.filters.visible( element ) &&
		!$( element ).parents().addBack().filter(function() {
			return $.css( this, "visibility" ) === "hidden";
		}).length;
}

$.extend( $.expr[ ":" ], {
	data: $.expr.createPseudo ?
		$.expr.createPseudo(function( dataName ) {
			return function( elem ) {
				return !!$.data( elem, dataName );
			};
		}) :
		// support: jQuery <1.8
		function( elem, i, match ) {
			return !!$.data( elem, match[ 3 ] );
		},

	focusable: function( element ) {
		return focusable( element, !isNaN( $.attr( element, "tabindex" ) ) );
	},

	tabbable: function( element ) {
		var tabIndex = $.attr( element, "tabindex" ),
			isTabIndexNaN = isNaN( tabIndex );
		return ( isTabIndexNaN || tabIndex >= 0 ) && focusable( element, !isTabIndexNaN );
	}
});

// support: jQuery <1.8
if ( !$( "<a>" ).outerWidth( 1 ).jquery ) {
	$.each( [ "Width", "Height" ], function( i, name ) {
		var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ],
			type = name.toLowerCase(),
			orig = {
				innerWidth: $.fn.innerWidth,
				innerHeight: $.fn.innerHeight,
				outerWidth: $.fn.outerWidth,
				outerHeight: $.fn.outerHeight
			};

		function reduce( elem, size, border, margin ) {
			$.each( side, function() {
				size -= parseFloat( $.css( elem, "padding" + this ) ) || 0;
				if ( border ) {
					size -= parseFloat( $.css( elem, "border" + this + "Width" ) ) || 0;
				}
				if ( margin ) {
					size -= parseFloat( $.css( elem, "margin" + this ) ) || 0;
				}
			});
			return size;
		}

		$.fn[ "inner" + name ] = function( size ) {
			if ( size === undefined ) {
				return orig[ "inner" + name ].call( this );
			}

			return this.each(function() {
				$( this ).css( type, reduce( this, size ) + "px" );
			});
		};

		$.fn[ "outer" + name] = function( size, margin ) {
			if ( typeof size !== "number" ) {
				return orig[ "outer" + name ].call( this, size );
			}

			return this.each(function() {
				$( this).css( type, reduce( this, size, true, margin ) + "px" );
			});
		};
	});
}

// support: jQuery <1.8
if ( !$.fn.addBack ) {
	$.fn.addBack = function( selector ) {
		return this.add( selector == null ?
			this.prevObject : this.prevObject.filter( selector )
		);
	};
}

// support: jQuery 1.6.1, 1.6.2 (http://bugs.jquery.com/ticket/9413)
if ( $( "<a>" ).data( "a-b", "a" ).removeData( "a-b" ).data( "a-b" ) ) {
	$.fn.removeData = (function( removeData ) {
		return function( key ) {
			if ( arguments.length ) {
				return removeData.call( this, $.camelCase( key ) );
			} else {
				return removeData.call( this );
			}
		};
	})( $.fn.removeData );
}





// deprecated
$.ui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() );

$.support.selectstart = "onselectstart" in document.createElement( "div" );
$.fn.extend({
	disableSelection: function() {
		return this.bind( ( $.support.selectstart ? "selectstart" : "mousedown" ) +
			".ui-disableSelection", function( event ) {
				event.preventDefault();
			});
	},

	enableSelection: function() {
		return this.unbind( ".ui-disableSelection" );
	}
});

$.extend( $.ui, {
	// $.ui.plugin is deprecated. Use $.widget() extensions instead.
	plugin: {
		add: function( module, option, set ) {
			var i,
				proto = $.ui[ module ].prototype;
			for ( i in set ) {
				proto.plugins[ i ] = proto.plugins[ i ] || [];
				proto.plugins[ i ].push( [ option, set[ i ] ] );
			}
		},
		call: function( instance, name, args ) {
			var i,
				set = instance.plugins[ name ];
			if ( !set || !instance.element[ 0 ].parentNode || instance.element[ 0 ].parentNode.nodeType === 11 ) {
				return;
			}

			for ( i = 0; i < set.length; i++ ) {
				if ( instance.options[ set[ i ][ 0 ] ] ) {
					set[ i ][ 1 ].apply( instance.element, args );
				}
			}
		}
	},

	// only used by resizable
	hasScroll: function( el, a ) {

		//If overflow is hidden, the element might have extra content, but the user wants to hide it
		if ( $( el ).css( "overflow" ) === "hidden") {
			return false;
		}

		var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop",
			has = false;

		if ( el[ scroll ] > 0 ) {
			return true;
		}

		// TODO: determine which cases actually cause this to happen
		// if the element doesn't have the scroll set, see if it's possible to
		// set the scroll
		el[ scroll ] = 1;
		has = ( el[ scroll ] > 0 );
		el[ scroll ] = 0;
		return has;
	}
});

})( jQuery );
(function( $, undefined ) {

var uuid = 0,
	slice = Array.prototype.slice,
	_cleanData = $.cleanData;
$.cleanData = function( elems ) {
	for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
		try {
			$( elem ).triggerHandler( "remove" );
		// http://bugs.jquery.com/ticket/8235
		} catch( e ) {}
	}
	_cleanData( elems );
};

$.widget = function( name, base, prototype ) {
	var fullName, existingConstructor, constructor, basePrototype,
		// proxiedPrototype allows the provided prototype to remain unmodified
		// so that it can be used as a mixin for multiple widgets (#8876)
		proxiedPrototype = {},
		namespace = name.split( "." )[ 0 ];

	name = name.split( "." )[ 1 ];
	fullName = namespace + "-" + name;

	if ( !prototype ) {
		prototype = base;
		base = $.Widget;
	}

	// create selector for plugin
	$.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) {
		return !!$.data( elem, fullName );
	};

	$[ namespace ] = $[ namespace ] || {};
	existingConstructor = $[ namespace ][ name ];
	constructor = $[ namespace ][ name ] = function( options, element ) {
		// allow instantiation without "new" keyword
		if ( !this._createWidget ) {
			return new constructor( options, element );
		}

		// allow instantiation without initializing for simple inheritance
		// must use "new" keyword (the code above always passes args)
		if ( arguments.length ) {
			this._createWidget( options, element );
		}
	};
	// extend with the existing constructor to carry over any static properties
	$.extend( constructor, existingConstructor, {
		version: prototype.version,
		// copy the object used to create the prototype in case we need to
		// redefine the widget later
		_proto: $.extend( {}, prototype ),
		// track widgets that inherit from this widget in case this widget is
		// redefined after a widget inherits from it
		_childConstructors: []
	});

	basePrototype = new base();
	// we need to make the options hash a property directly on the new instance
	// otherwise we'll modify the options hash on the prototype that we're
	// inheriting from
	basePrototype.options = $.widget.extend( {}, basePrototype.options );
	$.each( prototype, function( prop, value ) {
		if ( !$.isFunction( value ) ) {
			proxiedPrototype[ prop ] = value;
			return;
		}
		proxiedPrototype[ prop ] = (function() {
			var _super = function() {
					return base.prototype[ prop ].apply( this, arguments );
				},
				_superApply = function( args ) {
					return base.prototype[ prop ].apply( this, args );
				};
			return function() {
				var __super = this._super,
					__superApply = this._superApply,
					returnValue;

				this._super = _super;
				this._superApply = _superApply;

				returnValue = value.apply( this, arguments );

				this._super = __super;
				this._superApply = __superApply;

				return returnValue;
			};
		})();
	});
	constructor.prototype = $.widget.extend( basePrototype, {
		// TODO: remove support for widgetEventPrefix
		// always use the name + a colon as the prefix, e.g., draggable:start
		// don't prefix for widgets that aren't DOM-based
		widgetEventPrefix: existingConstructor ? (basePrototype.widgetEventPrefix || name) : name
	}, proxiedPrototype, {
		constructor: constructor,
		namespace: namespace,
		widgetName: name,
		widgetFullName: fullName
	});

	// If this widget is being redefined then we need to find all widgets that
	// are inheriting from it and redefine all of them so that they inherit from
	// the new version of this widget. We're essentially trying to replace one
	// level in the prototype chain.
	if ( existingConstructor ) {
		$.each( existingConstructor._childConstructors, function( i, child ) {
			var childPrototype = child.prototype;

			// redefine the child widget using the same prototype that was
			// originally used, but inherit from the new version of the base
			$.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto );
		});
		// remove the list of existing child constructors from the old constructor
		// so the old child constructors can be garbage collected
		delete existingConstructor._childConstructors;
	} else {
		base._childConstructors.push( constructor );
	}

	$.widget.bridge( name, constructor );
};

$.widget.extend = function( target ) {
	var input = slice.call( arguments, 1 ),
		inputIndex = 0,
		inputLength = input.length,
		key,
		value;
	for ( ; inputIndex < inputLength; inputIndex++ ) {
		for ( key in input[ inputIndex ] ) {
			value = input[ inputIndex ][ key ];
			if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) {
				// Clone objects
				if ( $.isPlainObject( value ) ) {
					target[ key ] = $.isPlainObject( target[ key ] ) ?
						$.widget.extend( {}, target[ key ], value ) :
						// Don't extend strings, arrays, etc. with objects
						$.widget.extend( {}, value );
				// Copy everything else by reference
				} else {
					target[ key ] = value;
				}
			}
		}
	}
	return target;
};

$.widget.bridge = function( name, object ) {
	var fullName = object.prototype.widgetFullName || name;
	$.fn[ name ] = function( options ) {
		var isMethodCall = typeof options === "string",
			args = slice.call( arguments, 1 ),
			returnValue = this;

		// allow multiple hashes to be passed on init
		options = !isMethodCall && args.length ?
			$.widget.extend.apply( null, [ options ].concat(args) ) :
			options;

		if ( isMethodCall ) {
			this.each(function() {
				var methodValue,
					instance = $.data( this, fullName );
				if ( !instance ) {
					return $.error( "cannot call methods on " + name + " prior to initialization; " +
						"attempted to call method '" + options + "'" );
				}
				if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) {
					return $.error( "no such method '" + options + "' for " + name + " widget instance" );
				}
				methodValue = instance[ options ].apply( instance, args );
				if ( methodValue !== instance && methodValue !== undefined ) {
					returnValue = methodValue && methodValue.jquery ?
						returnValue.pushStack( methodValue.get() ) :
						methodValue;
					return false;
				}
			});
		} else {
			this.each(function() {
				var instance = $.data( this, fullName );
				if ( instance ) {
					instance.option( options || {} )._init();
				} else {
					$.data( this, fullName, new object( options, this ) );
				}
			});
		}

		return returnValue;
	};
};

$.Widget = function( /* options, element */ ) {};
$.Widget._childConstructors = [];

$.Widget.prototype = {
	widgetName: "widget",
	widgetEventPrefix: "",
	defaultElement: "<div>",
	options: {
		disabled: false,

		// callbacks
		create: null
	},
	_createWidget: function( options, element ) {
		element = $( element || this.defaultElement || this )[ 0 ];
		this.element = $( element );
		this.uuid = uuid++;
		this.eventNamespace = "." + this.widgetName + this.uuid;
		this.options = $.widget.extend( {},
			this.options,
			this._getCreateOptions(),
			options );

		this.bindings = $();
		this.hoverable = $();
		this.focusable = $();

		if ( element !== this ) {
			$.data( element, this.widgetFullName, this );
			this._on( true, this.element, {
				remove: function( event ) {
					if ( event.target === element ) {
						this.destroy();
					}
				}
			});
			this.document = $( element.style ?
				// element within the document
				element.ownerDocument :
				// element is window or document
				element.document || element );
			this.window = $( this.document[0].defaultView || this.document[0].parentWindow );
		}

		this._create();
		this._trigger( "create", null, this._getCreateEventData() );
		this._init();
	},
	_getCreateOptions: $.noop,
	_getCreateEventData: $.noop,
	_create: $.noop,
	_init: $.noop,

	destroy: function() {
		this._destroy();
		// we can probably remove the unbind calls in 2.0
		// all event bindings should go through this._on()
		this.element
			.unbind( this.eventNamespace )
			// 1.9 BC for #7810
			// TODO remove dual storage
			.removeData( this.widgetName )
			.removeData( this.widgetFullName )
			// support: jquery <1.6.3
			// http://bugs.jquery.com/ticket/9413
			.removeData( $.camelCase( this.widgetFullName ) );
		this.widget()
			.unbind( this.eventNamespace )
			.removeAttr( "aria-disabled" )
			.removeClass(
				this.widgetFullName + "-disabled " +
				"ui-state-disabled" );

		// clean up events and states
		this.bindings.unbind( this.eventNamespace );
		this.hoverable.removeClass( "ui-state-hover" );
		this.focusable.removeClass( "ui-state-focus" );
	},
	_destroy: $.noop,

	widget: function() {
		return this.element;
	},

	option: function( key, value ) {
		var options = key,
			parts,
			curOption,
			i;

		if ( arguments.length === 0 ) {
			// don't return a reference to the internal hash
			return $.widget.extend( {}, this.options );
		}

		if ( typeof key === "string" ) {
			// handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
			options = {};
			parts = key.split( "." );
			key = parts.shift();
			if ( parts.length ) {
				curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );
				for ( i = 0; i < parts.length - 1; i++ ) {
					curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};
					curOption = curOption[ parts[ i ] ];
				}
				key = parts.pop();
				if ( arguments.length === 1 ) {
					return curOption[ key ] === undefined ? null : curOption[ key ];
				}
				curOption[ key ] = value;
			} else {
				if ( arguments.length === 1 ) {
					return this.options[ key ] === undefined ? null : this.options[ key ];
				}
				options[ key ] = value;
			}
		}

		this._setOptions( options );

		return this;
	},
	_setOptions: function( options ) {
		var key;

		for ( key in options ) {
			this._setOption( key, options[ key ] );
		}

		return this;
	},
	_setOption: function( key, value ) {
		this.options[ key ] = value;

		if ( key === "disabled" ) {
			this.widget()
				.toggleClass( this.widgetFullName + "-disabled ui-state-disabled", !!value )
				.attr( "aria-disabled", value );
			this.hoverable.removeClass( "ui-state-hover" );
			this.focusable.removeClass( "ui-state-focus" );
		}

		return this;
	},

	enable: function() {
		return this._setOption( "disabled", false );
	},
	disable: function() {
		return this._setOption( "disabled", true );
	},

	_on: function( suppressDisabledCheck, element, handlers ) {
		var delegateElement,
			instance = this;

		// no suppressDisabledCheck flag, shuffle arguments
		if ( typeof suppressDisabledCheck !== "boolean" ) {
			handlers = element;
			element = suppressDisabledCheck;
			suppressDisabledCheck = false;
		}

		// no element argument, shuffle and use this.element
		if ( !handlers ) {
			handlers = element;
			element = this.element;
			delegateElement = this.widget();
		} else {
			// accept selectors, DOM elements
			element = delegateElement = $( element );
			this.bindings = this.bindings.add( element );
		}

		$.each( handlers, function( event, handler ) {
			function handlerProxy() {
				// allow widgets to customize the disabled handling
				// - disabled as an array instead of boolean
				// - disabled class as method for disabling individual parts
				if ( !suppressDisabledCheck &&
						( instance.options.disabled === true ||
							$( this ).hasClass( "ui-state-disabled" ) ) ) {
					return;
				}
				return ( typeof handler === "string" ? instance[ handler ] : handler )
					.apply( instance, arguments );
			}

			// copy the guid so direct unbinding works
			if ( typeof handler !== "string" ) {
				handlerProxy.guid = handler.guid =
					handler.guid || handlerProxy.guid || $.guid++;
			}

			var match = event.match( /^(\w+)\s*(.*)$/ ),
				eventName = match[1] + instance.eventNamespace,
				selector = match[2];
			if ( selector ) {
				delegateElement.delegate( selector, eventName, handlerProxy );
			} else {
				element.bind( eventName, handlerProxy );
			}
		});
	},

	_off: function( element, eventName ) {
		eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) + this.eventNamespace;
		element.unbind( eventName ).undelegate( eventName );
	},

	_delay: function( handler, delay ) {
		function handlerProxy() {
			return ( typeof handler === "string" ? instance[ handler ] : handler )
				.apply( instance, arguments );
		}
		var instance = this;
		return setTimeout( handlerProxy, delay || 0 );
	},

	_hoverable: function( element ) {
		this.hoverable = this.hoverable.add( element );
		this._on( element, {
			mouseenter: function( event ) {
				$( event.currentTarget ).addClass( "ui-state-hover" );
			},
			mouseleave: function( event ) {
				$( event.currentTarget ).removeClass( "ui-state-hover" );
			}
		});
	},

	_focusable: function( element ) {
		this.focusable = this.focusable.add( element );
		this._on( element, {
			focusin: function( event ) {
				$( event.currentTarget ).addClass( "ui-state-focus" );
			},
			focusout: function( event ) {
				$( event.currentTarget ).removeClass( "ui-state-focus" );
			}
		});
	},

	_trigger: function( type, event, data ) {
		var prop, orig,
			callback = this.options[ type ];

		data = data || {};
		event = $.Event( event );
		event.type = ( type === this.widgetEventPrefix ?
			type :
			this.widgetEventPrefix + type ).toLowerCase();
		// the original event may come from any element
		// so we need to reset the target on the new event
		event.target = this.element[ 0 ];

		// copy original event properties over to the new event
		orig = event.originalEvent;
		if ( orig ) {
			for ( prop in orig ) {
				if ( !( prop in event ) ) {
					event[ prop ] = orig[ prop ];
				}
			}
		}

		this.element.trigger( event, data );
		return !( $.isFunction( callback ) &&
			callback.apply( this.element[0], [ event ].concat( data ) ) === false ||
			event.isDefaultPrevented() );
	}
};

$.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {
	$.Widget.prototype[ "_" + method ] = function( element, options, callback ) {
		if ( typeof options === "string" ) {
			options = { effect: options };
		}
		var hasOptions,
			effectName = !options ?
				method :
				options === true || typeof options === "number" ?
					defaultEffect :
					options.effect || defaultEffect;
		options = options || {};
		if ( typeof options === "number" ) {
			options = { duration: options };
		}
		hasOptions = !$.isEmptyObject( options );
		options.complete = callback;
		if ( options.delay ) {
			element.delay( options.delay );
		}
		if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) {
			element[ method ]( options );
		} else if ( effectName !== method && element[ effectName ] ) {
			element[ effectName ]( options.duration, options.easing, callback );
		} else {
			element.queue(function( next ) {
				$( this )[ method ]();
				if ( callback ) {
					callback.call( element[ 0 ] );
				}
				next();
			});
		}
	};
});

})( jQuery );
(function( $, undefined ) {

$.ui = $.ui || {};

var cachedScrollbarWidth,
	max = Math.max,
	abs = Math.abs,
	round = Math.round,
	rhorizontal = /left|center|right/,
	rvertical = /top|center|bottom/,
	roffset = /[\+\-]\d+(\.[\d]+)?%?/,
	rposition = /^\w+/,
	rpercent = /%$/,
	_position = $.fn.position;

function getOffsets( offsets, width, height ) {
	return [
		parseFloat( offsets[ 0 ] ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ),
		parseFloat( offsets[ 1 ] ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 )
	];
}

function parseCss( element, property ) {
	return parseInt( $.css( element, property ), 10 ) || 0;
}

function getDimensions( elem ) {
	var raw = elem[0];
	if ( raw.nodeType === 9 ) {
		return {
			width: elem.width(),
			height: elem.height(),
			offset: { top: 0, left: 0 }
		};
	}
	if ( $.isWindow( raw ) ) {
		return {
			width: elem.width(),
			height: elem.height(),
			offset: { top: elem.scrollTop(), left: elem.scrollLeft() }
		};
	}
	if ( raw.preventDefault ) {
		return {
			width: 0,
			height: 0,
			offset: { top: raw.pageY, left: raw.pageX }
		};
	}
	return {
		width: elem.outerWidth(),
		height: elem.outerHeight(),
		offset: elem.offset()
	};
}

$.position = {
	scrollbarWidth: function() {
		if ( cachedScrollbarWidth !== undefined ) {
			return cachedScrollbarWidth;
		}
		var w1, w2,
			div = $( "<div style='display:block;position:absolute;width:50px;height:50px;overflow:hidden;'><div style='height:100px;width:auto;'></div></div>" ),
			innerDiv = div.children()[0];

		$( "body" ).append( div );
		w1 = innerDiv.offsetWidth;
		div.css( "overflow", "scroll" );

		w2 = innerDiv.offsetWidth;

		if ( w1 === w2 ) {
			w2 = div[0].clientWidth;
		}

		div.remove();

		return (cachedScrollbarWidth = w1 - w2);
	},
	getScrollInfo: function( within ) {
		var overflowX = within.isWindow || within.isDocument ? "" :
				within.element.css( "overflow-x" ),
			overflowY = within.isWindow || within.isDocument ? "" :
				within.element.css( "overflow-y" ),
			hasOverflowX = overflowX === "scroll" ||
				( overflowX === "auto" && within.width < within.element[0].scrollWidth ),
			hasOverflowY = overflowY === "scroll" ||
				( overflowY === "auto" && within.height < within.element[0].scrollHeight );
		return {
			width: hasOverflowY ? $.position.scrollbarWidth() : 0,
			height: hasOverflowX ? $.position.scrollbarWidth() : 0
		};
	},
	getWithinInfo: function( element ) {
		var withinElement = $( element || window ),
			isWindow = $.isWindow( withinElement[0] ),
			isDocument = !!withinElement[ 0 ] && withinElement[ 0 ].nodeType === 9;
		return {
			element: withinElement,
			isWindow: isWindow,
			isDocument: isDocument,
			offset: withinElement.offset() || { left: 0, top: 0 },
			scrollLeft: withinElement.scrollLeft(),
			scrollTop: withinElement.scrollTop(),
			width: isWindow ? withinElement.width() : withinElement.outerWidth(),
			height: isWindow ? withinElement.height() : withinElement.outerHeight()
		};
	}
};

$.fn.position = function( options ) {
	if ( !options || !options.of ) {
		return _position.apply( this, arguments );
	}

	// make a copy, we don't want to modify arguments
	options = $.extend( {}, options );

	var atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions,
		target = $( options.of ),
		within = $.position.getWithinInfo( options.within ),
		scrollInfo = $.position.getScrollInfo( within ),
		collision = ( options.collision || "flip" ).split( " " ),
		offsets = {};

	dimensions = getDimensions( target );
	if ( target[0].preventDefault ) {
		// force left top to allow flipping
		options.at = "left top";
	}
	targetWidth = dimensions.width;
	targetHeight = dimensions.height;
	targetOffset = dimensions.offset;
	// clone to reuse original targetOffset later
	basePosition = $.extend( {}, targetOffset );

	// force my and at to have valid horizontal and vertical positions
	// if a value is missing or invalid, it will be converted to center
	$.each( [ "my", "at" ], function() {
		var pos = ( options[ this ] || "" ).split( " " ),
			horizontalOffset,
			verticalOffset;

		if ( pos.length === 1) {
			pos = rhorizontal.test( pos[ 0 ] ) ?
				pos.concat( [ "center" ] ) :
				rvertical.test( pos[ 0 ] ) ?
					[ "center" ].concat( pos ) :
					[ "center", "center" ];
		}
		pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center";
		pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center";

		// calculate offsets
		horizontalOffset = roffset.exec( pos[ 0 ] );
		verticalOffset = roffset.exec( pos[ 1 ] );
		offsets[ this ] = [
			horizontalOffset ? horizontalOffset[ 0 ] : 0,
			verticalOffset ? verticalOffset[ 0 ] : 0
		];

		// reduce to just the positions without the offsets
		options[ this ] = [
			rposition.exec( pos[ 0 ] )[ 0 ],
			rposition.exec( pos[ 1 ] )[ 0 ]
		];
	});

	// normalize collision option
	if ( collision.length === 1 ) {
		collision[ 1 ] = collision[ 0 ];
	}

	if ( options.at[ 0 ] === "right" ) {
		basePosition.left += targetWidth;
	} else if ( options.at[ 0 ] === "center" ) {
		basePosition.left += targetWidth / 2;
	}

	if ( options.at[ 1 ] === "bottom" ) {
		basePosition.top += targetHeight;
	} else if ( options.at[ 1 ] === "center" ) {
		basePosition.top += targetHeight / 2;
	}

	atOffset = getOffsets( offsets.at, targetWidth, targetHeight );
	basePosition.left += atOffset[ 0 ];
	basePosition.top += atOffset[ 1 ];

	return this.each(function() {
		var collisionPosition, using,
			elem = $( this ),
			elemWidth = elem.outerWidth(),
			elemHeight = elem.outerHeight(),
			marginLeft = parseCss( this, "marginLeft" ),
			marginTop = parseCss( this, "marginTop" ),
			collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) + scrollInfo.width,
			collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) + scrollInfo.height,
			position = $.extend( {}, basePosition ),
			myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() );

		if ( options.my[ 0 ] === "right" ) {
			position.left -= elemWidth;
		} else if ( options.my[ 0 ] === "center" ) {
			position.left -= elemWidth / 2;
		}

		if ( options.my[ 1 ] === "bottom" ) {
			position.top -= elemHeight;
		} else if ( options.my[ 1 ] === "center" ) {
			position.top -= elemHeight / 2;
		}

		position.left += myOffset[ 0 ];
		position.top += myOffset[ 1 ];

		// if the browser doesn't support fractions, then round for consistent results
		if ( !$.support.offsetFractions ) {
			position.left = round( position.left );
			position.top = round( position.top );
		}

		collisionPosition = {
			marginLeft: marginLeft,
			marginTop: marginTop
		};

		$.each( [ "left", "top" ], function( i, dir ) {
			if ( $.ui.position[ collision[ i ] ] ) {
				$.ui.position[ collision[ i ] ][ dir ]( position, {
					targetWidth: targetWidth,
					targetHeight: targetHeight,
					elemWidth: elemWidth,
					elemHeight: elemHeight,
					collisionPosition: collisionPosition,
					collisionWidth: collisionWidth,
					collisionHeight: collisionHeight,
					offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ],
					my: options.my,
					at: options.at,
					within: within,
					elem : elem
				});
			}
		});

		if ( options.using ) {
			// adds feedback as second argument to using callback, if present
			using = function( props ) {
				var left = targetOffset.left - position.left,
					right = left + targetWidth - elemWidth,
					top = targetOffset.top - position.top,
					bottom = top + targetHeight - elemHeight,
					feedback = {
						target: {
							element: target,
							left: targetOffset.left,
							top: targetOffset.top,
							width: targetWidth,
							height: targetHeight
						},
						element: {
							element: elem,
							left: position.left,
							top: position.top,
							width: elemWidth,
							height: elemHeight
						},
						horizontal: right < 0 ? "left" : left > 0 ? "right" : "center",
						vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle"
					};
				if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) {
					feedback.horizontal = "center";
				}
				if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) {
					feedback.vertical = "middle";
				}
				if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) {
					feedback.important = "horizontal";
				} else {
					feedback.important = "vertical";
				}
				options.using.call( this, props, feedback );
			};
		}

		elem.offset( $.extend( position, { using: using } ) );
	});
};

$.ui.position = {
	fit: {
		left: function( position, data ) {
			var within = data.within,
				withinOffset = within.isWindow ? within.scrollLeft : within.offset.left,
				outerWidth = within.width,
				collisionPosLeft = position.left - data.collisionPosition.marginLeft,
				overLeft = withinOffset - collisionPosLeft,
				overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset,
				newOverRight;

			// element is wider than within
			if ( data.collisionWidth > outerWidth ) {
				// element is initially over the left side of within
				if ( overLeft > 0 && overRight <= 0 ) {
					newOverRight = position.left + overLeft + data.collisionWidth - outerWidth - withinOffset;
					position.left += overLeft - newOverRight;
				// element is initially over right side of within
				} else if ( overRight > 0 && overLeft <= 0 ) {
					position.left = withinOffset;
				// element is initially over both left and right sides of within
				} else {
					if ( overLeft > overRight ) {
						position.left = withinOffset + outerWidth - data.collisionWidth;
					} else {
						position.left = withinOffset;
					}
				}
			// too far left -> align with left edge
			} else if ( overLeft > 0 ) {
				position.left += overLeft;
			// too far right -> align with right edge
			} else if ( overRight > 0 ) {
				position.left -= overRight;
			// adjust based on position and margin
			} else {
				position.left = max( position.left - collisionPosLeft, position.left );
			}
		},
		top: function( position, data ) {
			var within = data.within,
				withinOffset = within.isWindow ? within.scrollTop : within.offset.top,
				outerHeight = data.within.height,
				collisionPosTop = position.top - data.collisionPosition.marginTop,
				overTop = withinOffset - collisionPosTop,
				overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset,
				newOverBottom;

			// element is taller than within
			if ( data.collisionHeight > outerHeight ) {
				// element is initially over the top of within
				if ( overTop > 0 && overBottom <= 0 ) {
					newOverBottom = position.top + overTop + data.collisionHeight - outerHeight - withinOffset;
					position.top += overTop - newOverBottom;
				// element is initially over bottom of within
				} else if ( overBottom > 0 && overTop <= 0 ) {
					position.top = withinOffset;
				// element is initially over both top and bottom of within
				} else {
					if ( overTop > overBottom ) {
						position.top = withinOffset + outerHeight - data.collisionHeight;
					} else {
						position.top = withinOffset;
					}
				}
			// too far up -> align with top
			} else if ( overTop > 0 ) {
				position.top += overTop;
			// too far down -> align with bottom edge
			} else if ( overBottom > 0 ) {
				position.top -= overBottom;
			// adjust based on position and margin
			} else {
				position.top = max( position.top - collisionPosTop, position.top );
			}
		}
	},
	flip: {
		left: function( position, data ) {
			var within = data.within,
				withinOffset = within.offset.left + within.scrollLeft,
				outerWidth = within.width,
				offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left,
				collisionPosLeft = position.left - data.collisionPosition.marginLeft,
				overLeft = collisionPosLeft - offsetLeft,
				overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft,
				myOffset = data.my[ 0 ] === "left" ?
					-data.elemWidth :
					data.my[ 0 ] === "right" ?
						data.elemWidth :
						0,
				atOffset = data.at[ 0 ] === "left" ?
					data.targetWidth :
					data.at[ 0 ] === "right" ?
						-data.targetWidth :
						0,
				offset = -2 * data.offset[ 0 ],
				newOverRight,
				newOverLeft;

			if ( overLeft < 0 ) {
				newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth - outerWidth - withinOffset;
				if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) {
					position.left += myOffset + atOffset + offset;
				}
			}
			else if ( overRight > 0 ) {
				newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset + atOffset + offset - offsetLeft;
				if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) {
					position.left += myOffset + atOffset + offset;
				}
			}
		},
		top: function( position, data ) {
			var within = data.within,
				withinOffset = within.offset.top + within.scrollTop,
				outerHeight = within.height,
				offsetTop = within.isWindow ? within.scrollTop : within.offset.top,
				collisionPosTop = position.top - data.collisionPosition.marginTop,
				overTop = collisionPosTop - offsetTop,
				overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop,
				top = data.my[ 1 ] === "top",
				myOffset = top ?
					-data.elemHeight :
					data.my[ 1 ] === "bottom" ?
						data.elemHeight :
						0,
				atOffset = data.at[ 1 ] === "top" ?
					data.targetHeight :
					data.at[ 1 ] === "bottom" ?
						-data.targetHeight :
						0,
				offset = -2 * data.offset[ 1 ],
				newOverTop,
				newOverBottom;
			if ( overTop < 0 ) {
				newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight - outerHeight - withinOffset;
				if ( ( position.top + myOffset + atOffset + offset) > overTop && ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) ) {
					position.top += myOffset + atOffset + offset;
				}
			}
			else if ( overBottom > 0 ) {
				newOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset + offset - offsetTop;
				if ( ( position.top + myOffset + atOffset + offset) > overBottom && ( newOverTop > 0 || abs( newOverTop ) < overBottom ) ) {
					position.top += myOffset + atOffset + offset;
				}
			}
		}
	},
	flipfit: {
		left: function() {
			$.ui.position.flip.left.apply( this, arguments );
			$.ui.position.fit.left.apply( this, arguments );
		},
		top: function() {
			$.ui.position.flip.top.apply( this, arguments );
			$.ui.position.fit.top.apply( this, arguments );
		}
	}
};

// fraction support test
(function () {
	var testElement, testElementParent, testElementStyle, offsetLeft, i,
		body = document.getElementsByTagName( "body" )[ 0 ],
		div = document.createElement( "div" );

	//Create a "fake body" for testing based on method used in jQuery.support
	testElement = document.createElement( body ? "div" : "body" );
	testElementStyle = {
		visibility: "hidden",
		width: 0,
		height: 0,
		border: 0,
		margin: 0,
		background: "none"
	};
	if ( body ) {
		$.extend( testElementStyle, {
			position: "absolute",
			left: "-1000px",
			top: "-1000px"
		});
	}
	for ( i in testElementStyle ) {
		testElement.style[ i ] = testElementStyle[ i ];
	}
	testElement.appendChild( div );
	testElementParent = body || document.documentElement;
	testElementParent.insertBefore( testElement, testElementParent.firstChild );

	div.style.cssText = "position: absolute; left: 10.7432222px;";

	offsetLeft = $( div ).offset().left;
	$.support.offsetFractions = offsetLeft > 10 && offsetLeft < 11;

	testElement.innerHTML = "";
	testElementParent.removeChild( testElement );
})();

}( jQuery ) );
(function( $, undefined ) {

$.widget( "ui.autocomplete", {
	version: "1.10.4",
	defaultElement: "<input>",
	options: {
		appendTo: null,
		autoFocus: false,
		delay: 300,
		minLength: 1,
		position: {
			my: "left top",
			at: "left bottom",
			collision: "none"
		},
		source: null,

		// callbacks
		change: null,
		close: null,
		focus: null,
		open: null,
		response: null,
		search: null,
		select: null
	},

	requestIndex: 0,
	pending: 0,

	_create: function() {
		// Some browsers only repeat keydown events, not keypress events,
		// so we use the suppressKeyPress flag to determine if we've already
		// handled the keydown event. #7269
		// Unfortunately the code for & in keypress is the same as the up arrow,
		// so we use the suppressKeyPressRepeat flag to avoid handling keypress
		// events when we know the keydown event was used to modify the
		// search term. #7799
		var suppressKeyPress, suppressKeyPressRepeat, suppressInput,
			nodeName = this.element[0].nodeName.toLowerCase(),
			isTextarea = nodeName === "textarea",
			isInput = nodeName === "input";

		this.isMultiLine =
			// Textareas are always multi-line
			isTextarea ? true :
			// Inputs are always single-line, even if inside a contentEditable element
			// IE also treats inputs as contentEditable
			isInput ? false :
			// All other element types are determined by whether or not they're contentEditable
			this.element.prop( "isContentEditable" );

		this.valueMethod = this.element[ isTextarea || isInput ? "val" : "text" ];
		this.isNewMenu = true;

		this.element
			.addClass( "ui-autocomplete-input" )
			.attr( "autocomplete", "off" );

		this._on( this.element, {
			keydown: function( event ) {
				if ( this.element.prop( "readOnly" ) ) {
					suppressKeyPress = true;
					suppressInput = true;
					suppressKeyPressRepeat = true;
					return;
				}

				suppressKeyPress = false;
				suppressInput = false;
				suppressKeyPressRepeat = false;
				var keyCode = $.ui.keyCode;
				switch( event.keyCode ) {
				case keyCode.PAGE_UP:
					suppressKeyPress = true;
					this._move( "previousPage", event );
					break;
				case keyCode.PAGE_DOWN:
					suppressKeyPress = true;
					this._move( "nextPage", event );
					break;
				case keyCode.UP:
					suppressKeyPress = true;
					this._keyEvent( "previous", event );
					break;
				case keyCode.DOWN:
					suppressKeyPress = true;
					this._keyEvent( "next", event );
					break;
				case keyCode.ENTER:
				case keyCode.NUMPAD_ENTER:
					// when menu is open and has focus
					if ( this.menu.active ) {
						// #6055 - Opera still allows the keypress to occur
						// which causes forms to submit
						suppressKeyPress = true;
						event.preventDefault();
						this.menu.select( event );
					}
					break;
				case keyCode.TAB:
					if ( this.menu.active ) {
						this.menu.select( event );
					}
					break;
				case keyCode.ESCAPE:
					if ( this.menu.element.is( ":visible" ) ) {
						this._value( this.term );
						this.close( event );
						// Different browsers have different default behavior for escape
						// Single press can mean undo or clear
						// Double press in IE means clear the whole form
						event.preventDefault();
					}
					break;
				default:
					suppressKeyPressRepeat = true;
					// search timeout should be triggered before the input value is changed
					this._searchTimeout( event );
					break;
				}
			},
			keypress: function( event ) {
				if ( suppressKeyPress ) {
					suppressKeyPress = false;
					if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
						event.preventDefault();
					}
					return;
				}
				if ( suppressKeyPressRepeat ) {
					return;
				}

				// replicate some key handlers to allow them to repeat in Firefox and Opera
				var keyCode = $.ui.keyCode;
				switch( event.keyCode ) {
				case keyCode.PAGE_UP:
					this._move( "previousPage", event );
					break;
				case keyCode.PAGE_DOWN:
					this._move( "nextPage", event );
					break;
				case keyCode.UP:
					this._keyEvent( "previous", event );
					break;
				case keyCode.DOWN:
					this._keyEvent( "next", event );
					break;
				}
			},
			input: function( event ) {
				if ( suppressInput ) {
					suppressInput = false;
					event.preventDefault();
					return;
				}
				this._searchTimeout( event );
			},
			focus: function() {
				this.selectedItem = null;
				this.previous = this._value();
			},
			blur: function( event ) {
				if ( this.cancelBlur ) {
					delete this.cancelBlur;
					return;
				}

				clearTimeout( this.searching );
				this.close( event );
				this._change( event );
			}
		});

		this._initSource();
		this.menu = $( "<ul>" )
			.addClass( "ui-autocomplete ui-front" )
			.appendTo( this._appendTo() )
			.menu({
				// disable ARIA support, the live region takes care of that
				role: null
			})
			.hide()
			.data( "ui-menu" );

		this._on( this.menu.element, {
			mousedown: function( event ) {
				// prevent moving focus out of the text field
				event.preventDefault();

				// IE doesn't prevent moving focus even with event.preventDefault()
				// so we set a flag to know when we should ignore the blur event
				this.cancelBlur = true;
				this._delay(function() {
					delete this.cancelBlur;
				});

				// clicking on the scrollbar causes focus to shift to the body
				// but we can't detect a mouseup or a click immediately afterward
				// so we have to track the next mousedown and close the menu if
				// the user clicks somewhere outside of the autocomplete
				var menuElement = this.menu.element[ 0 ];
				if ( !$( event.target ).closest( ".ui-menu-item" ).length ) {
					this._delay(function() {
						var that = this;
						this.document.one( "mousedown", function( event ) {
							if ( event.target !== that.element[ 0 ] &&
									event.target !== menuElement &&
									!$.contains( menuElement, event.target ) ) {
								that.close();
							}
						});
					});
				}
			},
			menufocus: function( event, ui ) {
				// support: Firefox
				// Prevent accidental activation of menu items in Firefox (#7024 #9118)
				if ( this.isNewMenu ) {
					this.isNewMenu = false;
					if ( event.originalEvent && /^mouse/.test( event.originalEvent.type ) ) {
						this.menu.blur();

						this.document.one( "mousemove", function() {
							$( event.target ).trigger( event.originalEvent );
						});

						return;
					}
				}

				var item = ui.item.data( "ui-autocomplete-item" );
				if ( false !== this._trigger( "focus", event, { item: item } ) ) {
					// use value to match what will end up in the input, if it was a key event
					if ( event.originalEvent && /^key/.test( event.originalEvent.type ) ) {
						this._value( item.value );
					}
				} else {
					// Normally the input is populated with the item's value as the
					// menu is navigated, causing screen readers to notice a change and
					// announce the item. Since the focus event was canceled, this doesn't
					// happen, so we update the live region so that screen readers can
					// still notice the change and announce it.
					this.liveRegion.text( item.value );
				}
			},
			menuselect: function( event, ui ) {
				var item = ui.item.data( "ui-autocomplete-item" ),
					previous = this.previous;

				// only trigger when focus was lost (click on menu)
				if ( this.element[0] !== this.document[0].activeElement ) {
					this.element.focus();
					this.previous = previous;
					// #6109 - IE triggers two focus events and the second
					// is asynchronous, so we need to reset the previous
					// term synchronously and asynchronously :-(
					this._delay(function() {
						this.previous = previous;
						this.selectedItem = item;
					});
				}

				if ( false !== this._trigger( "select", event, { item: item } ) ) {
					this._value( item.value );
				}
				// reset the term after the select event
				// this allows custom select handling to work properly
				this.term = this._value();

				this.close( event );
				this.selectedItem = item;
			}
		});

		this.liveRegion = $( "<span>", {
				role: "status",
				"aria-live": "polite"
			})
			.addClass( "ui-helper-hidden-accessible" )
			.insertBefore( this.element );

		// turning off autocomplete prevents the browser from remembering the
		// value when navigating through history, so we re-enable autocomplete
		// if the page is unloaded before the widget is destroyed. #7790
		this._on( this.window, {
			beforeunload: function() {
				this.element.removeAttr( "autocomplete" );
			}
		});
	},

	_destroy: function() {
		clearTimeout( this.searching );
		this.element
			.removeClass( "ui-autocomplete-input" )
			.removeAttr( "autocomplete" );
		this.menu.element.remove();
		this.liveRegion.remove();
	},

	_setOption: function( key, value ) {
		this._super( key, value );
		if ( key === "source" ) {
			this._initSource();
		}
		if ( key === "appendTo" ) {
			this.menu.element.appendTo( this._appendTo() );
		}
		if ( key === "disabled" && value && this.xhr ) {
			this.xhr.abort();
		}
	},

	_appendTo: function() {
		var element = this.options.appendTo;

		if ( element ) {
			element = element.jquery || element.nodeType ?
				$( element ) :
				this.document.find( element ).eq( 0 );
		}

		if ( !element ) {
			element = this.element.closest( ".ui-front" );
		}

		if ( !element.length ) {
			element = this.document[0].body;
		}

		return element;
	},

	_initSource: function() {
		var array, url,
			that = this;
		if ( $.isArray(this.options.source) ) {
			array = this.options.source;
			this.source = function( request, response ) {
				response( $.ui.autocomplete.filter( array, request.term ) );
			};
		} else if ( typeof this.options.source === "string" ) {
			url = this.options.source;
			this.source = function( request, response ) {
				if ( that.xhr ) {
					that.xhr.abort();
				}
				that.xhr = $.ajax({
					url: url,
					data: request,
					dataType: "json",
					success: function( data ) {
						response( data );
					},
					error: function() {
						response( [] );
					}
				});
			};
		} else {
			this.source = this.options.source;
		}
	},

	_searchTimeout: function( event ) {
		clearTimeout( this.searching );
		this.searching = this._delay(function() {
			// only search if the value has changed
			if ( this.term !== this._value() ) {
				this.selectedItem = null;
				this.search( null, event );
			}
		}, this.options.delay );
	},

	search: function( value, event ) {
		value = value != null ? value : this._value();

		// always save the actual value, not the one passed as an argument
		this.term = this._value();

		if ( value.length < this.options.minLength ) {
			return this.close( event );
		}

		if ( this._trigger( "search", event ) === false ) {
			return;
		}

		return this._search( value );
	},

	_search: function( value ) {
		this.pending++;
		this.element.addClass( "ui-autocomplete-loading" );
		this.cancelSearch = false;

		this.source( { term: value }, this._response() );
	},

	_response: function() {
		var index = ++this.requestIndex;

		return $.proxy(function( content ) {
			if ( index === this.requestIndex ) {
				this.__response( content );
			}

			this.pending--;
			if ( !this.pending ) {
				this.element.removeClass( "ui-autocomplete-loading" );
			}
		}, this );
	},

	__response: function( content ) {
		if ( content ) {
			content = this._normalize( content );
		}
		this._trigger( "response", null, { content: content } );
		if ( !this.options.disabled && content && content.length && !this.cancelSearch ) {
			this._suggest( content );
			this._trigger( "open" );
		} else {
			// use ._close() instead of .close() so we don't cancel future searches
			this._close();
		}
	},

	close: function( event ) {
		this.cancelSearch = true;
		this._close( event );
	},

	_close: function( event ) {
		if ( this.menu.element.is( ":visible" ) ) {
			this.menu.element.hide();
			this.menu.blur();
			this.isNewMenu = true;
			this._trigger( "close", event );
		}
	},

	_change: function( event ) {
		if ( this.previous !== this._value() ) {
			this._trigger( "change", event, { item: this.selectedItem } );
		}
	},

	_normalize: function( items ) {
		// assume all items have the right format when the first item is complete
		if ( items.length && items[0].label && items[0].value ) {
			return items;
		}
		return $.map( items, function( item ) {
			if ( typeof item === "string" ) {
				return {
					label: item,
					value: item
				};
			}
			return $.extend({
				label: item.label || item.value,
				value: item.value || item.label
			}, item );
		});
	},

	_suggest: function( items ) {
		var ul = this.menu.element.empty();
		this._renderMenu( ul, items );
		this.isNewMenu = true;
		this.menu.refresh();

		// size and position menu
		ul.show();
		this._resizeMenu();
		ul.position( $.extend({
			of: this.element
		}, this.options.position ));

		if ( this.options.autoFocus ) {
			this.menu.next();
		}
	},

	_resizeMenu: function() {
		var ul = this.menu.element;
		ul.outerWidth( Math.max(
			// Firefox wraps long text (possibly a rounding bug)
			// so we add 1px to avoid the wrapping (#7513)
			ul.width( "" ).outerWidth() + 1,
			this.element.outerWidth()
		) );
	},

	_renderMenu: function( ul, items ) {
		var that = this;
		$.each( items, function( index, item ) {
			that._renderItemData( ul, item );
		});
	},

	_renderItemData: function( ul, item ) {
		return this._renderItem( ul, item ).data( "ui-autocomplete-item", item );
	},

	_renderItem: function( ul, item ) {
		return $( "<li>" )
			.append( $( "<a>" ).text( item.label ) )
			.appendTo( ul );
	},

	_move: function( direction, event ) {
		if ( !this.menu.element.is( ":visible" ) ) {
			this.search( null, event );
			return;
		}
		if ( this.menu.isFirstItem() && /^previous/.test( direction ) ||
				this.menu.isLastItem() && /^next/.test( direction ) ) {
			this._value( this.term );
			this.menu.blur();
			return;
		}
		this.menu[ direction ]( event );
	},

	widget: function() {
		return this.menu.element;
	},

	_value: function() {
		return this.valueMethod.apply( this.element, arguments );
	},

	_keyEvent: function( keyEvent, event ) {
		if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
			this._move( keyEvent, event );

			// prevents moving cursor to beginning/end of the text field in some browsers
			event.preventDefault();
		}
	}
});

$.extend( $.ui.autocomplete, {
	escapeRegex: function( value ) {
		return value.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&");
	},
	filter: function(array, term) {
		var matcher = new RegExp( $.ui.autocomplete.escapeRegex(term), "i" );
		return $.grep( array, function(value) {
			return matcher.test( value.label || value.value || value );
		});
	}
});

// live region extension, adding a `messages` option
// NOTE: This is an experimental API. We are still investigating
// a full solution for string manipulation and internationalization.
$.widget( "ui.autocomplete", $.ui.autocomplete, {
	options: {
		messages: {
			noResults: function () {
				if ($("html").attr("lang") == "en") {
					return "No suggestions available.";
				} else {
					return "Inga sökförslag är tillgängliga.";

				}
			},
			results: function (amount) {
				if ($("html").attr("lang") == "en") {
					return amount + (amount > 1 ? " suggestions are" : " suggestion is") +
						" available, use up and down arrow keys to navigate.";
				} else {
					return amount + (amount > 1 ? " sökförslag är tillgängliga" : " sökförslag är tillgängligt") +
						", använd pil up och pil ner för att navigera.";
                }
			}
		}
	},

	__response: function( content ) {
		var message;
		this._superApply( arguments );
		if ( this.options.disabled || this.cancelSearch ) {
			return;
		}
		if ( content && content.length ) {
			message = this.options.messages.results( content.length );
		} else {
			message = this.options.messages.noResults;
		}
		this.liveRegion.text( message );
	}
});

}( jQuery ));
(function( $, undefined ) {

$.widget( "ui.menu", {
	version: "1.10.4",
	defaultElement: "<ul>",
	delay: 300,
	options: {
		icons: {
			submenu: "ui-icon-carat-1-e"
		},
		menus: "ul",
		position: {
			my: "left top",
			at: "right top"
		},
		role: "menu",

		// callbacks
		blur: null,
		focus: null,
		select: null
	},

	_create: function() {
		this.activeMenu = this.element;
		// flag used to prevent firing of the click handler
		// as the event bubbles up through nested menus
		this.mouseHandled = false;
		this.element
			.uniqueId()
			.addClass( "ui-menu ui-widget ui-widget-content ui-corner-all" )
			.toggleClass( "ui-menu-icons", !!this.element.find( ".ui-icon" ).length )
			.attr({
				role: this.options.role,
				tabIndex: 0
			})
			// need to catch all clicks on disabled menu
			// not possible through _on
			.bind( "click" + this.eventNamespace, $.proxy(function( event ) {
				if ( this.options.disabled ) {
					event.preventDefault();
				}
			}, this ));

		if ( this.options.disabled ) {
			this.element
				.addClass( "ui-state-disabled" )
				.attr( "aria-disabled", "true" );
		}

		this._on({
			// Prevent focus from sticking to links inside menu after clicking
			// them (focus should always stay on UL during navigation).
			"mousedown .ui-menu-item > a": function( event ) {
				event.preventDefault();
			},
			"click .ui-state-disabled > a": function( event ) {
				event.preventDefault();
			},
			"click .ui-menu-item:has(a)": function( event ) {
				var target = $( event.target ).closest( ".ui-menu-item" );
				if ( !this.mouseHandled && target.not( ".ui-state-disabled" ).length ) {
					this.select( event );

					// Only set the mouseHandled flag if the event will bubble, see #9469.
					if ( !event.isPropagationStopped() ) {
						this.mouseHandled = true;
					}

					// Open submenu on click
					if ( target.has( ".ui-menu" ).length ) {
						this.expand( event );
					} else if ( !this.element.is( ":focus" ) && $( this.document[ 0 ].activeElement ).closest( ".ui-menu" ).length ) {

						// Redirect focus to the menu
						this.element.trigger( "focus", [ true ] );

						// If the active item is on the top level, let it stay active.
						// Otherwise, blur the active item since it is no longer visible.
						if ( this.active && this.active.parents( ".ui-menu" ).length === 1 ) {
							clearTimeout( this.timer );
						}
					}
				}
			},
			"mouseenter .ui-menu-item": function( event ) {
				var target = $( event.currentTarget );
				// Remove ui-state-active class from siblings of the newly focused menu item
				// to avoid a jump caused by adjacent elements both having a class with a border
				target.siblings().children( ".ui-state-active" ).removeClass( "ui-state-active" );
				this.focus( event, target );
			},
			mouseleave: "collapseAll",
			"mouseleave .ui-menu": "collapseAll",
			focus: function( event, keepActiveItem ) {
				// If there's already an active item, keep it active
				// If not, activate the first item
				var item = this.active || this.element.children( ".ui-menu-item" ).eq( 0 );

				if ( !keepActiveItem ) {
					this.focus( event, item );
				}
			},
			blur: function( event ) {
				this._delay(function() {
					if ( !$.contains( this.element[0], this.document[0].activeElement ) ) {
						this.collapseAll( event );
					}
				});
			},
			keydown: "_keydown"
		});

		this.refresh();

		// Clicks outside of a menu collapse any open menus
		this._on( this.document, {
			click: function( event ) {
				if ( !$( event.target ).closest( ".ui-menu" ).length ) {
					this.collapseAll( event );
				}

				// Reset the mouseHandled flag
				this.mouseHandled = false;
			}
		});
	},

	_destroy: function() {
		// Destroy (sub)menus
		this.element
			.removeAttr( "aria-activedescendant" )
			.find( ".ui-menu" ).addBack()
				.removeClass( "ui-menu ui-widget ui-widget-content ui-corner-all ui-menu-icons" )
				.removeAttr( "role" )
				.removeAttr( "tabIndex" )
				.removeAttr( "aria-labelledby" )
				.removeAttr( "aria-expanded" )
				.removeAttr( "aria-hidden" )
				.removeAttr( "aria-disabled" )
				.removeUniqueId()
				.show();

		// Destroy menu items
		this.element.find( ".ui-menu-item" )
			.removeClass( "ui-menu-item" )
			.removeAttr( "role" )
			.removeAttr( "aria-disabled" )
			.children( "a" )
				.removeUniqueId()
				.removeClass( "ui-corner-all ui-state-hover" )
				.removeAttr( "tabIndex" )
				.removeAttr( "role" )
				.removeAttr( "aria-haspopup" )
				.children().each( function() {
					var elem = $( this );
					if ( elem.data( "ui-menu-submenu-carat" ) ) {
						elem.remove();
					}
				});

		// Destroy menu dividers
		this.element.find( ".ui-menu-divider" ).removeClass( "ui-menu-divider ui-widget-content" );
	},

	_keydown: function( event ) {
		var match, prev, character, skip, regex,
			preventDefault = true;

		function escape( value ) {
			return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" );
		}

		switch ( event.keyCode ) {
		case $.ui.keyCode.PAGE_UP:
			this.previousPage( event );
			break;
		case $.ui.keyCode.PAGE_DOWN:
			this.nextPage( event );
			break;
		case $.ui.keyCode.HOME:
			this._move( "first", "first", event );
			break;
		case $.ui.keyCode.END:
			this._move( "last", "last", event );
			break;
		case $.ui.keyCode.UP:
			this.previous( event );
			break;
		case $.ui.keyCode.DOWN:
			this.next( event );
			break;
		case $.ui.keyCode.LEFT:
			this.collapse( event );
			break;
		case $.ui.keyCode.RIGHT:
			if ( this.active && !this.active.is( ".ui-state-disabled" ) ) {
				this.expand( event );
			}
			break;
		case $.ui.keyCode.ENTER:
		case $.ui.keyCode.SPACE:
			this._activate( event );
			break;
		case $.ui.keyCode.ESCAPE:
			this.collapse( event );
			break;
		default:
			preventDefault = false;
			prev = this.previousFilter || "";
			character = String.fromCharCode( event.keyCode );
			skip = false;

			clearTimeout( this.filterTimer );

			if ( character === prev ) {
				skip = true;
			} else {
				character = prev + character;
			}

			regex = new RegExp( "^" + escape( character ), "i" );
			match = this.activeMenu.children( ".ui-menu-item" ).filter(function() {
				return regex.test( $( this ).children( "a" ).text() );
			});
			match = skip && match.index( this.active.next() ) !== -1 ?
				this.active.nextAll( ".ui-menu-item" ) :
				match;

			// If no matches on the current filter, reset to the last character pressed
			// to move down the menu to the first item that starts with that character
			if ( !match.length ) {
				character = String.fromCharCode( event.keyCode );
				regex = new RegExp( "^" + escape( character ), "i" );
				match = this.activeMenu.children( ".ui-menu-item" ).filter(function() {
					return regex.test( $( this ).children( "a" ).text() );
				});
			}

			if ( match.length ) {
				this.focus( event, match );
				if ( match.length > 1 ) {
					this.previousFilter = character;
					this.filterTimer = this._delay(function() {
						delete this.previousFilter;
					}, 1000 );
				} else {
					delete this.previousFilter;
				}
			} else {
				delete this.previousFilter;
			}
		}

		if ( preventDefault ) {
			event.preventDefault();
		}
	},

	_activate: function( event ) {
		if ( !this.active.is( ".ui-state-disabled" ) ) {
			if ( this.active.children( "a[aria-haspopup='true']" ).length ) {
				this.expand( event );
			} else {
				this.select( event );
			}
		}
	},

	refresh: function() {
		var menus,
			icon = this.options.icons.submenu,
			submenus = this.element.find( this.options.menus );

		this.element.toggleClass( "ui-menu-icons", !!this.element.find( ".ui-icon" ).length );

		// Initialize nested menus
		submenus.filter( ":not(.ui-menu)" )
			.addClass( "ui-menu ui-widget ui-widget-content ui-corner-all" )
			.hide()
			.attr({
				role: this.options.role,
				"aria-hidden": "true",
				"aria-expanded": "false"
			})
			.each(function() {
				var menu = $( this ),
					item = menu.prev( "a" ),
					submenuCarat = $( "<span>" )
						.addClass( "ui-menu-icon ui-icon " + icon )
						.data( "ui-menu-submenu-carat", true );

				item
					.attr( "aria-haspopup", "true" )
					.prepend( submenuCarat );
				menu.attr( "aria-labelledby", item.attr( "id" ) );
			});

		menus = submenus.add( this.element );

		// Don't refresh list items that are already adapted
		menus.children( ":not(.ui-menu-item):has(a)" )
			.addClass( "ui-menu-item" )
			.attr( "role", "presentation" )
			.children( "a" )
				.uniqueId()
				.addClass( "ui-corner-all" )
				.attr({
					tabIndex: -1,
					role: this._itemRole()
				});

		// Initialize unlinked menu-items containing spaces and/or dashes only as dividers
		menus.children( ":not(.ui-menu-item)" ).each(function() {
			var item = $( this );
			// hyphen, em dash, en dash
			if ( !/[^\-\u2014\u2013\s]/.test( item.text() ) ) {
				item.addClass( "ui-widget-content ui-menu-divider" );
			}
		});

		// Add aria-disabled attribute to any disabled menu item
		menus.children( ".ui-state-disabled" ).attr( "aria-disabled", "true" );

		// If the active item has been removed, blur the menu
		if ( this.active && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
			this.blur();
		}
	},

	_itemRole: function() {
		return {
			menu: "menuitem",
			listbox: "option"
		}[ this.options.role ];
	},

	_setOption: function( key, value ) {
		if ( key === "icons" ) {
			this.element.find( ".ui-menu-icon" )
				.removeClass( this.options.icons.submenu )
				.addClass( value.submenu );
		}
		this._super( key, value );
	},

	focus: function( event, item ) {
		var nested, focused;
		this.blur( event, event && event.type === "focus" );

		this._scrollIntoView( item );

		this.active = item.first();
		focused = this.active.children( "a" ).addClass( "ui-state-focus" );
		// Only update aria-activedescendant if there's a role
		// otherwise we assume focus is managed elsewhere
		if ( this.options.role ) {
			this.element.attr( "aria-activedescendant", focused.attr( "id" ) );
		}

		// Highlight active parent menu item, if any
		this.active
			.parent()
			.closest( ".ui-menu-item" )
			.children( "a:first" )
			.addClass( "ui-state-active" );

		if ( event && event.type === "keydown" ) {
			this._close();
		} else {
			this.timer = this._delay(function() {
				this._close();
			}, this.delay );
		}

		nested = item.children( ".ui-menu" );
		if ( nested.length && event && ( /^mouse/.test( event.type ) ) ) {
			this._startOpening(nested);
		}
		this.activeMenu = item.parent();

		this._trigger( "focus", event, { item: item } );
	},

	_scrollIntoView: function( item ) {
		var borderTop, paddingTop, offset, scroll, elementHeight, itemHeight;
		if ( this._hasScroll() ) {
			borderTop = parseFloat( $.css( this.activeMenu[0], "borderTopWidth" ) ) || 0;
			paddingTop = parseFloat( $.css( this.activeMenu[0], "paddingTop" ) ) || 0;
			offset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop;
			scroll = this.activeMenu.scrollTop();
			elementHeight = this.activeMenu.height();
			itemHeight = item.height();

			if ( offset < 0 ) {
				this.activeMenu.scrollTop( scroll + offset );
			} else if ( offset + itemHeight > elementHeight ) {
				this.activeMenu.scrollTop( scroll + offset - elementHeight + itemHeight );
			}
		}
	},

	blur: function( event, fromFocus ) {
		if ( !fromFocus ) {
			clearTimeout( this.timer );
		}

		if ( !this.active ) {
			return;
		}

		this.active.children( "a" ).removeClass( "ui-state-focus" );
		this.active = null;

		this._trigger( "blur", event, { item: this.active } );
	},

	_startOpening: function( submenu ) {
		clearTimeout( this.timer );

		// Don't open if already open fixes a Firefox bug that caused a .5 pixel
		// shift in the submenu position when mousing over the carat icon
		if ( submenu.attr( "aria-hidden" ) !== "true" ) {
			return;
		}

		this.timer = this._delay(function() {
			this._close();
			this._open( submenu );
		}, this.delay );
	},

	_open: function( submenu ) {
		var position = $.extend({
			of: this.active
		}, this.options.position );

		clearTimeout( this.timer );
		this.element.find( ".ui-menu" ).not( submenu.parents( ".ui-menu" ) )
			.hide()
			.attr( "aria-hidden", "true" );

		submenu
			.show()
			.removeAttr( "aria-hidden" )
			.attr( "aria-expanded", "true" )
			.position( position );
	},

	collapseAll: function( event, all ) {
		clearTimeout( this.timer );
		this.timer = this._delay(function() {
			// If we were passed an event, look for the submenu that contains the event
			var currentMenu = all ? this.element :
				$( event && event.target ).closest( this.element.find( ".ui-menu" ) );

			// If we found no valid submenu ancestor, use the main menu to close all sub menus anyway
			if ( !currentMenu.length ) {
				currentMenu = this.element;
			}

			this._close( currentMenu );

			this.blur( event );
			this.activeMenu = currentMenu;
		}, this.delay );
	},

	// With no arguments, closes the currently active menu - if nothing is active
	// it closes all menus.  If passed an argument, it will search for menus BELOW
	_close: function( startMenu ) {
		if ( !startMenu ) {
			startMenu = this.active ? this.active.parent() : this.element;
		}

		startMenu
			.find( ".ui-menu" )
				.hide()
				.attr( "aria-hidden", "true" )
				.attr( "aria-expanded", "false" )
			.end()
			.find( "a.ui-state-active" )
				.removeClass( "ui-state-active" );
	},

	collapse: function( event ) {
		var newItem = this.active &&
			this.active.parent().closest( ".ui-menu-item", this.element );
		if ( newItem && newItem.length ) {
			this._close();
			this.focus( event, newItem );
		}
	},

	expand: function( event ) {
		var newItem = this.active &&
			this.active
				.children( ".ui-menu " )
				.children( ".ui-menu-item" )
				.first();

		if ( newItem && newItem.length ) {
			this._open( newItem.parent() );

			// Delay so Firefox will not hide activedescendant change in expanding submenu from AT
			this._delay(function() {
				this.focus( event, newItem );
			});
		}
	},

	next: function( event ) {
		this._move( "next", "first", event );
	},

	previous: function( event ) {
		this._move( "prev", "last", event );
	},

	isFirstItem: function() {
		return this.active && !this.active.prevAll( ".ui-menu-item" ).length;
	},

	isLastItem: function() {
		return this.active && !this.active.nextAll( ".ui-menu-item" ).length;
	},

	_move: function( direction, filter, event ) {
		var next;
		if ( this.active ) {
			if ( direction === "first" || direction === "last" ) {
				next = this.active
					[ direction === "first" ? "prevAll" : "nextAll" ]( ".ui-menu-item" )
					.eq( -1 );
			} else {
				next = this.active
					[ direction + "All" ]( ".ui-menu-item" )
					.eq( 0 );
			}
		}
		if ( !next || !next.length || !this.active ) {
			next = this.activeMenu.children( ".ui-menu-item" )[ filter ]();
		}

		this.focus( event, next );
	},

	nextPage: function( event ) {
		var item, base, height;

		if ( !this.active ) {
			this.next( event );
			return;
		}
		if ( this.isLastItem() ) {
			return;
		}
		if ( this._hasScroll() ) {
			base = this.active.offset().top;
			height = this.element.height();
			this.active.nextAll( ".ui-menu-item" ).each(function() {
				item = $( this );
				return item.offset().top - base - height < 0;
			});

			this.focus( event, item );
		} else {
			this.focus( event, this.activeMenu.children( ".ui-menu-item" )
				[ !this.active ? "first" : "last" ]() );
		}
	},

	previousPage: function( event ) {
		var item, base, height;
		if ( !this.active ) {
			this.next( event );
			return;
		}
		if ( this.isFirstItem() ) {
			return;
		}
		if ( this._hasScroll() ) {
			base = this.active.offset().top;
			height = this.element.height();
			this.active.prevAll( ".ui-menu-item" ).each(function() {
				item = $( this );
				return item.offset().top - base + height > 0;
			});

			this.focus( event, item );
		} else {
			this.focus( event, this.activeMenu.children( ".ui-menu-item" ).first() );
		}
	},

	_hasScroll: function() {
		return this.element.outerHeight() < this.element.prop( "scrollHeight" );
	},

	select: function( event ) {
		// TODO: It should never be possible to not have an active item at this
		// point, but the tests don't trigger mouseenter before click.
		this.active = this.active || $( event.target ).closest( ".ui-menu-item" );
		var ui = { item: this.active };
		if ( !this.active.has( ".ui-menu" ).length ) {
			this.collapseAll( event, true );
		}
		this._trigger( "select", event, ui );
	}
});

}( jQuery ));
;// Unobtrusive Ajax support library for jQuery
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
// @version v3.2.6
// 
// Microsoft grants you the right to use these script files for the sole
// purpose of either: (i) interacting through your browser with the Microsoft
// website or online service, subject to the applicable licensing or use
// terms; or (ii) using the files as included with a Microsoft product subject
// to that product's license terms. Microsoft reserves all other rights to the
// files not expressly granted by Microsoft, whether by implication, estoppel
// or otherwise. Insofar as a script file is dual licensed under GPL,
// Microsoft neither took the code under GPL nor distributes it thereunder but
// under the terms set out in this paragraph. All notices and licenses
// below are for informational purposes only.
!function(t){function a(t,a){for(var e=window,r=(t||"").split(".");e&&r.length;)e=e[r.shift()];return"function"==typeof e?e:(a.push(t),Function.constructor.apply(null,a))}function e(t){return"GET"===t||"POST"===t}function r(t,a){e(a)||t.setRequestHeader("X-HTTP-Method-Override",a)}function n(a,e,r){var n;r.indexOf("application/x-javascript")===-1&&(n=(a.getAttribute("data-ajax-mode")||"").toUpperCase(),t(a.getAttribute("data-ajax-update")).each(function(a,r){switch(n){case"BEFORE":t(r).prepend(e);break;case"AFTER":t(r).append(e);break;case"REPLACE-WITH":t(r).replaceWith(e);break;default:t(r).html(e)}}))}function i(i,u){var o,c,d,s;if(o=i.getAttribute("data-ajax-confirm"),!o||window.confirm(o)){c=t(i.getAttribute("data-ajax-loading")),s=parseInt(i.getAttribute("data-ajax-loading-duration"),10)||0,t.extend(u,{type:i.getAttribute("data-ajax-method")||void 0,url:i.getAttribute("data-ajax-url")||void 0,cache:"true"===(i.getAttribute("data-ajax-cache")||"").toLowerCase(),beforeSend:function(t){var e;return r(t,d),e=a(i.getAttribute("data-ajax-begin"),["xhr"]).apply(i,arguments),e!==!1&&c.show(s),e},complete:function(){c.hide(s),a(i.getAttribute("data-ajax-complete"),["xhr","status"]).apply(i,arguments)},success:function(t,e,r){n(i,t,r.getResponseHeader("Content-Type")||"text/html"),a(i.getAttribute("data-ajax-success"),["data","status","xhr"]).apply(i,arguments)},error:function(){a(i.getAttribute("data-ajax-failure"),["xhr","status","error"]).apply(i,arguments)}}),u.data.push({name:"X-Requested-With",value:"XMLHttpRequest"}),d=u.type.toUpperCase(),e(d)||(u.type="POST",u.data.push({name:"X-HTTP-Method-Override",value:d}));var p=t(i);if(p.is("form")&&"multipart/form-data"==p.attr("enctype")){var f=new FormData;t.each(u.data,function(t,a){f.append(a.name,a.value)}),t("input[type=file]",p).each(function(){var a=this;t.each(a.files,function(t,e){f.append(a.name,e)})}),t.extend(u,{processData:!1,contentType:!1,data:f})}t.ajax(u)}}function u(a){var e=t(a).data(d);return!e||!e.validate||e.validate()}var o="unobtrusiveAjaxClick",c="unobtrusiveAjaxClickTarget",d="unobtrusiveValidation";t(document).on("click","a[data-ajax=true]",function(t){t.preventDefault(),i(this,{url:this.href,type:"GET",data:[]})}),t(document).on("click","form[data-ajax=true] input[type=image]",function(a){var e=a.target.name,r=t(a.target),n=t(r.parents("form")[0]),i=r.offset();n.data(o,[{name:e+".x",value:Math.round(a.pageX-i.left)},{name:e+".y",value:Math.round(a.pageY-i.top)}]),setTimeout(function(){n.removeData(o)},0)}),t(document).on("click","form[data-ajax=true] :submit",function(a){var e=a.currentTarget.name,r=t(a.target),n=t(r.parents("form")[0]);n.data(o,e?[{name:e,value:a.currentTarget.value}]:[]),n.data(c,r),setTimeout(function(){n.removeData(o),n.removeData(c)},0)}),t(document).on("submit","form[data-ajax=true]",function(a){var e=t(this).data(o)||[],r=t(this).data(c),n=r&&(r.hasClass("cancel")||void 0!==r.attr("formnovalidate"));a.preventDefault(),(n||u(this))&&i(this,{url:this.action,type:this.method||"GET",data:e.concat(t(this).serializeArray())})})}(jQuery);;/*! jQuery Validation Plugin - v1.17.0 - 7/29/2017
 * https://jqueryvalidation.org/
 * Copyright (c) 2017 Jörn Zaefferer; Licensed MIT */
!function(a){"function"==typeof define&&define.amd?define(["jquery"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){a.extend(a.fn,{validate:function(b){if(!this.length)return void(b&&b.debug&&window.console&&console.warn("Nothing selected, can't validate, returning nothing."));var c=a.data(this[0],"validator");return c?c:(this.attr("novalidate","novalidate"),c=new a.validator(b,this[0]),a.data(this[0],"validator",c),c.settings.onsubmit&&(this.on("click.validate",":submit",function(b){c.submitButton=b.currentTarget,a(this).hasClass("cancel")&&(c.cancelSubmit=!0),void 0!==a(this).attr("formnovalidate")&&(c.cancelSubmit=!0)}),this.on("submit.validate",function(b){function d(){var d,e;return c.submitButton&&(c.settings.submitHandler||c.formSubmitted)&&(d=a("<input type='hidden'/>").attr("name",c.submitButton.name).val(a(c.submitButton).val()).appendTo(c.currentForm)),!c.settings.submitHandler||(e=c.settings.submitHandler.call(c,c.currentForm,b),d&&d.remove(),void 0!==e&&e)}return c.settings.debug&&b.preventDefault(),c.cancelSubmit?(c.cancelSubmit=!1,d()):c.form()?c.pendingRequest?(c.formSubmitted=!0,!1):d():(c.focusInvalid(),!1)})),c)},valid:function(){var b,c,d;return a(this[0]).is("form")?b=this.validate().form():(d=[],b=!0,c=a(this[0].form).validate(),this.each(function(){b=c.element(this)&&b,b||(d=d.concat(c.errorList))}),c.errorList=d),b},rules:function(b,c){var d,e,f,g,h,i,j=this[0];if(null!=j&&(!j.form&&j.hasAttribute("contenteditable")&&(j.form=this.closest("form")[0],j.name=this.attr("name")),null!=j.form)){if(b)switch(d=a.data(j.form,"validator").settings,e=d.rules,f=a.validator.staticRules(j),b){case"add":a.extend(f,a.validator.normalizeRule(c)),delete f.messages,e[j.name]=f,c.messages&&(d.messages[j.name]=a.extend(d.messages[j.name],c.messages));break;case"remove":return c?(i={},a.each(c.split(/\s/),function(a,b){i[b]=f[b],delete f[b]}),i):(delete e[j.name],f)}return g=a.validator.normalizeRules(a.extend({},a.validator.classRules(j),a.validator.attributeRules(j),a.validator.dataRules(j),a.validator.staticRules(j)),j),g.required&&(h=g.required,delete g.required,g=a.extend({required:h},g)),g.remote&&(h=g.remote,delete g.remote,g=a.extend(g,{remote:h})),g}}}),a.extend(a.expr.pseudos||a.expr[":"],{blank:function(b){return!a.trim(""+a(b).val())},filled:function(b){var c=a(b).val();return null!==c&&!!a.trim(""+c)},unchecked:function(b){return!a(b).prop("checked")}}),a.validator=function(b,c){this.settings=a.extend(!0,{},a.validator.defaults,b),this.currentForm=c,this.init()},a.validator.format=function(b,c){return 1===arguments.length?function(){var c=a.makeArray(arguments);return c.unshift(b),a.validator.format.apply(this,c)}:void 0===c?b:(arguments.length>2&&c.constructor!==Array&&(c=a.makeArray(arguments).slice(1)),c.constructor!==Array&&(c=[c]),a.each(c,function(a,c){b=b.replace(new RegExp("\\{"+a+"\\}","g"),function(){return c})}),b)},a.extend(a.validator,{defaults:{messages:{},groups:{},rules:{},errorClass:"error",pendingClass:"pending",validClass:"valid",errorElement:"label",focusCleanup:!1,focusInvalid:!0,errorContainer:a([]),errorLabelContainer:a([]),onsubmit:!0,ignore:":hidden",ignoreTitle:!1,onfocusin:function(a){this.lastActive=a,this.settings.focusCleanup&&(this.settings.unhighlight&&this.settings.unhighlight.call(this,a,this.settings.errorClass,this.settings.validClass),this.hideThese(this.errorsFor(a)))},onfocusout:function(a){this.checkable(a)||!(a.name in this.submitted)&&this.optional(a)||this.element(a)},onkeyup:function(b,c){var d=[16,17,18,20,35,36,37,38,39,40,45,144,225];9===c.which&&""===this.elementValue(b)||a.inArray(c.keyCode,d)!==-1||(b.name in this.submitted||b.name in this.invalid)&&this.element(b)},onclick:function(a){a.name in this.submitted?this.element(a):a.parentNode.name in this.submitted&&this.element(a.parentNode)},highlight:function(b,c,d){"radio"===b.type?this.findByName(b.name).addClass(c).removeClass(d):a(b).addClass(c).removeClass(d)},unhighlight:function(b,c,d){"radio"===b.type?this.findByName(b.name).removeClass(c).addClass(d):a(b).removeClass(c).addClass(d)}},setDefaults:function(b){a.extend(a.validator.defaults,b)},messages:{required:"This field is required.",remote:"Please fix this field.",email:"Please enter a valid email address.",url:"Please enter a valid URL.",date:"Please enter a valid date.",dateISO:"Please enter a valid date (ISO).",number:"Please enter a valid number.",digits:"Please enter only digits.",equalTo:"Please enter the same value again.",maxlength:a.validator.format("Please enter no more than {0} characters."),minlength:a.validator.format("Please enter at least {0} characters."),rangelength:a.validator.format("Please enter a value between {0} and {1} characters long."),range:a.validator.format("Please enter a value between {0} and {1}."),max:a.validator.format("Please enter a value less than or equal to {0}."),min:a.validator.format("Please enter a value greater than or equal to {0}."),step:a.validator.format("Please enter a multiple of {0}.")},autoCreateRanges:!1,prototype:{init:function(){function b(b){!this.form&&this.hasAttribute("contenteditable")&&(this.form=a(this).closest("form")[0],this.name=a(this).attr("name"));var c=a.data(this.form,"validator"),d="on"+b.type.replace(/^validate/,""),e=c.settings;e[d]&&!a(this).is(e.ignore)&&e[d].call(c,this,b)}this.labelContainer=a(this.settings.errorLabelContainer),this.errorContext=this.labelContainer.length&&this.labelContainer||a(this.currentForm),this.containers=a(this.settings.errorContainer).add(this.settings.errorLabelContainer),this.submitted={},this.valueCache={},this.pendingRequest=0,this.pending={},this.invalid={},this.reset();var c,d=this.groups={};a.each(this.settings.groups,function(b,c){"string"==typeof c&&(c=c.split(/\s/)),a.each(c,function(a,c){d[c]=b})}),c=this.settings.rules,a.each(c,function(b,d){c[b]=a.validator.normalizeRule(d)}),a(this.currentForm).on("focusin.validate focusout.validate keyup.validate",":text, [type='password'], [type='file'], select, textarea, [type='number'], [type='search'], [type='tel'], [type='url'], [type='email'], [type='datetime'], [type='date'], [type='month'], [type='week'], [type='time'], [type='datetime-local'], [type='range'], [type='color'], [type='radio'], [type='checkbox'], [contenteditable], [type='button']",b).on("click.validate","select, option, [type='radio'], [type='checkbox']",b),this.settings.invalidHandler&&a(this.currentForm).on("invalid-form.validate",this.settings.invalidHandler)},form:function(){return this.checkForm(),a.extend(this.submitted,this.errorMap),this.invalid=a.extend({},this.errorMap),this.valid()||a(this.currentForm).triggerHandler("invalid-form",[this]),this.showErrors(),this.valid()},checkForm:function(){this.prepareForm();for(var a=0,b=this.currentElements=this.elements();b[a];a++)this.check(b[a]);return this.valid()},element:function(b){var c,d,e=this.clean(b),f=this.validationTargetFor(e),g=this,h=!0;return void 0===f?delete this.invalid[e.name]:(this.prepareElement(f),this.currentElements=a(f),d=this.groups[f.name],d&&a.each(this.groups,function(a,b){b===d&&a!==f.name&&(e=g.validationTargetFor(g.clean(g.findByName(a))),e&&e.name in g.invalid&&(g.currentElements.push(e),h=g.check(e)&&h))}),c=this.check(f)!==!1,h=h&&c,c?this.invalid[f.name]=!1:this.invalid[f.name]=!0,this.numberOfInvalids()||(this.toHide=this.toHide.add(this.containers)),this.showErrors(),a(b).attr("aria-invalid",!c)),h},showErrors:function(b){if(b){var c=this;a.extend(this.errorMap,b),this.errorList=a.map(this.errorMap,function(a,b){return{message:a,element:c.findByName(b)[0]}}),this.successList=a.grep(this.successList,function(a){return!(a.name in b)})}this.settings.showErrors?this.settings.showErrors.call(this,this.errorMap,this.errorList):this.defaultShowErrors()},resetForm:function(){a.fn.resetForm&&a(this.currentForm).resetForm(),this.invalid={},this.submitted={},this.prepareForm(),this.hideErrors();var b=this.elements().removeData("previousValue").removeAttr("aria-invalid");this.resetElements(b)},resetElements:function(a){var b;if(this.settings.unhighlight)for(b=0;a[b];b++)this.settings.unhighlight.call(this,a[b],this.settings.errorClass,""),this.findByName(a[b].name).removeClass(this.settings.validClass);else a.removeClass(this.settings.errorClass).removeClass(this.settings.validClass)},numberOfInvalids:function(){return this.objectLength(this.invalid)},objectLength:function(a){var b,c=0;for(b in a)void 0!==a[b]&&null!==a[b]&&a[b]!==!1&&c++;return c},hideErrors:function(){this.hideThese(this.toHide)},hideThese:function(a){a.not(this.containers).text(""),this.addWrapper(a).hide()},valid:function(){return 0===this.size()},size:function(){return this.errorList.length},focusInvalid:function(){if(this.settings.focusInvalid)try{a(this.findLastActive()||this.errorList.length&&this.errorList[0].element||[]).filter(":visible").focus().trigger("focusin")}catch(b){}},findLastActive:function(){var b=this.lastActive;return b&&1===a.grep(this.errorList,function(a){return a.element.name===b.name}).length&&b},elements:function(){var b=this,c={};return a(this.currentForm).find("input, select, textarea, [contenteditable]").not(":submit, :reset, :image, :disabled").not(this.settings.ignore).filter(function(){var d=this.name||a(this).attr("name");return!d&&b.settings.debug&&window.console&&console.error("%o has no name assigned",this),this.hasAttribute("contenteditable")&&(this.form=a(this).closest("form")[0],this.name=d),!(d in c||!b.objectLength(a(this).rules()))&&(c[d]=!0,!0)})},clean:function(b){return a(b)[0]},errors:function(){var b=this.settings.errorClass.split(" ").join(".");return a(this.settings.errorElement+"."+b,this.errorContext)},resetInternals:function(){this.successList=[],this.errorList=[],this.errorMap={},this.toShow=a([]),this.toHide=a([])},reset:function(){this.resetInternals(),this.currentElements=a([])},prepareForm:function(){this.reset(),this.toHide=this.errors().add(this.containers)},prepareElement:function(a){this.reset(),this.toHide=this.errorsFor(a)},elementValue:function(b){var c,d,e=a(b),f=b.type;return"radio"===f||"checkbox"===f?this.findByName(b.name).filter(":checked").val():"number"===f&&"undefined"!=typeof b.validity?b.validity.badInput?"NaN":e.val():(c=b.hasAttribute("contenteditable")?e.text():e.val(),"file"===f?"C:\\fakepath\\"===c.substr(0,12)?c.substr(12):(d=c.lastIndexOf("/"),d>=0?c.substr(d+1):(d=c.lastIndexOf("\\"),d>=0?c.substr(d+1):c)):"string"==typeof c?c.replace(/\r/g,""):c)},check:function(b){b=this.validationTargetFor(this.clean(b));var c,d,e,f,g=a(b).rules(),h=a.map(g,function(a,b){return b}).length,i=!1,j=this.elementValue(b);if("function"==typeof g.normalizer?f=g.normalizer:"function"==typeof this.settings.normalizer&&(f=this.settings.normalizer),f){if(j=f.call(b,j),"string"!=typeof j)throw new TypeError("The normalizer should return a string value.");delete g.normalizer}for(d in g){e={method:d,parameters:g[d]};try{if(c=a.validator.methods[d].call(this,j,b,e.parameters),"dependency-mismatch"===c&&1===h){i=!0;continue}if(i=!1,"pending"===c)return void(this.toHide=this.toHide.not(this.errorsFor(b)));if(!c)return this.formatAndAdd(b,e),!1}catch(k){throw this.settings.debug&&window.console&&console.log("Exception occurred when checking element "+b.id+", check the '"+e.method+"' method.",k),k instanceof TypeError&&(k.message+=".  Exception occurred when checking element "+b.id+", check the '"+e.method+"' method."),k}}if(!i)return this.objectLength(g)&&this.successList.push(b),!0},customDataMessage:function(b,c){return a(b).data("msg"+c.charAt(0).toUpperCase()+c.substring(1).toLowerCase())||a(b).data("msg")},customMessage:function(a,b){var c=this.settings.messages[a];return c&&(c.constructor===String?c:c[b])},findDefined:function(){for(var a=0;a<arguments.length;a++)if(void 0!==arguments[a])return arguments[a]},defaultMessage:function(b,c){"string"==typeof c&&(c={method:c});var d=this.findDefined(this.customMessage(b.name,c.method),this.customDataMessage(b,c.method),!this.settings.ignoreTitle&&b.title||void 0,a.validator.messages[c.method],"<strong>Warning: No message defined for "+b.name+"</strong>"),e=/\$?\{(\d+)\}/g;return"function"==typeof d?d=d.call(this,c.parameters,b):e.test(d)&&(d=a.validator.format(d.replace(e,"{$1}"),c.parameters)),d},formatAndAdd:function(a,b){var c=this.defaultMessage(a,b);this.errorList.push({message:c,element:a,method:b.method}),this.errorMap[a.name]=c,this.submitted[a.name]=c},addWrapper:function(a){return this.settings.wrapper&&(a=a.add(a.parent(this.settings.wrapper))),a},defaultShowErrors:function(){var a,b,c;for(a=0;this.errorList[a];a++)c=this.errorList[a],this.settings.highlight&&this.settings.highlight.call(this,c.element,this.settings.errorClass,this.settings.validClass),this.showLabel(c.element,c.message);if(this.errorList.length&&(this.toShow=this.toShow.add(this.containers)),this.settings.success)for(a=0;this.successList[a];a++)this.showLabel(this.successList[a]);if(this.settings.unhighlight)for(a=0,b=this.validElements();b[a];a++)this.settings.unhighlight.call(this,b[a],this.settings.errorClass,this.settings.validClass);this.toHide=this.toHide.not(this.toShow),this.hideErrors(),this.addWrapper(this.toShow).show()},validElements:function(){return this.currentElements.not(this.invalidElements())},invalidElements:function(){return a(this.errorList).map(function(){return this.element})},showLabel:function(b,c){var d,e,f,g,h=this.errorsFor(b),i=this.idOrName(b),j=a(b).attr("aria-describedby");h.length?(h.removeClass(this.settings.validClass).addClass(this.settings.errorClass),h.html(c)):(h=a("<"+this.settings.errorElement+">").attr("id",i+"-error").addClass(this.settings.errorClass).html(c||""),d=h,this.settings.wrapper&&(d=h.hide().show().wrap("<"+this.settings.wrapper+"/>").parent()),this.labelContainer.length?this.labelContainer.append(d):this.settings.errorPlacement?this.settings.errorPlacement.call(this,d,a(b)):d.insertAfter(b),h.is("label")?h.attr("for",i):0===h.parents("label[for='"+this.escapeCssMeta(i)+"']").length&&(f=h.attr("id"),j?j.match(new RegExp("\\b"+this.escapeCssMeta(f)+"\\b"))||(j+=" "+f):j=f,a(b).attr("aria-describedby",j),e=this.groups[b.name],e&&(g=this,a.each(g.groups,function(b,c){c===e&&a("[name='"+g.escapeCssMeta(b)+"']",g.currentForm).attr("aria-describedby",h.attr("id"))})))),!c&&this.settings.success&&(h.text(""),"string"==typeof this.settings.success?h.addClass(this.settings.success):this.settings.success(h,b)),this.toShow=this.toShow.add(h)},errorsFor:function(b){var c=this.escapeCssMeta(this.idOrName(b)),d=a(b).attr("aria-describedby"),e="label[for='"+c+"'], label[for='"+c+"'] *";return d&&(e=e+", #"+this.escapeCssMeta(d).replace(/\s+/g,", #")),this.errors().filter(e)},escapeCssMeta:function(a){return a.replace(/([\\!"#$%&'()*+,.\/:;<=>?@\[\]^`{|}~])/g,"\\$1")},idOrName:function(a){return this.groups[a.name]||(this.checkable(a)?a.name:a.id||a.name)},validationTargetFor:function(b){return this.checkable(b)&&(b=this.findByName(b.name)),a(b).not(this.settings.ignore)[0]},checkable:function(a){return/radio|checkbox/i.test(a.type)},findByName:function(b){return a(this.currentForm).find("[name='"+this.escapeCssMeta(b)+"']")},getLength:function(b,c){switch(c.nodeName.toLowerCase()){case"select":return a("option:selected",c).length;case"input":if(this.checkable(c))return this.findByName(c.name).filter(":checked").length}return b.length},depend:function(a,b){return!this.dependTypes[typeof a]||this.dependTypes[typeof a](a,b)},dependTypes:{"boolean":function(a){return a},string:function(b,c){return!!a(b,c.form).length},"function":function(a,b){return a(b)}},optional:function(b){var c=this.elementValue(b);return!a.validator.methods.required.call(this,c,b)&&"dependency-mismatch"},startRequest:function(b){this.pending[b.name]||(this.pendingRequest++,a(b).addClass(this.settings.pendingClass),this.pending[b.name]=!0)},stopRequest:function(b,c){this.pendingRequest--,this.pendingRequest<0&&(this.pendingRequest=0),delete this.pending[b.name],a(b).removeClass(this.settings.pendingClass),c&&0===this.pendingRequest&&this.formSubmitted&&this.form()?(a(this.currentForm).submit(),this.submitButton&&a("input:hidden[name='"+this.submitButton.name+"']",this.currentForm).remove(),this.formSubmitted=!1):!c&&0===this.pendingRequest&&this.formSubmitted&&(a(this.currentForm).triggerHandler("invalid-form",[this]),this.formSubmitted=!1)},previousValue:function(b,c){return c="string"==typeof c&&c||"remote",a.data(b,"previousValue")||a.data(b,"previousValue",{old:null,valid:!0,message:this.defaultMessage(b,{method:c})})},destroy:function(){this.resetForm(),a(this.currentForm).off(".validate").removeData("validator").find(".validate-equalTo-blur").off(".validate-equalTo").removeClass("validate-equalTo-blur")}},classRuleSettings:{required:{required:!0},email:{email:!0},url:{url:!0},date:{date:!0},dateISO:{dateISO:!0},number:{number:!0},digits:{digits:!0},creditcard:{creditcard:!0}},addClassRules:function(b,c){b.constructor===String?this.classRuleSettings[b]=c:a.extend(this.classRuleSettings,b)},classRules:function(b){var c={},d=a(b).attr("class");return d&&a.each(d.split(" "),function(){this in a.validator.classRuleSettings&&a.extend(c,a.validator.classRuleSettings[this])}),c},normalizeAttributeRule:function(a,b,c,d){/min|max|step/.test(c)&&(null===b||/number|range|text/.test(b))&&(d=Number(d),isNaN(d)&&(d=void 0)),d||0===d?a[c]=d:b===c&&"range"!==b&&(a[c]=!0)},attributeRules:function(b){var c,d,e={},f=a(b),g=b.getAttribute("type");for(c in a.validator.methods)"required"===c?(d=b.getAttribute(c),""===d&&(d=!0),d=!!d):d=f.attr(c),this.normalizeAttributeRule(e,g,c,d);return e.maxlength&&/-1|2147483647|524288/.test(e.maxlength)&&delete e.maxlength,e},dataRules:function(b){var c,d,e={},f=a(b),g=b.getAttribute("type");for(c in a.validator.methods)d=f.data("rule"+c.charAt(0).toUpperCase()+c.substring(1).toLowerCase()),this.normalizeAttributeRule(e,g,c,d);return e},staticRules:function(b){var c={},d=a.data(b.form,"validator");return d.settings.rules&&(c=a.validator.normalizeRule(d.settings.rules[b.name])||{}),c},normalizeRules:function(b,c){return a.each(b,function(d,e){if(e===!1)return void delete b[d];if(e.param||e.depends){var f=!0;switch(typeof e.depends){case"string":f=!!a(e.depends,c.form).length;break;case"function":f=e.depends.call(c,c)}f?b[d]=void 0===e.param||e.param:(a.data(c.form,"validator").resetElements(a(c)),delete b[d])}}),a.each(b,function(d,e){b[d]=a.isFunction(e)&&"normalizer"!==d?e(c):e}),a.each(["minlength","maxlength"],function(){b[this]&&(b[this]=Number(b[this]))}),a.each(["rangelength","range"],function(){var c;b[this]&&(a.isArray(b[this])?b[this]=[Number(b[this][0]),Number(b[this][1])]:"string"==typeof b[this]&&(c=b[this].replace(/[\[\]]/g,"").split(/[\s,]+/),b[this]=[Number(c[0]),Number(c[1])]))}),a.validator.autoCreateRanges&&(null!=b.min&&null!=b.max&&(b.range=[b.min,b.max],delete b.min,delete b.max),null!=b.minlength&&null!=b.maxlength&&(b.rangelength=[b.minlength,b.maxlength],delete b.minlength,delete b.maxlength)),b},normalizeRule:function(b){if("string"==typeof b){var c={};a.each(b.split(/\s/),function(){c[this]=!0}),b=c}return b},addMethod:function(b,c,d){a.validator.methods[b]=c,a.validator.messages[b]=void 0!==d?d:a.validator.messages[b],c.length<3&&a.validator.addClassRules(b,a.validator.normalizeRule(b))},methods:{required:function(b,c,d){if(!this.depend(d,c))return"dependency-mismatch";if("select"===c.nodeName.toLowerCase()){var e=a(c).val();return e&&e.length>0}return this.checkable(c)?this.getLength(b,c)>0:b.length>0},email:function(a,b){return this.optional(b)||/^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/.test(a)},url:function(a,b){return this.optional(b)||/^(?:(?:(?:https?|ftp):)?\/\/)(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})).?)(?::\d{2,5})?(?:[\/?#]\S*)?$/i.test(a)},date:function(a,b){return this.optional(b)||!/Invalid|NaN/.test(new Date(a).toString())},dateISO:function(a,b){return this.optional(b)||/^\d{4}[\/\-](0?[1-9]|1[012])[\/\-](0?[1-9]|[12][0-9]|3[01])$/.test(a)},number:function(a,b){return this.optional(b)||/^(?:-?\d+|-?\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$/.test(a)},digits:function(a,b){return this.optional(b)||/^\d+$/.test(a)},minlength:function(b,c,d){var e=a.isArray(b)?b.length:this.getLength(b,c);return this.optional(c)||e>=d},maxlength:function(b,c,d){var e=a.isArray(b)?b.length:this.getLength(b,c);return this.optional(c)||e<=d},rangelength:function(b,c,d){var e=a.isArray(b)?b.length:this.getLength(b,c);return this.optional(c)||e>=d[0]&&e<=d[1]},min:function(a,b,c){return this.optional(b)||a>=c},max:function(a,b,c){return this.optional(b)||a<=c},range:function(a,b,c){return this.optional(b)||a>=c[0]&&a<=c[1]},step:function(b,c,d){var e,f=a(c).attr("type"),g="Step attribute on input type "+f+" is not supported.",h=["text","number","range"],i=new RegExp("\\b"+f+"\\b"),j=f&&!i.test(h.join()),k=function(a){var b=(""+a).match(/(?:\.(\d+))?$/);return b&&b[1]?b[1].length:0},l=function(a){return Math.round(a*Math.pow(10,e))},m=!0;if(j)throw new Error(g);return e=k(d),(k(b)>e||l(b)%l(d)!==0)&&(m=!1),this.optional(c)||m},equalTo:function(b,c,d){var e=a(d);return this.settings.onfocusout&&e.not(".validate-equalTo-blur").length&&e.addClass("validate-equalTo-blur").on("blur.validate-equalTo",function(){a(c).valid()}),b===e.val()},remote:function(b,c,d,e){if(this.optional(c))return"dependency-mismatch";e="string"==typeof e&&e||"remote";var f,g,h,i=this.previousValue(c,e);return this.settings.messages[c.name]||(this.settings.messages[c.name]={}),i.originalMessage=i.originalMessage||this.settings.messages[c.name][e],this.settings.messages[c.name][e]=i.message,d="string"==typeof d&&{url:d}||d,h=a.param(a.extend({data:b},d.data)),i.old===h?i.valid:(i.old=h,f=this,this.startRequest(c),g={},g[c.name]=b,a.ajax(a.extend(!0,{mode:"abort",port:"validate"+c.name,dataType:"json",data:g,context:f.currentForm,success:function(a){var d,g,h,j=a===!0||"true"===a;f.settings.messages[c.name][e]=i.originalMessage,j?(h=f.formSubmitted,f.resetInternals(),f.toHide=f.errorsFor(c),f.formSubmitted=h,f.successList.push(c),f.invalid[c.name]=!1,f.showErrors()):(d={},g=a||f.defaultMessage(c,{method:e,parameters:b}),d[c.name]=i.message=g,f.invalid[c.name]=!0,f.showErrors(d)),i.valid=j,f.stopRequest(c,j)}},d)),"pending")}}});var b,c={};return a.ajaxPrefilter?a.ajaxPrefilter(function(a,b,d){var e=a.port;"abort"===a.mode&&(c[e]&&c[e].abort(),c[e]=d)}):(b=a.ajax,a.ajax=function(d){var e=("mode"in d?d:a.ajaxSettings).mode,f=("port"in d?d:a.ajaxSettings).port;return"abort"===e?(c[f]&&c[f].abort(),c[f]=b.apply(this,arguments),c[f]):b.apply(this,arguments)}),a});;/* NUGET: BEGIN LICENSE TEXT
 *
 * Microsoft grants you the right to use these script files for the sole
 * purpose of either: (i) interacting through your browser with the Microsoft
 * website or online service, subject to the applicable licensing or use
 * terms; or (ii) using the files as included with a Microsoft product subject
 * to that product's license terms. Microsoft reserves all other rights to the
 * files not expressly granted by Microsoft, whether by implication, estoppel
 * or otherwise. Insofar as a script file is dual licensed under GPL,
 * Microsoft neither took the code under GPL nor distributes it thereunder but
 * under the terms set out in this paragraph. All notices and licenses
 * below are for informational purposes only.
 *
 * NUGET: END LICENSE TEXT */
/* NUGET: BEGIN LICENSE TEXT
 *
 * Microsoft grants you the right to use these script files for the sole
 * purpose of either: (i) interacting through your browser with the Microsoft
 * website or online service, subject to the applicable licensing or use
 * terms; or (ii) using the files as included with a Microsoft product subject
 * to that product's license terms. Microsoft reserves all other rights to the
 * files not expressly granted by Microsoft, whether by implication, estoppel
 * or otherwise. Insofar as a script file is dual licensed under GPL,
 * Microsoft neither took the code under GPL nor distributes it thereunder but
 * under the terms set out in this paragraph. All notices and licenses
 * below are for informational purposes only.
 *
 * NUGET: END LICENSE TEXT */
/*
** Unobtrusive validation support library for jQuery and jQuery Validate
** Copyright (C) Microsoft Corporation. All rights reserved.
*/
(function(a){var d=a.validator,b,e="unobtrusiveValidation";function c(a,b,c){a.rules[b]=c;if(a.message)a.messages[b]=a.message}function j(a){return a.replace(/^\s+|\s+$/g,"").split(/\s*,\s*/g)}function f(a){return a.replace(/([!"#$%&'()*+,./:;<=>?@\[\\\]^`{|}~])/g,"\\$1")}function h(a){return a.substr(0,a.lastIndexOf(".")+1)}function g(a,b){if(a.indexOf("*.")===0)a=a.replace("*.",b);return a}function m(c,e){var b=a(this).find("[data-valmsg-for='"+f(e[0].name)+"']"),d=b.attr("data-valmsg-replace"),g=d?a.parseJSON(d)!==false:null;b.removeClass("field-validation-valid").addClass("field-validation-error");c.data("unobtrusiveContainer",b);if(g){b.empty();c.removeClass("input-validation-error").appendTo(b)}else c.hide()}function l(e,d){var c=a(this).find("[data-valmsg-summary=true]"),b=c.find("ul");if(b&&b.length&&d.errorList.length){b.empty();c.addClass("validation-summary-errors").removeClass("validation-summary-valid");a.each(d.errorList,function(){a("<li />").html(this.message).appendTo(b)})}}function k(d){var b=d.data("unobtrusiveContainer"),c=b.attr("data-valmsg-replace"),e=c?a.parseJSON(c):null;if(b){b.addClass("field-validation-valid").removeClass("field-validation-error");d.removeData("unobtrusiveContainer");e&&b.empty()}}function n(){var b=a(this),c="__jquery_unobtrusive_validation_form_reset";if(b.data(c))return;b.data(c,true);try{b.data("validator").resetForm()}finally{b.removeData(c)}b.find(".validation-summary-errors").addClass("validation-summary-valid").removeClass("validation-summary-errors");b.find(".field-validation-error").addClass("field-validation-valid").removeClass("field-validation-error").removeData("unobtrusiveContainer").find(">*").removeData("unobtrusiveContainer")}function i(b){var c=a(b),f=c.data(e),i=a.proxy(n,b),g=d.unobtrusive.options||{},h=function(e,d){var c=g[e];c&&a.isFunction(c)&&c.apply(b,d)};if(!f){f={options:{errorClass:g.errorClass||"input-validation-error",errorElement:g.errorElement||"span",errorPlacement:function(){m.apply(b,arguments);h("errorPlacement",arguments)},invalidHandler:function(){l.apply(b,arguments);h("invalidHandler",arguments)},messages:{},rules:{},success:function(){k.apply(b,arguments);h("success",arguments)}},attachValidation:function(){c.off("reset."+e,i).on("reset."+e,i).validate(this.options)},validate:function(){c.validate();return c.valid()}};c.data(e,f)}return f}d.unobtrusive={adapters:[],parseElement:function(b,h){var d=a(b),f=d.parents("form")[0],c,e,g;if(!f)return;c=i(f);c.options.rules[b.name]=e={};c.options.messages[b.name]=g={};a.each(this.adapters,function(){var c="data-val-"+this.name,i=d.attr(c),h={};if(i!==undefined){c+="-";a.each(this.params,function(){h[this]=d.attr(c+this)});this.adapt({element:b,form:f,message:i,params:h,rules:e,messages:g})}});a.extend(e,{__dummy__:true});!h&&c.attachValidation()},parse:function(c){var b=a(c),e=b.parents().addBack().filter("form").add(b.find("form")).has("[data-val=true]");b.find("[data-val=true]").each(function(){d.unobtrusive.parseElement(this,true)});e.each(function(){var a=i(this);a&&a.attachValidation()})}};b=d.unobtrusive.adapters;b.add=function(c,a,b){if(!b){b=a;a=[]}this.push({name:c,params:a,adapt:b});return this};b.addBool=function(a,b){return this.add(a,function(d){c(d,b||a,true)})};b.addMinMax=function(e,g,f,a,d,b){return this.add(e,[d||"min",b||"max"],function(b){var e=b.params.min,d=b.params.max;if(e&&d)c(b,a,[e,d]);else if(e)c(b,g,e);else d&&c(b,f,d)})};b.addSingleVal=function(a,b,d){return this.add(a,[b||"val"],function(e){c(e,d||a,e.params[b])})};d.addMethod("__dummy__",function(){return true});d.addMethod("regex",function(b,c,d){var a;if(this.optional(c))return true;a=(new RegExp(d)).exec(b);return a&&a.index===0&&a[0].length===b.length});d.addMethod("nonalphamin",function(c,d,b){var a;if(b){a=c.match(/\W/g);a=a&&a.length>=b}return a});if(d.methods.extension){b.addSingleVal("accept","mimtype");b.addSingleVal("extension","extension")}else b.addSingleVal("extension","extension","accept");b.addSingleVal("regex","pattern");b.addBool("creditcard").addBool("date").addBool("digits").addBool("email").addBool("number").addBool("url");b.addMinMax("length","minlength","maxlength","rangelength").addMinMax("range","min","max","range");b.addMinMax("minlength","minlength").addMinMax("maxlength","minlength","maxlength");b.add("equalto",["other"],function(b){var i=h(b.element.name),j=b.params.other,d=g(j,i),e=a(b.form).find(":input").filter("[name='"+f(d)+"']")[0];c(b,"equalTo",e)});b.add("required",function(a){(a.element.tagName.toUpperCase()!=="INPUT"||a.element.type.toUpperCase()!=="CHECKBOX")&&c(a,"required",true)});b.add("remote",["url","type","additionalfields"],function(b){var d={url:b.params.url,type:b.params.type||"GET",data:{}},e=h(b.element.name);a.each(j(b.params.additionalfields||b.element.name),function(i,h){var c=g(h,e);d.data[c]=function(){var d=a(b.form).find(":input").filter("[name='"+f(c)+"']");return d.is(":checkbox")?d.filter(":checked").val()||d.filter(":hidden").val()||"":d.is(":radio")?d.filter(":checked").val()||"":d.val()}});c(b,"remote",d)});b.add("password",["min","nonalphamin","regex"],function(a){a.params.min&&c(a,"minlength",a.params.min);a.params.nonalphamin&&c(a,"nonalphamin",a.params.nonalphamin);a.params.regex&&c(a,"regex",a.params.regex)});a(function(){d.unobtrusive.parse(document)})})(jQuery);;/*!
 * Bootstrap v3.0.3 (http://getbootstrap.com)
 * Copyright 2013 Twitter, Inc.
 * Licensed under http://www.apache.org/licenses/LICENSE-2.0
 */

if (typeof jQuery === "undefined") { throw new Error("Bootstrap requires jQuery") }

/* ========================================================================
 * Bootstrap: transition.js v3.0.3
 * http://getbootstrap.com/javascript/#transitions
 * ========================================================================
 * Copyright 2013 Twitter, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * ======================================================================== */


+function ($) { "use strict";

  // CSS TRANSITION SUPPORT (Shoutout: http://www.modernizr.com/)
  // ============================================================

  function transitionEnd() {
    var el = document.createElement('bootstrap')

    var transEndEventNames = {
      'WebkitTransition' : 'webkitTransitionEnd'
    , 'MozTransition'    : 'transitionend'
    , 'OTransition'      : 'oTransitionEnd otransitionend'
    , 'transition'       : 'transitionend'
    }

    for (var name in transEndEventNames) {
      if (el.style[name] !== undefined) {
        return { end: transEndEventNames[name] }
      }
    }
  }

  // http://blog.alexmaccaw.com/css-transitions
  $.fn.emulateTransitionEnd = function (duration) {
    var called = false, $el = this
    $(this).one($.support.transition.end, function () { called = true })
    var callback = function () { if (!called) $($el).trigger($.support.transition.end) }
    setTimeout(callback, duration)
    return this
  }

  $(function () {
    $.support.transition = transitionEnd()
  })

}(jQuery);

/* ========================================================================
 * Bootstrap: alert.js v3.0.3
 * http://getbootstrap.com/javascript/#alerts
 * ========================================================================
 * Copyright 2013 Twitter, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * ======================================================================== */


+function ($) { "use strict";

  // ALERT CLASS DEFINITION
  // ======================

  var dismiss = '[data-dismiss="alert"]'
  var Alert   = function (el) {
    $(el).on('click', dismiss, this.close)
  }

  Alert.prototype.close = function (e) {
    var $this    = $(this)
    var selector = $this.attr('data-target')

    if (!selector) {
      selector = $this.attr('href')
      selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
    }

    var $parent = $(selector)

    if (e) e.preventDefault()

    if (!$parent.length) {
      $parent = $this.hasClass('alert') ? $this : $this.parent()
    }

    $parent.trigger(e = $.Event('close.bs.alert'))

    if (e.isDefaultPrevented()) return

    $parent.removeClass('in')

    function removeElement() {
      $parent.trigger('closed.bs.alert').remove()
    }

    $.support.transition && $parent.hasClass('fade') ?
      $parent
        .one($.support.transition.end, removeElement)
        .emulateTransitionEnd(150) :
      removeElement()
  }


  // ALERT PLUGIN DEFINITION
  // =======================

  var old = $.fn.alert

  $.fn.alert = function (option) {
    return this.each(function () {
      var $this = $(this)
      var data  = $this.data('bs.alert')

      if (!data) $this.data('bs.alert', (data = new Alert(this)))
      if (typeof option == 'string') data[option].call($this)
    })
  }

  $.fn.alert.Constructor = Alert


  // ALERT NO CONFLICT
  // =================

  $.fn.alert.noConflict = function () {
    $.fn.alert = old
    return this
  }


  // ALERT DATA-API
  // ==============

  $(document).on('click.bs.alert.data-api', dismiss, Alert.prototype.close)

}(jQuery);

/* ========================================================================
 * Bootstrap: button.js v3.0.3
 * http://getbootstrap.com/javascript/#buttons
 * ========================================================================
 * Copyright 2013 Twitter, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * ======================================================================== */


+function ($) { "use strict";

  // BUTTON PUBLIC CLASS DEFINITION
  // ==============================

  var Button = function (element, options) {
    this.$element = $(element)
    this.options  = $.extend({}, Button.DEFAULTS, options)
  }

  Button.DEFAULTS = {
    loadingText: 'loading...'
  }

  Button.prototype.setState = function (state) {
    var d    = 'disabled'
    var $el  = this.$element
    var val  = $el.is('input') ? 'val' : 'html'
    var data = $el.data()

    state = state + 'Text'

    if (!data.resetText) $el.data('resetText', $el[val]())

    $el[val](data[state] || this.options[state])

    // push to event loop to allow forms to submit
    setTimeout(function () {
      state == 'loadingText' ?
        $el.addClass(d).attr(d, d) :
        $el.removeClass(d).removeAttr(d);
    }, 0)
  }

  Button.prototype.toggle = function () {
    var $parent = this.$element.closest('[data-toggle="buttons"]')
    var changed = true

    if ($parent.length) {
      var $input = this.$element.find('input')
      if ($input.prop('type') === 'radio') {
        // see if clicking on current one
        if ($input.prop('checked') && this.$element.hasClass('active'))
          changed = false
        else
          $parent.find('.active').removeClass('active')
      }
      if (changed) $input.prop('checked', !this.$element.hasClass('active')).trigger('change')
    }

    if (changed) this.$element.toggleClass('active')
  }


  // BUTTON PLUGIN DEFINITION
  // ========================

  var old = $.fn.button

  $.fn.button = function (option) {
    return this.each(function () {
      var $this   = $(this)
      var data    = $this.data('bs.button')
      var options = typeof option == 'object' && option

      if (!data) $this.data('bs.button', (data = new Button(this, options)))

      if (option == 'toggle') data.toggle()
      else if (option) data.setState(option)
    })
  }

  $.fn.button.Constructor = Button


  // BUTTON NO CONFLICT
  // ==================

  $.fn.button.noConflict = function () {
    $.fn.button = old
    return this
  }


  // BUTTON DATA-API
  // ===============

  $(document).on('click.bs.button.data-api', '[data-toggle^=button]', function (e) {
    var $btn = $(e.target)
    if (!$btn.hasClass('btn')) $btn = $btn.closest('.btn')
    $btn.button('toggle')
    e.preventDefault()
  })

}(jQuery);

/* ========================================================================
 * Bootstrap: carousel.js v3.0.3
 * http://getbootstrap.com/javascript/#carousel
 * ========================================================================
 * Copyright 2013 Twitter, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * ======================================================================== */


+function ($) { "use strict";

  // CAROUSEL CLASS DEFINITION
  // =========================

  var Carousel = function (element, options) {
    this.$element    = $(element)
    this.$indicators = this.$element.find('.carousel-indicators')
    this.options     = options
    this.paused      =
    this.sliding     =
    this.interval    =
    this.$active     =
    this.$items      = null

    this.options.pause == 'hover' && this.$element
      .on('mouseenter', $.proxy(this.pause, this))
      .on('mouseleave', $.proxy(this.cycle, this))
  }

  Carousel.DEFAULTS = {
    interval: 5000
  , pause: 'hover'
  , wrap: true
  }

  Carousel.prototype.cycle =  function (e) {
    e || (this.paused = false)

    this.interval && clearInterval(this.interval)

    this.options.interval
      && !this.paused
      && (this.interval = setInterval($.proxy(this.next, this), this.options.interval))

    return this
  }

  Carousel.prototype.getActiveIndex = function () {
    this.$active = this.$element.find('.item.active')
    this.$items  = this.$active.parent().children()

    return this.$items.index(this.$active)
  }

  Carousel.prototype.to = function (pos) {
    var that        = this
    var activeIndex = this.getActiveIndex()

    if (pos > (this.$items.length - 1) || pos < 0) return

    if (this.sliding)       return this.$element.one('slid.bs.carousel', function () { that.to(pos) })
    if (activeIndex == pos) return this.pause().cycle()

    return this.slide(pos > activeIndex ? 'next' : 'prev', $(this.$items[pos]))
  }

  Carousel.prototype.pause = function (e) {
    e || (this.paused = true)

    if (this.$element.find('.next, .prev').length && $.support.transition.end) {
      this.$element.trigger($.support.transition.end)
      this.cycle(true)
    }

    this.interval = clearInterval(this.interval)

    return this
  }

  Carousel.prototype.next = function () {
    if (this.sliding) return
    return this.slide('next')
  }

  Carousel.prototype.prev = function () {
    if (this.sliding) return
    return this.slide('prev')
  }

  Carousel.prototype.slide = function (type, next) {
    var $active   = this.$element.find('.item.active')
    var $next     = next || $active[type]()
    var isCycling = this.interval
    var direction = type == 'next' ? 'left' : 'right'
    var fallback  = type == 'next' ? 'first' : 'last'
    var that      = this

    if (!$next.length) {
      if (!this.options.wrap) return
      $next = this.$element.find('.item')[fallback]()
    }

    this.sliding = true

    isCycling && this.pause()

    var e = $.Event('slide.bs.carousel', { relatedTarget: $next[0], direction: direction })

    if ($next.hasClass('active')) return

    if (this.$indicators.length) {
      this.$indicators.find('.active').removeClass('active')
      this.$element.one('slid.bs.carousel', function () {
        var $nextIndicator = $(that.$indicators.children()[that.getActiveIndex()])
        $nextIndicator && $nextIndicator.addClass('active')
      })
    }

    if ($.support.transition && this.$element.hasClass('slide')) {
      this.$element.trigger(e)
      if (e.isDefaultPrevented()) return
      $next.addClass(type)
      $next[0].offsetWidth // force reflow
      $active.addClass(direction)
      $next.addClass(direction)
      $active
        .one($.support.transition.end, function () {
          $next.removeClass([type, direction].join(' ')).addClass('active')
          $active.removeClass(['active', direction].join(' '))
          that.sliding = false
          setTimeout(function () { that.$element.trigger('slid.bs.carousel') }, 0)
        })
        .emulateTransitionEnd(600)
    } else {
      this.$element.trigger(e)
      if (e.isDefaultPrevented()) return
      $active.removeClass('active')
      $next.addClass('active')
      this.sliding = false
      this.$element.trigger('slid.bs.carousel')
    }

    isCycling && this.cycle()

    return this
  }


  // CAROUSEL PLUGIN DEFINITION
  // ==========================

  var old = $.fn.carousel

  $.fn.carousel = function (option) {
    return this.each(function () {
      var $this   = $(this)
      var data    = $this.data('bs.carousel')
      var options = $.extend({}, Carousel.DEFAULTS, $this.data(), typeof option == 'object' && option)
      var action  = typeof option == 'string' ? option : options.slide

      if (!data) $this.data('bs.carousel', (data = new Carousel(this, options)))
      if (typeof option == 'number') data.to(option)
      else if (action) data[action]()
      else if (options.interval) data.pause().cycle()
    })
  }

  $.fn.carousel.Constructor = Carousel


  // CAROUSEL NO CONFLICT
  // ====================

  $.fn.carousel.noConflict = function () {
    $.fn.carousel = old
    return this
  }


  // CAROUSEL DATA-API
  // =================

  $(document).on('click.bs.carousel.data-api', '[data-slide], [data-slide-to]', function (e) {
    var $this   = $(this), href
    var $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) //strip for ie7
    var options = $.extend({}, $target.data(), $this.data())
    var slideIndex = $this.attr('data-slide-to')
    if (slideIndex) options.interval = false

    $target.carousel(options)

    if (slideIndex = $this.attr('data-slide-to')) {
      $target.data('bs.carousel').to(slideIndex)
    }

    e.preventDefault()
  })

  $(window).on('load', function () {
    $('[data-ride="carousel"]').each(function () {
      var $carousel = $(this)
      $carousel.carousel($carousel.data())
    })
  })

}(jQuery);

/* ========================================================================
 * Bootstrap: collapse.js v3.0.3
 * http://getbootstrap.com/javascript/#collapse
 * ========================================================================
 * Copyright 2013 Twitter, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * ======================================================================== */


+function ($) { "use strict";

  // COLLAPSE PUBLIC CLASS DEFINITION
  // ================================

  var Collapse = function (element, options) {
    this.$element      = $(element)
    this.options       = $.extend({}, Collapse.DEFAULTS, options)
    this.transitioning = null

    if (this.options.parent) this.$parent = $(this.options.parent)
    if (this.options.toggle) this.toggle()
  }

  Collapse.DEFAULTS = {
    toggle: true
  }

  Collapse.prototype.dimension = function () {
    var hasWidth = this.$element.hasClass('width')
    return hasWidth ? 'width' : 'height'
  }

  Collapse.prototype.show = function () {
    if (this.transitioning || this.$element.hasClass('in')) return

    var startEvent = $.Event('show.bs.collapse')
    this.$element.trigger(startEvent)
    if (startEvent.isDefaultPrevented()) return

    var actives = this.$parent && this.$parent.find('> .panel > .in')

    if (actives && actives.length) {
      var hasData = actives.data('bs.collapse')
      if (hasData && hasData.transitioning) return
      actives.collapse('hide')
      hasData || actives.data('bs.collapse', null)
    }

    var dimension = this.dimension()

    this.$element
      .removeClass('collapse')
      .addClass('collapsing')
      [dimension](0)

    this.transitioning = 1

    var complete = function () {
      this.$element
        .removeClass('collapsing')
        .addClass('in')
        [dimension]('auto')
      this.transitioning = 0
      this.$element.trigger('shown.bs.collapse')
    }

    if (!$.support.transition) return complete.call(this)

    var scrollSize = $.camelCase(['scroll', dimension].join('-'))

    this.$element
      .one($.support.transition.end, $.proxy(complete, this))
      .emulateTransitionEnd(350)
      [dimension](this.$element[0][scrollSize])
  }

  Collapse.prototype.hide = function () {
    if (this.transitioning || !this.$element.hasClass('in')) return

    var startEvent = $.Event('hide.bs.collapse')
    this.$element.trigger(startEvent)
    if (startEvent.isDefaultPrevented()) return

    var dimension = this.dimension()

    this.$element
      [dimension](this.$element[dimension]())
      [0].offsetHeight

    this.$element
      .addClass('collapsing')
      .removeClass('collapse')
      .removeClass('in')

    this.transitioning = 1

    var complete = function () {
      this.transitioning = 0
      this.$element
        .trigger('hidden.bs.collapse')
        .removeClass('collapsing')
        .addClass('collapse')
    }

    if (!$.support.transition) return complete.call(this)

    this.$element
      [dimension](0)
      .one($.support.transition.end, $.proxy(complete, this))
      .emulateTransitionEnd(350)
  }

  Collapse.prototype.toggle = function () {
    this[this.$element.hasClass('in') ? 'hide' : 'show']()
  }


  // COLLAPSE PLUGIN DEFINITION
  // ==========================

  var old = $.fn.collapse

  $.fn.collapse = function (option) {
    return this.each(function () {
      var $this   = $(this)
      var data    = $this.data('bs.collapse')
      var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option)

      if (!data) $this.data('bs.collapse', (data = new Collapse(this, options)))
      if (typeof option == 'string') data[option]()
    })
  }

  $.fn.collapse.Constructor = Collapse


  // COLLAPSE NO CONFLICT
  // ====================

  $.fn.collapse.noConflict = function () {
    $.fn.collapse = old
    return this
  }


  // COLLAPSE DATA-API
  // =================

  $(document).on('click.bs.collapse.data-api', '[data-toggle=collapse]', function (e) {
    var $this   = $(this), href
    var target  = $this.attr('data-target')
        || e.preventDefault()
        || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') //strip for ie7
    var $target = $(target)
    var data    = $target.data('bs.collapse')
    var option  = data ? 'toggle' : $this.data()
    var parent  = $this.attr('data-parent')
    var $parent = parent && $(parent)

    if (!data || !data.transitioning) {
      if ($parent) $parent.find('[data-toggle=collapse][data-parent="' + parent + '"]').not($this).addClass('collapsed')
      $this[$target.hasClass('in') ? 'addClass' : 'removeClass']('collapsed')
    }

    $target.collapse(option)
  })

}(jQuery);

/* ========================================================================
 * Bootstrap: dropdown.js v3.0.3
 * http://getbootstrap.com/javascript/#dropdowns
 * ========================================================================
 * Copyright 2013 Twitter, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * ======================================================================== */


+function ($) { "use strict";

  // DROPDOWN CLASS DEFINITION
  // =========================

  var backdrop = '.dropdown-backdrop'
  var toggle   = '[data-toggle=dropdown]'
  var Dropdown = function (element) {
    $(element).on('click.bs.dropdown', this.toggle)
  }

  Dropdown.prototype.toggle = function (e) {
    var $this = $(this)

    if ($this.is('.disabled, :disabled')) return

    var $parent  = getParent($this)
    var isActive = $parent.hasClass('open')

    clearMenus()

    if (!isActive) {
      if ('ontouchstart' in document.documentElement && !$parent.closest('.navbar-nav').length) {
        // if mobile we use a backdrop because click events don't delegate
        $('<div class="dropdown-backdrop"/>').insertAfter($(this)).on('click', clearMenus)
      }

      $parent.trigger(e = $.Event('show.bs.dropdown'))

      if (e.isDefaultPrevented()) return

      $parent
        .toggleClass('open')
        .trigger('shown.bs.dropdown')

      $this.focus()
    }

    return false
  }

  Dropdown.prototype.keydown = function (e) {
    if (!/(38|40|27)/.test(e.keyCode)) return

    var $this = $(this)

    e.preventDefault()
    e.stopPropagation()

    if ($this.is('.disabled, :disabled')) return

    var $parent  = getParent($this)
    var isActive = $parent.hasClass('open')

    if (!isActive || (isActive && e.keyCode == 27)) {
      if (e.which == 27) $parent.find(toggle).focus()
      return $this.click()
    }

    var $items = $('[role=menu] li:not(.divider):visible a', $parent)

    if (!$items.length) return

    var index = $items.index($items.filter(':focus'))

    if (e.keyCode == 38 && index > 0)                 index--                        // up
    if (e.keyCode == 40 && index < $items.length - 1) index++                        // down
    if (!~index)                                      index=0

    $items.eq(index).focus()
  }

  function clearMenus() {
    $(backdrop).remove()
    $(toggle).each(function (e) {
      var $parent = getParent($(this))
      if (!$parent.hasClass('open')) return
      $parent.trigger(e = $.Event('hide.bs.dropdown'))
      if (e.isDefaultPrevented()) return
      $parent.removeClass('open').trigger('hidden.bs.dropdown')
    })
  }

  function getParent($this) {
    var selector = $this.attr('data-target')

    if (!selector) {
      selector = $this.attr('href')
      selector = selector && /#/.test(selector) && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7
    }

    var $parent = selector && $(selector)

    return $parent && $parent.length ? $parent : $this.parent()
  }


  // DROPDOWN PLUGIN DEFINITION
  // ==========================

  var old = $.fn.dropdown

  $.fn.dropdown = function (option) {
    return this.each(function () {
      var $this = $(this)
      var data  = $this.data('bs.dropdown')

      if (!data) $this.data('bs.dropdown', (data = new Dropdown(this)))
      if (typeof option == 'string') data[option].call($this)
    })
  }

  $.fn.dropdown.Constructor = Dropdown


  // DROPDOWN NO CONFLICT
  // ====================

  $.fn.dropdown.noConflict = function () {
    $.fn.dropdown = old
    return this
  }


  // APPLY TO STANDARD DROPDOWN ELEMENTS
  // ===================================

  $(document)
    .on('click.bs.dropdown.data-api', clearMenus)
    .on('click.bs.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() })
    .on('click.bs.dropdown.data-api'  , toggle, Dropdown.prototype.toggle)
    .on('keydown.bs.dropdown.data-api', toggle + ', [role=menu]' , Dropdown.prototype.keydown)

}(jQuery);

/* ========================================================================
 * Bootstrap: modal.js v3.0.3
 * http://getbootstrap.com/javascript/#modals
 * ========================================================================
 * Copyright 2013 Twitter, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * ======================================================================== */


+function ($) { "use strict";

  // MODAL CLASS DEFINITION
  // ======================

  var Modal = function (element, options) {
    this.options   = options
    this.$element  = $(element)
    this.$backdrop =
    this.isShown   = null

    if (this.options.remote) this.$element.load(this.options.remote)
  }

  Modal.DEFAULTS = {
      backdrop: true
    , keyboard: true
    , show: true
  }

  Modal.prototype.toggle = function (_relatedTarget) {
    return this[!this.isShown ? 'show' : 'hide'](_relatedTarget)
  }

  Modal.prototype.show = function (_relatedTarget) {
    var that = this
    var e    = $.Event('show.bs.modal', { relatedTarget: _relatedTarget })

    this.$element.trigger(e)

    if (this.isShown || e.isDefaultPrevented()) return

    this.isShown = true

    this.escape()

    this.$element.on('click.dismiss.modal', '[data-dismiss="modal"]', $.proxy(this.hide, this))

    this.backdrop(function () {
      var transition = $.support.transition && that.$element.hasClass('fade')

      if (!that.$element.parent().length) {
        that.$element.appendTo(document.body) // don't move modals dom position
      }

      that.$element.show()

      if (transition) {
        that.$element[0].offsetWidth // force reflow
      }

      that.$element
        .addClass('in')
        .attr('aria-hidden', false)

      that.enforceFocus()

      var e = $.Event('shown.bs.modal', { relatedTarget: _relatedTarget })

      transition ?
        that.$element.find('.modal-dialog') // wait for modal to slide in
          .one($.support.transition.end, function () {
            that.$element.focus().trigger(e)
          })
          .emulateTransitionEnd(300) :
        that.$element.focus().trigger(e)
    })
  }

  Modal.prototype.hide = function (e) {
    if (e) e.preventDefault()

    e = $.Event('hide.bs.modal')

    this.$element.trigger(e)

    if (!this.isShown || e.isDefaultPrevented()) return

    this.isShown = false

    this.escape()

    $(document).off('focusin.bs.modal')

    this.$element
      .removeClass('in')
      .attr('aria-hidden', true)
      .off('click.dismiss.modal')

    $.support.transition && this.$element.hasClass('fade') ?
      this.$element
        .one($.support.transition.end, $.proxy(this.hideModal, this))
        .emulateTransitionEnd(300) :
      this.hideModal()
  }

  Modal.prototype.enforceFocus = function () {
    $(document)
      .off('focusin.bs.modal') // guard against infinite focus loop
      .on('focusin.bs.modal', $.proxy(function (e) {
        if (this.$element[0] !== e.target && !this.$element.has(e.target).length) {
          this.$element.focus()
        }
      }, this))
  }

  Modal.prototype.escape = function () {
    if (this.isShown && this.options.keyboard) {
      this.$element.on('keyup.dismiss.bs.modal', $.proxy(function (e) {
        e.which == 27 && this.hide()
      }, this))
    } else if (!this.isShown) {
      this.$element.off('keyup.dismiss.bs.modal')
    }
  }

  Modal.prototype.hideModal = function () {
    var that = this
    this.$element.hide()
    this.backdrop(function () {
      that.removeBackdrop()
      that.$element.trigger('hidden.bs.modal')
    })
  }

  Modal.prototype.removeBackdrop = function () {
    this.$backdrop && this.$backdrop.remove()
    this.$backdrop = null
  }

  Modal.prototype.backdrop = function (callback) {
    var that    = this
    var animate = this.$element.hasClass('fade') ? 'fade' : ''

    if (this.isShown && this.options.backdrop) {
      var doAnimate = $.support.transition && animate

      this.$backdrop = $('<div class="modal-backdrop ' + animate + '" />')
        .appendTo(document.body)

      this.$element.on('click.dismiss.modal', $.proxy(function (e) {
        if (e.target !== e.currentTarget) return
        this.options.backdrop == 'static'
          ? this.$element[0].focus.call(this.$element[0])
          : this.hide.call(this)
      }, this))

      if (doAnimate) this.$backdrop[0].offsetWidth // force reflow

      this.$backdrop.addClass('in')

      if (!callback) return

      doAnimate ?
        this.$backdrop
          .one($.support.transition.end, callback)
          .emulateTransitionEnd(150) :
        callback()

    } else if (!this.isShown && this.$backdrop) {
      this.$backdrop.removeClass('in')

      $.support.transition && this.$element.hasClass('fade')?
        this.$backdrop
          .one($.support.transition.end, callback)
          .emulateTransitionEnd(150) :
        callback()

    } else if (callback) {
      callback()
    }
  }


  // MODAL PLUGIN DEFINITION
  // =======================

  var old = $.fn.modal

  $.fn.modal = function (option, _relatedTarget) {
    return this.each(function () {
      var $this   = $(this)
      var data    = $this.data('bs.modal')
      var options = $.extend({}, Modal.DEFAULTS, $this.data(), typeof option == 'object' && option)

      if (!data) $this.data('bs.modal', (data = new Modal(this, options)))
      if (typeof option == 'string') data[option](_relatedTarget)
      else if (options.show) data.show(_relatedTarget)
    })
  }

  $.fn.modal.Constructor = Modal


  // MODAL NO CONFLICT
  // =================

  $.fn.modal.noConflict = function () {
    $.fn.modal = old
    return this
  }


  // MODAL DATA-API
  // ==============

  $(document).on('click.bs.modal.data-api', '[data-toggle="modal"]', function (e) {
    var $this   = $(this)
    var href    = $this.attr('href')
    var $target = $($this.attr('data-target') || (href && href.replace(/.*(?=#[^\s]+$)/, ''))) //strip for ie7
    var option  = $target.data('modal') ? 'toggle' : $.extend({ remote: !/#/.test(href) && href }, $target.data(), $this.data())

    e.preventDefault()

    $target
      .modal(option, this)
      .one('hide', function () {
        $this.is(':visible') && $this.focus()
      })
  })

  $(document)
    .on('show.bs.modal',  '.modal', function () { $(document.body).addClass('modal-open') })
    .on('hidden.bs.modal', '.modal', function () { $(document.body).removeClass('modal-open') })

}(jQuery);

/* ========================================================================
 * Bootstrap: tooltip.js v3.0.3
 * http://getbootstrap.com/javascript/#tooltip
 * Inspired by the original jQuery.tipsy by Jason Frame
 * ========================================================================
 * Copyright 2013 Twitter, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * ======================================================================== */


+function ($) { "use strict";

  // TOOLTIP PUBLIC CLASS DEFINITION
  // ===============================

  var Tooltip = function (element, options) {
    this.type       =
    this.options    =
    this.enabled    =
    this.timeout    =
    this.hoverState =
    this.$element   = null

    this.init('tooltip', element, options)
  }

  Tooltip.DEFAULTS = {
    animation: true
  , placement: 'top'
  , selector: false
  , template: '<div class="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>'
  , trigger: 'hover focus'
  , title: ''
  , delay: 0
  , html: false
  , container: false
  }

  Tooltip.prototype.init = function (type, element, options) {
    this.enabled  = true
    this.type     = type
    this.$element = $(element)
    this.options  = this.getOptions(options)

    var triggers = this.options.trigger.split(' ')

    for (var i = triggers.length; i--;) {
      var trigger = triggers[i]

      if (trigger == 'click') {
        this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this))
      } else if (trigger != 'manual') {
        var eventIn  = trigger == 'hover' ? 'mouseenter' : 'focus'
        var eventOut = trigger == 'hover' ? 'mouseleave' : 'blur'

        this.$element.on(eventIn  + '.' + this.type, this.options.selector, $.proxy(this.enter, this))
        this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this))
      }
    }

    this.options.selector ?
      (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) :
      this.fixTitle()
  }

  Tooltip.prototype.getDefaults = function () {
    return Tooltip.DEFAULTS
  }

  Tooltip.prototype.getOptions = function (options) {
    options = $.extend({}, this.getDefaults(), this.$element.data(), options)

    if (options.delay && typeof options.delay == 'number') {
      options.delay = {
        show: options.delay
      , hide: options.delay
      }
    }

    return options
  }

  Tooltip.prototype.getDelegateOptions = function () {
    var options  = {}
    var defaults = this.getDefaults()

    this._options && $.each(this._options, function (key, value) {
      if (defaults[key] != value) options[key] = value
    })

    return options
  }

  Tooltip.prototype.enter = function (obj) {
    var self = obj instanceof this.constructor ?
      obj : $(obj.currentTarget)[this.type](this.getDelegateOptions()).data('bs.' + this.type)

    clearTimeout(self.timeout)

    self.hoverState = 'in'

    if (!self.options.delay || !self.options.delay.show) return self.show()

    self.timeout = setTimeout(function () {
      if (self.hoverState == 'in') self.show()
    }, self.options.delay.show)
  }

  Tooltip.prototype.leave = function (obj) {
    var self = obj instanceof this.constructor ?
      obj : $(obj.currentTarget)[this.type](this.getDelegateOptions()).data('bs.' + this.type)

    clearTimeout(self.timeout)

    self.hoverState = 'out'

    if (!self.options.delay || !self.options.delay.hide) return self.hide()

    self.timeout = setTimeout(function () {
      if (self.hoverState == 'out') self.hide()
    }, self.options.delay.hide)
  }

  Tooltip.prototype.show = function () {
    var e = $.Event('show.bs.'+ this.type)

    if (this.hasContent() && this.enabled) {
      this.$element.trigger(e)

      if (e.isDefaultPrevented()) return

      var $tip = this.tip()

      this.setContent()

      if (this.options.animation) $tip.addClass('fade')

      var placement = typeof this.options.placement == 'function' ?
        this.options.placement.call(this, $tip[0], this.$element[0]) :
        this.options.placement

      var autoToken = /\s?auto?\s?/i
      var autoPlace = autoToken.test(placement)
      if (autoPlace) placement = placement.replace(autoToken, '') || 'top'

      $tip
        .detach()
        .css({ top: 0, left: 0, display: 'block' })
        .addClass(placement)

      this.options.container ? $tip.appendTo(this.options.container) : $tip.insertAfter(this.$element)

      var pos          = this.getPosition()
      var actualWidth  = $tip[0].offsetWidth
      var actualHeight = $tip[0].offsetHeight

      if (autoPlace) {
        var $parent = this.$element.parent()

        var orgPlacement = placement
        var docScroll    = document.documentElement.scrollTop || document.body.scrollTop
        var parentWidth  = this.options.container == 'body' ? window.innerWidth  : $parent.outerWidth()
        var parentHeight = this.options.container == 'body' ? window.innerHeight : $parent.outerHeight()
        var parentLeft   = this.options.container == 'body' ? 0 : $parent.offset().left

        placement = placement == 'bottom' && pos.top   + pos.height  + actualHeight - docScroll > parentHeight  ? 'top'    :
                    placement == 'top'    && pos.top   - docScroll   - actualHeight < 0                         ? 'bottom' :
                    placement == 'right'  && pos.right + actualWidth > parentWidth                              ? 'left'   :
                    placement == 'left'   && pos.left  - actualWidth < parentLeft                               ? 'right'  :
                    placement

        $tip
          .removeClass(orgPlacement)
          .addClass(placement)
      }

      var calculatedOffset = this.getCalculatedOffset(placement, pos, actualWidth, actualHeight)

      this.applyPlacement(calculatedOffset, placement)
      this.$element.trigger('shown.bs.' + this.type)
    }
  }

  Tooltip.prototype.applyPlacement = function(offset, placement) {
    var replace
    var $tip   = this.tip()
    var width  = $tip[0].offsetWidth
    var height = $tip[0].offsetHeight

    // manually read margins because getBoundingClientRect includes difference
    var marginTop = parseInt($tip.css('margin-top'), 10)
    var marginLeft = parseInt($tip.css('margin-left'), 10)

    // we must check for NaN for ie 8/9
    if (isNaN(marginTop))  marginTop  = 0
    if (isNaN(marginLeft)) marginLeft = 0

    offset.top  = offset.top  + marginTop
    offset.left = offset.left + marginLeft

    $tip
      .offset(offset)
      .addClass('in')

    // check to see if placing tip in new offset caused the tip to resize itself
    var actualWidth  = $tip[0].offsetWidth
    var actualHeight = $tip[0].offsetHeight

    if (placement == 'top' && actualHeight != height) {
      replace = true
      offset.top = offset.top + height - actualHeight
    }

    if (/bottom|top/.test(placement)) {
      var delta = 0

      if (offset.left < 0) {
        delta       = offset.left * -2
        offset.left = 0

        $tip.offset(offset)

        actualWidth  = $tip[0].offsetWidth
        actualHeight = $tip[0].offsetHeight
      }

      this.replaceArrow(delta - width + actualWidth, actualWidth, 'left')
    } else {
      this.replaceArrow(actualHeight - height, actualHeight, 'top')
    }

    if (replace) $tip.offset(offset)
  }

  Tooltip.prototype.replaceArrow = function(delta, dimension, position) {
    this.arrow().css(position, delta ? (50 * (1 - delta / dimension) + "%") : '')
  }

  Tooltip.prototype.setContent = function () {
    var $tip  = this.tip()
    var title = this.getTitle()

    $tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title)
    $tip.removeClass('fade in top bottom left right')
  }

  Tooltip.prototype.hide = function () {
    var that = this
    var $tip = this.tip()
    var e    = $.Event('hide.bs.' + this.type)

    function complete() {
      if (that.hoverState != 'in') $tip.detach()
    }

    this.$element.trigger(e)

    if (e.isDefaultPrevented()) return

    $tip.removeClass('in')

    $.support.transition && this.$tip.hasClass('fade') ?
      $tip
        .one($.support.transition.end, complete)
        .emulateTransitionEnd(150) :
      complete()

    this.$element.trigger('hidden.bs.' + this.type)

    return this
  }

  Tooltip.prototype.fixTitle = function () {
    var $e = this.$element
    if ($e.attr('title') || typeof($e.attr('data-original-title')) != 'string') {
      $e.attr('data-original-title', $e.attr('title') || '').attr('title', '')
    }
  }

  Tooltip.prototype.hasContent = function () {
    return this.getTitle()
  }

  Tooltip.prototype.getPosition = function () {
    var el = this.$element[0]
    return $.extend({}, (typeof el.getBoundingClientRect == 'function') ? el.getBoundingClientRect() : {
      width: el.offsetWidth
    , height: el.offsetHeight
    }, this.$element.offset())
  }

  Tooltip.prototype.getCalculatedOffset = function (placement, pos, actualWidth, actualHeight) {
    return placement == 'bottom' ? { top: pos.top + pos.height,   left: pos.left + pos.width / 2 - actualWidth / 2  } :
           placement == 'top'    ? { top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2  } :
           placement == 'left'   ? { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth } :
        /* placement == 'right' */ { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width   }
  }

  Tooltip.prototype.getTitle = function () {
    var title
    var $e = this.$element
    var o  = this.options

    title = $e.attr('data-original-title')
      || (typeof o.title == 'function' ? o.title.call($e[0]) :  o.title)

    return title
  }

  Tooltip.prototype.tip = function () {
    return this.$tip = this.$tip || $(this.options.template)
  }

  Tooltip.prototype.arrow = function () {
    return this.$arrow = this.$arrow || this.tip().find('.tooltip-arrow')
  }

  Tooltip.prototype.validate = function () {
    if (!this.$element[0].parentNode) {
      this.hide()
      this.$element = null
      this.options  = null
    }
  }

  Tooltip.prototype.enable = function () {
    this.enabled = true
  }

  Tooltip.prototype.disable = function () {
    this.enabled = false
  }

  Tooltip.prototype.toggleEnabled = function () {
    this.enabled = !this.enabled
  }

  Tooltip.prototype.toggle = function (e) {
    var self = e ? $(e.currentTarget)[this.type](this.getDelegateOptions()).data('bs.' + this.type) : this
    self.tip().hasClass('in') ? self.leave(self) : self.enter(self)
  }

  Tooltip.prototype.destroy = function () {
    this.hide().$element.off('.' + this.type).removeData('bs.' + this.type)
  }


  // TOOLTIP PLUGIN DEFINITION
  // =========================

  var old = $.fn.tooltip

  $.fn.tooltip = function (option) {
    return this.each(function () {
      var $this   = $(this)
      var data    = $this.data('bs.tooltip')
      var options = typeof option == 'object' && option

      if (!data) $this.data('bs.tooltip', (data = new Tooltip(this, options)))
      if (typeof option == 'string') data[option]()
    })
  }

  $.fn.tooltip.Constructor = Tooltip


  // TOOLTIP NO CONFLICT
  // ===================

  $.fn.tooltip.noConflict = function () {
    $.fn.tooltip = old
    return this
  }

}(jQuery);

/* ========================================================================
 * Bootstrap: popover.js v3.0.3
 * http://getbootstrap.com/javascript/#popovers
 * ========================================================================
 * Copyright 2013 Twitter, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * ======================================================================== */


+function ($) { "use strict";

  // POPOVER PUBLIC CLASS DEFINITION
  // ===============================

  var Popover = function (element, options) {
    this.init('popover', element, options)
  }

  if (!$.fn.tooltip) throw new Error('Popover requires tooltip.js')

  Popover.DEFAULTS = $.extend({} , $.fn.tooltip.Constructor.DEFAULTS, {
    placement: 'right'
  , trigger: 'click'
  , content: ''
  , template: '<div class="popover"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>'
  })


  // NOTE: POPOVER EXTENDS tooltip.js
  // ================================

  Popover.prototype = $.extend({}, $.fn.tooltip.Constructor.prototype)

  Popover.prototype.constructor = Popover

  Popover.prototype.getDefaults = function () {
    return Popover.DEFAULTS
  }

  Popover.prototype.setContent = function () {
    var $tip    = this.tip()
    var title   = this.getTitle()
    var content = this.getContent()

    $tip.find('.popover-title')[this.options.html ? 'html' : 'text'](title)
    $tip.find('.popover-content')[this.options.html ? 'html' : 'text'](content)

    $tip.removeClass('fade top bottom left right in')

    // IE8 doesn't accept hiding via the `:empty` pseudo selector, we have to do
    // this manually by checking the contents.
    if (!$tip.find('.popover-title').html()) $tip.find('.popover-title').hide()
  }

  Popover.prototype.hasContent = function () {
    return this.getTitle() || this.getContent()
  }

  Popover.prototype.getContent = function () {
    var $e = this.$element
    var o  = this.options

    return $e.attr('data-content')
      || (typeof o.content == 'function' ?
            o.content.call($e[0]) :
            o.content)
  }

  Popover.prototype.arrow = function () {
    return this.$arrow = this.$arrow || this.tip().find('.arrow')
  }

  Popover.prototype.tip = function () {
    if (!this.$tip) this.$tip = $(this.options.template)
    return this.$tip
  }


  // POPOVER PLUGIN DEFINITION
  // =========================

  var old = $.fn.popover

  $.fn.popover = function (option) {
    return this.each(function () {
      var $this   = $(this)
      var data    = $this.data('bs.popover')
      var options = typeof option == 'object' && option

      if (!data) $this.data('bs.popover', (data = new Popover(this, options)))
      if (typeof option == 'string') data[option]()
    })
  }

  $.fn.popover.Constructor = Popover


  // POPOVER NO CONFLICT
  // ===================

  $.fn.popover.noConflict = function () {
    $.fn.popover = old
    return this
  }

}(jQuery);

/* ========================================================================
 * Bootstrap: scrollspy.js v3.0.3
 * http://getbootstrap.com/javascript/#scrollspy
 * ========================================================================
 * Copyright 2013 Twitter, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * ======================================================================== */


+function ($) { "use strict";

  // SCROLLSPY CLASS DEFINITION
  // ==========================

  function ScrollSpy(element, options) {
    var href
    var process  = $.proxy(this.process, this)

    this.$element       = $(element).is('body') ? $(window) : $(element)
    this.$body          = $('body')
    this.$scrollElement = this.$element.on('scroll.bs.scroll-spy.data-api', process)
    this.options        = $.extend({}, ScrollSpy.DEFAULTS, options)
    this.selector       = (this.options.target
      || ((href = $(element).attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) //strip for ie7
      || '') + ' .nav li > a'
    this.offsets        = $([])
    this.targets        = $([])
    this.activeTarget   = null

    this.refresh()
    this.process()
  }

  ScrollSpy.DEFAULTS = {
    offset: 10
  }

  ScrollSpy.prototype.refresh = function () {
    var offsetMethod = this.$element[0] == window ? 'offset' : 'position'

    this.offsets = $([])
    this.targets = $([])

    var self     = this
    var $targets = this.$body
      .find(this.selector)
      .map(function () {
        var $el   = $(this)
        var href  = $el.data('target') || $el.attr('href')
        var $href = /^#\w/.test(href) && $(href)

        return ($href
          && $href.length
          && [[ $href[offsetMethod]().top + (!$.isWindow(self.$scrollElement.get(0)) && self.$scrollElement.scrollTop()), href ]]) || null
      })
      .sort(function (a, b) { return a[0] - b[0] })
      .each(function () {
        self.offsets.push(this[0])
        self.targets.push(this[1])
      })
  }

  ScrollSpy.prototype.process = function () {
    var scrollTop    = this.$scrollElement.scrollTop() + this.options.offset
    var scrollHeight = this.$scrollElement[0].scrollHeight || this.$body[0].scrollHeight
    var maxScroll    = scrollHeight - this.$scrollElement.height()
    var offsets      = this.offsets
    var targets      = this.targets
    var activeTarget = this.activeTarget
    var i

    if (scrollTop >= maxScroll) {
      return activeTarget != (i = targets.last()[0]) && this.activate(i)
    }

    for (i = offsets.length; i--;) {
      activeTarget != targets[i]
        && scrollTop >= offsets[i]
        && (!offsets[i + 1] || scrollTop <= offsets[i + 1])
        && this.activate( targets[i] )
    }
  }

  ScrollSpy.prototype.activate = function (target) {
    this.activeTarget = target

    $(this.selector)
      .parents('.active')
      .removeClass('active')

    var selector = this.selector
      + '[data-target="' + target + '"],'
      + this.selector + '[href="' + target + '"]'

    var active = $(selector)
      .parents('li')
      .addClass('active')

    if (active.parent('.dropdown-menu').length)  {
      active = active
        .closest('li.dropdown')
        .addClass('active')
    }

    active.trigger('activate.bs.scrollspy')
  }


  // SCROLLSPY PLUGIN DEFINITION
  // ===========================

  var old = $.fn.scrollspy

  $.fn.scrollspy = function (option) {
    return this.each(function () {
      var $this   = $(this)
      var data    = $this.data('bs.scrollspy')
      var options = typeof option == 'object' && option

      if (!data) $this.data('bs.scrollspy', (data = new ScrollSpy(this, options)))
      if (typeof option == 'string') data[option]()
    })
  }

  $.fn.scrollspy.Constructor = ScrollSpy


  // SCROLLSPY NO CONFLICT
  // =====================

  $.fn.scrollspy.noConflict = function () {
    $.fn.scrollspy = old
    return this
  }


  // SCROLLSPY DATA-API
  // ==================

  $(window).on('load', function () {
    $('[data-spy="scroll"]').each(function () {
      var $spy = $(this)
      $spy.scrollspy($spy.data())
    })
  })

}(jQuery);

/* ========================================================================
 * Bootstrap: tab.js v3.0.3
 * http://getbootstrap.com/javascript/#tabs
 * ========================================================================
 * Copyright 2013 Twitter, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * ======================================================================== */


+function ($) { "use strict";

  // TAB CLASS DEFINITION
  // ====================

  var Tab = function (element) {
    this.element = $(element)
  }

  Tab.prototype.show = function () {
    var $this    = this.element
    var $ul      = $this.closest('ul:not(.dropdown-menu)')
    var selector = $this.data('target')

    if (!selector) {
      selector = $this.attr('href')
      selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7
    }

    if ($this.parent('li').hasClass('active')) return

    var previous = $ul.find('.active:last a')[0]
    var e        = $.Event('show.bs.tab', {
      relatedTarget: previous
    })

    $this.trigger(e)

    if (e.isDefaultPrevented()) return

    var $target = $(selector)

    this.activate($this.parent('li'), $ul)
    this.activate($target, $target.parent(), function () {
      $this.trigger({
        type: 'shown.bs.tab'
      , relatedTarget: previous
      })
    })
  }

  Tab.prototype.activate = function (element, container, callback) {
    var $active    = container.find('> .active')
    var transition = callback
      && $.support.transition
      && $active.hasClass('fade')

    function next() {
      $active
        .removeClass('active')
        .find('> .dropdown-menu > .active')
        .removeClass('active')

      element.addClass('active')

      if (transition) {
        element[0].offsetWidth // reflow for transition
        element.addClass('in')
      } else {
        element.removeClass('fade')
      }

      if (element.parent('.dropdown-menu')) {
        element.closest('li.dropdown').addClass('active')
      }

      callback && callback()
    }

    transition ?
      $active
        .one($.support.transition.end, next)
        .emulateTransitionEnd(150) :
      next()

    $active.removeClass('in')
  }


  // TAB PLUGIN DEFINITION
  // =====================

  var old = $.fn.tab

  $.fn.tab = function ( option ) {
    return this.each(function () {
      var $this = $(this)
      var data  = $this.data('bs.tab')

      if (!data) $this.data('bs.tab', (data = new Tab(this)))
      if (typeof option == 'string') data[option]()
    })
  }

  $.fn.tab.Constructor = Tab


  // TAB NO CONFLICT
  // ===============

  $.fn.tab.noConflict = function () {
    $.fn.tab = old
    return this
  }


  // TAB DATA-API
  // ============

  $(document).on('click.bs.tab.data-api', '[data-toggle="tab"], [data-toggle="pill"]', function (e) {
    e.preventDefault()
    $(this).tab('show')
  })

}(jQuery);

/* ========================================================================
 * Bootstrap: affix.js v3.0.3
 * http://getbootstrap.com/javascript/#affix
 * ========================================================================
 * Copyright 2013 Twitter, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * ======================================================================== */


+function ($) { "use strict";

  // AFFIX CLASS DEFINITION
  // ======================

  var Affix = function (element, options) {
    this.options = $.extend({}, Affix.DEFAULTS, options)
    this.$window = $(window)
      .on('scroll.bs.affix.data-api', $.proxy(this.checkPosition, this))
      .on('click.bs.affix.data-api',  $.proxy(this.checkPositionWithEventLoop, this))

    this.$element = $(element)
    this.affixed  =
    this.unpin    = null

    this.checkPosition()
  }

  Affix.RESET = 'affix affix-top affix-bottom'

  Affix.DEFAULTS = {
    offset: 0
  }

  Affix.prototype.checkPositionWithEventLoop = function () {
    setTimeout($.proxy(this.checkPosition, this), 1)
  }

  Affix.prototype.checkPosition = function () {
    if (!this.$element.is(':visible')) return

    var scrollHeight = $(document).height()
    var scrollTop    = this.$window.scrollTop()
    var position     = this.$element.offset()
    var offset       = this.options.offset
    var offsetTop    = offset.top
    var offsetBottom = offset.bottom

    if (typeof offset != 'object')         offsetBottom = offsetTop = offset
    if (typeof offsetTop == 'function')    offsetTop    = offset.top()
    if (typeof offsetBottom == 'function') offsetBottom = offset.bottom()

    var affix = this.unpin   != null && (scrollTop + this.unpin <= position.top) ? false :
                offsetBottom != null && (position.top + this.$element.height() >= scrollHeight - offsetBottom) ? 'bottom' :
                offsetTop    != null && (scrollTop <= offsetTop) ? 'top' : false

    if (this.affixed === affix) return
    if (this.unpin) this.$element.css('top', '')

    this.affixed = affix
    this.unpin   = affix == 'bottom' ? position.top - scrollTop : null

    this.$element.removeClass(Affix.RESET).addClass('affix' + (affix ? '-' + affix : ''))

    if (affix == 'bottom') {
      this.$element.offset({ top: document.body.offsetHeight - offsetBottom - this.$element.height() })
    }
  }


  // AFFIX PLUGIN DEFINITION
  // =======================

  var old = $.fn.affix

  $.fn.affix = function (option) {
    return this.each(function () {
      var $this   = $(this)
      var data    = $this.data('bs.affix')
      var options = typeof option == 'object' && option

      if (!data) $this.data('bs.affix', (data = new Affix(this, options)))
      if (typeof option == 'string') data[option]()
    })
  }

  $.fn.affix.Constructor = Affix


  // AFFIX NO CONFLICT
  // =================

  $.fn.affix.noConflict = function () {
    $.fn.affix = old
    return this
  }


  // AFFIX DATA-API
  // ==============

  $(window).on('load', function () {
    $('[data-spy="affix"]').each(function () {
      var $spy = $(this)
      var data = $spy.data()

      data.offset = data.offset || {}

      if (data.offsetBottom) data.offset.bottom = data.offsetBottom
      if (data.offsetTop)    data.offset.top    = data.offsetTop

      $spy.affix(data)
    })
  })

}(jQuery);
;/*!
* jQuery Cycle2; version: 2.1.5 build: 20140415
* http://jquery.malsup.com/cycle2/
* Copyright (c) 2014 M. Alsup; Dual licensed: MIT/GPL
*/

/* Cycle2 core engine */
;(function($) {
"use strict";

var version = '2.1.5';

$.fn.cycle = function( options ) {
    // fix mistakes with the ready state
    var o;
    if ( this.length === 0 && !$.isReady ) {
        o = { s: this.selector, c: this.context };
        $.fn.cycle.log('requeuing slideshow (dom not ready)');
        $(function() {
            $( o.s, o.c ).cycle(options);
        });
        return this;
    }

    return this.each(function() {
        var data, opts, shortName, val;
        var container = $(this);
        var log = $.fn.cycle.log;

        if ( container.data('cycle.opts') )
            return; // already initialized

        if ( container.data('cycle-log') === false || 
            ( options && options.log === false ) ||
            ( opts && opts.log === false) ) {
            log = $.noop;
        }

        log('--c2 init--');
        data = container.data();
        for (var p in data) {
            // allow props to be accessed sans 'cycle' prefix and log the overrides
            if (data.hasOwnProperty(p) && /^cycle[A-Z]+/.test(p) ) {
                val = data[p];
                shortName = p.match(/^cycle(.*)/)[1].replace(/^[A-Z]/, lowerCase);
                log(shortName+':', val, '('+typeof val +')');
                data[shortName] = val;
            }
        }

        opts = $.extend( {}, $.fn.cycle.defaults, data, options || {});

        opts.timeoutId = 0;
        opts.paused = opts.paused || false; // #57
        opts.container = container;
        opts._maxZ = opts.maxZ;

        opts.API = $.extend ( { _container: container }, $.fn.cycle.API );
        opts.API.log = log;
        opts.API.trigger = function( eventName, args ) {
            opts.container.trigger( eventName, args );
            return opts.API;
        };

        container.data( 'cycle.opts', opts );
        container.data( 'cycle.API', opts.API );

        // opportunity for plugins to modify opts and API
        opts.API.trigger('cycle-bootstrap', [ opts, opts.API ]);

        opts.API.addInitialSlides();
        opts.API.preInitSlideshow();

        if ( opts.slides.length )
            opts.API.initSlideshow();
    });
};

$.fn.cycle.API = {
    opts: function() {
        return this._container.data( 'cycle.opts' );
    },
    addInitialSlides: function() {
        var opts = this.opts();
        var slides = opts.slides;
        opts.slideCount = 0;
        opts.slides = $(); // empty set
        
        // add slides that already exist
        slides = slides.jquery ? slides : opts.container.find( slides );

        if ( opts.random ) {
            slides.sort(function() {return Math.random() - 0.5;});
        }

        opts.API.add( slides );
    },

    preInitSlideshow: function() {
        var opts = this.opts();
        opts.API.trigger('cycle-pre-initialize', [ opts ]);
        var tx = $.fn.cycle.transitions[opts.fx];
        if (tx && $.isFunction(tx.preInit))
            tx.preInit( opts );
        opts._preInitialized = true;
    },

    postInitSlideshow: function() {
        var opts = this.opts();
        opts.API.trigger('cycle-post-initialize', [ opts ]);
        var tx = $.fn.cycle.transitions[opts.fx];
        if (tx && $.isFunction(tx.postInit))
            tx.postInit( opts );
    },

    initSlideshow: function() {
        var opts = this.opts();
        var pauseObj = opts.container;
        var slideOpts;
        opts.API.calcFirstSlide();

        if ( opts.container.css('position') == 'static' )
            opts.container.css('position', 'relative');

        $(opts.slides[opts.currSlide]).css({
            opacity: 1,
            display: 'block',
            visibility: 'visible'
        });
        opts.API.stackSlides( opts.slides[opts.currSlide], opts.slides[opts.nextSlide], !opts.reverse );

        if ( opts.pauseOnHover ) {
            // allow pauseOnHover to specify an element
            if ( opts.pauseOnHover !== true )
                pauseObj = $( opts.pauseOnHover );

            pauseObj.hover(
                function(){ opts.API.pause( true ); }, 
                function(){ opts.API.resume( true ); }
            );
        }

        // stage initial transition
        if ( opts.timeout ) {
            slideOpts = opts.API.getSlideOpts( opts.currSlide );
            opts.API.queueTransition( slideOpts, slideOpts.timeout + opts.delay );
        }

        opts._initialized = true;
        opts.API.updateView( true );
        opts.API.trigger('cycle-initialized', [ opts ]);
        opts.API.postInitSlideshow();
    },

    pause: function( hover ) {
        var opts = this.opts(),
            slideOpts = opts.API.getSlideOpts(),
            alreadyPaused = opts.hoverPaused || opts.paused;

        if ( hover )
            opts.hoverPaused = true; 
        else
            opts.paused = true;

        if ( ! alreadyPaused ) {
            opts.container.addClass('cycle-paused');
            opts.API.trigger('cycle-paused', [ opts ]).log('cycle-paused');

            if ( slideOpts.timeout ) {
                clearTimeout( opts.timeoutId );
                opts.timeoutId = 0;
                
                // determine how much time is left for the current slide
                opts._remainingTimeout -= ( $.now() - opts._lastQueue );
                if ( opts._remainingTimeout < 0 || isNaN(opts._remainingTimeout) )
                    opts._remainingTimeout = undefined;
            }
        }
    },

    resume: function( hover ) {
        var opts = this.opts(),
            alreadyResumed = !opts.hoverPaused && !opts.paused,
            remaining;

        if ( hover )
            opts.hoverPaused = false; 
        else
            opts.paused = false;

    
        if ( ! alreadyResumed ) {
            opts.container.removeClass('cycle-paused');
            // #gh-230; if an animation is in progress then don't queue a new transition; it will
            // happen naturally
            if ( opts.slides.filter(':animated').length === 0 )
                opts.API.queueTransition( opts.API.getSlideOpts(), opts._remainingTimeout );
            opts.API.trigger('cycle-resumed', [ opts, opts._remainingTimeout ] ).log('cycle-resumed');
        }
    },

    add: function( slides, prepend ) {
        var opts = this.opts();
        var oldSlideCount = opts.slideCount;
        var startSlideshow = false;
        var len;

        if ( $.type(slides) == 'string')
            slides = $.trim( slides );

        $( slides ).each(function(i) {
            var slideOpts;
            var slide = $(this);

            if ( prepend )
                opts.container.prepend( slide );
            else
                opts.container.append( slide );

            opts.slideCount++;
            slideOpts = opts.API.buildSlideOpts( slide );

            if ( prepend )
                opts.slides = $( slide ).add( opts.slides );
            else
                opts.slides = opts.slides.add( slide );

            opts.API.initSlide( slideOpts, slide, --opts._maxZ );

            slide.data('cycle.opts', slideOpts);
            opts.API.trigger('cycle-slide-added', [ opts, slideOpts, slide ]);
        });

        opts.API.updateView( true );

        startSlideshow = opts._preInitialized && (oldSlideCount < 2 && opts.slideCount >= 1);
        if ( startSlideshow ) {
            if ( !opts._initialized )
                opts.API.initSlideshow();
            else if ( opts.timeout ) {
                len = opts.slides.length;
                opts.nextSlide = opts.reverse ? len - 1 : 1;
                if ( !opts.timeoutId ) {
                    opts.API.queueTransition( opts );
                }
            }
        }
    },

    calcFirstSlide: function() {
        var opts = this.opts();
        var firstSlideIndex;
        firstSlideIndex = parseInt( opts.startingSlide || 0, 10 );
        if (firstSlideIndex >= opts.slides.length || firstSlideIndex < 0)
            firstSlideIndex = 0;

        opts.currSlide = firstSlideIndex;
        if ( opts.reverse ) {
            opts.nextSlide = firstSlideIndex - 1;
            if (opts.nextSlide < 0)
                opts.nextSlide = opts.slides.length - 1;
        }
        else {
            opts.nextSlide = firstSlideIndex + 1;
            if (opts.nextSlide == opts.slides.length)
                opts.nextSlide = 0;
        }
    },

    calcNextSlide: function() {
        var opts = this.opts();
        var roll;
        if ( opts.reverse ) {
            roll = (opts.nextSlide - 1) < 0;
            opts.nextSlide = roll ? opts.slideCount - 1 : opts.nextSlide-1;
            opts.currSlide = roll ? 0 : opts.nextSlide+1;
        }
        else {
            roll = (opts.nextSlide + 1) == opts.slides.length;
            opts.nextSlide = roll ? 0 : opts.nextSlide+1;
            opts.currSlide = roll ? opts.slides.length-1 : opts.nextSlide-1;
        }
    },

    calcTx: function( slideOpts, manual ) {
        var opts = slideOpts;
        var tx;

        if ( opts._tempFx )
            tx = $.fn.cycle.transitions[opts._tempFx];
        else if ( manual && opts.manualFx )
            tx = $.fn.cycle.transitions[opts.manualFx];

        if ( !tx )
            tx = $.fn.cycle.transitions[opts.fx];

        opts._tempFx = null;
        this.opts()._tempFx = null;

        if (!tx) {
            tx = $.fn.cycle.transitions.fade;
            opts.API.log('Transition "' + opts.fx + '" not found.  Using fade.');
        }
        return tx;
    },

    prepareTx: function( manual, fwd ) {
        var opts = this.opts();
        var after, curr, next, slideOpts, tx;

        if ( opts.slideCount < 2 ) {
            opts.timeoutId = 0;
            return;
        }
        if ( manual && ( !opts.busy || opts.manualTrump ) ) {
            opts.API.stopTransition();
            opts.busy = false;
            clearTimeout(opts.timeoutId);
            opts.timeoutId = 0;
        }
        if ( opts.busy )
            return;
        if ( opts.timeoutId === 0 && !manual )
            return;

        curr = opts.slides[opts.currSlide];
        next = opts.slides[opts.nextSlide];
        slideOpts = opts.API.getSlideOpts( opts.nextSlide );
        tx = opts.API.calcTx( slideOpts, manual );

        opts._tx = tx;

        if ( manual && slideOpts.manualSpeed !== undefined )
            slideOpts.speed = slideOpts.manualSpeed;

        // if ( opts.nextSlide === opts.currSlide )
        //     opts.API.calcNextSlide();

        // ensure that:
        //      1. advancing to a different slide
        //      2. this is either a manual event (prev/next, pager, cmd) or 
        //              a timer event and slideshow is not paused
        if ( opts.nextSlide != opts.currSlide && 
            (manual || (!opts.paused && !opts.hoverPaused && opts.timeout) )) { // #62

            opts.API.trigger('cycle-before', [ slideOpts, curr, next, fwd ]);
            if ( tx.before )
                tx.before( slideOpts, curr, next, fwd );

            after = function() {
                opts.busy = false;
                // #76; bail if slideshow has been destroyed
                if (! opts.container.data( 'cycle.opts' ) )
                    return;

                if (tx.after)
                    tx.after( slideOpts, curr, next, fwd );
                opts.API.trigger('cycle-after', [ slideOpts, curr, next, fwd ]);
                opts.API.queueTransition( slideOpts);
                opts.API.updateView( true );
            };

            opts.busy = true;
            if (tx.transition)
                tx.transition(slideOpts, curr, next, fwd, after);
            else
                opts.API.doTransition( slideOpts, curr, next, fwd, after);

            opts.API.calcNextSlide();
            opts.API.updateView();
        } else {
            opts.API.queueTransition( slideOpts );
        }
    },

    // perform the actual animation
    doTransition: function( slideOpts, currEl, nextEl, fwd, callback) {
        var opts = slideOpts;
        var curr = $(currEl), next = $(nextEl);
        var fn = function() {
            // make sure animIn has something so that callback doesn't trigger immediately
            next.animate(opts.animIn || { opacity: 1}, opts.speed, opts.easeIn || opts.easing, callback);
        };

        next.css(opts.cssBefore || {});
        curr.animate(opts.animOut || {}, opts.speed, opts.easeOut || opts.easing, function() {
            curr.css(opts.cssAfter || {});
            if (!opts.sync) {
                fn();
            }
        });
        if (opts.sync) {
            fn();
        }
    },

    queueTransition: function( slideOpts, specificTimeout ) {
        var opts = this.opts();
        var timeout = specificTimeout !== undefined ? specificTimeout : slideOpts.timeout;
        if (opts.nextSlide === 0 && --opts.loop === 0) {
            opts.API.log('terminating; loop=0');
            opts.timeout = 0;
            if ( timeout ) {
                setTimeout(function() {
                    opts.API.trigger('cycle-finished', [ opts ]);
                }, timeout);
            }
            else {
                opts.API.trigger('cycle-finished', [ opts ]);
            }
            // reset nextSlide
            opts.nextSlide = opts.currSlide;
            return;
        }
        if ( opts.continueAuto !== undefined ) {
            if ( opts.continueAuto === false || 
                ($.isFunction(opts.continueAuto) && opts.continueAuto() === false )) {
                opts.API.log('terminating automatic transitions');
                opts.timeout = 0;
                if ( opts.timeoutId )
                    clearTimeout(opts.timeoutId);
                return;
            }
        }
        if ( timeout ) {
            opts._lastQueue = $.now();
            if ( specificTimeout === undefined )
                opts._remainingTimeout = slideOpts.timeout;

            if ( !opts.paused && ! opts.hoverPaused ) {
                opts.timeoutId = setTimeout(function() { 
                    opts.API.prepareTx( false, !opts.reverse ); 
                }, timeout );
            }
        }
    },

    stopTransition: function() {
        var opts = this.opts();
        if ( opts.slides.filter(':animated').length ) {
            opts.slides.stop(false, true);
            opts.API.trigger('cycle-transition-stopped', [ opts ]);
        }

        if ( opts._tx && opts._tx.stopTransition )
            opts._tx.stopTransition( opts );
    },

    // advance slide forward or back
    advanceSlide: function( val ) {
        var opts = this.opts();
        clearTimeout(opts.timeoutId);
        opts.timeoutId = 0;
        opts.nextSlide = opts.currSlide + val;
        
        if (opts.nextSlide < 0)
            opts.nextSlide = opts.slides.length - 1;
        else if (opts.nextSlide >= opts.slides.length)
            opts.nextSlide = 0;

        opts.API.prepareTx( true,  val >= 0 );
        return false;
    },

    buildSlideOpts: function( slide ) {
        var opts = this.opts();
        var val, shortName;
        var slideOpts = slide.data() || {};
        for (var p in slideOpts) {
            // allow props to be accessed sans 'cycle' prefix and log the overrides
            if (slideOpts.hasOwnProperty(p) && /^cycle[A-Z]+/.test(p) ) {
                val = slideOpts[p];
                shortName = p.match(/^cycle(.*)/)[1].replace(/^[A-Z]/, lowerCase);
                opts.API.log('['+(opts.slideCount-1)+']', shortName+':', val, '('+typeof val +')');
                slideOpts[shortName] = val;
            }
        }

        slideOpts = $.extend( {}, $.fn.cycle.defaults, opts, slideOpts );
        slideOpts.slideNum = opts.slideCount;

        try {
            // these props should always be read from the master state object
            delete slideOpts.API;
            delete slideOpts.slideCount;
            delete slideOpts.currSlide;
            delete slideOpts.nextSlide;
            delete slideOpts.slides;
        } catch(e) {
            // no op
        }
        return slideOpts;
    },

    getSlideOpts: function( index ) {
        var opts = this.opts();
        if ( index === undefined )
            index = opts.currSlide;

        var slide = opts.slides[index];
        var slideOpts = $(slide).data('cycle.opts');
        return $.extend( {}, opts, slideOpts );
    },
    
    initSlide: function( slideOpts, slide, suggestedZindex ) {
        var opts = this.opts();
        slide.css( slideOpts.slideCss || {} );
        if ( suggestedZindex > 0 )
            slide.css( 'zIndex', suggestedZindex );

        // ensure that speed settings are sane
        if ( isNaN( slideOpts.speed ) )
            slideOpts.speed = $.fx.speeds[slideOpts.speed] || $.fx.speeds._default;
        if ( !slideOpts.sync )
            slideOpts.speed = slideOpts.speed / 2;

        slide.addClass( opts.slideClass );
    },

    updateView: function( isAfter, isDuring, forceEvent ) {
        var opts = this.opts();
        if ( !opts._initialized )
            return;
        var slideOpts = opts.API.getSlideOpts();
        var currSlide = opts.slides[ opts.currSlide ];

        if ( ! isAfter && isDuring !== true ) {
            opts.API.trigger('cycle-update-view-before', [ opts, slideOpts, currSlide ]);
            if ( opts.updateView < 0 )
                return;
        }

        if ( opts.slideActiveClass ) {
            opts.slides.removeClass( opts.slideActiveClass )
                .eq( opts.currSlide ).addClass( opts.slideActiveClass );
        }

        if ( isAfter && opts.hideNonActive )
            opts.slides.filter( ':not(.' + opts.slideActiveClass + ')' ).css('visibility', 'hidden');

        if ( opts.updateView === 0 ) {
            setTimeout(function() {
                opts.API.trigger('cycle-update-view', [ opts, slideOpts, currSlide, isAfter ]);
            }, slideOpts.speed / (opts.sync ? 2 : 1) );
        }

        if ( opts.updateView !== 0 )
            opts.API.trigger('cycle-update-view', [ opts, slideOpts, currSlide, isAfter ]);
        
        if ( isAfter )
            opts.API.trigger('cycle-update-view-after', [ opts, slideOpts, currSlide ]);
    },

    getComponent: function( name ) {
        var opts = this.opts();
        var selector = opts[name];
        if (typeof selector === 'string') {
            // if selector is a child, sibling combinator, adjancent selector then use find, otherwise query full dom
            return (/^\s*[\>|\+|~]/).test( selector ) ? opts.container.find( selector ) : $( selector );
        }
        if (selector.jquery)
            return selector;
        
        return $(selector);
    },

    stackSlides: function( curr, next, fwd ) {
        var opts = this.opts();
        if ( !curr ) {
            curr = opts.slides[opts.currSlide];
            next = opts.slides[opts.nextSlide];
            fwd = !opts.reverse;
        }

        // reset the zIndex for the common case:
        // curr slide on top,  next slide beneath, and the rest in order to be shown
        $(curr).css('zIndex', opts.maxZ);

        var i;
        var z = opts.maxZ - 2;
        var len = opts.slideCount;
        if (fwd) {
            for ( i = opts.currSlide + 1; i < len; i++ )
                $( opts.slides[i] ).css( 'zIndex', z-- );
            for ( i = 0; i < opts.currSlide; i++ )
                $( opts.slides[i] ).css( 'zIndex', z-- );
        }
        else {
            for ( i = opts.currSlide - 1; i >= 0; i-- )
                $( opts.slides[i] ).css( 'zIndex', z-- );
            for ( i = len - 1; i > opts.currSlide; i-- )
                $( opts.slides[i] ).css( 'zIndex', z-- );
        }

        $(next).css('zIndex', opts.maxZ - 1);
    },

    getSlideIndex: function( el ) {
        return this.opts().slides.index( el );
    }

}; // API

// default logger
$.fn.cycle.log = function log() {
    /*global console:true */
    if (window.console && console.log)
        console.log('[cycle2] ' + Array.prototype.join.call(arguments, ' ') );
};

$.fn.cycle.version = function() { return 'Cycle2: ' + version; };

// helper functions

function lowerCase(s) {
    return (s || '').toLowerCase();
}

// expose transition object
$.fn.cycle.transitions = {
    custom: {
    },
    none: {
        before: function( opts, curr, next, fwd ) {
            opts.API.stackSlides( next, curr, fwd );
            opts.cssBefore = { opacity: 1, visibility: 'visible', display: 'block' };
        }
    },
    fade: {
        before: function( opts, curr, next, fwd ) {
            var css = opts.API.getSlideOpts( opts.nextSlide ).slideCss || {};
            opts.API.stackSlides( curr, next, fwd );
            opts.cssBefore = $.extend(css, { opacity: 0, visibility: 'visible', display: 'block' });
            opts.animIn = { opacity: 1 };
            opts.animOut = { opacity: 0 };
        }
    },
    fadeout: {
        before: function( opts , curr, next, fwd ) {
            var css = opts.API.getSlideOpts( opts.nextSlide ).slideCss || {};
            opts.API.stackSlides( curr, next, fwd );
            opts.cssBefore = $.extend(css, { opacity: 1, visibility: 'visible', display: 'block' });
            opts.animOut = { opacity: 0 };
        }
    },
    scrollHorz: {
        before: function( opts, curr, next, fwd ) {
            opts.API.stackSlides( curr, next, fwd );
            var w = opts.container.css('overflow','hidden').width();
            opts.cssBefore = { left: fwd ? w : - w, top: 0, opacity: 1, visibility: 'visible', display: 'block' };
            opts.cssAfter = { zIndex: opts._maxZ - 2, left: 0 };
            opts.animIn = { left: 0 };
            opts.animOut = { left: fwd ? -w : w };
        }
    }
};

// @see: http://jquery.malsup.com/cycle2/api
$.fn.cycle.defaults = {
    allowWrap:        true,
    autoSelector:     '.cycle-slideshow[data-cycle-auto-init!=false]',
    delay:            0,
    easing:           null,
    fx:              'fade',
    hideNonActive:    true,
    loop:             0,
    manualFx:         undefined,
    manualSpeed:      undefined,
    manualTrump:      true,
    maxZ:             100,
    pauseOnHover:     false,
    reverse:          false,
    slideActiveClass: 'cycle-slide-active',
    slideClass:       'cycle-slide',
    slideCss:         { position: 'absolute', top: 0, left: 0 },
    slides:          '> img',
    speed:            500,
    startingSlide:    0,
    sync:             true,
    timeout:          4000,
    updateView:       0
};

// automatically find and run slideshows
$(document).ready(function() {
    $( $.fn.cycle.defaults.autoSelector ).cycle();
});

})(jQuery);

/*! Cycle2 autoheight plugin; Copyright (c) M.Alsup, 2012; version: 20130913 */
(function($) {
"use strict";

$.extend($.fn.cycle.defaults, {
    autoHeight: 0, // setting this option to false disables autoHeight logic
    autoHeightSpeed: 250,
    autoHeightEasing: null
});    

$(document).on( 'cycle-initialized', function( e, opts ) {
    var autoHeight = opts.autoHeight;
    var t = $.type( autoHeight );
    var resizeThrottle = null;
    var ratio;

    if ( t !== 'string' && t !== 'number' )
        return;

    // bind events
    opts.container.on( 'cycle-slide-added cycle-slide-removed', initAutoHeight );
    opts.container.on( 'cycle-destroyed', onDestroy );

    if ( autoHeight == 'container' ) {
        opts.container.on( 'cycle-before', onBefore );
    }
    else if ( t === 'string' && /\d+\:\d+/.test( autoHeight ) ) { 
        // use ratio
        ratio = autoHeight.match(/(\d+)\:(\d+)/);
        ratio = ratio[1] / ratio[2];
        opts._autoHeightRatio = ratio;
    }

    // if autoHeight is a number then we don't need to recalculate the sentinel
    // index on resize
    if ( t !== 'number' ) {
        // bind unique resize handler per slideshow (so it can be 'off-ed' in onDestroy)
        opts._autoHeightOnResize = function () {
            clearTimeout( resizeThrottle );
            resizeThrottle = setTimeout( onResize, 50 );
        };

        $(window).on( 'resize orientationchange', opts._autoHeightOnResize );
    }

    setTimeout( onResize, 30 );

    function onResize() {
        initAutoHeight( e, opts );
    }
});

function initAutoHeight( e, opts ) {
    var clone, height, sentinelIndex;
    var autoHeight = opts.autoHeight;

    if ( autoHeight == 'container' ) {
        height = $( opts.slides[ opts.currSlide ] ).outerHeight();
        opts.container.height( height );
    }
    else if ( opts._autoHeightRatio ) { 
        opts.container.height( opts.container.width() / opts._autoHeightRatio );
    }
    else if ( autoHeight === 'calc' || ( $.type( autoHeight ) == 'number' && autoHeight >= 0 ) ) {
        if ( autoHeight === 'calc' )
            sentinelIndex = calcSentinelIndex( e, opts );
        else if ( autoHeight >= opts.slides.length )
            sentinelIndex = 0;
        else 
            sentinelIndex = autoHeight;

        // only recreate sentinel if index is different
        if ( sentinelIndex == opts._sentinelIndex )
            return;

        opts._sentinelIndex = sentinelIndex;
        if ( opts._sentinel )
            opts._sentinel.remove();

        // clone existing slide as sentinel
        clone = $( opts.slides[ sentinelIndex ].cloneNode(true) );
        
        // #50; remove special attributes from cloned content
        clone.removeAttr( 'id name rel' ).find( '[id],[name],[rel]' ).removeAttr( 'id name rel' );

        clone.css({
            position: 'static',
            visibility: 'hidden',
            display: 'block'
        }).prependTo( opts.container ).addClass('cycle-sentinel cycle-slide').removeClass('cycle-slide-active');
        clone.find( '*' ).css( 'visibility', 'hidden' );

        opts._sentinel = clone;
    }
}    

function calcSentinelIndex( e, opts ) {
    var index = 0, max = -1;

    // calculate tallest slide index
    opts.slides.each(function(i) {
        var h = $(this).height();
        if ( h > max ) {
            max = h;
            index = i;
        }
    });
    return index;
}

function onBefore( e, opts, outgoing, incoming, forward ) {
    var h = $(incoming).outerHeight();
    opts.container.animate( { height: h }, opts.autoHeightSpeed, opts.autoHeightEasing );
}

function onDestroy( e, opts ) {
    if ( opts._autoHeightOnResize ) {
        $(window).off( 'resize orientationchange', opts._autoHeightOnResize );
        opts._autoHeightOnResize = null;
    }
    opts.container.off( 'cycle-slide-added cycle-slide-removed', initAutoHeight );
    opts.container.off( 'cycle-destroyed', onDestroy );
    opts.container.off( 'cycle-before', onBefore );

    if ( opts._sentinel ) {
        opts._sentinel.remove();
        opts._sentinel = null;
    }
}

})(jQuery);

/*! caption plugin for Cycle2;  version: 20130306 */
(function($) {
"use strict";

$.extend($.fn.cycle.defaults, {
    caption:          '> .cycle-caption',
    captionTemplate:  '{{slideNum}} / {{slideCount}}',
    overlay:          '> .cycle-overlay',
    overlayTemplate:  '<div>{{title}}</div><div>{{desc}}</div>',
    captionModule:    'caption'
});    

$(document).on( 'cycle-update-view', function( e, opts, slideOpts, currSlide ) {
    if ( opts.captionModule !== 'caption' )
        return;
    var el;
    $.each(['caption','overlay'], function() {
        var name = this; 
        var template = slideOpts[name+'Template'];
        var el = opts.API.getComponent( name );
        if( el.length && template ) {
            el.html( opts.API.tmpl( template, slideOpts, opts, currSlide ) );
            el.show();
        }
        else {
            el.hide();
        }
    });
});

$(document).on( 'cycle-destroyed', function( e, opts ) {
    var el;
    $.each(['caption','overlay'], function() {
        var name = this, template = opts[name+'Template'];
        if ( opts[name] && template ) {
            el = opts.API.getComponent( 'caption' );
            el.empty();
        }
    });
});

})(jQuery);

/*! command plugin for Cycle2;  version: 20140415 */
(function($) {
"use strict";

var c2 = $.fn.cycle;

$.fn.cycle = function( options ) {
    var cmd, cmdFn, opts;
    var args = $.makeArray( arguments );

    if ( $.type( options ) == 'number' ) {
        return this.cycle( 'goto', options );
    }

    if ( $.type( options ) == 'string' ) {
        return this.each(function() {
            var cmdArgs;
            cmd = options;
            opts = $(this).data('cycle.opts');

            if ( opts === undefined ) {
                c2.log('slideshow must be initialized before sending commands; "' + cmd + '" ignored');
                return;
            }
            else {
                cmd = cmd == 'goto' ? 'jump' : cmd; // issue #3; change 'goto' to 'jump' internally
                cmdFn = opts.API[ cmd ];
                if ( $.isFunction( cmdFn )) {
                    cmdArgs = $.makeArray( args );
                    cmdArgs.shift();
                    return cmdFn.apply( opts.API, cmdArgs );
                }
                else {
                    c2.log( 'unknown command: ', cmd );
                }
            }
        });
    }
    else {
        return c2.apply( this, arguments );
    }
};

// copy props
$.extend( $.fn.cycle, c2 );

$.extend( c2.API, {
    next: function() {
        var opts = this.opts();
        if ( opts.busy && ! opts.manualTrump )
            return;
        
        var count = opts.reverse ? -1 : 1;
        if ( opts.allowWrap === false && ( opts.currSlide + count ) >= opts.slideCount )
            return;

        opts.API.advanceSlide( count );
        opts.API.trigger('cycle-next', [ opts ]).log('cycle-next');
    },

    prev: function() {
        var opts = this.opts();
        if ( opts.busy && ! opts.manualTrump )
            return;
        var count = opts.reverse ? 1 : -1;
        if ( opts.allowWrap === false && ( opts.currSlide + count ) < 0 )
            return;

        opts.API.advanceSlide( count );
        opts.API.trigger('cycle-prev', [ opts ]).log('cycle-prev');
    },

    destroy: function() {
        this.stop(); //#204

        var opts = this.opts();
        var clean = $.isFunction( $._data ) ? $._data : $.noop;  // hack for #184 and #201
        clearTimeout(opts.timeoutId);
        opts.timeoutId = 0;
        opts.API.stop();
        opts.API.trigger( 'cycle-destroyed', [ opts ] ).log('cycle-destroyed');
        opts.container.removeData();
        clean( opts.container[0], 'parsedAttrs', false );

        // #75; remove inline styles
        if ( ! opts.retainStylesOnDestroy ) {
            opts.container.removeAttr( 'style' );
            opts.slides.removeAttr( 'style' );
            opts.slides.removeClass( opts.slideActiveClass );
        }
        opts.slides.each(function() {
            $(this).removeData();
            clean( this, 'parsedAttrs', false );
        });
    },

    jump: function( index, fx ) {
        // go to the requested slide
        var fwd;
        var opts = this.opts();
        if ( opts.busy && ! opts.manualTrump )
            return;
        var num = parseInt( index, 10 );
        if (isNaN(num) || num < 0 || num >= opts.slides.length) {
            opts.API.log('goto: invalid slide index: ' + num);
            return;
        }
        if (num == opts.currSlide) {
            opts.API.log('goto: skipping, already on slide', num);
            return;
        }
        opts.nextSlide = num;
        clearTimeout(opts.timeoutId);
        opts.timeoutId = 0;
        opts.API.log('goto: ', num, ' (zero-index)');
        fwd = opts.currSlide < opts.nextSlide;
        opts._tempFx = fx;
        opts.API.prepareTx( true, fwd );
    },

    stop: function() {
        var opts = this.opts();
        var pauseObj = opts.container;
        clearTimeout(opts.timeoutId);
        opts.timeoutId = 0;
        opts.API.stopTransition();
        if ( opts.pauseOnHover ) {
            if ( opts.pauseOnHover !== true )
                pauseObj = $( opts.pauseOnHover );
            pauseObj.off('mouseenter mouseleave');
        }
        opts.API.trigger('cycle-stopped', [ opts ]).log('cycle-stopped');
    },

    reinit: function() {
        var opts = this.opts();
        opts.API.destroy();
        opts.container.cycle();
    },

    remove: function( index ) {
        var opts = this.opts();
        var slide, slideToRemove, slides = [], slideNum = 1;
        for ( var i=0; i < opts.slides.length; i++ ) {
            slide = opts.slides[i];
            if ( i == index ) {
                slideToRemove = slide;
            }
            else {
                slides.push( slide );
                $( slide ).data('cycle.opts').slideNum = slideNum;
                slideNum++;
            }
        }
        if ( slideToRemove ) {
            opts.slides = $( slides );
            opts.slideCount--;
            $( slideToRemove ).remove();
            if (index == opts.currSlide)
                opts.API.advanceSlide( 1 );
            else if ( index < opts.currSlide )
                opts.currSlide--;
            else
                opts.currSlide++;

            opts.API.trigger('cycle-slide-removed', [ opts, index, slideToRemove ]).log('cycle-slide-removed');
            opts.API.updateView();
        }
    }

});

// listen for clicks on elements with data-cycle-cmd attribute
$(document).on('click.cycle', '[data-cycle-cmd]', function(e) {
    // issue cycle command
    e.preventDefault();
    var el = $(this);
    var command = el.data('cycle-cmd');
    var context = el.data('cycle-context') || '.cycle-slideshow';
    $(context).cycle(command, el.data('cycle-arg'));
});


})(jQuery);

/*! hash plugin for Cycle2;  version: 20130905 */
(function($) {
"use strict";

$(document).on( 'cycle-pre-initialize', function( e, opts ) {
    onHashChange( opts, true );

    opts._onHashChange = function() {
        onHashChange( opts, false );
    };

    $( window ).on( 'hashchange', opts._onHashChange);
});

$(document).on( 'cycle-update-view', function( e, opts, slideOpts ) {
    if ( slideOpts.hash && ( '#' + slideOpts.hash ) != window.location.hash ) {
        opts._hashFence = true;
        window.location.hash = slideOpts.hash;
    }
});

$(document).on( 'cycle-destroyed', function( e, opts) {
    if ( opts._onHashChange ) {
        $( window ).off( 'hashchange', opts._onHashChange );
    }
});

function onHashChange( opts, setStartingSlide ) {
    var hash;
    if ( opts._hashFence ) {
        opts._hashFence = false;
        return;
    }
    
    hash = window.location.hash.substring(1);

    opts.slides.each(function(i) {
        if ( $(this).data( 'cycle-hash' ) == hash ) {
            if ( setStartingSlide === true ) {
                opts.startingSlide = i;
            }
            else {
                var fwd = opts.currSlide < i;
                opts.nextSlide = i;
                opts.API.prepareTx( true, fwd );
            }
            return false;
        }
    });
}

})(jQuery);

/*! loader plugin for Cycle2;  version: 20131121 */
(function($) {
"use strict";

$.extend($.fn.cycle.defaults, {
    loader: false
});

$(document).on( 'cycle-bootstrap', function( e, opts ) {
    var addFn;

    if ( !opts.loader )
        return;

    // override API.add for this slideshow
    addFn = opts.API.add;
    opts.API.add = add;

    function add( slides, prepend ) {
        var slideArr = [];
        if ( $.type( slides ) == 'string' )
            slides = $.trim( slides );
        else if ( $.type( slides) === 'array' ) {
            for (var i=0; i < slides.length; i++ )
                slides[i] = $(slides[i])[0];
        }

        slides = $( slides );
        var slideCount = slides.length;

        if ( ! slideCount )
            return;

        slides.css('visibility','hidden').appendTo('body').each(function(i) { // appendTo fixes #56
            var count = 0;
            var slide = $(this);
            var images = slide.is('img') ? slide : slide.find('img');
            slide.data('index', i);
            // allow some images to be marked as unimportant (and filter out images w/o src value)
            images = images.filter(':not(.cycle-loader-ignore)').filter(':not([src=""])');
            if ( ! images.length ) {
                --slideCount;
                slideArr.push( slide );
                return;
            }

            count = images.length;
            images.each(function() {
                // add images that are already loaded
                if ( this.complete ) {
                    imageLoaded();
                }
                else {
                    $(this).load(function() {
                        imageLoaded();
                    }).on("error", function() {
                        if ( --count === 0 ) {
                            // ignore this slide
                            opts.API.log('slide skipped; img not loaded:', this.src);
                            if ( --slideCount === 0 && opts.loader == 'wait') {
                                addFn.apply( opts.API, [ slideArr, prepend ] );
                            }
                        }
                    });
                }
            });

            function imageLoaded() {
                if ( --count === 0 ) {
                    --slideCount;
                    addSlide( slide );
                }
            }
        });

        if ( slideCount )
            opts.container.addClass('cycle-loading');
        

        function addSlide( slide ) {
            var curr;
            if ( opts.loader == 'wait' ) {
                slideArr.push( slide );
                if ( slideCount === 0 ) {
                    // #59; sort slides into original markup order
                    slideArr.sort( sorter );
                    addFn.apply( opts.API, [ slideArr, prepend ] );
                    opts.container.removeClass('cycle-loading');
                }
            }
            else {
                curr = $(opts.slides[opts.currSlide]);
                addFn.apply( opts.API, [ slide, prepend ] );
                curr.show();
                opts.container.removeClass('cycle-loading');
            }
        }

        function sorter(a, b) {
            return a.data('index') - b.data('index');
        }
    }
});

})(jQuery);

/*! pager plugin for Cycle2;  version: 20140415 */
(function($) {
"use strict";

$.extend($.fn.cycle.defaults, {
    pager:            '> .cycle-pager',
    pagerActiveClass: 'cycle-pager-active',
    pagerEvent:       'click.cycle',
    pagerEventBubble: undefined,
    pagerTemplate:    '<span>&bull;</span>'
});

$(document).on( 'cycle-bootstrap', function( e, opts, API ) {
    // add method to API
    API.buildPagerLink = buildPagerLink;
});

$(document).on( 'cycle-slide-added', function( e, opts, slideOpts, slideAdded ) {
    if ( opts.pager ) {
        opts.API.buildPagerLink ( opts, slideOpts, slideAdded );
        opts.API.page = page;
    }
});

$(document).on( 'cycle-slide-removed', function( e, opts, index, slideRemoved ) {
    if ( opts.pager ) {
        var pagers = opts.API.getComponent( 'pager' );
        pagers.each(function() {
            var pager = $(this);
            $( pager.children()[index] ).remove();
        });
    }
});

$(document).on( 'cycle-update-view', function( e, opts, slideOpts ) {
    var pagers;

    if ( opts.pager ) {
        pagers = opts.API.getComponent( 'pager' );
        pagers.each(function() {
           $(this).children().removeClass( opts.pagerActiveClass )
            .eq( opts.currSlide ).addClass( opts.pagerActiveClass );
        });
    }
});

$(document).on( 'cycle-destroyed', function( e, opts ) {
    var pager = opts.API.getComponent( 'pager' );

    if ( pager ) {
        pager.children().off( opts.pagerEvent ); // #202
        if ( opts.pagerTemplate )
            pager.empty();
    }
});

function buildPagerLink( opts, slideOpts, slide ) {
    var pagerLink;
    var pagers = opts.API.getComponent( 'pager' );
    pagers.each(function() {
        var pager = $(this);
        if ( slideOpts.pagerTemplate ) {
            var markup = opts.API.tmpl( slideOpts.pagerTemplate, slideOpts, opts, slide[0] );
            pagerLink = $( markup ).appendTo( pager );
        }
        else {
            pagerLink = pager.children().eq( opts.slideCount - 1 );
        }
        pagerLink.on( opts.pagerEvent, function(e) {
            if ( ! opts.pagerEventBubble )
                e.preventDefault();
            opts.API.page( pager, e.currentTarget);
        });
    });
}

function page( pager, target ) {
    /*jshint validthis:true */
    var opts = this.opts();
    if ( opts.busy && ! opts.manualTrump )
        return;

    var index = pager.children().index( target );
    var nextSlide = index;
    var fwd = opts.currSlide < nextSlide;
    if (opts.currSlide == nextSlide) {
        return; // no op, clicked pager for the currently displayed slide
    }
    opts.nextSlide = nextSlide;
    opts._tempFx = opts.pagerFx;
    opts.API.prepareTx( true, fwd );
    opts.API.trigger('cycle-pager-activated', [opts, pager, target ]);
}

})(jQuery);

/*! prevnext plugin for Cycle2;  version: 20140408 */
(function($) {
"use strict";

$.extend($.fn.cycle.defaults, {
    next:           '> .cycle-next',
    nextEvent:      'click.cycle',
    disabledClass:  'disabled',
    prev:           '> .cycle-prev',
    prevEvent:      'click.cycle',
    swipe:          false
});

$(document).on( 'cycle-initialized', function( e, opts ) {
    opts.API.getComponent( 'next' ).on( opts.nextEvent, function(e) {
        e.preventDefault();
        opts.API.next();
    });

    opts.API.getComponent( 'prev' ).on( opts.prevEvent, function(e) {
        e.preventDefault();
        opts.API.prev();
    });

    if ( opts.swipe ) {
        var nextEvent = opts.swipeVert ? 'swipeUp.cycle' : 'swipeLeft.cycle swipeleft.cycle';
        var prevEvent = opts.swipeVert ? 'swipeDown.cycle' : 'swipeRight.cycle swiperight.cycle';
        opts.container.on( nextEvent, function(e) {
            opts._tempFx = opts.swipeFx;
            opts.API.next();
        });
        opts.container.on( prevEvent, function() {
            opts._tempFx = opts.swipeFx;
            opts.API.prev();
        });
    }
});

$(document).on( 'cycle-update-view', function( e, opts, slideOpts, currSlide ) {
    if ( opts.allowWrap )
        return;

    var cls = opts.disabledClass;
    var next = opts.API.getComponent( 'next' );
    var prev = opts.API.getComponent( 'prev' );
    var prevBoundry = opts._prevBoundry || 0;
    var nextBoundry = (opts._nextBoundry !== undefined)?opts._nextBoundry:opts.slideCount - 1;

    if ( opts.currSlide == nextBoundry )
        next.addClass( cls ).prop( 'disabled', true );
    else
        next.removeClass( cls ).prop( 'disabled', false );

    if ( opts.currSlide === prevBoundry )
        prev.addClass( cls ).prop( 'disabled', true );
    else
        prev.removeClass( cls ).prop( 'disabled', false );
});


$(document).on( 'cycle-destroyed', function( e, opts ) {
    opts.API.getComponent( 'prev' ).off( opts.nextEvent );
    opts.API.getComponent( 'next' ).off( opts.prevEvent );
    opts.container.off( 'swipeleft.cycle swiperight.cycle swipeLeft.cycle swipeRight.cycle swipeUp.cycle swipeDown.cycle' );
});

})(jQuery);

/*! progressive loader plugin for Cycle2;  version: 20130315 */
(function($) {
"use strict";

$.extend($.fn.cycle.defaults, {
    progressive: false
});

$(document).on( 'cycle-pre-initialize', function( e, opts ) {
    if ( !opts.progressive )
        return;

    var API = opts.API;
    var nextFn = API.next;
    var prevFn = API.prev;
    var prepareTxFn = API.prepareTx;
    var type = $.type( opts.progressive );
    var slides, scriptEl;

    if ( type == 'array' ) {
        slides = opts.progressive;
    }
    else if ($.isFunction( opts.progressive ) ) {
        slides = opts.progressive( opts );
    }
    else if ( type == 'string' ) {
        scriptEl = $( opts.progressive );
        slides = $.trim( scriptEl.html() );
        if ( !slides )
            return;
        // is it json array?
        if ( /^(\[)/.test( slides ) ) {
            try {
                slides = $.parseJSON( slides );
            }
            catch(err) {
                API.log( 'error parsing progressive slides', err );
                return;
            }
        }
        else {
            // plain text, split on delimeter
            slides = slides.split( new RegExp( scriptEl.data('cycle-split') || '\n') );
            
            // #95; look for empty slide
            if ( ! slides[ slides.length - 1 ] )
                slides.pop();
        }
    }



    if ( prepareTxFn ) {
        API.prepareTx = function( manual, fwd ) {
            var index, slide;

            if ( manual || slides.length === 0 ) {
                prepareTxFn.apply( opts.API, [ manual, fwd ] );
                return;
            }

            if ( fwd && opts.currSlide == ( opts.slideCount-1) ) {
                slide = slides[ 0 ];
                slides = slides.slice( 1 );
                opts.container.one('cycle-slide-added', function(e, opts ) {
                    setTimeout(function() {
                        opts.API.advanceSlide( 1 );
                    },50);
                });
                opts.API.add( slide );
            }
            else if ( !fwd && opts.currSlide === 0 ) {
                index = slides.length-1;
                slide = slides[ index ];
                slides = slides.slice( 0, index );
                opts.container.one('cycle-slide-added', function(e, opts ) {
                    setTimeout(function() {
                        opts.currSlide = 1;
                        opts.API.advanceSlide( -1 );
                    },50);
                });
                opts.API.add( slide, true );
            }
            else {
                prepareTxFn.apply( opts.API, [ manual, fwd ] );
            }
        };
    }

    if ( nextFn ) {
        API.next = function() {
            var opts = this.opts();
            if ( slides.length && opts.currSlide == ( opts.slideCount - 1 ) ) {
                var slide = slides[ 0 ];
                slides = slides.slice( 1 );
                opts.container.one('cycle-slide-added', function(e, opts ) {
                    nextFn.apply( opts.API );
                    opts.container.removeClass('cycle-loading');
                });
                opts.container.addClass('cycle-loading');
                opts.API.add( slide );
            }
            else {
                nextFn.apply( opts.API );    
            }
        };
    }
    
    if ( prevFn ) {
        API.prev = function() {
            var opts = this.opts();
            if ( slides.length && opts.currSlide === 0 ) {
                var index = slides.length-1;
                var slide = slides[ index ];
                slides = slides.slice( 0, index );
                opts.container.one('cycle-slide-added', function(e, opts ) {
                    opts.currSlide = 1;
                    opts.API.advanceSlide( -1 );
                    opts.container.removeClass('cycle-loading');
                });
                opts.container.addClass('cycle-loading');
                opts.API.add( slide, true );
            }
            else {
                prevFn.apply( opts.API );
            }
        };
    }
});

})(jQuery);

/*! tmpl plugin for Cycle2;  version: 20121227 */
(function($) {
"use strict";

$.extend($.fn.cycle.defaults, {
    tmplRegex: '{{((.)?.*?)}}'
});

$.extend($.fn.cycle.API, {
    tmpl: function( str, opts /*, ... */) {
        var regex = new RegExp( opts.tmplRegex || $.fn.cycle.defaults.tmplRegex, 'g' );
        var args = $.makeArray( arguments );
        args.shift();
        return str.replace(regex, function(_, str) {
            var i, j, obj, prop, names = str.split('.');
            for (i=0; i < args.length; i++) {
                obj = args[i];
                if ( ! obj )
                    continue;
                if (names.length > 1) {
                    prop = obj;
                    for (j=0; j < names.length; j++) {
                        obj = prop;
                        prop = prop[ names[j] ] || str;
                    }
                } else {
                    prop = obj[str];
                }

                if ($.isFunction(prop))
                    return prop.apply(obj, args);
                if (prop !== undefined && prop !== null && prop != str)
                    return prop;
            }
            return str;
        });
    }
});    

})(jQuery);
;/*! swipe plugin for Cycle2;  version: 20121120 */
(function($) {
"use strict";

// this script adds support for touch events.  the logic is lifted from jQuery Mobile.
// if you have jQuery Mobile installed, you do NOT need this script

var supportTouch = 'ontouchend' in document;

$.event.special.swipe = $.event.special.swipe || {
    scrollSupressionThreshold: 10,   // More than this horizontal displacement, and we will suppress scrolling.
    durationThreshold: 1000,         // More time than this, and it isn't a swipe.
    horizontalDistanceThreshold: 30, // Swipe horizontal displacement must be more than this.
    verticalDistanceThreshold: 75,   // Swipe vertical displacement must be less than this.

    setup: function() {
        var $this = $( this );

        $this.bind( 'touchstart', function( event ) {
            var data = event.originalEvent.touches ? event.originalEvent.touches[ 0 ] : event;
            var stop, start = {
                time: ( new Date() ).getTime(),
                coords: [ data.pageX, data.pageY ],
                origin: $( event.target )
            };

            function moveHandler( event ) {
                if ( !start )
                    return;

                var data = event.originalEvent.touches ? event.originalEvent.touches[ 0 ] : event;

                stop = {
                    time: ( new Date() ).getTime(),
                    coords: [ data.pageX, data.pageY ]
                };

                // prevent scrolling
                if ( Math.abs( start.coords[ 0 ] - stop.coords[ 0 ] ) > $.event.special.swipe.scrollSupressionThreshold ) {
                    event.preventDefault();
                }
            }

            $this.bind( 'touchmove', moveHandler )
                .one( 'touchend', function( event ) {
                    $this.unbind( 'touchmove', moveHandler );

                    if ( start && stop ) {
                        if ( stop.time - start.time < $.event.special.swipe.durationThreshold &&
                                Math.abs( start.coords[ 0 ] - stop.coords[ 0 ] ) > $.event.special.swipe.horizontalDistanceThreshold &&
                                Math.abs( start.coords[ 1 ] - stop.coords[ 1 ] ) < $.event.special.swipe.verticalDistanceThreshold ) {

                            start.origin.trigger( "swipe" )
                                .trigger( start.coords[0] > stop.coords[ 0 ] ? "swipeleft" : "swiperight" );
                        }
                    }
                    start = stop = undefined;
                });
        });
    }
};

$.event.special.swipeleft = $.event.special.swipeleft || {
    setup: function() {
        $( this ).bind( 'swipe', $.noop );
    }
};
$.event.special.swiperight = $.event.special.swiperight || $.event.special.swipeleft;

})(jQuery);
;/*!
 * response.js 0.9.0+201404091831
 * https://github.com/ryanve/response.js
 * MIT License (c) 2014 Ryan Van Etten
 */

(function(root, name, make) {
  var $ = root['jQuery'] || root['Zepto'] || root['ender'] || root['elo'];
  if (typeof module != 'undefined' && module['exports']) module['exports'] = make($);
  else root[name] = make($);
}(this, 'Response', function($) {

  if (typeof $ != 'function') {
    try {
      return void console.warn('response.js aborted due to missing dependency');
    } catch (e) {}
  }

  var Response
    , Elemset
    , root = this
    , name = 'Response'
    , old = root[name]
    , initContentKey = 'init' + name
    , win = window
    , doc = document
    , docElem = doc.documentElement
    , ready = $.domReady || $
    , $win = $(win)
    , DMS = typeof DOMStringMap != 'undefined'
    , AP = Array.prototype
    , OP = Object.prototype
    , push = AP.push
    , concat = AP.concat
    , toString = OP.toString
    , owns = OP.hasOwnProperty
    , isArray = Array.isArray || function(item) {
        return '[object Array]' === toString.call(item);
      }
    , defaultPoints = {
          width: [0, 320, 481, 641, 961, 1025, 1281]
        , height: [0, 481]
        , ratio: [1, 1.5, 2] // device-pixel-ratio
      }
    , propTests = {}
    , isCustom = {}
    , sets = { all: [] }
    , suid = 1
    , screenW = screen.width   
    , screenH = screen.height  
    , screenMax = screenW > screenH ? screenW : screenH
    , screenMin = screenW + screenH - screenMax
    , deviceW = function() { return screenW; }
    , deviceH = function() { return screenH; }
    , regexFunkyPunc = /[^a-z0-9_\-\.]/gi
    , regexTrimPunc = /^[\W\s]+|[\W\s]+$|/g
    , regexCamels = /([a-z])([A-Z])/g
    , regexDashB4 = /-(.)/g
    , regexDataPrefix = /^data-(.+)$/

    , procreate = Object.create || function(parent) {
        /** @constructor */
        function Type() {}
        Type.prototype = parent;
        return new Type;
      }
    , namespaceIt = function(eventName, customNamespace) {
        customNamespace = customNamespace || name;
        return eventName.replace(regexTrimPunc, '') + '.' + customNamespace.replace(regexTrimPunc, '');
      }
    , event = {
          allLoaded: namespaceIt('allLoaded') // fires on lazy elemsets when all elems in a set have been loaded once
          //, update: namespaceIt('update') // fires on each elem in a set each time that elem is updated
        , crossover: namespaceIt('crossover') // fires on window each time dynamic breakpoint bands is crossed
      }
    
      // normalized matchMedia
    , matchMedia = win.matchMedia || win.msMatchMedia
    , media = matchMedia ? bind(matchMedia, win) : function() {
        return {}; 
      }
    , mq = matchMedia ? function(q) {
        return !!matchMedia.call(win, q);
      } : function() {
        return false;
      }
  
      // http://ryanve.com/lab/dimensions
      // http://github.com/ryanve/verge/issues/13
    , viewportW = function() {
        var a = docElem.clientWidth, b = win.innerWidth;
        return a < b ? b : a;
      }
    , viewportH = function() {
        var a = docElem.clientHeight, b = win.innerHeight;
        return a < b ? b : a;
      }

    , band = bind(between, viewportW)
    , wave = bind(between, viewportH)
    , device = {
          'band': bind(between, deviceW)
        , 'wave': bind(between, deviceH)
      };

  function isNumber(item) {
    return item === +item;
  }
  
  /**
   * @param {Function} fn
   * @param {*=} scope
   * @return {Function}
   */
  function bind(fn, scope) {
    return function() {
      return fn.apply(scope, arguments);
    };
  }

  /**
   * @this {Function}
   * @param {number} min
   * @param {number=} max
   * @return {boolean}
   */
  function between(min, max) {
    var point = this.call();
    return point >= (min || 0) && (!max || point <= max);
  }

  /**
   * @param {{length:number}} stack
   * @param {Function} fn
   * @param {*=} scope
   * @return {Array}
   */
  function map(stack, fn, scope) {
    for (var r = [], l = stack.length, i = 0; i < l;) r[i] = fn.call(scope, stack[i], i++, stack);
    return r;
  }

  /**
   * @param {string|{length:number}} list
   * @return {Array} new and compact
   */
  function compact(list) {
    return !list ? [] : sift(typeof list == 'string' ? list.split(' ') : list);
  }

  /**
   * @since 0.4.0, supports scope and sparse-item iteration since 0.6.2
   * @param {{length:number}} stack
   * @param {Function} fn
   * @param {*=} scope
   */
  function each(stack, fn, scope) {
    if (null == stack) return stack;
    for (var l = stack.length, i = 0; i < l;) fn.call(scope || stack[i], stack[i], i++, stack);
    return stack;
  }

  /**
   * @since 0.4.0 skips null|undefined since 0.6.2, adds `0` since 0.7.11
   * @param {{length:number}} stack
   * @param {(string|number)=} prefix
   * @param {(string|number)=} suffix
   * @return {Array} new array of affixed strings or added numbers
   */
  function affix(stack, prefix, suffix) {
    if (null == prefix) prefix = '';
    if (null == suffix) suffix = '';
    for (var r = [], l = stack.length, i = 0; i < l; i++)
      null == stack[i] || r.push(prefix + stack[i] + suffix);
    return r;
  }

  /**
   * @param {{length:number}} stack to iterate
   * @param {(Function|string|*)=} fn callback or typestring
   * @param {(Object|boolean|*)=} scope or inversion boolean
   * @since 0.4.0, supports scope and typestrings since 0.6.2
   * @example Response.sift([5, 0, 'str'], isFinite) // [5, 0]
   * @example Response.sift([5, 0, 'str']) // [5, 'str']
   */
  function sift(stack, fn, scope) {
    var fail, l, v, r = [], u = 0, i = 0, run = typeof fn == 'function', not = true === scope;
    for (l = stack && stack.length, scope = not ? null : scope; i < l; i++) {
      v = stack[i];
      fail = run ? !fn.call(scope, v, i, stack) : fn ? typeof v !== fn : !v;
      fail === not && (r[u++] = v);
    }
    return r;
  }

  /**
   * @since 0.3.0
   * @param {Object|Array|Function|*} r receiver
   * @param {Object|Array|Function|*} s supplier Undefined values are ignored.
   * @return {Object|Array|Function|*} receiver
   */
  function merge(r, s) {
    if (null == r || null == s) return r;
    if (typeof s == 'object' && isNumber(s.length)) push.apply(r, sift(s, 'undefined', true));
    else for (var k in s) owns.call(s, k) && void 0 !== s[k] && (r[k] = s[k]);
    return r;
  }

  /**
   * @description Call `fn` on each stack value or directly on a non-stack item
   * @since 0.3.0 scope support added in 0.6.2
   * @param {*} item stack or non-stack item
   * @param {Function} fn callback
   * @param {*=} scope defaults to current item
   */
  function route(item, fn, scope) {
    if (null == item) return item;
    if (typeof item == 'object' && !item.nodeType && isNumber(item.length)) each(item, fn, scope);
    else fn.call(scope || item, item);
    return item;
  }
  
  /**
   * Response.dpr(decimal) Tests if a minimum device pixel ratio is active. 
   * Or (version added in 0.3.0) returns the device-pixel-ratio
   * @param {number} decimal is the integer or float to test.
   * @return {boolean|number}
   * @example Response.dpr() // get the device-pixel-ratio (or 0 if undetectable)
   * @example Response.dpr(1.5) // true when device-pixel-ratio is 1.5+
   * @example Response.dpr(2) // true when device-pixel-ratio is 2+
   */
  function dpr(decimal) {
    // Consider: github.com/ryanve/res
    var dPR = win.devicePixelRatio;
    if (null == decimal) return dPR || (dpr(2) ? 2 : dpr(1.5) ? 1.5 : dpr(1) ? 1 : 0); // approx
    if (!isFinite(decimal)) return false;

    // Use window.devicePixelRatio if supported - supported by Webkit 
    // (Safari/Chrome/Android) and Presto 2.8+ (Opera) browsers.     
    if (dPR && dPR > 0) return dPR >= decimal; 

    // Fallback to .matchMedia/.msMatchMedia. Supported by Gecko (FF6+) and more:
    // @link developer.mozilla.org/en/DOM/window.matchMedia
    // -webkit-min- and -o-min- omitted (Webkit/Opera supported above)
    // The generic min-device-pixel-ratio is expected to be added to the W3 spec.
    // Return false if neither method is available.
    decimal = 'only all and (min--moz-device-pixel-ratio:' + decimal + ')';
    if (mq(decimal)) return true;
    return mq(decimal.replace('-moz-', ''));
  }

  /**
   * Response.camelize
   * @example Response.camelize('data-casa-blanca') // casaBlanca
   */
  function camelize(s) {
    // Remove data- prefix and convert remaining dashed string to camelCase:
    return s.replace(regexDataPrefix, '$1').replace(regexDashB4, function(m, m1) {
      return m1.toUpperCase();
    });
  }

  /**
   * Response.datatize
   * Converts pulpFiction (or data-pulpFiction) to data-pulp-fiction
   * @example Response.datatize('casaBlanca')  // data-casa-blanca
   */
  function datatize(s) {
    // Make sure there's no data- already in s for it to work right in IE8.
    return 'data-' + (s ? s.replace(regexDataPrefix, '$1').replace(regexCamels, '$1-$2').toLowerCase() : s);
  }

  /**
   * Convert stringified primitives back to JavaScript.
   * @param {string|*} s String to parse into a JavaScript value.
   * @return {*}
   */
  function parse(s) {
    var n; // undefined, or becomes number
    return typeof s != 'string' || !s ? s
      : 'false' === s ? false
      : 'true' === s ? true
      : 'null' === s ? null
      : 'undefined' === s || (n = (+s)) || 0 === n || 'NaN' === s ? n
      : s;
  }
  
  /**
   * @param {Element|{length:number}} e
   * @return {Element|*}
   */
  function first(e) {
    return !e || e.nodeType ? e : e[0];
  }

  /**
   * internal-use function to iterate a node's attributes
   * @param {Element} el
   * @param {Function} fn
   * @param {(boolean|*)=} exp
   */
  function eachAttr(el, fn, exp) {
    var test, n, a, i, l;
    if (!el.attributes) return;
    test = typeof exp == 'boolean' ? /^data-/ : test;
    for (i = 0, l = el.attributes.length; i < l;) {
      if (a = el.attributes[i++]) {
        n = '' + a.name;
        test && test.test(n) !== exp || null == a.value || fn.call(el, a.value, n, a);
      }
    }
  }

  /**
   * Get object containing an element's data attrs.
   * @param {Element} el
   * @return {DOMStringMap|Object|undefined}
   */
  function getDataset(el) {
    var ob;
    if (!el || 1 !== el.nodeType) return;  // undefined
    if (ob = DMS && el.dataset) return ob; // native
    ob = {}; // Fallback plain object cannot mutate the dataset via reference.
    eachAttr(el, function(v, k) {
      ob[camelize(k)] = '' + v;
    }, true);
    return ob;
  }
  
  /**
   * @param {Element} el
   * @param {Object} ob
   * @param {Function} fn
   */
  function setViaObject(el, ob, fn) {
    for (var n in ob) owns.call(ob, n) && fn(el, n, ob[n]);
  }
  
  /**
   * @param {Object|Array|Function} el
   * @param {(string|Object|*)=} k
   * @param {*=} v
   */  
  function dataset(el, k, v) {
    el = first(el);
    if (!el || !el.setAttribute) return;
    if (void 0 === k && v === k) return getDataset(el);
    var exact = isArray(k) && datatize(k[0]);
    if (typeof k == 'object' && !exact) {
      k && setViaObject(el, k, dataset);
    } else {
      k = exact || datatize(k);
      if (!k) return;
      if (void 0 === v) {
        k = el.getAttribute(k); // repurpose
        return null == k ? v : exact ? parse(k) : '' + k; // normalize
      }
      el.setAttribute(k, v = '' + v);
      return v; // current value
    }
  }

  /**
   * Response.deletes(elem, keys) Delete HTML5 data attributes (remove them from them DOM)
   * @since 0.3.0
   * @param {Element|{length:number}} elem is a DOM element or stack of them
   * @param {string|Array} ssv data attribute key(s) in camelCase or lowercase to delete
   */
  function deletes(elem, ssv) {
    ssv = compact(ssv);
    route(elem, function(el) {
      each(ssv, function(k) {
        el.removeAttribute(datatize(k));
      });
    });
  }

  function sel(keys) {
    // Convert an array of data keys into a selector string
    // Converts ["a","b","c"] into "[data-a],[data-b],[data-c]"
    // Double-slash escapes periods so that attrs like data-density-1.5 will work
    // @link api.jquery.com/category/selectors/
    // @link github.com/jquery/sizzle/issues/76
    for (var k, r = [], i = 0, l = keys.length; i < l;)
      (k = keys[i++]) && r.push('[' + datatize(k.replace(regexTrimPunc, '').replace('.', '\\.')) + ']');
    return r.join();
  }

  /**
   * Response.target() Get the corresponding data attributes for an array of data keys.
   * @since 0.1.9
   * @param {Array} keys is the array of data keys whose attributes you want to select.
   * @return {Object} jQuery stack
   * @example Response.target(['a', 'b', 'c']) //  $('[data-a],[data-b],[data-c]')
   * @example Response.target('a b c']) //  $('[data-a],[data-b],[data-c]')
   */
  function target(keys) {
    return $(sel(compact(keys)));  
  }

  /** 
   * @since 0.3.0
   * @return {number} like jQuery(window).scrollLeft()
   */
  function scrollX() {
    return window.pageXOffset || docElem.scrollLeft; 
  }

  /** 
   * @since 0.3.0
   * @return {number} like $(window).scrollTop()
   */
  function scrollY() { 
    return window.pageYOffset || docElem.scrollTop; 
  }

  /**
   * area methods inX/inY/inViewport
   * @since 0.3.0
   */
  function rectangle(el, verge) {
    // Local handler for area methods:
    // adapted from github.com/ryanve/dime
    // The native object is read-only so we 
    // have use a copy in order to modify it.
    var r = el.getBoundingClientRect ? el.getBoundingClientRect() : {};
    verge = typeof verge == 'number' ? verge || 0 : 0;
    return {
        top: (r.top || 0) - verge
      , left: (r.left || 0) - verge
      , bottom: (r.bottom || 0) + verge
      , right: (r.right || 0) + verge
    };
  }
     
  // The verge is the amount of pixels to act as a cushion around the viewport. It can be any 
  // integer. If verge is zero, then the inX/inY/inViewport methods are exact. If verge is set to 100, 
  // then those methods return true when for elements that are are in the viewport *or* near it, 
  // with *near* being defined as within 100 pixels outside the viewport edge. Elements immediately 
  // outside the viewport are 'on the verge' of being scrolled to.

  function inX(elem, verge) {
    var r = rectangle(first(elem), verge);
    return !!r && r.right >= 0 && r.left <= viewportW();
  }

  function inY(elem, verge) {
    var r = rectangle(first(elem), verge);
    return !!r && r.bottom >= 0 && r.top <= viewportH();
  }

  function inViewport(elem, verge) {
    // equiv to: inX(elem, verge) && inY(elem, verge)
    // But just manually do both to avoid calling rectangle() and first() twice.
    // It actually gzips smaller this way too:
    var r = rectangle(first(elem), verge);
    return !!r && r.bottom >= 0 && r.top <= viewportH() && r.right >= 0 && r.left <= viewportW();
  }
  
  /**
   * @description Detect whether elem should act in src or markup mode.
   * @param {Element} elem
   * @return {number}
   */
  function detectMode(elem) {
    // Normalize to lowercase to ensure compatibility across HTML/XHTML/XML.
    // These are the elems that can use src attr per the W3 spec:
    //dev.w3.org/html5/spec-author-view/index.html#attributes-1
    //stackoverflow.com/q/8715689/770127
    //stackoverflow.com/a/4878963/770127
    var srcElems = { img:1, input:1, source:3, embed:3, track:3, iframe:5, audio:5, video:5, script:5 }
      , modeID = srcElems[ elem.nodeName.toLowerCase() ] || -1;

    // -5 => markup mode for video/audio/iframe w/o src attr.
    // -1 => markup mode for any elem not in the array above.
    //  1 => src mode  for img/input (empty content model). Images.
    //  3 => src mode  for source/embed/track (empty content model). Media *or* time data.
    //  5 => src mode  for audio/video/iframe/script *with* src attr.
    //  If we at some point we need to differentiate <track> we'll use 4, but for now
    //  it's grouped with the other non-image empty content elems that use src.
    //  hasAttribute is not supported in IE7 so check elem.getAttribute('src')
    return 4 > modeID ? modeID : null != elem.getAttribute('src') ? 5 : -5;
  }

  /**
   * Response.store()
   * Store a data value on each elem targeted by a jQuery selector. We use this for storing an 
   * elem's orig (no-js) state. This gives us the ability to return the elem to its orig state.
   * The data it stores is either the src attr or the innerHTML based on result of detectMode().
   * @since 0.1.9
   * @param {Object} $elems DOM element | jQuery object | nodeList | array of elements
   * @param {string} key is the key to use to store the orig value w/ @link api.jquery.com/data/
   * @param {string=} source  (@since 0.6.2) an optional attribute name to read data from
   */
  function store($elems, key, source) {
    var valToStore;
    if (!$elems || null == key) throw new TypeError('@store');
    source = typeof source == 'string' && source;
    route($elems, function(el) {
      if (source) valToStore = el.getAttribute(source);
      else if (0 < detectMode(el)) valToStore = el.getAttribute('src');
      else valToStore = el.innerHTML;
      null == valToStore ? deletes(el, key) : dataset(el, key, valToStore); 
    });
    return Response;
  }

  /**
   * Response.access() Access data-* values for element from an array of data-* keys. 
   * @since 0.1.9 added support for space-separated strings in 0.3.1
   * @param {Object} elem is a native or jQuery element whose values to access.
   * @param {Array|string} keys is an array or SSV string of data keys
   * @return {Array} dataset values corresponding to each key. Since 0.4.0 if
   *   the params are wrong then the return is an empty array.
   */
  function access(elem, keys) {
    var ret = [];
    elem && keys && each(compact(keys), function(k) {
      ret.push(dataset(elem, k));
    }, elem);
    return ret;
  }

  function addTest(prop, fn) {
    if (typeof prop == 'string' && typeof fn == 'function') {
      propTests[prop] = fn;
      isCustom[prop] = 1;
    }
    return Response;
  }
    
  // Prototype object for element sets used in Response.create
  // Each element in the set inherits this as well, so some of the 
  // methods apply to the set, while others apply to single elements.
  Elemset = (function() {
    var crossover = event.crossover
      //, update = event.update
      , min = Math.min;

    // Techically data attributes names can contain uppercase in HTML, but, The DOM lowercases 
    // attributes, so they must be lowercase regardless when we target them in jQuery. Force them 
    // lowercase here to prevent issues. Removing all punc marks except for dashes, underscores,
    // and periods so that we don't have to worry about escaping anything crazy.
    // Rules @link dev.w3.org/html5/spec/Overview.html#custom-data-attribute
    // jQuery selectors @link api.jquery.com/category/selectors/ 
    function sanitize(key) {
      // Allow lowercase alphanumerics, dashes, underscores, and periods:
      return typeof key == 'string' ? key.toLowerCase().replace(regexFunkyPunc, '') : '';
    }
    
    function ascending(a, b) {
      return a - b;
    }

    return {
        $e: 0 // jQuery instance
      , mode: 0 // integer  defined per element
      , breakpoints: null // array, validated @ configure()
      , prefix: null // string, validated @ configure()
      , prop: 'width' // string, validated @ configure()
      , keys: [] // array, defined @ configure()
      , dynamic: null // boolean, defined @ configure()
      , custom: 0 // boolean, see addTest()
      , values: [] // array, available values
      , fn: 0 // callback, the test fn, defined @ configure()
      , verge: null // integer  uses default based on device size
      , newValue: 0
      , currValue: 1
      , aka: null
      , lazy: null
      , i: 0  // integer, the index of the current highest active breakpoint min
      , uid: null

      , reset: function() {
          var subjects = this.breakpoints, i = subjects.length, tempIndex = 0;
          while (!tempIndex && i--) this.fn(subjects[i]) && (tempIndex = i);
          if (tempIndex !== this.i) {
            // Crossover occurred. Fire the crossover events:
            $win.trigger(crossover).trigger(this.prop + crossover);
            this.i = tempIndex || 0;
          }
          return this;
        }

      , configure: function(options) {
          merge(this, options);
        
          var i, points, prefix, aliases, aliasKeys, isNumeric = true, prop = this.prop;
          this.uid = suid++;
          if (null == this.verge) this.verge = min(screenMax, 500);
          if (!(this.fn = propTests[prop])) throw new TypeError('@create');

          // If we get to here then we know the prop is one one our supported props:
          // 'width', 'height', 'device-width', 'device-height', 'device-pixel-ratio'
          if (null == this.dynamic) this.dynamic = 'device' !== prop.slice(0, 6);
          
          this.custom = isCustom[prop];
          prefix = this.prefix ? sift(map(compact(this.prefix), sanitize)) : ['min-' + prop + '-'];
          aliases = 1 < prefix.length ? prefix.slice(1) : 0;
          this.prefix = prefix[0];
          points = this.breakpoints;
          
          // Sort and validate (#valid8) custom breakpoints if supplied.
          // Must be done before keys are created so that the keys match:
          if (isArray(points)) {
            each(points, function(v) {
              if (!v && v !== 0) throw 'invalid breakpoint';
              isNumeric = isNumeric && isFinite(v);
            });
            
            isNumeric && points.sort(ascending);
            if (!points.length) throw new TypeError('.breakpoints');
          } else {
            // The default breakpoints are presorted.
            points = defaultPoints[prop] || defaultPoints[prop.split('-').pop()];
            if (!points) throw new TypeError('.prop');
          }

          this.breakpoints = points;
          this.keys = affix(this.breakpoints, this.prefix); // Create array of data keys.
          this.aka = null; // Reset just in case a value was merged in.

          if (aliases) {
            aliasKeys = [];
            i = aliases.length;
            while (i--) aliasKeys.push(affix(this.breakpoints, aliases[i]));
            this.aka = aliasKeys; // this.aka is an array of arrays (one for each alias)
            this.keys = concat.apply(this.keys, aliasKeys); // flatten aliases into this.keys
          }

          sets.all = sets.all.concat(sets[this.uid] = this.keys); // combined keys ===> sets.all
          return this;
        }

      , target: function() {
          this.$e = $(sel(sets[this.uid])); // Cache selection. DOM must be ready.
          store(this.$e, initContentKey);  // Store original (no-js) value to data key.
          this.keys.push(initContentKey);  // #keys now equals #breakpoints+1
          return this;
        }

      // The rest of the methods are designed for use with single elements.
      // They are for use in a cloned instances within a loop.
      , decideValue: function() {
          // Return the first value from the values array that passes the boolean
          // test callback. If none pass the test, then return the fallback value.
          // this.breakpoints.length === this.values.length + 1  
          // The extra member in the values array is the initContentKey value.
          var val = null, subjects = this.breakpoints, sL = subjects.length, i = sL;
          while (val == null && i--) this.fn(subjects[i]) && (val = this.values[i]);
          this.newValue = typeof val == 'string' ? val : this.values[sL];
          return this; // chainable
        }

      , prepareData: function(elem) {
          this.$e = $(elem);
          this.mode = detectMode(elem);
          this.values = access(this.$e, this.keys);
          if (this.aka) {
            // If there are alias keys then there may be alias values. Merge the values from 
            // all the aliases into the values array. The merge method only merges in truthy values
            // and prevents falsey values from overwriting truthy ones. (See Response.merge)
            // Each of the this.aka arrays has the same length as the this.values
            // array, so no new indexes will be added, just filled if there's truthy values.
            var i = this.aka.length;
            while (i--) this.values = merge(this.values, access(this.$e, this.aka[i]));
          }
          return this.decideValue();
        }

      , updateDOM: function() {
          // Apply the method that performs the actual swap. When updateDOM called this.$e and this.e refer
          // to single elements. Only update the DOM when the new value is different than the current value.
          if (this.currValue === this.newValue) { return this; }
          this.currValue = this.newValue;
          if (0 < this.mode) { 
            this.$e[0].setAttribute('src', this.newValue); 
          } else if (null == this.newValue) { 
            this.$e.empty && this.$e.empty(); 
          } else {
            if (this.$e.html) {
              this.$e.html(this.newValue); 
            } else {
              this.$e.empty && this.$e.empty();
              this.$e[0].innerHTML = this.newValue;
            }
          }
          // this.$e.trigger(update); // may add this event in future
          return this;
        }
    };
  }());
  
  // The keys are the prop and the values are the method that tests that prop.
  // The props with dashes in them are added via array notation below.
  // Props marked as dynamic change when the viewport is resized:
  propTests['width'] = band;   // dynamic
  propTests['height'] = wave;  // dynamic
  propTests['device-width'] = device.band;
  propTests['device-height'] = device.wave;
  propTests['device-pixel-ratio'] = dpr;

  function resize(fn) {
    $win.on('resize', fn);
    return Response; // chain
  }

  function crossover(prop, fn) {
    var temp, eventToFire, eventCrossover = event.crossover;
    if (typeof prop == 'function') {// support args in reverse
      temp = fn;
      fn = prop;
      prop = temp;
    }
    eventToFire = prop ? ('' + prop + eventCrossover) : eventCrossover;
    $win.on(eventToFire, fn);
    return Response; // chain
  }

  /**
   * Response.action A facade for calling functions on both the ready and resize events.
   * @link http://responsejs.com/#action
   * @since 0.1.3
   * @param {Function|Array} action is the callback name or array of callback names to call.
   * @example Response.action(myFunc1) // call myFunc1() on ready/resize
   * @example Response.action([myFunc1, myFunc2]) // call myFunc1(), myFunc2() ...
   */
  function action(fnOrArr) {
    route(fnOrArr, function(fn) {
      ready(fn);
      resize(fn);
    });
    return Response;
  }
  
  /**
   * Create their own Response attribute sets, with custom breakpoints and data-* names.
   * @since 0.1.9
   * @param {Object|Array} args is an options object or an array of options objects.
   * @link http://responsejs.com/#create
   * @example Response.create(object) // single
   * @example Response.create([object1, object2]) // bulk
   */
  function create(args) {
    route(args, function(options) {
      if (typeof options != 'object') throw new TypeError('@create');
      var elemset = procreate(Elemset).configure(options)
        , lowestNonZeroBP
        , verge = elemset.verge
        , breakpoints = elemset.breakpoints
        , scrollName = namespaceIt('scroll')
        , resizeName = namespaceIt('resize');

      if (!breakpoints.length) return;

      // Identify the lowest nonzero breakpoint. (They're already sorted low to high by now.)
      lowestNonZeroBP = breakpoints[0] || breakpoints[1] || false;
    
      ready(function() {
        var allLoaded = event.allLoaded, lazy = !!elemset.lazy;
        
        function resizeHandler() {
          elemset.reset();
          each(elemset.$e, function(el, i) {
            elemset[i].decideValue().updateDOM();
          }).trigger(allLoaded);
        }
        
        function scrollHandler() {
          each(elemset.$e, function(el, i) {
            inViewport(elemset[i].$e, verge) && elemset[i].updateDOM();
          });
        }

        // Target elements containing this set's Response data attributes and chain into the 
        // loop that occurs on ready. The selector is cached to elemset.$e for later use.
        each(elemset.target().$e, function(el, i) {
          elemset[i] = procreate(elemset).prepareData(el);// Inherit from elemset
          if (!lazy || inViewport(elemset[i].$e, verge)) {
            // If not lazy update all the elems in the set. If
            // lazy, only update elems in the current viewport.
            elemset[i].updateDOM(); 
          }
        });

        // device-* props are static and only need to be tested once. The others are
        // dynamic, meaning they need to be tested on resize. Also if a device so small
        // that it doesn't support the lowestNonZeroBP then we don't need to listen for 
        // resize events b/c we know the device can't resize beyond that breakpoint.

        if (elemset.dynamic && (elemset.custom || lowestNonZeroBP < screenMax)) {
           resize(resizeHandler, resizeName);
        }

        // We don't have to re-decide the content on scrolls because neither the viewport or device
        // properties change from a scroll. This setup minimizes the operations binded to the scroll 
        // event. Once everything in the set has been swapped once, the scroll handler is deactivated
        // through the use of a custom event.
        if (!lazy) return;
        
        $win.on(scrollName, scrollHandler);
        elemset.$e.one(allLoaded, function() {
          $win.off(scrollName, scrollHandler);
        });
      });
    });
    return Response;
  }
  
  function noConflict(callback) {
    if (root[name] === Response) root[name] = old;
    if (typeof callback == 'function') callback.call(root, Response);
    return Response;
  }
  
  // Many methods are @deprecated (see issue #51)
  Response = {
      deviceMin: function() { return screenMin; }
    , deviceMax: function() { return screenMax; }
    //, sets: function(prop) {// must be uid
    //  return $(sel(sets[prop] || sets.all));
    //}
    , noConflict: noConflict
    , create: create
    , addTest: addTest
    , datatize: datatize
    , camelize: camelize
    , render: parse
    , store: store
    , access: access
    , target: target
    , object: procreate
    , crossover: crossover
    , action: action
    , resize: resize
    , ready: ready
    , affix: affix
    , sift: sift
    , dpr: dpr
    , deletes: deletes
    , scrollX: scrollX
    , scrollY: scrollY
    , deviceW: deviceW
    , deviceH: deviceH
    , device: device
    , inX: inX
    , inY: inY
    , route: route
    , merge: merge
    , media: media
    , mq: mq
    , wave: wave
    , band: band
    , map: map
    , each: each
    , inViewport: inViewport
    , dataset: dataset
    , viewportH: viewportH
    , viewportW: viewportW
  };

  // Initialize
  ready(function() {
    var settings = dataset(doc.body, 'responsejs'), parse = win.JSON && JSON.parse || $.parseJSON;
    settings = settings && parse ? parse(settings) : settings;
    settings && settings.create && create(settings.create);
    // Remove .no-responsejs and add .responsejs
    docElem.className = docElem.className.replace(/(^|\s)(no-)?responsejs(\s|$)/, '$1$3') + ' responsejs ';
  });

  return Response;
}));;/*
 * jQuery Highlight plugin
 *
 * Based on highlight v3 by Johann Burkard
 * http://johannburkard.de/blog/programming/javascript/highlight-javascript-text-higlighting-jquery-plugin.html
 *
 * Code a little bit refactored and cleaned (in my humble opinion).
 * Most important changes:
 *  - has an option to highlight only entire words (wordsOnly - false by default),
 *  - has an option to be case sensitive (caseSensitive - false by default)
 *  - highlight element tag and class names can be specified in options
 *
 * Usage:
 *   // wrap every occurrance of text 'lorem' in content
 *   // with <span class='highlight'> (default options)
 *   $('#content').highlight('lorem');
 *
 *   // search for and highlight more terms at once
 *   // so you can save some time on traversing DOM
 *   $('#content').highlight(['lorem', 'ipsum']);
 *   $('#content').highlight('lorem ipsum');
 *
 *   // search only for entire word 'lorem'
 *   $('#content').highlight('lorem', { wordsOnly: true });
 *
 *   // don't ignore case during search of term 'lorem'
 *   $('#content').highlight('lorem', { caseSensitive: true });
 *
 *   // wrap every occurrance of term 'ipsum' in content
 *   // with <em class='important'>
 *   $('#content').highlight('ipsum', { element: 'em', className: 'important' });
 *
 *   // remove default highlight
 *   $('#content').unhighlight();
 *
 *   // remove custom highlight
 *   $('#content').unhighlight({ element: 'em', className: 'important' });
 *
 *
 * Copyright (c) 2009 Bartek Szopka
 *
 * Licensed under MIT license.
 *
 */

jQuery.extend({
    highlight: function (node, re, nodeName, className) {
        if (node.nodeType === 3) {
            var match = node.data.match(re);
            if (match) {
                var highlight = document.createElement(nodeName || 'span');
                highlight.className = className || 'highlight';
                var wordNode = node.splitText(match.index);
                wordNode.splitText(match[0].length);
                var wordClone = wordNode.cloneNode(true);
                highlight.appendChild(wordClone);
                wordNode.parentNode.replaceChild(highlight, wordNode);
                return 1; //skip added node in parent
            }
        } else if ((node.nodeType === 1 && node.childNodes) && // only element nodes that have children
                !/(script|style)/i.test(node.tagName) && // ignore script and style nodes
                !(node.tagName === nodeName.toUpperCase() && node.className === className)) { // skip if already highlighted
            for (var i = 0; i < node.childNodes.length; i++) {
                i += jQuery.highlight(node.childNodes[i], re, nodeName, className);
            }
        }
        return 0;
    }
});

jQuery.fn.unhighlight = function (options) {
    var settings = { className: 'highlight', element: 'span' };
    jQuery.extend(settings, options);

    return this.find(settings.element + "." + settings.className).each(function () {
        var parent = this.parentNode;
        parent.replaceChild(this.firstChild, this);
        parent.normalize();
    }).end();
};

jQuery.fn.highlight = function (words, options) {
    var settings = { className: 'highlight', element: 'span', caseSensitive: false, wordsOnly: false };
    jQuery.extend(settings, options);
    
    if (words.constructor === String) {
        words = [words];
    }
    words = jQuery.grep(words, function(word, i){
      return word != '';
    });
    words = jQuery.map(words, function(word, i) {
      return word.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
    });
    if (words.length == 0) { return this; };

    var flag = settings.caseSensitive ? "" : "i";
    var pattern = "(" + words.join("|") + ")";
    if (settings.wordsOnly) {
        pattern = "\\b" + pattern + "\\b";
    }
    var re = new RegExp(pattern, flag);
    
    return this.each(function () {
        jQuery.highlight(this, re, settings.element, settings.className);
    });
};
;!function () { function a(b, c, d) { var e = a.resolve(b); if (null == e) { d = d || b, c = c || "root"; var f = new Error('Failed to require "' + d + '" from "' + c + '"'); throw f.path = d, f.parent = c, f.require = !0, f } var g = a.modules[e]; if (!g._resolving && !g.exports) { var h = {}; h.exports = {}, h.client = h.component = !0, g._resolving = !0, g.call(this, h.exports, a.relative(e), h), delete g._resolving, g.exports = h.exports } return g.exports } a.modules = {}, a.aliases = {}, a.resolve = function (b) { "/" === b.charAt(0) && (b = b.slice(1)); for (var c = [b, b + ".js", b + ".json", b + "/index.js", b + "/index.json"], d = 0; d < c.length; d++) { var b = c[d]; if (a.modules.hasOwnProperty(b)) return b; if (a.aliases.hasOwnProperty(b)) return a.aliases[b] } }, a.normalize = function (a, b) { var c = []; if ("." != b.charAt(0)) return b; a = a.split("/"), b = b.split("/"); for (var d = 0; d < b.length; ++d) ".." == b[d] ? a.pop() : "." != b[d] && "" != b[d] && c.push(b[d]); return a.concat(c).join("/") }, a.register = function (b, c) { a.modules[b] = c }, a.alias = function (b, c) { if (!a.modules.hasOwnProperty(b)) throw new Error('Failed to alias "' + b + '", it does not exist'); a.aliases[c] = b }, a.relative = function (b) { function c(a, b) { for (var c = a.length; c--;) if (a[c] === b) return c; return -1 } function d(c) { var e = d.resolve(c); return a(e, b, c) } var e = a.normalize(b, ".."); return d.resolve = function (d) { var f = d.charAt(0); if ("/" == f) return d.slice(1); if ("." == f) return a.normalize(e, d); var g = b.split("/"), h = c(g, "deps") + 1; return h || (h = 0), d = g.slice(0, h + 1).join("/") + "/deps/" + d }, d.exists = function (b) { return a.modules.hasOwnProperty(d.resolve(b)) }, d }, a.register("component-classes/index.js", function (a, b, c) { function d(a) { if (!a) throw new Error("A DOM element reference is required"); this.el = a, this.list = a.classList } var e = b("indexof"), f = /\s+/, g = Object.prototype.toString; c.exports = function (a) { return new d(a) }, d.prototype.add = function (a) { if (this.list) return this.list.add(a), this; var b = this.array(), c = e(b, a); return ~c || b.push(a), this.el.className = b.join(" "), this }, d.prototype.remove = function (a) { if ("[object RegExp]" == g.call(a)) return this.removeMatching(a); if (this.list) return this.list.remove(a), this; var b = this.array(), c = e(b, a); return ~c && b.splice(c, 1), this.el.className = b.join(" "), this }, d.prototype.removeMatching = function (a) { for (var b = this.array(), c = 0; c < b.length; c++) a.test(b[c]) && this.remove(b[c]); return this }, d.prototype.toggle = function (a, b) { return this.list ? ("undefined" != typeof b ? b !== this.list.toggle(a, b) && this.list.toggle(a) : this.list.toggle(a), this) : ("undefined" != typeof b ? b ? this.add(a) : this.remove(a) : this.has(a) ? this.remove(a) : this.add(a), this) }, d.prototype.array = function () { var a = this.el.className.replace(/^\s+|\s+$/g, ""), b = a.split(f); return "" === b[0] && b.shift(), b }, d.prototype.has = d.prototype.contains = function (a) { return this.list ? this.list.contains(a) : !!~e(this.array(), a) } }), a.register("segmentio-extend/index.js", function (a, b, c) { c.exports = function (a) { for (var b, c = Array.prototype.slice.call(arguments, 1), d = 0; b = c[d]; d++) if (b) for (var e in b) a[e] = b[e]; return a } }), a.register("component-indexof/index.js", function (a, b, c) { c.exports = function (a, b) { if (a.indexOf) return a.indexOf(b); for (var c = 0; c < a.length; ++c) if (a[c] === b) return c; return -1 } }), a.register("component-event/index.js", function (a) { var b = window.addEventListener ? "addEventListener" : "attachEvent", c = window.removeEventListener ? "removeEventListener" : "detachEvent", d = "addEventListener" !== b ? "on" : ""; a.bind = function (a, c, e, f) { return a[b](d + c, e, f || !1), e }, a.unbind = function (a, b, e, f) { return a[c](d + b, e, f || !1), e } }), a.register("timoxley-to-array/index.js", function (a, b, c) { function d(a) { return "[object Array]" === Object.prototype.toString.call(a) } c.exports = function (a) { if ("undefined" == typeof a) return []; if (null === a) return [null]; if (a === window) return [window]; if ("string" == typeof a) return [a]; if (d(a)) return a; if ("number" != typeof a.length) return [a]; if ("function" == typeof a && a instanceof Function) return [a]; for (var b = [], c = 0; c < a.length; c++) (Object.prototype.hasOwnProperty.call(a, c) || c in a) && b.push(a[c]); return b.length ? b : [] } }), a.register("javve-events/index.js", function (a, b) { var c = b("event"), d = b("to-array"); a.bind = function (a, b, e, f) { a = d(a); for (var g = 0; g < a.length; g++) c.bind(a[g], b, e, f) }, a.unbind = function (a, b, e, f) { a = d(a); for (var g = 0; g < a.length; g++) c.unbind(a[g], b, e, f) } }), a.register("javve-get-by-class/index.js", function (a, b, c) { c.exports = function () { return document.getElementsByClassName ? function (a, b, c) { return c ? a.getElementsByClassName(b)[0] : a.getElementsByClassName(b) } : document.querySelector ? function (a, b, c) { return b = "." + b, c ? a.querySelector(b) : a.querySelectorAll(b) } : function (a, b, c) { var d = [], e = "*"; null == a && (a = document); for (var f = a.getElementsByTagName(e), g = f.length, h = new RegExp("(^|\\s)" + b + "(\\s|$)"), i = 0, j = 0; g > i; i++) if (h.test(f[i].className)) { if (c) return f[i]; d[j] = f[i], j++ } return d } }() }), a.register("javve-get-attribute/index.js", function (a, b, c) { c.exports = function (a, b) { var c = a.getAttribute && a.getAttribute(b) || null; if (!c) for (var d = a.attributes, e = d.length, f = 0; e > f; f++) void 0 !== b[f] && b[f].nodeName === b && (c = b[f].nodeValue); return c } }), a.register("javve-natural-sort/index.js", function (a, b, c) { c.exports = function (a, b, c) { var d, e, f = /(^-?[0-9]+(\.?[0-9]*)[df]?e?[0-9]?$|^0x[0-9a-f]+$|[0-9]+)/gi, g = /(^[ ]*|[ ]*$)/g, h = /(^([\w ]+,?[\w ]+)?[\w ]+,?[\w ]+\d+:\d+(:\d+)?[\w ]?|^\d{1,4}[\/\-]\d{1,4}[\/\-]\d{1,4}|^\w+, \w+ \d+, \d{4})/, i = /^0x[0-9a-f]+$/i, j = /^0/, c = c || {}, k = function (a) { return c.insensitive && ("" + a).toLowerCase() || "" + a }, l = k(a).replace(g, "") || "", m = k(b).replace(g, "") || "", n = l.replace(f, "\x00$1\x00").replace(/\0$/, "").replace(/^\0/, "").split("\x00"), o = m.replace(f, "\x00$1\x00").replace(/\0$/, "").replace(/^\0/, "").split("\x00"), p = parseInt(l.match(i)) || 1 != n.length && l.match(h) && Date.parse(l), q = parseInt(m.match(i)) || p && m.match(h) && Date.parse(m) || null, r = c.desc ? -1 : 1; if (q) { if (q > p) return -1 * r; if (p > q) return 1 * r } for (var s = 0, t = Math.max(n.length, o.length) ; t > s; s++) { if (d = !(n[s] || "").match(j) && parseFloat(n[s]) || n[s] || 0, e = !(o[s] || "").match(j) && parseFloat(o[s]) || o[s] || 0, isNaN(d) !== isNaN(e)) return isNaN(d) ? 1 : -1; if (typeof d != typeof e && (d += "", e += ""), e > d) return -1 * r; if (d > e) return 1 * r } return 0 } }), a.register("javve-to-string/index.js", function (a, b, c) { c.exports = function (a) { return a = void 0 === a ? "" : a, a = null === a ? "" : a, a = a.toString() } }), a.register("component-type/index.js", function (a, b, c) { var d = Object.prototype.toString; c.exports = function (a) { switch (d.call(a)) { case "[object Date]": return "date"; case "[object RegExp]": return "regexp"; case "[object Arguments]": return "arguments"; case "[object Array]": return "array"; case "[object Error]": return "error" } return null === a ? "null" : void 0 === a ? "undefined" : a !== a ? "nan" : a && 1 === a.nodeType ? "element" : typeof a.valueOf() } }), a.register("list.js/index.js", function (a, b, c) { !function (a, d) { "use strict"; var e = a.document, f = b("get-by-class"), g = b("extend"), h = b("indexof"), i = function (a, c, i) { var j, k = this, l = b("./src/item")(k), m = b("./src/add-async")(k), n = b("./src/parse")(k); j = { start: function () { k.listClass = "list", k.searchClass = "search", k.sortClass = "sort", k.page = 200, k.i = 1, k.items = [], k.visibleItems = [], k.matchingItems = [], k.searched = !1, k.filtered = !1, k.handlers = { updated: [] }, k.plugins = {}, k.helpers = { getByClass: f, extend: g, indexOf: h }, g(k, c), k.listContainer = "string" == typeof a ? e.getElementById(a) : a, k.listContainer && (k.list = f(k.listContainer, k.listClass, !0), k.templater = b("./src/templater")(k), k.search = b("./src/search")(k), k.filter = b("./src/filter")(k), k.sort = b("./src/sort")(k), this.items(), k.update(), this.plugins()) }, items: function () { n(k.list), i !== d && k.add(i) }, plugins: function () { for (var a = 0; a < k.plugins.length; a++) { var b = k.plugins[a]; k[b.name] = b, b.init(k) } } }, this.add = function (a, b) { if (b) return m(a, b), void 0; var c = [], e = !1; a[0] === d && (a = [a]); for (var f = 0, g = a.length; g > f; f++) { var h = null; a[f] instanceof l ? (h = a[f], h.reload()) : (e = k.items.length > k.page ? !0 : !1, h = new l(a[f], d, e)), k.items.push(h), c.push(h) } return k.update(), c }, this.show = function (a, b) { return this.i = a, this.page = b, k.update(), k }, this.remove = function (a, b, c) { for (var d = 0, e = 0, f = k.items.length; f > e; e++) k.items[e].values()[a] == b && (k.templater.remove(k.items[e], c), k.items.splice(e, 1), f--, e--, d++); return k.update(), d }, this.get = function (a, b) { for (var c = [], d = 0, e = k.items.length; e > d; d++) { var f = k.items[d]; f.values()[a] == b && c.push(f) } return c }, this.size = function () { return k.items.length }, this.clear = function () { return k.templater.clear(), k.items = [], k }, this.on = function (a, b) { return k.handlers[a].push(b), k }, this.off = function (a, b) { var c = k.handlers[a], d = h(c, b); return d > -1 && c.splice(d, 1), k }, this.trigger = function (a) { for (var b = k.handlers[a].length; b--;) k.handlers[a][b](k); return k }, this.reset = { filter: function () { for (var a = k.items, b = a.length; b--;) a[b].filtered = !1; return k }, search: function () { for (var a = k.items, b = a.length; b--;) a[b].found = !1; return k } }, this.update = function () { var a = k.items, b = a.length; k.visibleItems = [], k.matchingItems = [], k.templater.clear(); for (var c = 0; b > c; c++) a[c].matching() && k.matchingItems.length + 1 >= k.i && k.visibleItems.length < k.page ? (a[c].show(), k.visibleItems.push(a[c]), k.matchingItems.push(a[c])) : a[c].matching() ? (k.matchingItems.push(a[c]), a[c].hide()) : a[c].hide(); return k.trigger("updated"), k }, j.start() }; c.exports = i }(window) }), a.register("list.js/src/search.js", function (a, b, c) { var d = b("events"), e = b("get-by-class"), f = b("to-string"); c.exports = function (a) { var b, c, g, h, i = { resetList: function () { a.i = 1, a.templater.clear(), h = void 0 }, setOptions: function (a) { 2 == a.length && a[1] instanceof Array ? c = a[1] : 2 == a.length && "function" == typeof a[1] ? h = a[1] : 3 == a.length && (c = a[1], h = a[2]) }, setColumns: function () { c = void 0 === c ? i.toArray(a.items[0].values()) : c }, setSearchString: function (a) { a = f(a).toLowerCase(), a = a.replace(/[-[\]{}()*+?.,\\^$|#]/g, "\\$&"), g = a }, toArray: function (a) { var b = []; for (var c in a) b.push(c); return b } }, j = { list: function () { for (var b = 0, c = a.items.length; c > b; b++) j.item(a.items[b]) }, item: function (a) { a.found = !1; for (var b = 0, d = c.length; d > b; b++) if (j.values(a.values(), c[b])) return a.found = !0, void 0 }, values: function (a, c) { return a.hasOwnProperty(c) && (b = f(a[c]).toLowerCase(), "" !== g && b.search(g) > -1) ? !0 : !1 }, reset: function () { a.reset.search(), a.searched = !1 } }, k = function (b) { return a.trigger("searchStart"), i.resetList(), i.setSearchString(b), i.setOptions(arguments), i.setColumns(), "" === g ? j.reset() : (a.searched = !0, h ? h(g, c) : j.list()), a.update(), a.trigger("searchComplete"), a.visibleItems }; return a.handlers.searchStart = a.handlers.searchStart || [], a.handlers.searchComplete = a.handlers.searchComplete || [], d.bind(e(a.listContainer, a.searchClass), "keyup", function (b) { var c = b.target || b.srcElement, d = "" === c.value && !a.searched; d || k(c.value) }), d.bind(e(a.listContainer, a.searchClass), "input", function (a) { var b = a.target || a.srcElement; "" === b.value && k("") }), a.helpers.toString = f, k } }), a.register("list.js/src/sort.js", function (a, b, c) { var d = b("natural-sort"), e = b("classes"), f = b("events"), g = b("get-by-class"), h = b("get-attribute"); c.exports = function (a) { a.sortFunction = a.sortFunction || function (a, b, c) { return c.desc = "desc" == c.order ? !0 : !1, d(a.values()[c.valueName], b.values()[c.valueName], c) }; var b = { els: void 0, clear: function () { for (var a = 0, c = b.els.length; c > a; a++) e(b.els[a]).remove("asc"), e(b.els[a]).remove("desc") }, getOrder: function (a) { var b = h(a, "data-order"); return "asc" == b || "desc" == b ? b : e(a).has("desc") ? "asc" : e(a).has("asc") ? "desc" : "asc" }, getInSensitive: function (a, b) { var c = h(a, "data-insensitive"); b.insensitive = "true" === c ? !0 : !1 }, setOrder: function (a) { for (var c = 0, d = b.els.length; d > c; c++) { var f = b.els[c]; if (h(f, "data-sort") === a.valueName) { var g = h(f, "data-order"); "asc" == g || "desc" == g ? g == a.order && e(f).add(a.order) : e(f).add(a.order) } } } }, c = function () { a.trigger("sortStart"), options = {}; var c = arguments[0].currentTarget || arguments[0].srcElement || void 0; c ? (options.valueName = h(c, "data-sort"), b.getInSensitive(c, options), options.order = b.getOrder(c)) : (options = arguments[1] || options, options.valueName = arguments[0], options.order = options.order || "asc", options.insensitive = "undefined" == typeof options.insensitive ? !0 : options.insensitive), b.clear(), b.setOrder(options), options.sortFunction = options.sortFunction || a.sortFunction, a.items.sort(function (a, b) { return options.sortFunction(a, b, options) }), a.update(), a.trigger("sortComplete") }; return a.handlers.sortStart = a.handlers.sortStart || [], a.handlers.sortComplete = a.handlers.sortComplete || [], b.els = g(a.listContainer, a.sortClass), f.bind(b.els, "click", c), a.on("searchStart", b.clear), a.on("filterStart", b.clear), a.helpers.classes = e, a.helpers.naturalSort = d, a.helpers.events = f, a.helpers.getAttribute = h, c } }), a.register("list.js/src/item.js", function (a, b, c) { c.exports = function (a) { return function (b, c, d) { var e = this; this._values = {}, this.found = !1, this.filtered = !1; var f = function (b, c, d) { if (void 0 === c) d ? e.values(b, d) : e.values(b); else { e.elm = c; var f = a.templater.get(e, b); e.values(f) } }; this.values = function (b, c) { if (void 0 === b) return e._values; for (var d in b) e._values[d] = b[d]; c !== !0 && a.templater.set(e, e.values()) }, this.show = function () { a.templater.show(e) }, this.hide = function () { a.templater.hide(e) }, this.matching = function () { return a.filtered && a.searched && e.found && e.filtered || a.filtered && !a.searched && e.filtered || !a.filtered && a.searched && e.found || !a.filtered && !a.searched }, this.visible = function () { return e.elm.parentNode == a.list ? !0 : !1 }, f(b, c, d) } } }), a.register("list.js/src/templater.js", function (a, b, c) { var d = b("get-by-class"), e = function (a) { function b(b) { if (void 0 === b) { for (var c = a.list.childNodes, d = 0, e = c.length; e > d; d++) if (void 0 === c[d].data) return c[d]; return null } if (-1 !== b.indexOf("<")) { var f = document.createElement("div"); return f.innerHTML = b, f.firstChild } return document.getElementById(a.item) } var c = b(a.item), e = this; this.get = function (a, b) { e.create(a); for (var c = {}, f = 0, g = b.length; g > f; f++) { var h = d(a.elm, b[f], !0); c[b[f]] = h ? h.innerHTML : "" } return c }, this.set = function (a, b) { if (!e.create(a)) for (var c in b) if (b.hasOwnProperty(c)) { var f = d(a.elm, c, !0); f && ("IMG" === f.tagName && "" !== b[c] ? f.src = b[c] : f.innerHTML = b[c]) } }, this.create = function (a) { if (void 0 !== a.elm) return !1; var b = c.cloneNode(!0); return b.removeAttribute("id"), a.elm = b, e.set(a, a.values()), !0 }, this.remove = function (b) { a.list.removeChild(b.elm) }, this.show = function (b) { e.create(b), a.list.appendChild(b.elm) }, this.hide = function (b) { void 0 !== b.elm && b.elm.parentNode === a.list && a.list.removeChild(b.elm) }, this.clear = function () { if (a.list.hasChildNodes()) for (; a.list.childNodes.length >= 1;) a.list.removeChild(a.list.firstChild) } }; c.exports = function (a) { return new e(a) } }), a.register("list.js/src/filter.js", function (a, b, c) { c.exports = function (a) { return a.handlers.filterStart = a.handlers.filterStart || [], a.handlers.filterComplete = a.handlers.filterComplete || [], function (b) { if (a.trigger("filterStart"), a.i = 1, a.reset.filter(), void 0 === b) a.filtered = !1; else { a.filtered = !0; for (var c = a.items, d = 0, e = c.length; e > d; d++) { var f = c[d]; f.filtered = b(f) ? !0 : !1 } } return a.update(), a.trigger("filterComplete"), a.visibleItems } } }), a.register("list.js/src/add-async.js", function (a, b, c) { c.exports = function (a) { return function (b, c, d) { var e = b.splice(0, 100); d = d || [], d = d.concat(a.add(e)), b.length > 0 ? setTimeout(function () { addAsync(b, c, d) }, 10) : (a.update(), c(d)) } } }), a.register("list.js/src/parse.js", function (a, b, c) { c.exports = function (a) { var c = b("./item")(a), d = function (a) { for (var b = a.childNodes, c = [], d = 0, e = b.length; e > d; d++) void 0 === b[d].data && c.push(b[d]); return c }, e = function (b, d) { for (var e = 0, f = b.length; f > e; e++) a.items.push(new c(d, b[e])) }, f = function (b, c) { var d = b.splice(0, 100); e(d, c), b.length > 0 ? setTimeout(function () { init.items.indexAsync(b, c) }, 10) : a.update() }; return function () { var b = d(a.list), c = a.valueNames; a.indexAsync ? f(b, c) : e(b, c) } } }), a.alias("component-classes/index.js", "list.js/deps/classes/index.js"), a.alias("component-classes/index.js", "classes/index.js"), a.alias("component-indexof/index.js", "component-classes/deps/indexof/index.js"), a.alias("segmentio-extend/index.js", "list.js/deps/extend/index.js"), a.alias("segmentio-extend/index.js", "extend/index.js"), a.alias("component-indexof/index.js", "list.js/deps/indexof/index.js"), a.alias("component-indexof/index.js", "indexof/index.js"), a.alias("javve-events/index.js", "list.js/deps/events/index.js"), a.alias("javve-events/index.js", "events/index.js"), a.alias("component-event/index.js", "javve-events/deps/event/index.js"), a.alias("timoxley-to-array/index.js", "javve-events/deps/to-array/index.js"), a.alias("javve-get-by-class/index.js", "list.js/deps/get-by-class/index.js"), a.alias("javve-get-by-class/index.js", "get-by-class/index.js"), a.alias("javve-get-attribute/index.js", "list.js/deps/get-attribute/index.js"), a.alias("javve-get-attribute/index.js", "get-attribute/index.js"), a.alias("javve-natural-sort/index.js", "list.js/deps/natural-sort/index.js"), a.alias("javve-natural-sort/index.js", "natural-sort/index.js"), a.alias("javve-to-string/index.js", "list.js/deps/to-string/index.js"), a.alias("javve-to-string/index.js", "list.js/deps/to-string/index.js"), a.alias("javve-to-string/index.js", "to-string/index.js"), a.alias("javve-to-string/index.js", "javve-to-string/index.js"), a.alias("component-type/index.js", "list.js/deps/type/index.js"), a.alias("component-type/index.js", "type/index.js"), "object" == typeof exports ? module.exports = a("list.js") : "function" == typeof define && define.amd ? define(function () { return a("list.js") }) : this.List = a("list.js") }();;!function(){function a(b,c,d){var e=a.resolve(b);if(null==e){d=d||b,c=c||"root";var f=new Error('Failed to require "'+d+'" from "'+c+'"');throw f.path=d,f.parent=c,f.require=!0,f}var g=a.modules[e];if(!g._resolving&&!g.exports){var h={};h.exports={},h.client=h.component=!0,g._resolving=!0,g.call(this,h.exports,a.relative(e),h),delete g._resolving,g.exports=h.exports}return g.exports}a.modules={},a.aliases={},a.resolve=function(b){"/"===b.charAt(0)&&(b=b.slice(1));for(var c=[b,b+".js",b+".json",b+"/index.js",b+"/index.json"],d=0;d<c.length;d++){var b=c[d];if(a.modules.hasOwnProperty(b))return b;if(a.aliases.hasOwnProperty(b))return a.aliases[b]}},a.normalize=function(a,b){var c=[];if("."!=b.charAt(0))return b;a=a.split("/"),b=b.split("/");for(var d=0;d<b.length;++d)".."==b[d]?a.pop():"."!=b[d]&&""!=b[d]&&c.push(b[d]);return a.concat(c).join("/")},a.register=function(b,c){a.modules[b]=c},a.alias=function(b,c){if(!a.modules.hasOwnProperty(b))throw new Error('Failed to alias "'+b+'", it does not exist');a.aliases[c]=b},a.relative=function(b){function c(a,b){for(var c=a.length;c--;)if(a[c]===b)return c;return-1}function d(c){var e=d.resolve(c);return a(e,b,c)}var e=a.normalize(b,"..");return d.resolve=function(d){var f=d.charAt(0);if("/"==f)return d.slice(1);if("."==f)return a.normalize(e,d);var g=b.split("/"),h=c(g,"deps")+1;return h||(h=0),d=g.slice(0,h+1).join("/")+"/deps/"+d},d.exists=function(b){return a.modules.hasOwnProperty(d.resolve(b))},d},a.register("component-indexof/index.js",function(a,b,c){c.exports=function(a,b){if(a.indexOf)return a.indexOf(b);for(var c=0;c<a.length;++c)if(a[c]===b)return c;return-1}}),a.register("component-classes/index.js",function(a,b,c){function d(a){if(!a)throw new Error("A DOM element reference is required");this.el=a,this.list=a.classList}var e=b("indexof"),f=/\s+/,g=Object.prototype.toString;c.exports=function(a){return new d(a)},d.prototype.add=function(a){if(this.list)return this.list.add(a),this;var b=this.array(),c=e(b,a);return~c||b.push(a),this.el.className=b.join(" "),this},d.prototype.remove=function(a){if("[object RegExp]"==g.call(a))return this.removeMatching(a);if(this.list)return this.list.remove(a),this;var b=this.array(),c=e(b,a);return~c&&b.splice(c,1),this.el.className=b.join(" "),this},d.prototype.removeMatching=function(a){for(var b=this.array(),c=0;c<b.length;c++)a.test(b[c])&&this.remove(b[c]);return this},d.prototype.toggle=function(a){return this.list?(this.list.toggle(a),this):(this.has(a)?this.remove(a):this.add(a),this)},d.prototype.array=function(){var a=this.el.className.replace(/^\s+|\s+$/g,""),b=a.split(f);return""===b[0]&&b.shift(),b},d.prototype.has=d.prototype.contains=function(a){return this.list?this.list.contains(a):!!~e(this.array(),a)}}),a.register("segmentio-extend/index.js",function(a,b,c){c.exports=function(a){for(var b,c=Array.prototype.slice.call(arguments,1),d=0;b=c[d];d++)if(b)for(var e in b)a[e]=b[e];return a}}),a.register("component-event/index.js",function(a){var b=void 0!==window.addEventListener?"addEventListener":"attachEvent",c=void 0!==window.removeEventListener?"removeEventListener":"detachEvent",d="addEventListener"!==b?"on":"";a.bind=function(a,c,e,f){return a[b](d+c,e,f||!1),e},a.unbind=function(a,b,e,f){return a[c](d+b,e,f||!1),e}}),a.register("component-type/index.js",function(a,b,c){var d=Object.prototype.toString;c.exports=function(a){switch(d.call(a)){case"[object Function]":return"function";case"[object Date]":return"date";case"[object RegExp]":return"regexp";case"[object Arguments]":return"arguments";case"[object Array]":return"array";case"[object String]":return"string"}return null===a?"null":void 0===a?"undefined":a&&1===a.nodeType?"element":a===Object(a)?"object":typeof a}}),a.register("timoxley-is-collection/index.js",function(a,b,c){function d(a){return"object"==typeof a&&/^\[object (NodeList)\]$/.test(Object.prototype.toString.call(a))&&a.hasOwnProperty("length")&&(0==a.length||"object"==typeof a[0]&&a[0].nodeType>0)}var e=b("type");c.exports=function(a){var b=e(a);if("array"===b)return 1;switch(b){case"arguments":return 2;case"object":if(d(a))return 2;try{if("length"in a&&!a.tagName&&(!a.scrollTo||!a.document)&&!a.apply)return 2}catch(c){}default:return 0}}}),a.register("javve-events/index.js",function(a,b){var c=b("event"),d=b("is-collection");a.bind=function(a,b,e,f){if(d(a)){if(a&&void 0!==a[0])for(var g=0;g<a.length;g++)c.bind(a[g],b,e,f)}else c.bind(a,b,e,f)},a.unbind=function(a,b,e,f){if(d(a)){if(a&&void 0!==a[0])for(var g=0;g<a.length;g++)c.unbind(a[g],b,e,f)}else c.unbind(a,b,e,f)}}),a.register("javve-get-by-class/index.js",function(a,b,c){c.exports=function(){return document.getElementsByClassName?function(a,b,c){return c?a.getElementsByClassName(b)[0]:a.getElementsByClassName(b)}:document.querySelector?function(a,b,c){return c?a.querySelector(b):a.querySelectorAll(b)}:function(a,b,c){var d=[],e="*";null==a&&(a=document);for(var f=a.getElementsByTagName(e),g=f.length,h=new RegExp("(^|\\s)"+b+"(\\s|$)"),i=0,j=0;g>i;i++)if(h.test(f[i].className)){if(c)return f[i];d[j]=f[i],j++}return d}}()}),a.register("javve-to-string/index.js",function(a,b,c){c.exports=function(a){return a=void 0===a?"":a,a=null===a?"":a,a=a.toString()}}),a.register("list.fuzzysearch.js/index.js",function(a,b,c){var d=(b("classes"),b("events")),e=b("extend"),f=b("to-string"),g=b("get-by-class");c.exports=function(a){a=a||{},e(a,{location:0,distance:100,threshold:.4,multiSearch:!0,searchClass:"fuzzy-search"});var c,h=b("./src/fuzzy"),i={search:function(b,d){for(var e=a.multiSearch?b.replace(/ +$/,"").split(/ +/):[b],f=0,g=c.items.length;g>f;f++)i.item(c.items[f],d,e)},item:function(a,b,c){for(var d=!0,e=0;e<c.length;e++){for(var f=!1,g=0,h=b.length;h>g;g++)i.values(a.values(),b[g],c[e])&&(f=!0);f||(d=!1)}a.found=d},values:function(b,c,d){if(b.hasOwnProperty(c)){var e=f(b[c]).toLowerCase();if(h(e,d,a))return!0}return!1}};return{init:function(b){c=b,d.bind(g(c.listContainer,a.searchClass),"keyup",function(a){var b=a.target||a.srcElement;c.search(b.value,i.search)})},search:function(a,b){c.search(a,b,i.search)},name:a.name||"fuzzySearch"}}}),a.register("list.fuzzysearch.js/src/fuzzy.js",function(a,b,c){c.exports=function(a,b,c){function d(a,c){var d=a/b.length,e=Math.abs(h-c);return f?d+e/f:e?1:d}var e=c.location||0,f=c.distance||100,g=c.threshold||.4;if(b===a)return!0;if(b.length>32)return!1;var h=e,i=function(){var a,c={};for(a=0;a<b.length;a++)c[b.charAt(a)]=0;for(a=0;a<b.length;a++)c[b.charAt(a)]|=1<<b.length-a-1;return c}(),j=g,k=a.indexOf(b,h);-1!=k&&(j=Math.min(d(0,k),j),k=a.lastIndexOf(b,h+b.length),-1!=k&&(j=Math.min(d(0,k),j)));var l=1<<b.length-1;k=-1;for(var m,n,o,p=b.length+a.length,q=0;q<b.length;q++){for(m=0,n=p;n>m;)d(q,h+n)<=j?m=n:p=n,n=Math.floor((p-m)/2+m);p=n;var r=Math.max(1,h-n+1),s=Math.min(h+n,a.length)+b.length,t=Array(s+2);t[s+1]=(1<<q)-1;for(var u=s;u>=r;u--){var v=i[a.charAt(u-1)];if(t[u]=0===q?(t[u+1]<<1|1)&v:(t[u+1]<<1|1)&v|((o[u+1]|o[u])<<1|1)|o[u+1],t[u]&l){var w=d(q,u-1);if(j>=w){if(j=w,k=u-1,!(k>h))break;r=Math.max(1,2*h-k)}}}if(d(q+1,h)>j)break;o=t}return 0>k?!1:!0}}),a.alias("component-classes/index.js","list.fuzzysearch.js/deps/classes/index.js"),a.alias("component-classes/index.js","classes/index.js"),a.alias("component-indexof/index.js","component-classes/deps/indexof/index.js"),a.alias("segmentio-extend/index.js","list.fuzzysearch.js/deps/extend/index.js"),a.alias("segmentio-extend/index.js","extend/index.js"),a.alias("javve-events/index.js","list.fuzzysearch.js/deps/events/index.js"),a.alias("javve-events/index.js","events/index.js"),a.alias("component-event/index.js","javve-events/deps/event/index.js"),a.alias("timoxley-is-collection/index.js","javve-events/deps/is-collection/index.js"),a.alias("component-type/index.js","timoxley-is-collection/deps/type/index.js"),a.alias("javve-get-by-class/index.js","list.fuzzysearch.js/deps/get-by-class/index.js"),a.alias("javve-get-by-class/index.js","get-by-class/index.js"),a.alias("javve-to-string/index.js","list.fuzzysearch.js/deps/to-string/index.js"),a.alias("javve-to-string/index.js","list.fuzzysearch.js/deps/to-string/index.js"),a.alias("javve-to-string/index.js","to-string/index.js"),a.alias("javve-to-string/index.js","javve-to-string/index.js"),a.alias("list.fuzzysearch.js/index.js","list.fuzzysearch.js/index.js"),"object"==typeof exports?module.exports=a("list.fuzzysearch.js"):"function"==typeof define&&define.amd?define(function(){return a("list.fuzzysearch.js")}):this.ListFuzzySearch=a("list.fuzzysearch.js")}();;/*
 * 
 * TableSorter 2.0 - Client-side table sorting with ease!
 * Version 2.0.5b
 * @requires jQuery v1.2.3
 * 
 * Copyright (c) 2007 Christian Bach
 * Examples and docs at: http://tablesorter.com
 * Dual licensed under the MIT and GPL licenses:
 * http://www.opensource.org/licenses/mit-license.php
 * http://www.gnu.org/licenses/gpl.html
 * 
 */
/**
 * 
 * @description Create a sortable table with multi-column sorting capabilitys
 * 
 * @example $('table').tablesorter();
 * @desc Create a simple tablesorter interface.
 * 
 * @example $('table').tablesorter({ sortList:[[0,0],[1,0]] });
 * @desc Create a tablesorter interface and sort on the first and secound column column headers.
 * 
 * @example $('table').tablesorter({ headers: { 0: { sorter: false}, 1: {sorter: false} } });
 *          
 * @desc Create a tablesorter interface and disableing the first and second  column headers.
 *      
 * 
 * @example $('table').tablesorter({ headers: { 0: {sorter:"integer"}, 1: {sorter:"currency"} } });
 * 
 * @desc Create a tablesorter interface and set a column parser for the first
 *       and second column.
 * 
 * 
 * @param Object
 *            settings An object literal containing key/value pairs to provide
 *            optional settings.
 * 
 * 
 * @option String cssHeader (optional) A string of the class name to be appended
 *         to sortable tr elements in the thead of the table. Default value:
 *         "header"
 * 
 * @option String cssAsc (optional) A string of the class name to be appended to
 *         sortable tr elements in the thead on a ascending sort. Default value:
 *         "headerSortUp"
 * 
 * @option String cssDesc (optional) A string of the class name to be appended
 *         to sortable tr elements in the thead on a descending sort. Default
 *         value: "headerSortDown"
 * 
 * @option String sortInitialOrder (optional) A string of the inital sorting
 *         order can be asc or desc. Default value: "asc"
 * 
 * @option String sortMultisortKey (optional) A string of the multi-column sort
 *         key. Default value: "shiftKey"
 * 
 * @option String textExtraction (optional) A string of the text-extraction
 *         method to use. For complex html structures inside td cell set this
 *         option to "complex", on large tables the complex option can be slow.
 *         Default value: "simple"
 * 
 * @option Object headers (optional) An array containing the forces sorting
 *         rules. This option let's you specify a default sorting rule. Default
 *         value: null
 * 
 * @option Array sortList (optional) An array containing the forces sorting
 *         rules. This option let's you specify a default sorting rule. Default
 *         value: null
 * 
 * @option Array sortForce (optional) An array containing forced sorting rules.
 *         This option let's you specify a default sorting rule, which is
 *         prepended to user-selected rules. Default value: null
 * 
 * @option Boolean sortLocaleCompare (optional) Boolean flag indicating whatever
 *         to use String.localeCampare method or not. Default set to true.
 * 
 * 
 * @option Array sortAppend (optional) An array containing forced sorting rules.
 *         This option let's you specify a default sorting rule, which is
 *         appended to user-selected rules. Default value: null
 * 
 * @option Boolean widthFixed (optional) Boolean flag indicating if tablesorter
 *         should apply fixed widths to the table columns. This is usefull when
 *         using the pager companion plugin. This options requires the dimension
 *         jquery plugin. Default value: false
 * 
 * @option Boolean cancelSelection (optional) Boolean flag indicating if
 *         tablesorter should cancel selection of the table headers text.
 *         Default value: true
 * 
 * @option Boolean debug (optional) Boolean flag indicating if tablesorter
 *         should display debuging information usefull for development.
 * 
 * @type jQuery
 * 
 * @name tablesorter
 * 
 * @cat Plugins/Tablesorter
 * 
 * @author Christian Bach/christian.bach@polyester.se
 */

(function ($) {
    $.extend({
        tablesorter: new
        function () {

            var parsers = [],
                widgets = [];

            this.defaults = {
                cssHeader: "header",
                cssAsc: "headerSortUp",
                cssDesc: "headerSortDown",
                cssChildRow: "expand-child",
                sortInitialOrder: "asc",
                sortMultiSortKey: "shiftKey",
                sortForce: null,
                sortAppend: null,
                sortLocaleCompare: true,
                textExtraction: "simple",
                parsers: {}, widgets: [],
                widgetZebra: {
                    css: ["even", "odd"]
                }, headers: {}, widthFixed: false,
                cancelSelection: true,
                sortList: [],
                headerList: [],
                dateFormat: "us",
                decimal: '/\.|\,/g',
                onRenderHeader: null,
                selectorHeaders: 'thead th',
                debug: false
            };

            /* debuging utils */

            function benchmark(s, d) {
                log(s + "," + (new Date().getTime() - d.getTime()) + "ms");
            }

            this.benchmark = benchmark;

            function log(s) {
                if (typeof console != "undefined" && typeof console.debug != "undefined") {
                    console.log(s);
                } else {
                    alert(s);
                }
            }

            /* parsers utils */

            function buildParserCache(table, $headers) {

                if (table.config.debug) {
                    var parsersDebug = "";
                }

                if (table.tBodies.length == 0) return; // In the case of empty tables
                var rows = table.tBodies[0].rows;

                if (rows[0]) {

                    var list = [],
                        cells = rows[0].cells,
                        l = cells.length;

                    for (var i = 0; i < l; i++) {

                        var p = false;

                        if ($.metadata && ($($headers[i]).metadata() && $($headers[i]).metadata().sorter)) {

                            p = getParserById($($headers[i]).metadata().sorter);

                        } else if ((table.config.headers[i] && table.config.headers[i].sorter)) {

                            p = getParserById(table.config.headers[i].sorter);
                        }
                        if (!p) {

                            p = detectParserForColumn(table, rows, -1, i);
                        }

                        if (table.config.debug) {
                            parsersDebug += "column:" + i + " parser:" + p.id + "\n";
                        }

                        list.push(p);
                    }
                }

                if (table.config.debug) {
                    log(parsersDebug);
                }

                return list;
            };

            function detectParserForColumn(table, rows, rowIndex, cellIndex) {
                var l = parsers.length,
                    node = false,
                    nodeValue = false,
                    keepLooking = true;
                while (nodeValue == '' && keepLooking) {
                    rowIndex++;
                    if (rows[rowIndex]) {
                        node = getNodeFromRowAndCellIndex(rows, rowIndex, cellIndex);
                        nodeValue = trimAndGetNodeText(table.config, node);
                        if (table.config.debug) {
                            log('Checking if value was empty on row:' + rowIndex);
                        }
                    } else {
                        keepLooking = false;
                    }
                }
                for (var i = 1; i < l; i++) {
                    if (parsers[i].is(nodeValue, table, node)) {
                        return parsers[i];
                    }
                }
                // 0 is always the generic parser (text)
                return parsers[0];
            }

            function getNodeFromRowAndCellIndex(rows, rowIndex, cellIndex) {
                return rows[rowIndex].cells[cellIndex];
            }

            function trimAndGetNodeText(config, node) {
                return $.trim(getElementText(config, node));
            }

            function getParserById(name) {
                var l = parsers.length;
                for (var i = 0; i < l; i++) {
                    if (parsers[i].id.toLowerCase() == name.toLowerCase()) {
                        return parsers[i];
                    }
                }
                return false;
            }

            /* utils */

            function buildCache(table) {

                if (table.config.debug) {
                    var cacheTime = new Date();
                }

                var totalRows = (table.tBodies[0] && table.tBodies[0].rows.length) || 0,
                    totalCells = (table.tBodies[0].rows[0] && table.tBodies[0].rows[0].cells.length) || 0,
                    parsers = table.config.parsers,
                    cache = {
                        row: [],
                        normalized: []
                    };

                for (var i = 0; i < totalRows; ++i) {

                    /** Add the table data to main data array */
                    var c = $(table.tBodies[0].rows[i]),
                        cols = [];

                    // if this is a child row, add it to the last row's children and
                    // continue to the next row
                    if (c.hasClass(table.config.cssChildRow)) {
                        cache.row[cache.row.length - 1] = cache.row[cache.row.length - 1].add(c);
                        // go to the next for loop
                        continue;
                    }

                    cache.row.push(c);

                    for (var j = 0; j < totalCells; ++j) {
                        cols.push(parsers[j].format(getElementText(table.config, c[0].cells[j]), table, c[0].cells[j]));
                    }

                    cols.push(cache.normalized.length); // add position for rowCache
                    cache.normalized.push(cols);
                    cols = null;
                };

                if (table.config.debug) {
                    benchmark("Building cache for " + totalRows + " rows:", cacheTime);
                }

                return cache;
            };

            function getElementText(config, node) {

                var text = "";

                if (!node) return "";

                if (!config.supportsTextContent) config.supportsTextContent = node.textContent || false;

                if (config.textExtraction == "simple") {
                    if (config.supportsTextContent) {
                        text = node.textContent;
                    } else {
                        if (node.childNodes[0] && node.childNodes[0].hasChildNodes()) {
                            text = node.childNodes[0].innerHTML;
                        } else {
                            text = node.innerHTML;
                        }
                    }
                } else {
                    if (typeof(config.textExtraction) == "function") {
                        text = config.textExtraction(node);
                    } else {
                        text = $(node).text();
                    }
                }
                return text;
            }

            function appendToTable(table, cache) {

                if (table.config.debug) {
                    var appendTime = new Date()
                }

                var c = cache,
                    r = c.row,
                    n = c.normalized,
                    totalRows = n.length,
                    checkCell = (n[0].length - 1),
                    tableBody = $(table.tBodies[0]),
                    rows = [];


                for (var i = 0; i < totalRows; i++) {
                    var pos = n[i][checkCell];

                    rows.push(r[pos]);

                    if (!table.config.appender) {

                        //var o = ;
                        var l = r[pos].length;
                        for (var j = 0; j < l; j++) {
                            tableBody[0].appendChild(r[pos][j]);
                        }

                        // 
                    }
                }



                if (table.config.appender) {

                    table.config.appender(table, rows);
                }

                rows = null;

                if (table.config.debug) {
                    benchmark("Rebuilt table:", appendTime);
                }

                // apply table widgets
                applyWidget(table);

                // trigger sortend
                setTimeout(function () {
                    $(table).trigger("sortEnd");
                }, 0);

            };

            function buildHeaders(table) {

                if (table.config.debug) {
                    var time = new Date();
                }

                var meta = ($.metadata) ? true : false;
                
                var header_index = computeTableHeaderCellIndexes(table);

                $tableHeaders = $(table.config.selectorHeaders, table).each(function (index) {

                    this.column = header_index[this.parentNode.rowIndex + "-" + this.cellIndex];
                    // this.column = index;
                    this.order = formatSortingOrder(table.config.sortInitialOrder);
                    
					
					this.count = this.order;

                    if (checkHeaderMetadata(this) || checkHeaderOptions(table, index)) this.sortDisabled = true;
					if (checkHeaderOptionsSortingLocked(table, index)) this.order = this.lockedOrder = checkHeaderOptionsSortingLocked(table, index);

                    if (!this.sortDisabled) {
                        var $th = $(this).addClass(table.config.cssHeader);
                        if (table.config.onRenderHeader) table.config.onRenderHeader.apply($th);
                    }

                    // add cell to headerList
                    table.config.headerList[index] = this;
                });

                if (table.config.debug) {
                    benchmark("Built headers:", time);
                    log($tableHeaders);
                }

                return $tableHeaders;

            };

            // from:
            // http://www.javascripttoolbox.com/lib/table/examples.php
            // http://www.javascripttoolbox.com/temp/table_cellindex.html


            function computeTableHeaderCellIndexes(t) {
                var matrix = [];
                var lookup = {};
                var thead = t.getElementsByTagName('THEAD')[0];
                var trs = thead.getElementsByTagName('TR');

                for (var i = 0; i < trs.length; i++) {
                    var cells = trs[i].cells;
                    for (var j = 0; j < cells.length; j++) {
                        var c = cells[j];

                        var rowIndex = c.parentNode.rowIndex;
                        var cellId = rowIndex + "-" + c.cellIndex;
                        var rowSpan = c.rowSpan || 1;
                        var colSpan = c.colSpan || 1
                        var firstAvailCol;
                        if (typeof(matrix[rowIndex]) == "undefined") {
                            matrix[rowIndex] = [];
                        }
                        // Find first available column in the first row
                        for (var k = 0; k < matrix[rowIndex].length + 1; k++) {
                            if (typeof(matrix[rowIndex][k]) == "undefined") {
                                firstAvailCol = k;
                                break;
                            }
                        }
                        lookup[cellId] = firstAvailCol;
                        for (var k = rowIndex; k < rowIndex + rowSpan; k++) {
                            if (typeof(matrix[k]) == "undefined") {
                                matrix[k] = [];
                            }
                            var matrixrow = matrix[k];
                            for (var l = firstAvailCol; l < firstAvailCol + colSpan; l++) {
                                matrixrow[l] = "x";
                            }
                        }
                    }
                }
                return lookup;
            }

            function checkCellColSpan(table, rows, row) {
                var arr = [],
                    r = table.tHead.rows,
                    c = r[row].cells;

                for (var i = 0; i < c.length; i++) {
                    var cell = c[i];

                    if (cell.colSpan > 1) {
                        arr = arr.concat(checkCellColSpan(table, headerArr, row++));
                    } else {
                        if (table.tHead.length == 1 || (cell.rowSpan > 1 || !r[row + 1])) {
                            arr.push(cell);
                        }
                        // headerArr[row] = (i+row);
                    }
                }
                return arr;
            };

            function checkHeaderMetadata(cell) {
                if (($.metadata) && ($(cell).metadata().sorter === false)) {
                    return true;
                };
                return false;
            }

            function checkHeaderOptions(table, i) {
                if ((table.config.headers[i]) && (table.config.headers[i].sorter === false)) {
                    return true;
                };
                return false;
            }
			
			 function checkHeaderOptionsSortingLocked(table, i) {
                if ((table.config.headers[i]) && (table.config.headers[i].lockedOrder)) return table.config.headers[i].lockedOrder;
                return false;
            }
			
            function applyWidget(table) {
                var c = table.config.widgets;
                var l = c.length;
                for (var i = 0; i < l; i++) {

                    getWidgetById(c[i]).format(table);
                }

            }

            function getWidgetById(name) {
                var l = widgets.length;
                for (var i = 0; i < l; i++) {
                    if (widgets[i].id.toLowerCase() == name.toLowerCase()) {
                        return widgets[i];
                    }
                }
            };

            function formatSortingOrder(v) {
                if (typeof(v) != "Number") {
                    return (v.toLowerCase() == "desc") ? 1 : 0;
                } else {
                    return (v == 1) ? 1 : 0;
                }
            }

            function isValueInArray(v, a) {
                var l = a.length;
                for (var i = 0; i < l; i++) {
                    if (a[i][0] == v) {
                        return true;
                    }
                }
                return false;
            }

            function setHeadersCss(table, $headers, list, css) {
                // remove all header information
                $headers.removeClass(css[0]).removeClass(css[1]);

                var h = [];
                $headers.each(function (offset) {
                    if (!this.sortDisabled) {
                        h[this.column] = $(this);
                    }
                });

                var l = list.length;
                for (var i = 0; i < l; i++) {
                    h[list[i][0]].addClass(css[list[i][1]]);
                }
            }

            function fixColumnWidth(table, $headers) {
                var c = table.config;
                if (c.widthFixed) {
                    var colgroup = $('<colgroup>');
                    $("tr:first td", table.tBodies[0]).each(function () {
                        colgroup.append($('<col>').css('width', $(this).width()));
                    });
                    $(table).prepend(colgroup);
                };
            }

            function updateHeaderSortCount(table, sortList) {
                var c = table.config,
                    l = sortList.length;
                for (var i = 0; i < l; i++) {
                    var s = sortList[i],
                        o = c.headerList[s[0]];
                    o.count = s[1];
                    o.count++;
                }
            }

            /* sorting methods */

            function multisort(table, sortList, cache) {

                if (table.config.debug) {
                    var sortTime = new Date();
                }

                var dynamicExp = "var sortWrapper = function(a,b) {",
                    l = sortList.length;

                // TODO: inline functions.
                for (var i = 0; i < l; i++) {

                    var c = sortList[i][0];
                    var order = sortList[i][1];
                    // var s = (getCachedSortType(table.config.parsers,c) == "text") ?
                    // ((order == 0) ? "sortText" : "sortTextDesc") : ((order == 0) ?
                    // "sortNumeric" : "sortNumericDesc");
                    // var s = (table.config.parsers[c].type == "text") ? ((order == 0)
                    // ? makeSortText(c) : makeSortTextDesc(c)) : ((order == 0) ?
                    // makeSortNumeric(c) : makeSortNumericDesc(c));
                    var s = (table.config.parsers[c].type == "text") ? ((order == 0) ? makeSortFunction("text", "asc", c) : makeSortFunction("text", "desc", c)) : ((order == 0) ? makeSortFunction("numeric", "asc", c) : makeSortFunction("numeric", "desc", c));
                    var e = "e" + i;

                    dynamicExp += "var " + e + " = " + s; // + "(a[" + c + "],b[" + c
                    // + "]); ";
                    dynamicExp += "if(" + e + ") { return " + e + "; } ";
                    dynamicExp += "else { ";

                }

                // if value is the same keep orignal order
                var orgOrderCol = cache.normalized[0].length - 1;
                dynamicExp += "return a[" + orgOrderCol + "]-b[" + orgOrderCol + "];";

                for (var i = 0; i < l; i++) {
                    dynamicExp += "}; ";
                }

                dynamicExp += "return 0; ";
                dynamicExp += "}; ";

                if (table.config.debug) {
                    benchmark("Evaling expression:" + dynamicExp, new Date());
                }

                eval(dynamicExp);

                cache.normalized.sort(sortWrapper);

                if (table.config.debug) {
                    benchmark("Sorting on " + sortList.toString() + " and dir " + order + " time:", sortTime);
                }

                return cache;
            };

            function makeSortFunction(type, direction, index) {
                var a = "a[" + index + "]",
                    b = "b[" + index + "]";
                if (type == 'text' && direction == 'asc') {
                    return "(" + a + " == " + b + " ? 0 : (" + a + " === null ? Number.POSITIVE_INFINITY : (" + b + " === null ? Number.NEGATIVE_INFINITY : (" + a + " < " + b + ") ? -1 : 1 )));";
                } else if (type == 'text' && direction == 'desc') {
                    return "(" + a + " == " + b + " ? 0 : (" + a + " === null ? Number.POSITIVE_INFINITY : (" + b + " === null ? Number.NEGATIVE_INFINITY : (" + b + " < " + a + ") ? -1 : 1 )));";
                } else if (type == 'numeric' && direction == 'asc') {
                    return "(" + a + " === null && " + b + " === null) ? 0 :(" + a + " === null ? Number.POSITIVE_INFINITY : (" + b + " === null ? Number.NEGATIVE_INFINITY : " + a + " - " + b + "));";
                } else if (type == 'numeric' && direction == 'desc') {
                    return "(" + a + " === null && " + b + " === null) ? 0 :(" + a + " === null ? Number.POSITIVE_INFINITY : (" + b + " === null ? Number.NEGATIVE_INFINITY : " + b + " - " + a + "));";
                }
            };

            function makeSortText(i) {
                return "((a[" + i + "] < b[" + i + "]) ? -1 : ((a[" + i + "] > b[" + i + "]) ? 1 : 0));";
            };

            function makeSortTextDesc(i) {
                return "((b[" + i + "] < a[" + i + "]) ? -1 : ((b[" + i + "] > a[" + i + "]) ? 1 : 0));";
            };

            function makeSortNumeric(i) {
                return "a[" + i + "]-b[" + i + "];";
            };

            function makeSortNumericDesc(i) {
                return "b[" + i + "]-a[" + i + "];";
            };

            function sortText(a, b) {
                if (table.config.sortLocaleCompare) return a.localeCompare(b);
                return ((a < b) ? -1 : ((a > b) ? 1 : 0));
            };

            function sortTextDesc(a, b) {
                if (table.config.sortLocaleCompare) return b.localeCompare(a);
                return ((b < a) ? -1 : ((b > a) ? 1 : 0));
            };

            function sortNumeric(a, b) {
                return a - b;
            };

            function sortNumericDesc(a, b) {
                return b - a;
            };

            function getCachedSortType(parsers, i) {
                return parsers[i].type;
            }; /* public methods */
            this.construct = function (settings) {
                return this.each(function () {
                    // if no thead or tbody quit.
                    if (!this.tHead || !this.tBodies) return;
                    // declare
                    var $this, $document, $headers, cache, config, shiftDown = 0,
                        sortOrder;
                    // new blank config object
                    this.config = {};
                    // merge and extend.
                    config = $.extend(this.config, $.tablesorter.defaults, settings);
                    // store common expression for speed
                    $this = $(this);
                    // save the settings where they read
                    $.data(this, "tablesorter", config);
                    // build headers
                    $headers = buildHeaders(this);
                    // try to auto detect column type, and store in tables config
                    this.config.parsers = buildParserCache(this, $headers);
                    // build the cache for the tbody cells
                    cache = buildCache(this);
                    // get the css class names, could be done else where.
                    var sortCSS = [config.cssDesc, config.cssAsc];
                    // fixate columns if the users supplies the fixedWidth option
                    fixColumnWidth(this);
                    // apply event handling to headers
                    // this is to big, perhaps break it out?
                    $headers.click(

                    function (e) {
                        var totalRows = ($this[0].tBodies[0] && $this[0].tBodies[0].rows.length) || 0;
                        if (!this.sortDisabled && totalRows > 0) {
                            // Only call sortStart if sorting is
                            // enabled.
                            $this.trigger("sortStart");
                            // store exp, for speed
                            var $cell = $(this);
                            // get current column index
                            var i = this.column;
                            // get current column sort order
                            this.order = this.count++ % 2;
							// always sort on the locked order.
							if(this.lockedOrder) this.order = this.lockedOrder;
							
							// user only whants to sort on one
                            // column
                            if (!e[config.sortMultiSortKey]) {
                                // flush the sort list
                                config.sortList = [];
                                if (config.sortForce != null) {
                                    var a = config.sortForce;
                                    for (var j = 0; j < a.length; j++) {
                                        if (a[j][0] != i) {
                                            config.sortList.push(a[j]);
                                        }
                                    }
                                }
                                // add column to sort list
                                config.sortList.push([i, this.order]);
                                // multi column sorting
                            } else {
                                // the user has clicked on an all
                                // ready sortet column.
                                if (isValueInArray(i, config.sortList)) {
                                    // revers the sorting direction
                                    // for all tables.
                                    for (var j = 0; j < config.sortList.length; j++) {
                                        var s = config.sortList[j],
                                            o = config.headerList[s[0]];
                                        if (s[0] == i) {
                                            o.count = s[1];
                                            o.count++;
                                            s[1] = o.count % 2;
                                        }
                                    }
                                } else {
                                    // add column to sort list array
                                    config.sortList.push([i, this.order]);
                                }
                            };
                            setTimeout(function () {
                                // set css for headers
                                setHeadersCss($this[0], $headers, config.sortList, sortCSS);
                                appendToTable(
	                                $this[0], multisort(
	                                $this[0], config.sortList, cache)
								);
                            }, 1);
                            // stop normal event by returning false
                            return false;
                        }
                        // cancel selection
                    }).mousedown(function () {
                        if (config.cancelSelection) {
                            this.onselectstart = function () {
                                return false
                            };
                            return false;
                        }
                    });
                    // apply easy methods that trigger binded events
                    $this.bind("update", function () {
                        var me = this;
                        setTimeout(function () {
                            // rebuild parsers.
                            me.config.parsers = buildParserCache(
                            me, $headers);
                            // rebuild the cache map
                            cache = buildCache(me);
                        }, 1);
                    }).bind("updateCell", function (e, cell) {
                        var config = this.config;
                        // get position from the dom.
                        var pos = [(cell.parentNode.rowIndex - 1), cell.cellIndex];
                        // update cache
                        cache.normalized[pos[0]][pos[1]] = config.parsers[pos[1]].format(
                        getElementText(config, cell), cell);
                    }).bind("sorton", function (e, list) {
                        $(this).trigger("sortStart");
                        config.sortList = list;
                        // update and store the sortlist
                        var sortList = config.sortList;
                        // update header count index
                        updateHeaderSortCount(this, sortList);
                        // set css for headers
                        setHeadersCss(this, $headers, sortList, sortCSS);
                        // sort the table and append it to the dom
                        appendToTable(this, multisort(this, sortList, cache));
                    }).bind("appendCache", function () {
                        appendToTable(this, cache);
                    }).bind("applyWidgetId", function (e, id) {
                        getWidgetById(id).format(this);
                    }).bind("applyWidgets", function () {
                        // apply widgets
                        applyWidget(this);
                    });
                    if ($.metadata && ($(this).metadata() && $(this).metadata().sortlist)) {
                        config.sortList = $(this).metadata().sortlist;
                    }
                    // if user has supplied a sort list to constructor.
                    if (config.sortList.length > 0) {
                        $this.trigger("sorton", [config.sortList]);
                    }
                    // apply widgets
                    applyWidget(this);
                });
            };
            this.addParser = function (parser) {
                var l = parsers.length,
                    a = true;
                for (var i = 0; i < l; i++) {
                    if (parsers[i].id.toLowerCase() == parser.id.toLowerCase()) {
                        a = false;
                    }
                }
                if (a) {
                    parsers.push(parser);
                };
            };
            this.addWidget = function (widget) {
                widgets.push(widget);
            };
            this.formatFloat = function (s) {
                var i = parseFloat(s);
                return (isNaN(i)) ? 0 : i;
            };
            this.formatInt = function (s) {
                var i = parseInt(s);
                return (isNaN(i)) ? 0 : i;
            };
            this.isDigit = function (s, config) {
                // replace all an wanted chars and match.
                return /^[-+]?\d*$/.test($.trim(s.replace(/[,.']/g, '')));
            };
            this.clearTableBody = function (table) {
                if ($.browser.msie) {
                    function empty() {
                        while (this.firstChild)
                        this.removeChild(this.firstChild);
                    }
                    empty.apply(table.tBodies[0]);
                } else {
                    table.tBodies[0].innerHTML = "";
                }
            };
        }
    });

    // extend plugin scope
    $.fn.extend({
        tablesorter: $.tablesorter.construct
    });

    // make shortcut
    var ts = $.tablesorter;

    // add default parsers
    ts.addParser({
        id: "text",
        is: function (s) {
            return true;
        }, format: function (s) {
            return $.trim(s.toLocaleLowerCase());
        }, type: "text"
    });

    ts.addParser({
        id: "digit",
        is: function (s, table) {
            var c = table.config;
            return $.tablesorter.isDigit(s, c);
        }, format: function (s) {
            return $.tablesorter.formatFloat(s);
        }, type: "numeric"
    });

    ts.addParser({
        id: "currency",
        is: function (s) {
            return /^[£$€?.]/.test(s);
        }, format: function (s) {
            return $.tablesorter.formatFloat(s.replace(new RegExp(/[£$€]/g), ""));
        }, type: "numeric"
    });

    ts.addParser({
        id: "ipAddress",
        is: function (s) {
            return /^\d{2,3}[\.]\d{2,3}[\.]\d{2,3}[\.]\d{2,3}$/.test(s);
        }, format: function (s) {
            var a = s.split("."),
                r = "",
                l = a.length;
            for (var i = 0; i < l; i++) {
                var item = a[i];
                if (item.length == 2) {
                    r += "0" + item;
                } else {
                    r += item;
                }
            }
            return $.tablesorter.formatFloat(r);
        }, type: "numeric"
    });

    ts.addParser({
        id: "url",
        is: function (s) {
            return /^(https?|ftp|file):\/\/$/.test(s);
        }, format: function (s) {
            return jQuery.trim(s.replace(new RegExp(/(https?|ftp|file):\/\//), ''));
        }, type: "text"
    });

    ts.addParser({
        id: "isoDate",
        is: function (s) {
            return /^\d{4}[\/-]\d{1,2}[\/-]\d{1,2}$/.test(s);
        }, format: function (s) {
            return $.tablesorter.formatFloat((s != "") ? new Date(s.replace(
            new RegExp(/-/g), "/")).getTime() : "0");
        }, type: "numeric"
    });

    ts.addParser({
        id: "percent",
        is: function (s) {
            return /\%$/.test($.trim(s));
        }, format: function (s) {
            return $.tablesorter.formatFloat(s.replace(new RegExp(/%/g), ""));
        }, type: "numeric"
    });

    ts.addParser({
        id: "usLongDate",
        is: function (s) {
            return s.match(new RegExp(/^[A-Za-z]{3,10}\.? [0-9]{1,2}, ([0-9]{4}|'?[0-9]{2}) (([0-2]?[0-9]:[0-5][0-9])|([0-1]?[0-9]:[0-5][0-9]\s(AM|PM)))$/));
        }, format: function (s) {
            return $.tablesorter.formatFloat(new Date(s).getTime());
        }, type: "numeric"
    });

    ts.addParser({
        id: "shortDate",
        is: function (s) {
            return /\d{1,2}[\/\-]\d{1,2}[\/\-]\d{2,4}/.test(s);
        }, format: function (s, table) {
            var c = table.config;
            s = s.replace(/\-/g, "/");
            if (c.dateFormat == "us") {
                // reformat the string in ISO format
                s = s.replace(/(\d{1,2})[\/\-](\d{1,2})[\/\-](\d{4})/, "$3/$1/$2");
            } else if (c.dateFormat == "uk") {
                // reformat the string in ISO format
                s = s.replace(/(\d{1,2})[\/\-](\d{1,2})[\/\-](\d{4})/, "$3/$2/$1");
            } else if (c.dateFormat == "dd/mm/yy" || c.dateFormat == "dd-mm-yy") {
                s = s.replace(/(\d{1,2})[\/\-](\d{1,2})[\/\-](\d{2})/, "$1/$2/$3");
            }
            return $.tablesorter.formatFloat(new Date(s).getTime());
        }, type: "numeric"
    });
    ts.addParser({
        id: "time",
        is: function (s) {
            return /^(([0-2]?[0-9]:[0-5][0-9])|([0-1]?[0-9]:[0-5][0-9]\s(am|pm)))$/.test(s);
        }, format: function (s) {
            return $.tablesorter.formatFloat(new Date("2000/01/01 " + s).getTime());
        }, type: "numeric"
    });
    ts.addParser({
        id: "metadata",
        is: function (s) {
            return false;
        }, format: function (s, table, cell) {
            var c = table.config,
                p = (!c.parserMetadataName) ? 'sortValue' : c.parserMetadataName;
            return $(cell).metadata()[p];
        }, type: "numeric"
    });
    // add default widgets
    ts.addWidget({
        id: "zebra",
        format: function (table) {
            if (table.config.debug) {
                var time = new Date();
            }
            var $tr, row = -1,
                odd;
            // loop through the visible rows
            $("tr:visible", table.tBodies[0]).each(function (i) {
                $tr = $(this);
                // style children rows the same way the parent
                // row was styled
                if (!$tr.hasClass(table.config.cssChildRow)) row++;
                odd = (row % 2 == 0);
                $tr.removeClass(
                table.config.widgetZebra.css[odd ? 0 : 1]).addClass(
                table.config.widgetZebra.css[odd ? 1 : 0])
            });
            if (table.config.debug) {
                $.tablesorter.benchmark("Applying Zebra widget", time);
            }
        }
    });
})(jQuery);;// =============================
//
//  eNumber search
//
// =============================

function cl(s) {
    console.log(s);
}

var UAH = (function($) {

    var base = {};

    base.filtering = (function () {
        'use strict';

        var enabledFilters = [], self = {};

        self.filters = {
            categoryFilter: function (item) {
                if (self.filterParameters.categoryFilterTarget == "") {
                    return true;
                } else {
                    if (item.values().category.indexOf(self.filterParameters.categoryFilterTarget) !== -1) {
                        return true;
                    } else {
                        return false;
                    }
                }
            },
            categoryFilterSeaArea: function(item){
                if (self.filterParameters.categoryFilterTarget == "") {
                    return true;
                } else {
                    if (item.values().category.indexOf(self.filterParameters.categoryFilterTarget) !== -1) {
                        return true;
                    } else {
                        return false;
                    }
                }
            },
            decisionFilter: function(item) {
                var hasDecision = item.values().decision.toLowerCase() === true.toString().toLowerCase();

                if (hasDecision === self.filterParameters.filterItemsWithDecision) {
                    return true;
                } else {
                    return false;
                }
            },
            animalRawFilter: function(item) {
                var hasAnimalRaw = item.values().animalRaw.toLowerCase() === true.toString().toLowerCase();

                if (hasAnimalRaw === self.filterParameters.filterItemsWithAnimalRaw) {
                    return true;
                } else {
                    return false;
                }
            },
            productFilter: function(item) {
                if (self.filterParameters.productFilterTarget == "") {
                    return true;
                } else {
                    if (item.values().product === self.filterParameters.productFilterTarget) {
                        return true;
                    } else {
                        return false;
                    }
                }
            }
        };

        self.applyFiltering = function (list) {
            list.filter(function (item) {
                var result = false;
                for (var i = 0; i < enabledFilters.length; i++) {
                   
                    result = enabledFilters[i](item);

                    if (!result) {
                        break;
                    }
                }

                return result;
            });
        };

        self.removeFilter = function (list, filter) {
            list.filter(function (item) {
                for (var i = 0; i < enabledFilters.length; i++) {
                    if (enabledFilters[i] == filter) {
                        return true;
                    }
                }
            });
        };

        self.enableFilter = function(filter) {
            if (enabledFilters.indexOf(filter) === -1) {
                enabledFilters.push(filter);
            }
        };

        self.disableFilter = function (filter) {
            if (enabledFilters.indexOf(filter) !== -1) {
                enabledFilters.pop(filter);
            }
        };

        self.filterParameters = {
            categoryFilterTarget: "",
            filterItemsWithDecision: false,
            filterItemsWithAnimalRaw: false,
            productFilterTarget: ""
        };

        return self;
    })();

    base.faq = function () {
        var $wrapper = $('#faq');
        if ($wrapper.length == 0) return false;

        var $textFilter = $('#faq-text-filter');
        var $content = $('.faq-content');

        var options = {
            valueNames: ['e-number', 'e-number-stripped', 'name', 'category', 'decision', 'supplier', 'product', 'animalRaw'],
            page: "300"
        };

        var faqList = new List('faq', options);
        faqList.sort('e-number', { order: "asc" });

        $('.category-filter').on('change', function () {
            var $t = $(this);
            base.filtering.filterParameters.categoryFilterTarget = $t.val();
            base.filtering.enableFilter(base.filtering.filters.categoryFilterSeaArea);
            base.filtering.applyFiltering(faqList);
        });

        $('.product-filter').on('change', function () {
            var $t = $(this);
            base.filtering.filterParameters.productFilterTarget = $t.val();

            base.filtering.enableFilter(base.filtering.filters.productFilter);
            base.filtering.applyFiltering(faqList);
        });

        $('#decision-taken, #repealed-decisions').on('change', function (event) {
            if (event.target.id === 'decision-taken') {
                base.filtering.filterParameters.filterItemsWithDecision = true;
            } else if (event.target.id === 'repealed-decisions') {
                base.filtering.filterParameters.filterItemsWithDecision = false;
            } else {
                return;
            }

            base.filtering.enableFilter(base.filtering.filters.decisionFilter);
            base.filtering.applyFiltering(faqList);
        });

        $('#animal-raw').on('change', function (event) {
            if (event.target.id === 'animal-raw') {
                var isChecked = this.checked;
                if (isChecked) {
                    base.filtering.filterParameters.filterItemsWithAnimalRaw = true;
                } else {
                    base.filtering.filterParameters.filterItemsWithAnimalRaw = false;
                }
            } else {
                return;
            }

            base.filtering.enableFilter(base.filtering.filters.animalRawFilter);
            base.filtering.applyFiltering(faqList);
        });

        $('#seaarea-open').on('change', function (event) {
            if (event.target.id === 'seaarea-open') {
                var isChecked = this.checked;
                if (isChecked) {
                    base.filtering.filterParameters.filterItemsWithAnimalRaw = true;
                    base.filtering.enableFilter(base.filtering.filters.animalRawFilter);
                    base.filtering.applyFiltering(faqList);
                } else {
                    base.filtering.filterParameters.filterItemsWithAnimalRaw = false;
                    base.filtering.removeFilter(faqList, base.filtering.filters.animalRawFilter);
                    base.filtering.disableFilter(base.filtering.filters.animalRawFilter);
                    if (base.filtering.filterParameters.categoryFilterTarget !== "") {
                        base.filtering.applyFiltering(faqList);
                    }
                }
            } else {
                return;
            }
        });

        var $totalHits = $('.total-hits');
        var $emptyListMsg = $('.empty-list-msg');
        var updateTotalHits = function () {
            var hits = faqList.visibleItems.length;
            $totalHits.text(hits);
            if (hits == 0) {
                $emptyListMsg.find('.search-term').text($textFilter.val());
                $emptyListMsg.show();
            } else {
                $emptyListMsg.hide();
            }

        };
        updateTotalHits();
        faqList.on('updated', function () {
            updateTotalHits();

            $content.unhighlight();
            var v = $textFilter.val();
            if (!v) return;
            var vArr = v.split(" ");
            for (var i = 0; vArr.length > i; i++) {
                $content.highlight(vArr[i]);
            };
        });
    };

    //Modules that will run on all pages
    base.setup = function () {
        base.faq();
    };

    return base;
}(jQuery));

jQuery(document).ready(function () {
    $("span.e-number").each(function () {
        var stripped = $(this).text().split(' ').join('');
        $(this).after("<span class='e-number-stripped' style='display:none'>" + stripped + "</span>");
    });
    UAH.setup();
});;//main initialization file for livsmedelsverket js. this file must always come first of the livsmedelsverket.js files
$(document).ready(function () {
    livsmedelsverket.initialize();
});


var livsmedelsverket = livsmedelsverket || function () {
    var initialize = function () {
        livsmedelsverket.response.initialize();
        livsmedelsverket.Navigation.initialize();
        livsmedelsverket.tabfocus.initialize();
        livsmedelsverket.Comment.initialize();
        livsmedelsverket.Slider.initialize();
        livsmedelsverket.CatComplete.initialize();
        livsmedelsverket.Tables.initialize();
        livsmedelsverket.WorkRooms.initialize();
        livsmedelsverket.County.initialize();
        livsmedelsverket.Expand.initialize();
        livsmedelsverket.MyShortcuts.initialize();
        livsmedelsverket.xformblock.initialize();
        livsmedelsverket.Nkp.initialize();
        livsmedelsverket.Community.initialize();
        livsmedelsverket.cookieconsent.initialize();
        livsmedelsverket.magnifyimage.initialize();
        livsmedelsverket.wellsubstance.initialize();
        livsmedelsverket.blog.initialize();
        livsmedelsverket.jobads.initialize();
        livsmedelsverket.EmailValidationSubS.initialize();

        window.addToCart = function (articleNb) {   
            articleNb = articleNb || "";
            var cart = window.open("http://fm.isydistribution.se/Broschyr/EX11046.lasso?article=" + articleNb, "cartwin", "width=800, height=600, scrollbars, resizable, status");
            cart.focus();
        };
    };

    return {
        initialize: initialize
    };
}();

$(window).load(function () {
    //TODO: in order to use matchMedia and have it working in IE8 we need to include respond.js library - https://github.com/scottjehl/Respond
    if (matchMedia('only screen and (min-width: 768px)').matches) {
        var highestCol = Math.max($('footer .col1').height(), $('footer .col2').height(), $('footer .col3').height());
        $('.cols').height(highestCol);
    }
});

$(window).resize(function () {
    if (matchMedia('only screen and (min-width: 768px)').matches) {
        var highestCol = Math.max($('footer .col1').height(), $('footer .col2').height(), $('footer .col3').height());
        $('.cols').height(highestCol);
    } else {
        $('.cols').css('height', 'auto');
    }
});;livsmedelsverket = livsmedelsverket || {};

livsmedelsverket.blog = function () {
    var initialize = function() {
        $("#blogloadmore").on("click", function () {
            var focusitem;
            var listitemshidden = $('#bloglist .case-wrapper:hidden');
            for (var i = 0; i < listitemshidden.length; i++) {
                if (i < blogsToShow) {
                    $(listitemshidden[i]).css("display", "list-item");
                    if (i == 0) {
                        focusitem = $(listitemshidden[i]);
                    }
                }
            }
            var listitemsvisible = $('#bloglist .case-wrapper:visible');
            $('.blogCount').text(listitemsvisible.length);
            var listitemstotal = $('#bloglist .case-wrapper');
            if (listitemstotal.length == listitemsvisible.length) {
                $(this).hide();
            }
            if (focusitem) {
                focusitem.focus();
            }
        });
    } 
	return {
		initialize: initialize
	};
}();;livsmedelsverket = livsmedelsverket || {};

livsmedelsverket.CatComplete = function () {
    var initialize = function () {
        $.widget("custom.catcomplete", $.ui.autocomplete, {
            _renderMenu: function (ul, items) {
                var self = this, categories = {};

                $.each(items, function (index, item) {
                    if (!categories.hasOwnProperty(item.category)) {
                        categories[item.category] = [item];
                    } else {
                        categories[item.category] = categories[item.category].concat([item]);
                    }
                });

                $.each(categories, function (category, items) {
                    var categorieShown = false;
                    var li;
                    $.each(items, function (index, item) {
                        if (item.category == '' || currentLang != "sv") {
                            li = self._renderItemData(ul, item);
                            li.attr("aria-label", item.category + " : " + item.label);
                        }
                        else {
                            if (!categorieShown) {
                                ul.append("<li class='ui-autocomplete-category clearfix'>" + category + " <a href='" + item.categorySearchPageUrl + "'><span class='result-num'>" + item.hitsPerCategory + " träffar </span> Visa Alla</a></li>");
                                categorieShown = true;
                            }
                            li = self._renderItemData(ul, item);
                            li.attr("aria-label", item.category + " : " + item.label);
                        }
                    });
                });
            }
        });
    };
    return {
        initialize: initialize
    };
}();

$(function () {
    var quicksearch = $("#quicksearchTextbox"),
        quicksearchmobile = $("#quicksearchTextboxmobile");
    if (quicksearch) {
        Autocomplete(quicksearch);
    }
    if (quicksearchmobile) {
        Autocomplete(quicksearchmobile);
    }
    
});
var Autocomplete = function (element) {
    element.catcomplete({
        select: function (event, ui) {
            if (ui.item.pageUrl != undefined) {
                window.location.href = ui.item.pageUrl;
            }
        },
        source: function (request, response) {
            $.ajax({
                url: "/" + currentLang + "/find/rest/spellcheck/get/" + request.term + "?size=1",
                type: "GET",
                dataType: "json",
                async: false,
                success: function (data) {
                    $.ajax({
                        url: "/api/autocomplete/?query=" + request.term + "&lang=" + currentLang,
                        type: "GET",
                        async: true,
                        dataType: "json",
                        success: function (data) {
                            if (response.length > 0)
                                response.push(data);
                            else if (data.length > 0)
                                response(data);
                        }
                    });

                    response($.map(data.Hits, function (item) {
                        return {
                            label: item.Suggestion,
                            value: item.Suggestion,
                            category: ""
                        };
                    }
                    ));
                }
            });

        },
        minLength: 2,
        delay: 600
    });
};;var MaxHeadingLength = 75;
var MaxPreambleLength = 300;
var MaxCommentLength = 3000;

$(function () {
    if ($('#Case_Heading').length) {
        CheckTextCount($('#Case_Heading'), MaxHeadingLength);
    }
    if ($('#Case_Preamble').length) {
        CheckTextCount($('#Case_Preamble'), MaxPreambleLength);
    }
    if ($('#Case_Comment').length) {
        CheckTextCount($('#Case_Comment'), MaxCommentLength);
    }
});

$('#Case_Heading').keyup(function () {
    UpdateTextCount(this, MaxHeadingLength);
});
$('#Case_Heading').keydown(function () {
    UpdateTextCount(this, MaxHeadingLength);
});

$('#Case_Preamble').keyup(function () {
    UpdateTextCount(this, MaxPreambleLength);
});
$('#Case_Preamble').keydown(function () {
    UpdateTextCount(this, MaxPreambleLength);
});

function CountCommentKeyUp(selector) {
    $(selector).keyup(function () {
        UpdateTextCount(this, MaxCommentLength);
    }); 
}

function CountCommentKeyDown(selector) {
    $(selector).keydown(function () {
        UpdateTextCount(this, MaxCommentLength);
    }); 
}

function ResetCounter (selector) {
    $(selector).siblings("span").text("3000");

}


function CheckTextCount(selector, maxlength) {

    var count = selector.val().length;
    var remainingCount = maxlength - count;
    var textCounter = selector.siblings(".charCount");

    if (remainingCount <= 0) {

        textCounter.text(0);
    }
    else {
        textCounter.text(remainingCount);
    }
}

function UpdateTextCount(selector, maxlength) {

    var count = $(selector).val().length;
    var remainingCount = maxlength - count;
    var textCounter = $(selector).siblings('.charCount');

    if (remainingCount <= 0) {
        textCounter.text(0);
    }
    else {
        textCounter.text(remainingCount);
    }
}


;livsmedelsverket = livsmedelsverket || {};

livsmedelsverket.Comment = function () {
    var initialize = function() {
        $(".comment .closed").click(function () {
            setToggle($(this));
            $(".comment i.fa-plus, .comment i.fa-minus").toggleClass("fa-plus fa-minus");
        });
        expand();
    },
        expand = function() {
            $("[data-expand-div='True']").each(function() {
                setToggle($(this));
                $(".comment i.fa").removeClass("fa-plus").addClass("fa-minus");
                this.scrollIntoView();
            });
        },
        setToggle = function($element) {
            $element.toggleClass("open").toggleClass("closed");
            $(".comment form").toggle();

        };
    return {
        initialize: initialize
    };
}();

;livsmedelsverket = livsmedelsverket || {};

livsmedelsverket.Community = function () {

    var initialize = function () {
        setUpLikeClick();
        setUpFollowlick();
        setUpCommentClick();
        setUpAddCommentClick();
        setUpCommentClickInList();
        setUpRemoveCommentClick();
        hidePreviousCommentsInList();
        setUpAnswerClick();
        getMoreScrollContent();
        setUpAddCommentClickInList();
        setUpNotificationClick();
        removeFile();
        removeImage();
        removeFileOnChange();
        removeImageOnChange();
        setUpRemoveListCommentClick();
    };

    return {
        initialize: initialize
    };

    function setUpLikeClick() {
        $(document).on("click", ".like", function () {
            const rootElement = $(this).parent();
            const contentId = rootElement.data("contentid");
            const workroomId = rootElement.data("workroomid");

            handleLikeClick(contentId, workroomId).done(function (data) {
                updateLikeButton(rootElement, data);
            });
        });
    }
    //TODO:
    //Refactor the detail-view clicks and the ListClicks to work better
    //Suggestion: the functions take a trigger and a target and then it should be able to be useable by both


    function setUpNotificationClick() {

        $(document).on("click", ".notification-sign span.show-activity", function () {
            var id = $(this).parent().siblings(".social-interaction").data("contentid");
            $.post("/api/CommunitySocialInteraction/ContentHasBeenSeen?contentId=" + id);
            var $jscommentlist = $(this).closest(".case-block").find(".social-comment.social-interaction-btn.js-comment-list");
            $jscommentlist.addClass('scroll');
            $jscommentlist.click();
        });
    }
    function setUpAddCommentClickInList() {
        $(document).on("click",
            ".js-send-comment-list",
            function () {
                var commentsection = $(this).closest(".social-interaction");
                var id = $(this).closest(".social-interaction").data("contentid");

                var comment = $(commentsection).find(".comment-text-area").val();
                if (!comment.length) {
                    return;
                }

                //add comment to list
                handlePostComment(id, comment).then(function (data) {
                    var newComment = data.Comments[0];
                    var hasAdminAccess = data.UserHasAdminRights;
                    var contentId = data.ContentId;

                    var commentHtml;
                    if (hasAdminAccess) {
                        commentHtml = '<div class="comment" data-contentid=' + contentId + ' data-commentid=' + newComment.Id.StoreId + ':' + newComment.Id.ExternalId + '><a href="#" class="js-remove-list-comment-button removeBtn" title="Ta bort"><i class="fa fa-trash-o"></i> Ta bort</a><p class="comment-content">' + newComment.Comment + '</p> <div class="comment-by"><span class="creator">' + newComment.UserName + '</span><span class="timestamp"> ' + newComment.PublishDate + '</span></div></div > ';
                    } else {
                        commentHtml =
                            '<div class="comment"><p class="comment-content" data-contentid=' + contentId + ' data-commentid=' + newComment.Id.StoreId + ':' + newComment.Id.ExternalId + '>' + newComment.Comment + '</p> <div class="comment-by"><span class="creator">' + newComment.UserName + '</span><span class="timestamp"> ' + newComment.PublishDate + '</span></div></div > ';
                    }

                    commentsection.find(".comments").prepend(commentHtml);

                    if (commentsection.find(".comment").length > 5) {
                        commentsection.find(".comment").last().remove();
                    }
                    $(".comment-text-area").val('');

                    commentsection.find(".nrofcomments").html(data.Comments.length);
                    commentsection.find(".js-thanks-for-comment").show();
                });
            });
    }

    function setUpAnswerClick() {
        $(document).on("click", ".js-send-answer-list", function () {
            const section = $(this).closest(".social-interaction");
            const contentId = section.data("contentid");
            const workroomId = section.data("workroomid");
        });

    }
    function setUpFollowlick() {
        $(document).on("click", ".follow", function () {
            const parent = $(this).parent();
            const contentId = parent.data("contentid");
            const workroomId = parent.data("workroomid");

            handleFollowClick(contentId, workroomId).done(function (data) {
                updateFollowButton(parent, data, true);
            });
        });
    }
    function setUpAddCommentClick() {
        $(document).on("click",
            ".js-send-comment-button",
            function () {
                var commentsection = $(this).closest(".write-comment-area");

                var id = commentsection.siblings(".social-interaction").data("contentid");
                var comment = $(".comment-text-area").val();
                if (!comment.length) {
                    return;
                }
                //add comment to list
                var newComments = handlePostComment(id, comment).then(function (data) {
                    var newComment = data.Comments[0];
                    var hasAdminRights = data.UserHasAdminRights;
                    var contentId = data.ContentId;
                    //add comment
                    addCommentToHtml(newComment, contentId, hasAdminRights);

                    //clear comment field
                    $(".comment-text-area").val('');

                    //Update counter
                    $(".comment-section h2").html("Kommentarer (" + data.Comments.length + ")");
                    commentsection.siblings(".social-interaction").find(".nrofcomments").html(data.Comments.length);


                    //Light up thank you message
                    commentsection.find(".js-thanks-for-comment").show();
                });
            });
    }

    function setUpRemoveCommentClick() {
        $(document).on("click",
            ".js-remove-comment-button",
            function (e) {
                e.preventDefault();
                var commentsection = $(this).closest(".social-comment-wrapper");
                var id = commentsection.attr("data-contentId");
                var commentId = commentsection.attr("data-commentId");
                var IsListComment = false;

                handleRemoveComment(id, commentId, IsListComment);
            });
    }

    function setUpRemoveListCommentClick() {
        $(document).on("click",
            ".js-remove-list-comment-button",
            function (e) {
                e.preventDefault();
                var commentWrapper = $(this).closest(".social-interaction");
                var commentsection = $(this).closest(".comment");
                var id = commentsection.attr("data-contentId");
                var commentId = commentsection.attr("data-commentId");
                var IsListComment = true;

                handleRemoveComment(id, commentId, IsListComment).then(function (data) {

                    if (data.Comments.length >= 5) {
                        var hasAdminAccess = data.UserHasAdminRights;
                        var nextComment = data.Comments[4];
                        var commentHtml;
                        if (hasAdminAccess) {
                            commentHtml = '<div class="comment" data-contentid=' + data.ContentId + ' data-commentid=' + nextComment.Id.StoreId + ':' + nextComment.Id.ExternalId + '><a href="#" class="js-remove-list-comment-button removeBtn" title="Ta bort"><i class="fa fa-trash-o"></i> Ta bort</a><p class="comment-content">' + nextComment.Comment + '</p> <div class="comment-by"><span class="creator">' + nextComment.UserName + '</span><span class="timestamp"> ' + nextComment.PublishDate + '</span></div></div > ';
                        } else {
                            commentHtml =
                                '<div class="comment"><p class="comment-content" data-contentid=' + data.ContentId + ' data-commentid=' + nextComment.Id.StoreId + ':' + nextComment.Id.ExternalId + '>' + nextComment.Comment + '</p> <div class="comment-by"><span class="creator">' + nextComment.UserName + '</span><span class="timestamp"> ' + nextComment.PublishDate + '</span></div></div > ';
                        }

                        commentWrapper.find(".comments").append(commentHtml);
                    }
                    if (data.Comments.length <= 5) {
                        commentWrapper.find(".js-hide-previous-comments").hide();
                    }
                });
            });
    }

    function addCommentToHtml(comment, contentId, hasAdminRights) {
        var newComment = "";
        if (hasAdminRights) {
            newComment = '<div class="social-comment-wrapper" data-contentId=' + contentId + ' data-commentid=' + comment.Id.StoreId + ':' + comment.Id.ExternalId + '><a href="#" class="js-remove-comment-button" title="Ta bort"><i class="fa fa-trash-o"></i> Ta bort</a><div class="comment-content"><p> ' + comment.Comment + '</p></div><div class="comment-by"><span class="creator">' + comment.UserName + ' </span><span class="timestamp"> - ' + comment.PublishDate + '</span></div></div>';
        } else {
            newComment =
                '<div class="social-comment-wrapper" data-contentId=' + contentId + ' data-commentid=' + comment.Id.StoreId + ':' + comment.Id.ExternalId + '><div class="comment-content"><p> ' + comment.Comment + '</p></div><div class="comment-by"><span class="creator">' + comment.UserName + ' </span><span class="timestamp"> - ' + comment.PublishDate + '</span></div></div>';
        }
        $(".js-comment-list").prepend(newComment);
    }

    function handleLikeClick(contentId, workroomId) {
        return $.post("/api/CommunitySocialInteraction/UpdateLike?contentId=" + contentId + "&workroomId=" + (workroomId || ""));
    }

    function handleFollowClick(contentId, workroomId) {
        return $.post("/api/CommunitySocialInteraction/ToggleFollow?contentId=" + contentId + "&ignoreUseOption=true&workroomId=" + (workroomId || ""));
    }

    function handlePostComment(contentId, comment) {
        var encodedcomment = encodeURIComponent(comment);
      
        return $.ajax({
            url: "/api/CommunitySocialInteraction/PostComment?contentId=" + contentId,
            contentType: "application/json; charset=utf-8",
            data: JSON.stringify(comment),
            type: 'POST',
            success: function (result) {

                return result;
            }
        });
    }

    function handleRemoveComment(contentId, commentId, isListComment) {
        return $.ajax({
            url: "/api/CommunitySocialInteraction/DeleteComment?contentId=" + contentId + "&commentId=" + commentId,
            type: 'DELETE',
            success: function (result) {
                if (result != null) {
                    var commentsection;
                    if (isListComment) {
                        commentsection = $(".comments").find("[data-commentId='" + commentId + "']");
                        $(".social-comment").find(".nrofcomments").html(result.Comments.length);
                    }
                    else {
                        commentsection = $(".js-comment-list").find("[data-commentId='" + commentId + "']");
                        $(".comment-section h2").html("Kommentarer (" + result.Comments.length + ")");
                        $(".social-interaction").find(".nrofcomments").html(result.Comments.length);
                    }
                    commentsection.fadeOut(300, function () { $(this).remove(); });

                    return result;
                }
                return null;
            }
        });
    }

    function updateLikeButton(element, data) {
        element.find(".like").toggleClass("active", data.CurrentUserLikesContent);
        element.find(".like .like-count").text(data.NrOfLikes);
        //updateFollowButton(element, data.Follows);
        if (data.CurrentUserLikesContent) {
            element.find(".like").addClass("trigger-animation");
            setTimeout(function () {
                element.find(".like").removeClass("trigger-animation");

            }, 750);
        }
    }

    function updateFollowButton(element, data, mayTriggerAnimation) {
        element.find(".follow").toggleClass("active", data.CurrentUserIsFollowing);
        element.find(".follow span").text("Följ (" + data.NrOfFollowers + ")");
        if (data.CurrentUserIsFollowing && !!mayTriggerAnimation) {
            element.find(".follow").addClass("trigger-animation");
            setTimeout(function () {
                element.find(".follow").removeClass("trigger-animation");
            }, 750);
        }
    }

    function setUpCommentClickInList() {
        $(document).on("click", ".js-comment-list", function () {
            var rootElement = $(this);
            updateCommentButtonInList(rootElement);
        });
    }

    function updateCommentButtonInList(element, data) {
        $(element).toggleClass('active');
        $(element).closest(".case-wrapper").find(".write-comment-area").slideToggle(300, function () {
            if ($(element).hasClass('scroll')) {
                $('html,body').animate({
                    scrollTop: $(this).offset().top - 40
                }, "slow")
                $(element).removeClass('scroll');
            }
        });        
    }

    function hidePreviousCommentsInList() {
        $(document).on("click", ".js-hide-previous-comments", function () {
            $(this).toggleClass("hiddenComments");
            $(this).next(".comments").slideToggle(300);

            console.log($(this).find(".js-inner-comment-toggle").text());

            if ($(this).find(".js-inner-comment-toggle").text() == "Dölj tidigare kommentarer") {
                $(this).find(".js-inner-comment-toggle").text("Visa tidigare kommentarer");
            } else {
                $(this).find(".js-inner-comment-toggle").text("Dölj tidigare kommentarer");
            }
        });

    }

    function setUpCommentClick() {
        $(document).on("click", ".js-social-comment", function () {
            var rootElement = $(this);
            updateCommentButton(rootElement);
        });
    }

    function updateCommentButton(element, data) {
        $(element).toggleClass('active');

        //add a uni
        if ($(".case-list")[0]) {
            var $wrapper = $(element).closest(".case-wrapper");
            $wrapper.toggleClass("active-comment");
            $wrapper.find(".write-comment-area").slideToggle(300);
        } else {
            $(element).parent(".social-interaction").siblings(".write-comment-area").slideToggle(300);
        }
    }

    function removeImage() {
        $('#removeImage').on("click",
            function (event) {
                event.preventDefault();
                $("#caseImage").remove();
            });
    }

    function removeFile() {
        $('#removeFile').on("click",
            function (event) {
                event.preventDefault();
                $("#caseFile").remove();
            });
    }

    function removeImageOnChange() {
        $("#caseTopImage").change(function () {
            $("#caseImage").remove();
        });
    }

    function removeFileOnChange(parameters) {
        $("#caseAttachment").change(function () {
            $("#caseFile").remove();
        });
    }

    function getMoreScrollContent() {
        var pageIndex = 1;
        var scrollGate = false;

        //Add a class to the if below if you need to add more pagetypes to the scroll-getter
        if ($(".omni-list")[0] || $(".js-case-list")[0]) {
            $(window).scroll(function () {
                var hT = $('#scroll').offset().top,
                    hH = $('#scroll').outerHeight(),
                    wH = $(window).height(),
                    wS = $(this).scrollTop();
                if (wS > (hT + hH - wH)) {

                    if (!scrollGate) {
                        scrollGate = true;
                        lazyLoad();
                    }
                }
            });
        }

        function lazyLoad() {
            $('.spinner').css("display", "flex");
            var url = window.location.href;
            if (url.lastIndexOf("/") == url.length - 1) {
                url = url + "GetScrollContent/";
            }
            else {
                url = url + "/GetScrollContent";
            }
            $.ajax({
                type: 'POST',
                url: url,
                dataType: 'html',
                data: { pageIndex: pageIndex },
                cache: false,
                success: function (data) {
                    $('#article').append(data);
                    if ($(".no-more-content").length > 0) {
                        scrollGate = true;
                    } else {
                        scrollGate = false;
                    }
                    pageIndex += 1;
                    $('.spinner').css("display", "none");

                },
                error: function () {
                    $('.spinner').css("display", "none");
                }
            });
        }
    }
}();;/**
 * livsmedelsverket.cookieconsent.js
 * @namespace livsmedelsverket
 * @description The cookieconsent base framework.
 * @version 1.0.0
 */
livsmedelsverket = livsmedelsverket || {};

livsmedelsverket.cookieconsent = (function () {
        var setCookie = function (name, value, days) {
            var expires = "";
            if (days) {
                var date = new Date();
                date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
                expires = "; expires=" + date.toUTCString();
            }
            document.cookie = name + "=" + (value || "") + expires + "; path=/";
        },
        getCookie = function (name) {
            var nameEQ = name + "=";
            var ca = document.cookie.split(';');
            for (var i = 0; i < ca.length; i++) {
                var c = ca[i];
                while (c.charAt(0) === ' ') c = c.substring(1, c.length);
                if (c.indexOf(nameEQ) === 0) return c.substring(nameEQ.length, c.length);
            }
            return null;
        },
        eraseCookie = function (name) {
            document.cookie = name + '=; Max-Age=-99999999;';
        },
           
        setCookieSettings = function (cookie) {
            //console.log('settings - ',cookie);
            var cookiearray = cookie.split(',');
            for (var i = 0; i < cookiearray.length; i++) {
                var value = cookiearray[i].split(':')[1];

                if (i != 0 && value === '1') {
                    $('#cookie-option-' + (i + 1))[0].checked = true;
                    //$('#cookie-option-' + (i + 1)).attr('checked', 'true');
                } else if (i != 0 && value === '0') {
                    $('#cookie-option-' + (i + 1))[0].checked = false;
                    //$('#cookie-option-' + (i + 1)).removeAttr('checked');
                }

            }
            },
        isHidden = function (el) {
            var style = window.getComputedStyle(el);
            return (style.display === 'none')
        },
        bind = function () {
            //CookieConsent
            $('#cookie-save-button').on('click', function (e) {
                e.preventDefault();
                var $inputs = $('#cookieform :input[type=checkbox]');

                var values = {};
                var cookiestring = "";

                for (var i = 0; i < $inputs.length; i++) {
                    var input = $inputs[i];
                    var value = '';
                    if (input.checked) {
                        value = '1';
                    } else if (input.checked === false) {
                        value = '0';
                    }
                    if (i == 0) {
                        cookiestring += 'required:1,';
                    }
                    else if (i == 1) {
                        cookiestring += 'functional:' + value + ',';
                    }
                    else if (i == 2) {
                        cookiestring += 'analytic:' + value;
                    }

                }

                //console.log(cookiestring);
                setCookie('ConsentCookie', cookiestring, 365);
                setCookieSettings(cookiestring);
                $('#CookieConsent').hide();
                

                //reload page to show videos of forms
                location.reload();
                //if ($('.pdfLink').length > 0) {
                //    location.reload();
                //}

            });
            $('.acceptCookie').on('click', function () {
                setCookie('ConsentCookie', 'required:1,functional:1,analytic:1', 365);
                $('#CookieConsent').hide();

                setCookieSettings('required:1,functional:1,analytic:1');
                //reload page to show videos of forms
                location.reload();
            });
            $('.declineCookie').on('click', function () {
                setCookie('ConsentCookie', 'required:1,functional:0,analytic:0', 365);
                $('#CookieConsent').hide();
                setCookieSettings('required:1,functional:0,analytic:0');

            });
            $('.cookieSettings').on('click', function () {
                $('.consentcontent').hide();
                $('.cookie-policy').hide();
                $('.settingscontent').show();

                if (!$('#CookieConsent').is(':visible')) {
                    $('#CookieConsent').show();
                }
                $('#CookieConsent').focus();
            });
            $('.cookie-policy-link').on('click', function (e) {
                e.preventDefault();
                $('.consentcontent').hide();
                $('.settingscontent').hide();
                $('.cookie-policy').show();
                var closebtn = $('.closebtn');
                var acceptbtn = closebtn.siblings('.acceptCookie');
                if ($(this).hasClass('hasclosebtn') && getCookie('ConsentCookie')) {
                    closebtn.show();
                    acceptbtn.hide();
                } else {
                    closebtn.hide();
                    acceptbtn.show();
                }

                if (!$('#CookieConsent').is(':visible')) {
                    $('#CookieConsent').show();
                }
                $('#CookieConsent').focus();
            });
            $('#CookieConsent .backbtn').on('click', function (e) {
                e.preventDefault();
                var $this = $(this);
                if ($this.closest('.settingscontent').length > 0) {
                    $('.cookie-policy').hide();
                    $('.settingscontent').hide();
                    $('.consentcontent').show();
                    $('.acceptCookie').focus();
                }
                if ($this.closest('.cookie-policy').length > 0) {
                    $('.cookie-policy').hide();
                    $('.settingscontent').hide();
                    $('.consentcontent').show();
                    $('.acceptCookie').focus();
                }
            });
            $('.closebtn').on('click', function (e) {
                $('#CookieConsent').hide();
                $('.cookie-policy').hide();
                $('.settingscontent').hide();
                $('.consentcontent').hide();
            });
            $('.cookieinfo').on('click', function (e) {
                e.preventDefault();
                var $this = $(this);
                var content = $this.siblings('.cookieinfo_content');
                if ($this.attr('aria-expanded') == 'false') {
                    $this.attr('aria-expanded', 'true');
                    content.stop(true).slideDown({
                        duration: 400,
                        complete: function () { $this.addClass('minify'); }
                    });
                }
                else {
                    $this.attr('aria-expanded', 'false');
                    content.stop(true).slideUp({
                        duration: 400,
                        complete: function () { $this.removeClass('minify'); }
                    });
                }
            });
            // add all the elements inside modal which you want to make focusable
            var focusableElements =
                'button, [href], input:not([disabled]), select, textarea, [tabindex]:not([tabindex="-1"])';
            var consentmodal = document.querySelector('.consentcontent');
            var consentfirstFocusableElement = consentmodal.querySelectorAll(focusableElements)[0];
            var consentfocusableContent = consentmodal.querySelectorAll(focusableElements);
            var consentlastFocusableElement = consentfocusableContent[consentfocusableContent.length - 1];

            var settingsmodal = document.querySelector('.settingscontent');
            var settingsfirstFocusableElement = settingsmodal.querySelectorAll(focusableElements)[0];
            var settingsfocusableContent = settingsmodal.querySelectorAll(focusableElements);
            var settingslastFocusableElement = settingsfocusableContent[settingsfocusableContent.length - 1];

            var policymodal = document.querySelector('.cookie-policy');
            var policyfirstFocusableElement = policymodal.querySelectorAll(focusableElements)[0];
            var policyfocusableContent = policymodal.querySelectorAll(focusableElements);
            var policylastFocusableElement = policyfocusableContent[policyfocusableContent.length - 1];
            $(document).on('keydown', function (e) {
                let isTabPressed = e.key === 'Tab' || e.keyCode === 9;

                if (!isTabPressed) {
                    return;
                }
                if (!isHidden(consentmodal)) {
                    if (e.shiftKey) { // if shift key pressed for shift + tab combination
                        if (document.activeElement === consentfirstFocusableElement) {
                            consentlastFocusableElement.focus();
                            e.preventDefault();
                        }
                    } else { // if tab key is pressed
                        if (document.activeElement === consentlastFocusableElement) {
                            consentfirstFocusableElement.focus();
                            e.preventDefault();
                        }
                    }
                } else if (!isHidden(settingsmodal)) {
                    if (e.shiftKey) { // if shift key pressed for shift + tab combination
                        if (document.activeElement === settingsfirstFocusableElement) {
                            settingslastFocusableElement.focus(); 
                            e.preventDefault();
                        }
                    } else { // if tab key is pressed
                        if (document.activeElement === settingslastFocusableElement) { 
                            settingsfirstFocusableElement.focus(); 
                            e.preventDefault();
                        }
                    }
                } else if (!isHidden(policymodal)) {
                    if (e.shiftKey) { // if shift key pressed for shift + tab combination
                        if (document.activeElement === policyfirstFocusableElement) {
                            policylastFocusableElement.focus(); 
                            e.preventDefault();
                        }
                    } else { // if tab key is pressed
                        if (document.activeElement === policylastFocusableElement) { 
                            policyfirstFocusableElement.focus();
                            e.preventDefault();
                        }
                    }
                }
               

                
            });

        },
        initialize = function () {
            bind();

            var consentcookie = getCookie('ConsentCookie');
            if (consentcookie) {
                $('#CookieConsent').hide();
                setCookieSettings(consentcookie);

            } else {
                var cookiemodal = $('#CookieConsent');
                cookiemodal.show();
                //Set focus in the modal
                cookiemodal.focus();
            }
        };

    return {
        initialize: initialize,
        setCookie: setCookie,
        getCookie:getCookie
    };
})();

;livsmedelsverket = livsmedelsverket || {};

livsmedelsverket.County = function () {

    var initialize = function() {
        $("#ddlCounties").on("change", getMunicipalities);
    },
        getMunicipalities = function() {

            var $ddlCounties = $(this);

            var options = {
            	url: $ddlCounties.attr("data-livs-url"),
                type: 'GET',
                data: { county: $ddlCounties.find(":selected").text() }
            };

            $.ajax(options).done(function(data) {
                var $target = $($ddlCounties.attr("data-livs-target"));
                var $newHtml = $(data);
                $target.replaceWith($newHtml);
            });
        };
	return {
		initialize: initialize
	};
}();;livsmedelsverket = livsmedelsverket || {};

livsmedelsverket.EmailValidationSubS = function () {
    var initialize = function () {
        const email = document.querySelector('.emailField');
        const form = document.querySelector('.subscription-form form');
        const errorEmail = document.querySelector('.invalid-email-message');
        if (!form) {
            return;
        }
       form.addEventListener('submit', function (e) {
            if (email.value) {
                const regexMatch = /^\S+@\S+\.\S+$/.test(email.value);
                if (regexMatch) {
                    errorEmail.textContent = '';
                } else {
                    e.preventDefault();
                    errorEmail.textContent = 'Felaktig e-postadress';
                }
            } else {
                e.preventDefault();
                errorEmail.textContent = 'Du måste ange en e-postadress';
            }
        });
    };
    return {
        initialize: initialize
    };
}();;livsmedelsverket = livsmedelsverket || {};

livsmedelsverket.Expand = function () {

    var initialize = function () {
        $(".more-info").attr("aria-hidden", "true");
        $(".more-info").before("<a href='javascript:void(0)' class='info-expand' aria-expanded='false'><span class='expand-more'><i class='fa fa-plus expand-icon'></i>Visa mer</span><span class='expand-less'><i class='fa fa-minus expand-icon'></i>Dölj</span></a>");

        $(".info-expand").click(function () {
            var $this = $(this);
            var moreinfo = $this.next();
            moreinfo.toggleClass("active");
            toggleAriaHidden(moreinfo);
            

            $this.toggleClass("active");
            toggleAriaExpanded($this);

            //if ($this.hasClass('active')) {
            //    $('html, body').animate({ scrollTop: moreinfo.offset().top - 40 + 'px' }, 400);
            //}
            //$('html, body').animate({ scrollTop: moreinfo.offset().top - 40 + 'px' }, 400);
            
        });

        $(".item-heading").on("click", function () {
            if ($(this).parent().parent().siblings().hasClass('active')) {
                $('#results .results-item').each(function () {
                    $(this).removeClass("active");
                });
            }             
            $(this).parent().parent().toggleClass("active");
            //aria-expanded
            $('#results .results-item').each(function () {
                $(this).find('.item-heading').attr("aria-expanded", "false");
                $(this).find('.close-icon').siblings("span").text("Expandera");
                $(this).find('.item-info').attr("aria-hidden", "true");
            });
            if ($(this).parent().parent().hasClass('active')) {
                $(this).attr("aria-expanded", "true");
                $(this).find('.close-icon').siblings("span").text("Minifiera");
                $(this).siblings('.item-info').attr("aria-hidden", "false");
            }
        });

        $("#searchFood").focus(function () {
            $('.search-icon').css('z-index', '0');
        }).blur(function () {
            $('.search-icon').css('z-index', '10');
            });

        $('.clear-form').on("click", function () {
            $("#searchFood").val('');
            $("#resultItem li").remove();
            $("#searchFood").focus();
        });
        //close autocomplete list if clicked outside or focusout
        $(document).click(function (event) {
            var $target = $(event.target);
            if (!$target.closest('.search-bubble').length &&
                $('.search-bubble').is(":visible")) {
                setTimeout(function () {
                    //timeout for links to work in IOS
                    $("#resultItem").empty();
                    $("#resultItem").removeAttr("aria-label");
                }, 100)
                
            }
        });
        $('.search-bubble').focusout(function (event) {
            var $target = $(event.relatedTarget);
            console.log($target.closest('.search-bubble'));
            console.log($target.closest('.search-bubble').length);
            if (!$target.closest('.search-bubble').length) {
                setTimeout(function () {
                    //timeout for links to work in IOS
                    $("#resultItem").empty();
                    $("#resultItem").removeAttr("aria-label");
                }, 100)
            }
        });

    },
    toggleAriaExpanded = function (el) {
        if (el.attr("aria-expanded") == "false") {
            el.attr("aria-expanded", "true");
        } else {
            el.attr("aria-expanded", "false");
        }
    },
    toggleAriaHidden = function (el) {
        if (el.attr("aria-hidden") == "false") {
            el.attr("aria-hidden", "true");
        } else {
            el.attr("aria-hidden", "false");
        }
    },
    toggleAriaLabel = function (el, text1, text2) {
        if (el.attr("aria-label") == text1) {
            el.attr("aria-label", text2);
        } else {
            el.attr("aria-label", text1);
        }
    };
    
    return {
        initialize: initialize,
        toggleAriaExpanded: toggleAriaExpanded,
        toggleAriaHidden: toggleAriaHidden,
        toggleAriaLabel: toggleAriaLabel
    };
}();;livsmedelsverket = livsmedelsverket || {};

livsmedelsverket.jobads = function () {
    var initialize = function() {
        $("#jobadloadmore").on("click", function () {
            var focusitem;
            var listitemshidden = $('#jobadlist .case-wrapper:hidden');
            for (var i = 0; i < listitemshidden.length; i++) {
                if (i < blogsToShow) {
                    $(listitemshidden[i]).css("display", "list-item");
                    if (i == 0) {
                        focusitem = $(listitemshidden[i]);
                    }
                }
            }
            var listitemsvisible = $('#jobadlist .case-wrapper:visible');
            $('.blogCount').text(listitemsvisible.length);
            var listitemstotal = $('#jobadlist .case-wrapper');
            if (listitemstotal.length == listitemsvisible.length) {
                $(this).hide();
            }
            if (focusitem) {
                focusitem.focus();
            }
        });
    } 
	return {
		initialize: initialize
	};
}();;/**
 * livsmedelsverket.magnifiedimage.js
 * @namespace livsmedelsverket
 * @description The magnifiedimage base framework.
 * @version 1.0.0
 */
livsmedelsverket = livsmedelsverket || {};

livsmedelsverket.magnifyimage = (function () {

    blockId = 0,
    modalIsOpen = false,
    isHidden = function (el) {
        var style = window.getComputedStyle(el);
        return (style.display === 'none')
    },
        bind = function () {
            $('.closeMagnifiedImage').on('click', function (e) {
                $('body').css('overflow', 'unset');
                $('[data-modalblockid=' + livsmedelsverket.magnifyimage.blockId + ']').hide();
                livsmedelsverket.magnifyimage.modalIsOpen = false;

            });

            $('.openMagnifiedImage').on('click', function (e) {
                $('body').css('overflow', 'hidden');
                livsmedelsverket.magnifyimage.blockId = $(this).attr('data-blockId');
                $('[data-modalblockid=' + livsmedelsverket.magnifyimage.blockId + ']').show();
                livsmedelsverket.magnifyimage.modalIsOpen = true;

            });

            if ($('#MagnifyImage').length) {

                $(document).on('keydown',
                    function (e) {
                        let isTabPressed = e.key === 'Tab' || e.keyCode === 9;

                        if (!isTabPressed) {
                            return;
                        }
                        if (livsmedelsverket.magnifyimage.modalIsOpen) {

                            // add all the elements inside modal which you want to make focusable
                            var focusableElements = 'button, [tabindex]:not([tabindex="-1"])';
                            $('[data-modalblockid=' + livsmedelsverket.magnifyimage.blockId + ']').focus();
                            var magnifiedImagemodal = $('[data-modalblockid=' + livsmedelsverket.magnifyimage.blockId + ']')[0];
                            var magnifiedImagefirstFocusableElement = magnifiedImagemodal.querySelectorAll(focusableElements)[0];
                            var magnifiedImagefocusableContent = magnifiedImagemodal.querySelectorAll(focusableElements);
                            var magnifiedImagelastFocusableElement = magnifiedImagefocusableContent[magnifiedImagefocusableContent.length - 1];

                            if (e.shiftKey) { // if shift key pressed for shift + tab combination
                                if (document.activeElement === magnifiedImagefirstFocusableElement) {
                                    magnifiedImagelastFocusableElement.focus();
                                    e.preventDefault();
                                }
                            } else { // if tab key is pressed
                                if (document.activeElement === magnifiedImagelastFocusableElement) {
                                    magnifiedImagefirstFocusableElement.focus();
                                    e.preventDefault();
                                }
                            }
                        }
                    });
            }

        },
        initialize = function () {
            bind();
        };

    return {
        initialize: initialize,
    };
})();

;livsmedelsverket = livsmedelsverket || {};

livsmedelsverket.MyShortcuts = function () {

    var initialize = function () {
        $("aside.shortcuts").on("click", "#linkMyShortcuts", addShortcut);
        $("aside.shortcuts").on("click", "a.removeShortcut", removeShortcut);
    },
    addShortcut = function (event) {

        event.preventDefault();
        var $linkMyShortcuts = $(this);

        var options = {
            url: $linkMyShortcuts.attr("data-livs-url"),
            type: 'POST',
            data: { title: document.title, url: document.URL }
        };

        $.ajax(options).done(function (data) {
            var $target = $("#listOfShortcuts");
            var $newHtml = $(data);
            $target.replaceWith($newHtml);
        });
    },
    removeShortcut = function (event) {

        event.preventDefault();
        var $linkMyShortcuts = $(this);
        var shortcut = $linkMyShortcuts.attr("data-livs-shortcut");
        var options = {
            url: $linkMyShortcuts.attr("data-livs-url"),
            type: 'POST',
            data: { shortcut:shortcut }
        };

        $.ajax(options).done(function(data) {
            var $target = $("#listOfShortcuts");
            var $newHtml = $(data);
            $target.replaceWith($newHtml);
        });
    };
    return {
        initialize: initialize
    };
}();;livsmedelsverket = livsmedelsverket || {};

livsmedelsverket.Navigation = function() {
    var menuSection = $('.menu-section'),
        initialize = function () {
            setupClicks();
            addAttributesDesktop();
            setupShortcutLinks();
            setUlHasOpen();
        },
        toggleAriaHidden = function (el) {
            if (el.attr("aria-hidden") == "false") {
                el.attr("aria-hidden", "true");
            } else {
                el.attr("aria-hidden", "false");
            }
        },
        toggleAriaExpanded = function (el) {
            if (el.attr("aria-expanded") == "false") {
                el.attr("aria-expanded", "true");
            } else {
                el.attr("aria-expanded", "false");
            }
        },
        toggleExpandText = function (el) {
            if (el.html() == "Minimera") {
                el.html("Expandera");
            } else {
                el.html("Minimera");
            }
        },
        setupShortcutLinks = function () {
            var contentlink = $('#maincontent-shortcut'),
                menulink = $('#shortcutmenu'),
                subemulink = $('#shortcutsubmenu');
            if ($('#article').length < 1) {
                $('#main').attr('tabindex', '-1');//fix for IE
                contentlink.attr('href', '#main');
            }
            if ($('#pageMenu').length < 1) {
                menulink.hide();
            }
            if ($('#subMenu').length < 1) {
                subemulink.hide();
            }
        },
        setupClicks = function() {
            $(".searchToggle").click(function() {
                // $(".pageMenu").hide();
                $(".menuToggle").removeClass("selected");
                //$('.menuToggle').addClass('collapse');
                var pagemenu = $('.pageMenu');
                pagemenu.removeClass('in').addClass('collapse').addClass('hide-menu');
                //pagemenu.removeClass('in').addClass('collapse');
                
                $(".searchToggle").toggleClass("selected");
                $(".search > div").toggleClass('hide-search');
                $('body > header').toggleClass('search-open');
                return false;
            });
            $(".menuToggle").click(function() {
                $(".search > div").addClass('hide-search');
                $(".searchToggle").removeClass("selected");
                $(".menuToggle").toggleClass("selected");
                $('body > header').removeClass('search-open');
                var pagemenu = $('.pageMenu');
                if (pagemenu.is(":visible")) {
                    pagemenu.addClass('hide-menu');
                } else {
                    pagemenu.removeClass('hide-menu');
                }
            });
                        
            $("#shortcutmenu").click(function () {
                var pagemenu = $('.pageMenu');
                if (!pagemenu.is(":visible")) {
                    $(".menuToggle").click();
                }
            });
            $(".has-subnav a").click(function(evt) {
                //evt.preventDefault();
                evt.stopPropagation();
                //alert('has subnav');
                return true;
            });
            $(".has-subnav button").click(function (evt) {
                //evt.preventDefault();
                evt.stopPropagation();
                toggleMenuClick($(this));
                return true;
            });
            $(".has-subnav-span").click(function(evt) {
                evt.preventDefault();                
                toggleMenuClick($(this));
                evt.stopPropagation();
            });
            $(".has-subnav-span").on('keypress', function (evt) {
                if (evt.which == 13) {
                    evt.preventDefault();                    
                    toggleMenuClick($(this));
                    evt.stopPropagation();
                }
            });
            $(".targetLinks .toggle").click(function () {
                var $this = $(this);
                $this.parent().toggleClass("closed");
                $this.children("i").toggleClass("fa-plus").toggleClass("fa-minus");
                toggleExpandText($this.children("span"));
                toggleAriaExpanded($this);
                toggleAriaHidden($this.siblings("ul"));
                return false;
            });
            $(".targetLinks a[href^='#']").on('click', function (event) {
                var $this = $(this);
                
                if ($this.attr("href").length == 1) {
                    return;
                }
                var targetnode = $($this.attr('href'));
                if (targetnode) {
                    $('html, body').animate({
                        scrollTop: targetnode.offset().top
                    }, 500);
                    //focusfix for ie
                    targetnode.attr("tabindex", "-1");
                    targetnode.focus();
                }
            });
            
            $(".by-category").click(function () {
                var $this = $(this);
                if ($this.attr("aria-expanded") == "false") {
                    $this.attr("aria-expanded", "true");
                } else {
                    $this.attr("aria-expanded", "false");
                }
                $(".searchCategories").toggleClass("open");
                $(".by-category i").toggleClass("fa-plus");
                if (!$(".by-category i").hasClass("fa-plus")) {
                    $(".by-category i").addClass("fa-minus");
                } else {
                    $(".by-category i").removeClass("fa-minus");
                }
                return false;
            });

            /*search category filter*/
            $("aside.category-filters ul li.selected ul:first, aside.category-filters ul li.childSelected ul:first, aside.category-filters li.childSelected ul.childFacets li.childSelected ul.childFacets").show();

            /*search results category filters*/
            $('.category-filters h3:not(.desktopchoice)').on("click", function () {
                ToggleCategoryFilters();
            }).on('keypress', function (e) {
                e.preventDefault();
                if (e.key === "Enter") {
                    ToggleCategoryFilters();
                }
            });
            $('.category-filters .mobilechoicebtn').on("click", function () {
                ToggleCategoryFiltersSearch();
            }).on('keypress', function (e) {
                e.preventDefault();
                if (e.key === "Enter") {
                    ToggleCategoryFiltersSearch();
                }
            });
            var ToggleCategoryFiltersSearch = function () {
                $('.category-filters #filterchoicecontainer').toggleClass("open");
                if (!$(".category-filters .mobilechoicebtn span").hasClass("fa-minus")) {
                    $(".category-filters .mobilechoicebtn span").addClass("fa-minus");
                    $(".category-filters .mobilechoicebtn").attr("aria-expanded", "true");
                    var label = $(".category-filters .mobilechoicebtn").attr("aria-label");
                    label = label + ".";
                    $(".category-filters .mobilechoicebtn").attr("aria-label", label);
                } else {
                    $(".category-filters .mobilechoicebtn span").removeClass("fa-minus");
                    $(".category-filters .mobilechoicebtn").attr("aria-expanded", "false");
                    var label = $(".category-filters .mobilechoicebtn").attr("aria-label");
                    label = label.replace(".", "");
                    $(".category-filters .mobilechoicebtn").attr("aria-label", label);
                }
            };
            var ToggleCategoryFilters = function () {
                $('aside.category-filters #filterchoicecontainer').toggleClass("open");
                if (!$(".category-filters h3 span").hasClass("fa-minus")) {
                    $(".category-filters h3 span").addClass("fa-minus");
                    $(".category-filters h3:not(.desktopchoice)").attr("aria-expanded", "true");
                } else {
                    $(".category-filters h3 span").removeClass("fa-minus");
                    $(".category-filters h3:not(.desktopchoice)").attr("aria-expanded", "false");
                }
            };
            /*lexicon page a-o*/
            $('ul.indexes li a').click(function () {
                $(this).parent().siblings().removeClass("selected");
                $(this).parent().addClass("selected");
                //return false;
            });
            /*Login Auto-Focus*/
            $("section#login #UserName").focus();
            /*Cookies bar*/
            $('div.cookie-info').click(function () {
                $(this).slideUp();
            });
        };
    setUlHasOpen = function () {
        var firstul = $('header #pageMenu #MainNav');
        var listitems1 = firstul.find('> li');

        for (var i = 0; i < listitems1.length; i++) {
            var item = $(listitems1[i])
            if (item.hasClass('open')) {
                firstul.addClass('hasopen');
            }
            if (item.hasClass('has-subnav')) {
                var secondul = item.find('> .subnav > ul');
                var listitems2 = secondul.find('> li');

                for (var a = 0; a < listitems2.length; a++) {
                    var item2 = $(listitems2[a])
                    if (item2.hasClass('open')) {
                        secondul.addClass('hasopen');
                    }
                    if (item2.hasClass('has-subnav')) {
                        var thirdul = item2.find('> .subnav > ul');
                        var listitems3 = thirdul.find('> li');

                        for (var b = 0; b < listitems3.length; b++) {
                            var item3 = $(listitems3[b])
                            if (item3.hasClass('open')) {
                                thirdul.addClass('hasopen');
                                break;
                            }
                        }
                    }
                }
            }
        }
    };

    toggleMenuClick = function (el) {
        var li = el.closest('li');
        var ul = li.closest('ul');
        var anyliopen = ul.find('li.open:not(.selected)').length;
        var sibling = $(li.find('.subnav')[0]);
        if (li.hasClass('open')) {            
            li.removeClass('open');            
            //setTimeout(function () {                
            //    sibling.removeClass('shownav');
            //    //sibling.css('display', 'none');
            //}, 500);
            anyliopen--;
        } else {
            //sibling.css('display', 'flex');
            //sibling.addClass('shownav');  
            setTimeout(function () {                  
                ul.addClass('hasopen');
                li.addClass('open');  
            }, 200);
            anyliopen ++;
        }
        toggleExpandText(el.children("span:not(.border)"));
        toggleAriaExpanded(el);
        
        if (anyliopen > 0) {
            ul.addClass('hasopen');
        } else {
            ul.removeClass('hasopen');
        }
    };

    addAttributesDesktop = function () {
        var mobileSubNavLinks = $('.subnav ul a');
        var searchEl = $('#PageHead .searchToggle');
        if ($(window).width() < 767) {
            $.each(mobileSubNavLinks, function (idx, elem) {
                $(elem).attr("aria-hidden", "false");
            });
            searchEl.attr("aria-hidden", "false");
        }
    };
    return {
        initialize: initialize,
        toggleAriaExpanded: toggleAriaExpanded,
        toggleAriaHidden: toggleAriaHidden,
        toggleExpandText: toggleExpandText
    };
}();;livsmedelsverket = livsmedelsverket || {};

livsmedelsverket.Nkp = function () {

    var initialize = function () {
        setSelectionboxes();
        updateBlockListVisibility();
        operationalConditions();
        goalsAndActivitiesBlock();
        goalsAndActivitiesPageFilter();
        //nkpMobileMenu();
    };

    return {
        initialize: initialize
    };

    function setSelectionboxes() {

        var _legId;
        var _govId;
        var urlParams = new URLSearchParams(window.location.search);

        if (urlParams.has('legId')) {
            _legId = urlParams.get('legId');
            setSelectElement('legsislation', _legId)
        }

        if (urlParams.has('govId')) {
            _govId = urlParams.get('govId');
            setSelectElement('governmentAgency', _govId)
        }
        

    }
    function setSelectElement(id, valueToSelect) {
        let element = document.getElementById(id);
        element.value = valueToSelect;
        var eventObject = jQuery.Event("change"); // event you need to fire
        $(element).trigger(eventObject);
    }


    function operationalConditions() {
        var parent = $(".operational-conditions-section");

        $(".operational-conditions-section .content-toggle").on("click", function () {
            parent.toggleClass("expanded");
        });
    }

    function goalsAndActivitiesBlock() {
        $(".goalAndActivityBlock .expand").click(function () {
            var preview = $(this).parent(".preview");
            var mainContent = preview.siblings(".expanded-content");
            preview.hide();
            mainContent.show();
            setTimeout(function () {
                mainContent.addClass("show");
            }, 50);
        });
        $(".goalAndActivityBlock .minimize").click(function () {
            var mainContent = $(this).parent(".expanded-content");
            var preview = mainContent.siblings(".preview");
            mainContent.removeClass("show");
            setTimeout(function () {
                mainContent.hide();
                preview.show();
            }, 400);

        });
    }

    function goalsAndActivitiesPageFilter() {

        var legislationId = $(".goalAndActivity-filter-block #legsislation").val();
        var governmentAgencyId = $(".goalAndActivity-filter-block #governmentAgency").val();

        var state = {
            governmentAgencyId: parseInt(0 + governmentAgencyId),
            legislationId: parseInt(0 + legislationId)
        }

        $(".goalAndActivity-filter-block #legsislation").change(function (e) {
            
            var legislationId = $(".goalAndActivity-filter-block #legsislation").val();    
            setQueryVariable("legId", legislationId);
            updateBlockListVisibility();
        });

        $(".goalAndActivity-filter-block #governmentAgency").change(function (e) { 
            var governmentAgencyId = $(".goalAndActivity-filter-block #governmentAgency").val();
            setQueryVariable("govId", governmentAgencyId);
            updateBlockListVisibility();
        });
    }


    function setQueryVariable(_param, _value) {
        var searchParams = new URLSearchParams(window.location.search);
        var urlParams = new URLSearchParams(window.location.search);

        if (_param == 'govId' && urlParams.has('legId')) {
            var _legId = urlParams.get('legId');
            searchParams.set('legId', _legId);
        }

        if (_param == 'legId' && urlParams.has('govId')) {
            var _govId = urlParams.get('govId');
            searchParams.set('legId', _govId);
        }
        if (_value != '') {
            searchParams.set(_param, _value);
        }
        else {
            searchParams.delete(_param);
        }
        var refresh = window.location.protocol + "//" + window.location.host + window.location.pathname + '?' + searchParams.toString();
        window.history.pushState({ path: refresh }, '', refresh);
    }

    function shouldBeVisible(element, currentState) {
        var shouldShow = true;
        var elementBovernmentAgencyId = element.attr("data-agency");
        var elementLegislationId = parseInt(element.attr("data-legislation"));
        if (currentState.governmentAgencyId && elementBovernmentAgencyId.indexOf(currentState.governmentAgencyId) < 0) {
            shouldShow = false;
        }
        if (currentState.legislationId && currentState.legislationId !== elementLegislationId) {
            shouldShow = false;
        }
        return shouldShow;
    }

    function updateBlockListVisibility() {
        var _legId;
        var _govId;
        var urlParams = new URLSearchParams(window.location.search);

        if  (urlParams.has('legId')) {
            _legId = urlParams.get('legId');           
        }

        if (urlParams.has('govId')) {
            _govId = urlParams.get('govId');
        }
        var state = {
            governmentAgencyId: parseInt(0 + _govId),
            legislationId: parseInt(0 + _legId)
        }

        var noResult = true;
        $(".goalAndActivityBlock").each(function () {
            var me = $(this);
            if (shouldBeVisible(me, state)) {
                noResult = false;
                me.show();
            }
            else {
                me.hide();
            }
        });
        $(".emptyResult").css("display", noResult ? "block" : "none")
    }

    //function nkpMobileMenu() {
    //    //Remove stuff that should not be in the NKP menu
    //    removeNonNkpStuff();

    //    //find the menu
    //    var $nkpMenu = $("li.nkpContext");
    //    //Add resize listener to only do stuff while in mobile
    //    if ($(".nkpContext")[0]) {
    //        window.addEventListener('resize', function () {
    //            //breakpoint for mobile
    //            if (window.innerWidth < 768) {
    //                //menu is already opened?
    //                if ($nkpMenu.hasClass("selected")) {
    //                    $nkpMenu.addClass("noIcon");
    //                } else {
    //                    $nkpMenu.addClass("selected noIcon");
    //                }
    //            } else {
    //                $nkpMenu.removeClass("selected noIcon");
    //            }
    //        }, true);
    //        var event = document.createEvent("event");
    //        event.initEvent("resize", false, true);
    //        window.dispatchEvent(event);
    //    }

    //    function removeNonNkpStuff() {
    //        if ($(".nkpContext")[0]) {
    //            try {
    //                $(".supportMenu").closest(".container").remove();
    //            } catch (e) {
    //                console.log("missed non-nkp stuff");
    //            }
    //        }
    //    }
    //}
}();
;livsmedelsverket = livsmedelsverket || {};

livsmedelsverket.Publication = function () {
    // add all the elements inside modal which you want to make focusable
    var focusableElements =
        'button, [href], input:not([disabled]), select, textarea, [tabindex]:not([tabindex="-1"])';
    var pubmodal = document.querySelector('#pubModal');
    var pubmodalhtml = document.querySelector('#pubModal .htmlpublication');
    if (!pubmodal | !pubmodalhtml) { return; }
    var firstFocusableElement = pubmodalhtml.querySelectorAll(focusableElements)[0];
    var focusableContent = pubmodal.querySelectorAll(focusableElements);
    var lastFocusableElement = focusableContent[focusableContent.length - 1];
    var bind = function () {

        $('.showpub').on('click', function () {
            showPub();
            livsmedelsverket.PublicationMenu.createOrUpdateProgressBarLinks();
        });
        $('.pub-icon-button.close button').on('click', function () {
            $('#pubModal').hide();
            $('body').removeClass('puboverlay');
            $('.scroll-to-last').hide();
            $('.toc-nav.close button').click();
            removeUrlParameter("pub");
            $('html, body').animate({
                scrollTop: 0
            }, 0);
            $("#progressBar .pbarlink.active").removeClass('active');
        });
        $('.toc-nav button').on('click', function () {
            var $this = $(this);
            toggleToc();
            livsmedelsverket.Expand.toggleAriaExpanded($this);
            livsmedelsverket.Expand.toggleAriaLabel($this, "Dölj innehållsförteckning", "Öppna innehållsförteckning");
            toggleText($this.find('.text'), "Innehållsförteckning", "Dölj");
        });
        $('.scroll-to-last button').on('click', function () {
            var scrollheight = $(this).data('scroll');
            if (scrollheight) {
                scrollToHeight(scrollheight);
            }
            $('.scroll-to-last').hide();
        });

        $(document).on('keydown', function (e) {
            let isTabPressed = e.key === 'Tab' || e.keyCode === 9;

            if (!isTabPressed) {
                return;
            }

            if (!isHidden(pubmodal)) {
                if (e.shiftKey) { // if shift key pressed for shift + tab combination
                    if (document.activeElement === firstFocusableElement) {
                        lastFocusableElement.focus();
                        e.preventDefault();
                    }
                } else { // if tab key is pressed
                    if (document.activeElement === lastFocusableElement) {
                        firstFocusableElement.focus();
                        e.preventDefault();
                    }
                }
            }
        });
    },
        showPub = function () {
            $('#pubModal').show();
            $('body').addClass('puboverlay');
            $('.toc-nav button').focus();
            //var progresspercent = livsmedelsverket.cookieconsent.getCookie('pubprogress');
            //if (progresspercent && progresspercent > 0) {
            //    var height = $(document).height();
            //    var scrollheight = height * (progresspercent / 100);
            //    $('.scroll-to-last button').data('scroll', scrollheight);
            //    $('.scroll-to-last').show();
            //}
            document.body.scrollTop = 0; // For Safari
            document.documentElement.scrollTop = 0;
            setUrlParameter("pub", "show");


        },
        scrollToHeight = function (height) {
            $('html, body').animate({
                scrollTop: height
            }, 800);
        },
        isHidden = function (el) {
            var style = window.getComputedStyle(el);
            return (style.display === 'none')
        },
        toggleToc = function () {
            if ($('#pubModal').hasClass('pub-toc-expanded')) {
                $('#pubModal').removeClass('pub-toc-expanded');
                firstFocusableElement = pubmodalhtml.querySelectorAll(focusableElements)[0];
            } else {
                $('#pubModal').addClass('pub-toc-expanded');
                firstFocusableElement = pubmodal.querySelectorAll(focusableElements)[0];
            }

            if ($('#pub-toc').hasClass('hidden')) {
                $('#pub-toc').removeClass('hidden');
                $('#pub-toc a').first().focus();
            } else {
                $('#pub-toc').addClass('hidden');
            }

            if ($('.toc-nav').hasClass('closetoc')) {
                $('.toc-nav').removeClass('closetoc');
            } else {
                $('.toc-nav').addClass('closetoc');
            }

        },
        toggleText = function (el, text1, text2) {
            if (el.text() == text1) {
                el.text(text2);
            } else {
                el.text(text1);
            }
        };
    getUrlParameter = function (sParam) {
        var sPageURL = window.location.search.substring(1),
            sURLVariables = sPageURL.split('&'),
            sParameterName,
            i;

        for (i = 0; i < sURLVariables.length; i++) {
            sParameterName = sURLVariables[i].split('=');

            if (sParameterName[0] === sParam) {
                return sParameterName[1] === undefined ? true : decodeURIComponent(sParameterName[1]);
            }
        }
        return false;
    },
        setUrlParameter = function (sParam, sValue) {
            var sPageURL = window.location.search.substring(1),
                sUrl = window.location.href.split('?')[0],
                sURLVariables = sPageURL.split('&'),
                sParameterName,
                i;

            for (i = 0; i < sURLVariables.length; i++) {
                sParameterName = sURLVariables[i].split('=');

                if (sParameterName[0] === sParam) {
                    sParameterName[1] === sValue;
                    return;
                }
            }
            if (sPageURL) {
                window.history.pushState("", "", sUrl + '?' + sPageURL + '&' + sParam + '=' + sValue);
            } else {
                window.history.pushState("", "", sUrl + '?' + sParam + '=' + sValue);
            }
        },
        removeUrlParameter = function (sParam) {
            var sPageURL = window.location.search.substring(1),
                sUrl = window.location.href.split('?')[0],
                sURLVariables = sPageURL.split('&'),
                sParameterName,
                i;

            for (i = 0; i < sURLVariables.length; i++) {
                sParameterName = sURLVariables[i].split('=');

                if (sParameterName[0] === sParam) {
                    sURLVariables.splice(i, sParameterName[0].length);
                }
            }
            var params = sURLVariables.join('&');
            if (params) {
                window.history.pushState("", "", sUrl + '?' + params);
            } else {
                window.history.pushState("", "", sUrl);
            }


        },
        setProgressBar = function () {
            var windScroll = $(window).scrollTop();
            var headerOffset = $('.pub-header-inner-wrap').outerHeight()+5 || 0;
            var height = document.documentElement.scrollHeight - document.documentElement.clientHeight;
            var scrolled = ((windScroll+headerOffset) / height) * 100;
            document.getElementById("progressBar").style.width = scrolled + "%";
        }
    initialize = function () {
        //new wordintegration
        bind();
        if (getUrlParameter("pub") == "show") {
            showPub();
        }
        $(document).scroll(function () {
            setProgressBar();
            var scrollDistance = $(this).scrollTop();
            var $pubheader = $('.pub-header');

            if (scrollDistance > 300 && $('#pubModal').is(':visible')) {
                var progress = (scrollDistance / $(this).height()) * 100;
                $('.scroll-to-last').fadeOut();
                //livsmedelsverket.cookieconsent.setCookie('pubprogress', progress);
            } else if ($('#pubModal').is(':visible')) {
                //livsmedelsverket.cookieconsent.setCookie('pubprogress', '0');
            }


            if (scrollDistance > 39 && $pubheader) {
                if (!$pubheader.hasClass('pub-header-sticky')) {
                    $pubheader.addClass('pub-header-sticky')
                }
                if (!$('#pubModal').hasClass('pub-sticky')) {
                    $('#pubModal').addClass('pub-sticky');
                }
            } else {
                if ($pubheader.hasClass('pub-header-sticky')) {
                    $pubheader.removeClass('pub-header-sticky')
                }
                if ($('#pubModal').hasClass('pub-sticky')) {
                    $('#pubModal').removeClass('pub-sticky');
                }
            }
            if (scrollDistance > 79 && $pubheader) {
                if (!$pubheader.hasClass('pub-header-shadow')) {
                    $pubheader.addClass('pub-header-shadow')
                }
            } else {
                if ($pubheader.hasClass('pub-header-shadow')) {
                    $pubheader.removeClass('pub-header-shadow')
                }
            }
        });
        var cookIIC = $.cookie("itincart");
        if (cookIIC != null && cookIIC != "") {
            var res = cookIIC.split(",");
        }
        $('.ltsc').click(function () {
            if (numOfItemsInCart == 0) {
                $.cookie("itincart", this.id, { path: '/' });
            }
            else {
                $.cookie("itincart", $.cookie("itincart") + "," + this.id);
            }
            return true;
        });

        $('.print-button').click(function () {
            let userAgentString = navigator.userAgent;
            let firefoxAgent = userAgentString.indexOf("Firefox") > -1;

            if (firefoxAgent === true) {
                if (confirm('Den här utskriftsfunktionen är inte optimerad för Firefox webbläsare. Texten kan bli något kapad vid enstaka sidbrytningarna. Det går fortfarande att skriva ut om du trycker OK.')) {
                    window.print();
                }
            }
            else {
                window.print();
            }
        });

        $(document).ready(function () {
            const $container = $('#pubModal .htmlpublication');

            const colorGroups = [
                { group: '.heading-turquoise, .preamble-turquoise, .list-turquoise', blockClass: 'turquoise-block' },
                { group: '.heading-blue, .preamble-blue, .list-blue', blockClass: 'blue-block' },
                { group: '.heading-pink, .preamble-pink, .list-pink', blockClass: 'pink-block' },
                { group: '.heading-orange, .preamble-orange, .list-orange', blockClass: 'orange-block' },
                { group: '.heading-purple, .preamble-purple, .list-purple', blockClass: 'purple-block' },
                { group: '.heading-green, .preamble-green, .list-green', blockClass: 'green-block' }
            ];

            // Iterate over each color group
            colorGroups.forEach(function (colorGroup) {
                $container.find(colorGroup.group).each(function () {
                    const $startElement = $(this);
                    // If the parent does not already have the color block class
                    if (!$startElement.closest('.' + colorGroup.blockClass).length) {
                        // Select all the elements in the same group
                        const $groupElements = $startElement
                            .add($startElement.nextUntil(':not(' + colorGroup.group + ')')
                                .addBack()); // Includes the starting element and all subsequent until the next group

                        // Wrap all these elements in a div with the specific color block class
                        $groupElements.wrapAll('<div class="' + colorGroup.blockClass + '"></div>');
                    }
                });
            });
        });

    };
    return {
        initialize: initialize
    };
}();;livsmedelsverket = livsmedelsverket || {};

livsmedelsverket.PublicationMenu = function () {
   
    var createOrUpdateProgressBarLinks = function () {
        var $progressbar = $("#progressBar");
        var $progressbarDivs = $("#progressBar > div");

        // Avoid unnecessary update if the last link is already correctly positioned
        if ($progressbarDivs.length > 0 && $($progressbarDivs[$progressbarDivs.length - 1]).css('left') !== '-3px') {
            return;
        }
        $progressbar.empty(); // Clear previous progress links

        // Loop through each anchor link in the table of contents
        $('#pub-toc .toc1 > li a[href^="#"]').each(function () {
            var $this = $(this);
            var href = $this.attr('href');
            var target = $('.publicationarea [id=' + href.replace('#', '') + ']');

            if (target.length > 0) {
                var h2target = target.is('h2') ? target : target.closest('h2');
                if (h2target.length > 0) {
                    var targetScroll = h2target.offset().top;
                    var height = $(document).height() - $(window).height();
                    var targetpos = (targetScroll / height) * 100;

                    $progressbar.append("<div class='pbarlink' style='left:calc(" + targetpos + "% - 3px)'>" +
                        "<a href='" + href + "'><span class='sr-only'>" + h2target.text() + "</span></a>" +
                        "<div class='progresstt'>" + h2target.text() + "</div>" +
                        "</div>");
                }
            }
        });
    },
    initialize = function () {
        $scrollToTop = $('.scroll-to-top');

        var anchorLink = $('#pub-toc .toc1 > li a[href^="#"]');
        
        $('a[href*="#_"]').each(function () {
            $this = $(this);
            var text = decodeEntities($this.text());
            text = text.replace('\t', ' ');

            //add nocount class if text dont start with number
            if (!hasNumber(text.substring(0, 1))) {
                $this.addClass('nocount');
            }
            var array = text.split(' ');
            // console.log(array);
            var i;

            if (!menuNumbers) {
                //To make numbering in the menu work
                for (i = 0; i < array.length; i++) {
                    //remove if first part is a number
                    if ((i == 0) && isNumeric(array[i])) {
                        array.splice(i, 1);
                    }
                }
            }            
            
            $this.text(array.join(' '));
        });
        createOrUpdateProgressBarLinks();
        // Initialize expand/collapse buttons for TOC
        $('.toc2, .toc3, .toc4').each(function () {
            var $this = $(this);
            var li = $this.prev();
            var linktext = li.find('a').text();
            li.addClass("expand");
            li.append("<button class='expandbtn' aria-expanded='false' aria-label='Undermeny för " + linktext + ".'></button>");
        });

        function decodeEntities(encodedString) {
            var textArea = document.createElement('textarea');
            textArea.innerHTML = encodedString;
            return textArea.value;
        }
        function isNumeric(n) {
            return !isNaN(parseFloat(n)) && isFinite(n);
        }
        function hasNumber(myString) {
            return /\d/.test(myString);
        }
        function upDateAriaLabel(el) {
            var arialabel = el.attr('aria-label');
            if (arialabel.indexOf(".") == arialabel.length - 1) {
                arialabel = arialabel.replace(".", "");
            } else {
                arialabel = arialabel + ".";
            }
            el.attr('aria-label', arialabel)
        }
        $('.expand button').on('click', function () {
            var $this = $(this);
            var ultoexpand = $this.parent().next();
            var shouldopen = true;
            if (ultoexpand.hasClass('open')) {
                shouldopen = false;
            }
            
            if ($this.hasClass('exp-toc2')) {
                $('.expandbtn.exp-toc2').each(function () {
                    $(this).attr('aria-expanded', 'false')
                    upDateAriaLabel($(this));
                });
                $('.toc2').each(function () {
                    $(this).removeClass('open');
                    $(this).slideUp("slow");
                });
            }
            if (shouldopen) {
                ultoexpand.addClass('open');
                ultoexpand.slideDown("slow");
                $this.attr('aria-expanded', 'true')
                upDateAriaLabel($this);
            } else {
                ultoexpand.removeClass('open');
                ultoexpand.slideUp("slow");
                $this.attr('aria-expanded', 'false')
                upDateAriaLabel($this);
            }
        });
        $('.js-scroll-trigger').on('click', function () {
            $('html, body').animate({
                scrollTop: 0
            }, 800);
        });

        $(document).scroll(function () {
            var windscroll = $(window).scrollTop();
            var headerOffset = $('.pub-header-inner-wrap').outerHeight()+5 || 0;

            if (windscroll >= 1) {
                $('.publicationarea > h2').each(function (i) {
                    if ($(this).offset().top <= windscroll + headerOffset) {
                        $('#pub-toc .toc1 > li a[href^="#"].active').removeClass('active');
                        anchorLink.eq(i).addClass('active');
                        $("#progressBar .pbarlink").eq(i).addClass('active');
                    } else {
                        $("#progressBar .pbarlink").eq(i).removeClass('active');
                    }
                });
            } else {
                $('#pub-toc .toc1 > li a[href^="#"].active').removeClass('active');
            }
        });
        $(document).on('click', 'a[href^="#"]:not(.js-scroll-trigger)', function (event) {
            event.preventDefault();
            var headerOffset = $('.pub-header-inner-wrap').outerHeight() || 0;

            if (window.matchMedia('(max-width: 1199px)').matches) {
                $('.toc-nav.close button').click();
            }

            //scroll smooth to element width offset for header height
            $('html, body').animate({
                scrollTop: $($.attr(this, 'href')).offset().top - headerOffset
            }, 500);
            $($.attr(this, 'href')).attr('tabindex','-1').focus();
        });

        window.addEventListener("beforeprint", (event) => {
            // Dynamically add print-menu
            var printMenu = $('#pub-toc .toc-container').clone();

            // Append the new content to #print-menu
            $('#print-menu').append(printMenu);
        });
        window.addEventListener("afterprint", (event) => {
            // empty the print-menu after printing
            $('#print-menu').empty();
        });
    };
    return {
        initialize: initialize,
        createOrUpdateProgressBarLinks: createOrUpdateProgressBarLinks
    };
}();;livsmedelsverket = livsmedelsverket || {};

livsmedelsverket.Publications = function () {
    var numOfItemsInCart = 0;
    var initialize = function () {
        var cookIIC = $.cookie("itincart");
        if (cookIIC != null && cookIIC != "") {
            var res = cookIIC.split(",");
        }

        var filterbutton = $('.filterbutton');
        var clearfilterbtn = $('.clearfilter');
        var $topicBtn = $('div.pubFacets .expand-btn.topic');
        var $yearBtn = $('div.pubFacets .expand-btn.year');
        var $typeBtn = $('div.pubFacets .expand-btn.type');

        $(document).mouseup(function (e) {
            if (!$topicBtn.is(e.target) // if the target of the click isn't the container...
                && $topicBtn.parent().parent().has(e.target).length === 0) // ... nor a descendant of the container
            {
                $topicBtn.removeClass('expanded');
                var label = $topicBtn.attr('aria-label');
                label = label.replace(".","");
                $topicBtn.attr('aria-label', label);
                $topicBtn.parent().next().hide();
                $topicBtn.attr("aria-expanded", "false");
            }
            if (!$yearBtn.is(e.target) // if the target of the click isn't the container...
                && $yearBtn.parent().parent().has(e.target).length === 0) // ... nor a descendant of the container
            {
                $yearBtn.removeClass('expanded');
                var label = $yearBtn.attr('aria-label');
                label = label.replace(".", "");
                $yearBtn.attr('aria-label', label);
                $yearBtn.parent().next().hide();
                $yearBtn.attr("aria-expanded", "false");
            }
            if (!$typeBtn.is(e.target) // if the target of the click isn't the container...
                && $typeBtn.parent().parent().has(e.target).length === 0) // ... nor a descendant of the container
            {
                $typeBtn.removeClass('expanded');
                var label = $typeBtn.attr('aria-label');
                label = label.replace(".", "");
                $typeBtn.attr('aria-label', label);
                $typeBtn.parent().next().hide();
                $typeBtn.attr("aria-expanded", "false");
            }
        });
        $('.filteritems').on('mouseover', '.removeitem', function () {
            var $this = $(this);
            $this.parent().addClass('hover');
        });
        $('.filteritems').on('mouseout', '.removeitem',  function () {
            var $this = $(this);
            $this.parent().removeClass('hover');
        });

        $('div.pubFacets .expand-btn').click(function (e) {
            e.preventDefault();
            if ($(this).hasClass("expanded")) {
                $(this).removeClass("expanded");
                var arialabel = $(this).attr('aria-label');
                arialabel = arialabel.replace(".", "");
                $(this).attr('aria-label', arialabel);
                $(this).parent().next().hide();
                $(this).attr("aria-expanded", "false");
            }
            else {
                $(this).addClass("expanded");
                var arialabel = $(this).attr('aria-label');
                arialabel = arialabel + ".";
                $(this).attr('aria-label', arialabel);
                $(this).parent().next().show();
                $(this).attr("aria-expanded", "true");
            }
        });

        $('div.pubFacets input').click(function () {
            var name = $(this).attr('name');
            var value = $(this).attr('value');
            var filterbox = $('.filteritems');

            if (this.checked == false) {
                if (this.id.indexOf('Alla') > -1) {
                    $('div.pubFacets input[name="' + name + '"]').each(function (index, el) {
                        $(el).attr("checked", null);
                        filterbox.find('.filteritem[data-name="' + name + '"]').remove();
                    });
                }
                else {
                    $('div.pubFacets input[id="' + name + 'Alla"]').attr("checked", null);
                    if (value) {
                        filterbox.find('.filteritem[data-value="' + value + '"]').remove();
                    }
                }
                if (filterbox.find('.filteritem').length < 1 && !filterbutton.hasClass('hidden')) {
                    filterbutton.addClass('hidden');
                    clearfilterbtn.addClass('hidden');
                }
                return;
            }

            if (this.id.indexOf('Alla') > -1) {
                $('div.pubFacets input[name="' + name + '"]').each(function (index, el) {
                    value = $(el).attr('value');
                    if (value && value != "Alla" && filterbox.find('.filteritem[data-value="' + value + '"]').length < 1) {
                        $(el).prop("checked", true);
                        filterbox.append('<div class="filteritem" data-name="' + name + '" data-value="' + value + '">' + value + '<div class="removeitem" role="button" tabindex="0"><span class="fa fa-times" aria-hidden="true"></span><span class="sr-only">Ta bort filter ' + value + '</span></div></div>');
                    }
                });
            }
            else {
                $('div.pubFacets input[id="' + name + 'Alla"]').attr("checked", null);
                if (value && value != "Alla" && filterbox.find('.filteritem[data-value="' + value + '"]').length < 1) {
                    filterbox.append('<div class="filteritem" data-name="' + name + '" data-value="' + value + '">' + value + '<div class="removeitem" role="button" tabindex="0"><span class="fa fa-times" aria-hidden="true"></span><span class="sr-only">Ta bort filter ' + value + '</span></div></div>');
                }
            }
            if (filterbutton.hasClass('hidden')) {
                filterbutton.removeClass('hidden');
            }
            if (clearfilterbtn.hasClass('hidden')) {
                clearfilterbtn.removeClass('hidden');
            }
        });
        $('.filteritems').on('click', '.removeitem', function () {
            RemoveItem($(this));
        }).on('keypress', '.removeitem', function (e) {
            if (e.key === "Enter") {
                RemoveItem($(this));
            }
        });

        var RemoveItem = function ($this) {
            var filterbox = $('.filteritems');
            var value = $this.parent().data('value');
            var name = $this.parent().data('name');
            filterbox.find('.filteritem[data-value="' + value + '"]').remove();
            $('div.pubFacets input[value="' + value + '"]').attr("checked", null);
            $('div.pubFacets input[id="' + name + 'Alla"]').attr("checked", null);
            if (filterbox.find('.filteritem').length < 1 && !filterbutton.hasClass('hidden')) {
                filterbutton.addClass('hidden');
                clearfilterbtn.addClass('hidden');
                $('.productlistform').submit();
            }
        };
        clearfilterbtn.on('click', function (e) {
            e.preventDefault();
            var filterbox = $('.filteritems');
            $('div.pubFacets input').each(function (index, el) {
                $(el).attr("checked", null);
                var name = $(el).attr('name');
                filterbox.find('.filteritem[data-name="' + name + '"]').remove();
            });
            $('.productlistform').submit();
        });

        $('div.rs_ski a').click(function () {
            if ($(".topCart").attr("src").indexOf("gray") > -1) {
                $.cookie("itincart", this.id, { path: '/' });
            }
            else {
                $.cookie("itincart", $.cookie("itincart") + "," + this.id);
            }
            return true;
        });

    };

    
    return {
        initialize: initialize
    };
}();;livsmedelsverket = livsmedelsverket || {};

livsmedelsverket.response = function () {
    var initialize = function () {
        if (Response) {
            Response.create({
                prop: "width",
                breakpoints: [0, 320, 768, 992],
                dynamic: true,
                prefix: "src"
            });
        }
    };
    return {
        initialize: initialize
    };
}();


;    livsmedelsverket = livsmedelsverket || {};
	
    livsmedelsverket.Slider = function () {
		var initialize = function () {
			//pick a random slide for each page load.
		    var slides = $('.slide').toArray();
            var size = slides.length;

		    var x = Math.floor(size * Math.random()); //move random inside loop
		    $(slides[x]).children('a').removeClass('hidden');
		};
		return {
			initialize: initialize
		};
    }();;livsmedelsverket = livsmedelsverket || {};

livsmedelsverket.tabfocus = function() {
    var initialize = function () {
        tabfocuslistener();
        alertMessagesOnLoad();
        progressFocus();
    },
        tabfocuslistener = function () {
            function handleFirstTab(e) {
                if (e.keyCode === 9) {
                    document.body.classList.add('tab');

                    window.removeEventListener('keydown', handleFirstTab);
                    window.addEventListener('mousedown', handleMouseDownOnce);
                }
            }

            function handleMouseDownOnce() {
                document.body.classList.remove('tab');

                window.removeEventListener('mousedown', handleMouseDownOnce);
                window.addEventListener('keydown', handleFirstTab);
            }

            window.addEventListener('keydown', handleFirstTab);
        },
        //make message in role="alert" container to update and get read by screenreaders when page is loaded
        alertMessagesOnLoad = function () {
            setTimeout(function () {
                var messagecontainers = $('.js-onload-alert');
                if (!messagecontainers) { return }
                messagecontainers.each(function () {
                    var $this = $(this);
                        var text = $this.text();
                        if (text[text.length - 1] == ".") {
                            $this.text(text.substring(0, text.length - 1));
                        } else {
                            $this.text(text + '.');
                        }
                    
                });
            }, 500);
            
        }

        //make episerver forms progressbar focusable
    progressFocus = function () {
        var progressbar = $('.Form__NavigationBar__ProgressBar');
        if (!progressbar) { return }
        progressbar.attr('tabindex', '0');
    }

    
    return {
        initialize: initialize
    };
}();;    livsmedelsverket = livsmedelsverket || {};
	
    livsmedelsverket.Tables = function () {
		var initialize = function () {

		    $(".rs_content").wrap("<div tabindex=0 class='tableWrapper'></div>");

			$(".facility-listing").tablesorter().wrap("<div tabindex=0 class='tableWrapper'></div>");
	
		};
		return {
			initialize: initialize
		};
    }();;    livsmedelsverket = livsmedelsverket || {};
	
livsmedelsverket.wellsubstance = function () {
    var paramname = "filter",
        count = 0;
        initialize = function () {

            $('.substanceFilter input[type="checkbox"]:checked').each(function () {
                var name = this.id;
                var value = $(this).val();
                var item = $('div[data-filterid=' + value + ']');
                if (item.hasClass("show")) {
                    item.removeClass('show');
                    if (count <= 1) { count = 0 } else { count--; }
                } else {
                    item.addClass('show');
                    count++;
                }
                setText(name);
            });
            function setText(name, clicked) {
                if (clicked) {
                    $('#listfilterid').addClass('highlight');
                    setTimeout(function () {
                        $('#listfilterid').removeClass('highlight');
                    }, 200);
                }
                if (count == 1) {
                    $('.plural').removeClass('show');
                    $('.singular').addClass('show');
                } else {
                    $('.plural').addClass('show');
                    $('.singular').removeClass('show');
                }
                $('.listcount').html(count);
                var nameslist = $('.nameslist').text();
                if (nameslist.indexOf(name) >= 0) {
                    var array = nameslist.split(',');
                    array.splice(array.indexOf(name), 1);

                    nameslist = array.join(',');
                    
                } else {
                    if (!nameslist.length) {
                        nameslist += name;
                    } else {
                        nameslist += "," + name;
                    }
                }
                $('.nameslist').text(nameslist);
            }

            function insertParam(key, value, add) {
                key = encodeURIComponent(key);
                value = encodeURIComponent(value);

                // kvp looks like ['key1=value1', 'key2=value2', ...]
                var kvp = [];
                if (document.location.search.substr(1).indexOf('&') >= 0) {
                    kvp = document.location.search.substr(1).split('&');
                } else if (document.location.search.substr(1)) {
                    kvp = [document.location.search.substr(1)];
                }
                var novalues = false;
                var i = 0;

                for (; i < kvp.length; i++) {
                    if (kvp[i].indexOf(key + '=') >= 0) {
                        var pair = kvp[i].split('=');
                        if (add && pair[1].indexOf(value) == -1) {
                            if (pair[1] == "") {
                                pair[1] += value;
                            } else {
                                pair[1] += "," + value;
                            }
                        } else if (!add && pair[1].indexOf(value) >= 0) {
                            var values = pair[1].split(',');
                            values.splice(values.indexOf(value), 1);
                            pair[1] = values.join(',');
                            novalues = values.length == 0;
                        }

                        kvp[i] = pair.join('=');
                        break;
                    }
                }

                if (i >= kvp.length) {
                    kvp[kvp.length] = [key, value].join('=');
                }
                var params = '?' + kvp.join('&');
                if (novalues) {
                    params = "";
                }


                const refresh = window.location.protocol + "//" + window.location.host + window.location.pathname + params;
                window.history.pushState({ path: refresh }, '', refresh);
            }

            //Bind
            $(".substanceFilter .clear").click(function () {
                $('.substanceFilter input[type="checkbox"]').each(function () {
                    var $this = $(this);
                    if ($this.prop('checked')) {
                        $this.prop('checked', false);
                        $this.change();
                    } 
                    
                });
                return false;
            });
            $(".substanceFilter .markall").click(function () {
                $('.substanceFilter input[type="checkbox"]').each(function () {
                    var $this = $(this);
                    if (!$this.prop('checked')) {
                        $this.prop('checked', true);
                        $this.change();
                    }
                });
                return false;
            });
            $(".substanceFilter .toggle").click(function () {
                var $this = $(this);
                $this.parent().parent().toggleClass("closed");
                $this.children("span").toggleClass("fa-plus").toggleClass("fa-minus");
                if ($this.attr("aria-expanded") == "true") {
                    $this.attr("aria-label", "Expandera");
                } else {
                    $this.attr("aria-label", "Minifiera");
                }
                livsmedelsverket.Navigation.toggleAriaExpanded($this);
                livsmedelsverket.Navigation.toggleAriaHidden($this.parent().siblings(".filtercontent"));
                return false;
            });

            $('.substanceFilter input[type="checkbox"]').bind('change', function (v) {
                var name = this.id;
                var value = $(this).val();
                var item = $('div[data-filterid=' + value + ']');
                if (item.hasClass("show")) {
                    item.removeClass('show');
                    if (count <= 1) { count = 0 } else { count--;}
                    insertParam(paramname, name.toLowerCase(), false);
                } else {
                    item.addClass('show');
                    count++;
                    insertParam(paramname, name.toLowerCase(), true);
                }
                setText(name,true);
            });
        };
		return {
			initialize: initialize
		};
    }();;livsmedelsverket = livsmedelsverket || {};

livsmedelsverket.WorkRooms = function() {
    var initialize = function () {
            $(".workRooms-list#workRooms, .workRooms-start#workRooms, .workRooms-documents#workRooms, " +
                ".workRooms-forum#workRooms, .workRooms-members#workRooms, .workRooms-calendar#workRooms").on("click", "form.applyMembership input", function (e) {
                e.preventDefault();
                var element = $(this).closest("form");
                var target = $(element).closest(".row");
                formSubmit(element, target);
            });

            var dateToday = new Date();

            $(".datepicker").each(function () {
                $(this).datepicker({ minDate: dateToday });
                $(this).datepicker("option", "dateFormat", "yy-mm-dd");
                $(this).datepicker('setDate', $(this).attr("value"));
            });

            var myForm = $('#createCaseForm');
            if (myForm.length < 1) {
                myForm = $('#newforumtopicform');
            }
            if (myForm.length < 1) {
                myForm = $('#replyforumtopicform');
            }
            if (myForm.length < 1) {
                myForm = $('#createworkroompageform');
            }
            if (myForm.length < 1) {
                myForm = $('#createnewsentryform');
            }
        
            if (myForm.length && $.data(myForm[0], 'validator')) {
                $.data(myForm[0], 'validator').settings.ignore = "null";
            }
        
            tinymce.init({
                selector: ".js-html-text-area",
                theme: "modern",
                menubar: false,
                setup: function (editor) {
                    editor.on('keyUp', function () {
                        tinyMCE.triggerSave();

                        if (!$.isEmptyObject(myForm.validate().submitted))
                            myForm.validate().form();
                    });
                },
                plugins: [
                    "advlist autolink lists link image charmap preview hr anchor pagebreak",
                    "searchreplace wordcount visualblocks visualchars code fullscreen",
                    "insertdatetime media nonbreaking save table contextmenu directionality",
                    "template paste textcolor autoresize"
                ],
                toolbar1: "insertfile undo redo | bold italic | bullist numlist | link image | preview media",
                autosave_ask_before_unload: false,
                language: livsmedelsverket.globalVariables.tinyMCELang
            });

            attachEventHandlers();

        },
        attachEventHandlers = function () {

            $('#joinWorkroom').on('click', function (e) {
                e.preventDefault();
                var target = $(this).closest("p");
                var url = $(this).attr("href");
                $.ajax({
                    type: "POST",
                    url: url,
                    dataType: "json",
                    success: function (data) {
                        if (data.success == true) {
                            location.reload();
                        } else {
                            target.html(data.text);
                        }
                    },
                    error: function (error) {
                        alert('error: ' + eval(error));
                    }
                });
            });

            // Forum
            
            $('#newnewsentrysubmit').on('click', function (e) {
                e.preventDefault();
                var $form = $('#createnewsentryform');
                if ($form.valid()) {
                    var $submitbutton = $(this);
                    $submitbutton.attr('disabled', 'disabled');
                    $submitbutton.append('<span class="formsubmit fa fa-spinner fa-spin"></span>');
                    $form.submit();
                }
            });
            $('#createcasesubmit').on('click', function (e) {
                e.preventDefault();
                var $form = $('#createCaseForm');
                if ($form.valid()) {
                    var $submitbutton = $(this);
                    $submitbutton.attr('disabled', 'disabled');
                    $submitbutton.append('<span class="formsubmit fa fa-spinner fa-spin"></span>');
                    $form.submit();
                }
            });
            $('#createworkroomsubmit').on('click', function (e) {
                e.preventDefault();
                var $form = $('#createworkroompageform');
                if ($form.valid()) {
                    var $submitbutton = $(this);
                    $submitbutton.attr('disabled', 'disabled');
                    $submitbutton.append('<span class="formsubmit fa fa-spinner fa-spin"></span>');
                    $form.submit();
                }
            });
            $('#replyforumsubmit').on('click', function (e) {
                e.preventDefault();
                var $form = $('#replyforumtopicform');
                if ($form.valid()) {
                    var $submitbutton = $(this);
                    $submitbutton.attr('disabled', 'disabled');
                    $submitbutton.append('<span class="formsubmit fa fa-spinner fa-spin"></span>');
                    $form.submit();
                }
            });
            
            $('#createtopicsubmit').on('click', function (e) {
                e.preventDefault();
                var $form = $('#newforumtopicform');
                if ($form.valid()) {
                    var $submitbutton = $(this);
                    $submitbutton.attr('disabled', 'disabled');
                    $submitbutton.append('<span class="formsubmit fa fa-spinner fa-spin"></span>');
                    $form.submit();
                }
            });

            $('.js-edit-topicreply-dialog-trigger').on('click', function (e) {
                $(this).closest(".thread-item").find('.js-edit-topicreply-dialog').modal({
                    show: true
                });
            });

            $('.js-edit-topic-dialog-trigger').on('click', function (e) {
                $(this).closest(".topic").find('.js-edit-topic-dialog').modal({
                    show: true
                });
            });

            $('.js-report-topicreply-dialog-trigger').on('click', function (e) {
                $(this).closest(".thread-item").find('.js-report-topicreply-dialog').modal({
                    show: true
                });
            });

            $('.js-delete-topicreply-dialog-trigger').on('click', function (e) {
                $(this).closest(".thread-item").find('.js-delete-topicreply-dialog').modal({
                    show: true
                });
            });

            $('.js-edit-topicreply-dialog .stdButton').on('click', function (e) {
                e.preventDefault();
                var url = $(this).data("url"),
                    replyId = $(this).data("rid"),
                    currentPageId = $(this).data("pid"),
                    replyContent = tinyMCE.activeEditor.getContent(),
                    targetReply = $(this).closest(".thread-item");
                $.ajax({
                    type: "POST",
                    url: url,
                    data: { message: replyContent, replyId: replyId, currentPageId: currentPageId },
                    dataType: "json",
                    success: function (data) {
                        if (data.success == true) {
                            $(targetReply).find('.js-body').html(replyContent);
                            $(targetReply).find('.js-html-text-area').html(replyContent);
                            $('.js-edit-topicreply-dialog.in').modal("hide");
                        }
                    },
                    error: function (error) {
                        alert('error: ' + eval(error));
                    }
                });
            });

            $('.js-report-topicreply-dialog .stdButton').on('click', function (e) {
                e.preventDefault();
                var url = $(this).data("url"),
                    replyId = $(this).data("rid"),
                    description = $(this).closest(".modal-dialog").find("textarea").val(),
                    targetReply = $(this).closest(".thread-item");
                $.ajax({
                    type: "POST",
                    url: url,
                    data: { description: description, replyId: replyId },
                    dataType: "json",
                    success: function (data) {
                        if (data.success == true) {
                            $(targetReply).find('.js-report-topicreply-dialog-trigger').parent().html(data.text);
                            $('.js-report-topicreply-dialog.in').modal("hide");
                        }
                    },
                    error: function (error) {
                        alert('error: ' + eval(error));
                    }
                });
            });

            $('.js-edit-topic-dialog .stdButton').on('click', function (e) {
                e.preventDefault();
                var url = $(this).data("url"),
                    target = $(this).closest(".topic"),
                    tags = $(".radio-button-list :checked").map(function() {
                        return $(this).val();
                    }).toArray(),
                    forumCategory = $('select.forum-categories :selected').val();

                var jsonObject =  {
                    TopicId: $(this).data("rid"),
                    TopicTitle: $(".editTitle").val(),
                    TopicBody: tinyMCE.activeEditor.getContent(),
                    Tags: tags,
                    ForumId: forumCategory,
                    CurrentPageId: $(this).data("pid")
                };
                
                jQuery.ajax({
                    type: "POST",
                    url: url,
                    dataType: "json",
                    contentType: "application/json; charset=utf-8",
                    data: JSON.stringify(jsonObject),
                    success: function(data) {
                        if (data.topic != null) {
                            $(target).find('.js-title').html(data.topic.TopicTitle);
                            $(target).find('.js-html-text-area').html(data.topic.TopicBody);
                            $(target).find('.js-body').html(data.topic.TopicBody);
                            $(target).find('.js-tags').html(data.topic.Tags.join(', '));
                        }
                        $('.js-edit-topic-dialog').modal("hide");
                    },
                    error: function(error) {
                        alert('error: ' + eval(error));
                    }
                });

            });

            $('.js-delete-topicreply-dialog .stdButton').on('click', function (e) {
                e.preventDefault();
                var url = $(this).data("url"),
                    replyId = $(this).data("rid"),
                    targetReply = $(this).closest(".thread-item");
                $.ajax({
                    type: "POST",
                    url: url,
                    data: { replyId: replyId },
                    dataType: "json",
                    success: function (data) {
                        if (data.success == true) {
                            $(targetReply).slideUp();
                            $('.js-delete-topicreply-dialog.in').modal("hide");
                        }
                    },
                    error: function (error) {
                        alert('error: ' + eval(error));
                    }
                });
            });

            $('#subscribeToTopic').on('click', function (e) {
                var url = $(this).data("url");
                var topicId = $(this).data("id");
                $.ajax({
                    type: "POST",
                    url: url,
                    dataType: "json",
                    data: { topicId: topicId },
                    success: function (data) {
                    },
                    error: function (error) {
                        alert('error: ' + eval(error));
                    }
                });
            });

            // Documents
            $('.js-add-document-dialog-trigger').on('click', function (e) {
                e.preventDefault();
                if (actionIsNotDisabled($(this))) {
                    $('.js-add-document-dialog').modal({
                        show: true
                    });
                }
            });

            $('.js-add-folder-dialog-trigger').on('click', function (e) {
                e.preventDefault();
                if (actionIsNotDisabled($(this))) {
                    $('.js-add-folder-dialog').modal({
                        show: true
                    });
                }
            });

            $('.js-move-dialog-trigger').on('click', function (e) {
                e.preventDefault();
                if (actionIsNotDisabled($(this))) {
                    $('.js-move-dialog').modal({
                        show: true
                    });
                }
            });

            $('.js-move-dialog').on('show.bs.modal', function () {
                var checkedDocIds = $('#workRooms input:checkbox:checked').map(function() {
                    return this.value;
                }).get();
                $.each(checkedDocIds, function(index, value) {
                    $('select option[value="' + value + '"]').hide();
                });
            });

            $('.js-rename-content-dialog-trigger').on('click', function (e) {
                e.preventDefault();
                if (actionIsNotDisabled($(this))) {
                    $('.js-rename-content-dialog').modal({
                        show: true
                    });
                }
            });

            $('.js-add-version-dialog-trigger').on('click', function (e) {
                e.preventDefault();
                if (actionIsNotDisabled($(this))) {
                    $('.js-add-version-dialog').modal({
                        show: true
                    });
                }
            });

            $('.js-add-version-dialog .stdButton').on('click', function (e) {
                var valid = true;
                var file = $(this).closest(".modal-body").find('input[type = "file"]');
                if (file.val() == '') {
                    $(this).closest(".modal-body").find(".field-validation-error").removeClass("hidden");
                    valid = false;
                } else {
                    var checkedDocIds = $('#workRooms input:checkbox:checked').map(function () {
                        return this.value;
                    }).get();
                    $("#AddNewDocumentViewModel_OriginalDocumentId").val(checkedDocIds[0]);

                }
                return valid;
            });

            $('.js-view-versions-dialog-trigger').on('click', function (e) {
                e.preventDefault();
                if (actionIsNotDisabled($(this))) {
                    var checkedDocIds = $('#workRooms input:checkbox:checked').map(function () {
                        return this.value;
                    }).get();

                    var url = $(this).attr("href");
                    var workRoomId = $("#workRooms").data("id");
                    $.ajax({
                        type: "GET",
                        url: url,
                        data: { documentId: checkedDocIds[0], workRoomId: workRoomId },
                        traditional: true,
                        success: function (html) {
                            $('.js-view-versions-dialog').find(".modal-body").html(html);
                            $('.js-view-versions-dialog').modal({
                                show: true
                            });

                            $(".js-view-versions-dialog.in").on("click", ".js-make-documentvesion-active", function (e) {
                                e.preventDefault();
                                var url1 = $(this).attr("href");
                                $.ajax({
                                    type: "POST",
                                    url: url1,
                                    traditional: true,
                                    success: function () {
                                        location.reload(true);
                                    },
                                    error: function (error) {
                                        alert('error: ' + eval(error));
                                    }
                                });
                            });
                        },
                        error: function (error) {
                            alert('error: ' + eval(error));
                        }
                    });
                }
            });


            $('.js-add-document-dialog .stdButton').on('click', function (e) {
                var valid = true;
                var file = $(this).closest(".modal-body").find('input[type = "file"]');
                
                var existingFiles = [];
                $.each($('.js-item-name'), function(index, value) {
                    existingFiles.push(value.innerText);
                });
                
                if (file.val() == '') {
                    $(this).closest(".modal-body").find(".field-validation-error").removeClass("hidden");
                    valid = false;
                }
                else if ($.inArray(file.val().split('\\').pop(), existingFiles) > -1) {
                    $(this).closest(".modal-body").find(".field-validation-error.existing").removeClass("hidden");
                    valid = false;
                }
                return valid;
            });

            $('.js-add-folder-dialog .stdButton').on('click', function (e) {
                var valid = true;
                var text = $(this).closest(".modal-body").find('input[type = "text"]').val();
                if (text.length == 0) {
                    $(this).closest(".modal-body").find(".field-validation-error").removeClass("hidden");
                    valid = false;
                }
                return valid;
            });

            $('.js-delete-content-dialog-trigger').on('click', function (e) {
                e.preventDefault();
                if (actionIsNotDisabled($(this))) {
                    $('.js-delete-content-dialog').modal({
                        show: true
                    });
                }
            });

            $('.js-delete-content-dialog .stdButton').on('click', function (e) {
                e.preventDefault();
                var checkedDocIds = $('#workRooms input:checkbox:checked').map(function () {
                    return this.value;
                }).get();
                var url = $(this).data("url");
                $.ajax({
                    type: "POST",
                    url: url,
                    data: { docIds: checkedDocIds },
                    dataType: "json",
                    traditional: true,
                    success: function(data) {
                        $.each(data.deletedIds, function(index, value) {
                            $(".row").find("[data-id='" + value + "']").slideUp();;
                        });
                        $('.js-delete-content-dialog').modal("hide");
                    },
                    error: function(error) {
                        alert('error: ' + eval(error));
                    }
                });
            });

            $('.js-move-dialog .stdButton').on('click', function (e) {
                e.preventDefault();
                var checkedDocIds = $('#workRooms input:checkbox:checked').map(function() {
                        return this.value;
                    }).get(),
                    workRoomId = $("#workRooms").data("id"),
                    docId = $('select :selected').val(),
                    url = $(this).closest("form").attr("action"),
                    errorElement = $(this).closest(".modal-body").find(".field-validation-error");
                
                $.ajax({
                    type: "POST",
                    url: url,
                    data: { workRoomId: workRoomId, contentIds: checkedDocIds, parentId: docId },
                    dataType: "json",
                    traditional: true,
                    success: function (data) {
                        if (data.moved) {
                            $.each(checkedDocIds, function(index, value) {
                                $(".row").find("[data-id='" + value + "']").slideUp();
                            });
                            $('.js-move-dialog').modal("hide");
                        } else {
                            $(errorElement).removeClass("hidden").css("margin-top", 0);
                        }
                    },
                    error: function (error) {
                        alert('error: ' + eval(error));
                    }
                });

            });

            $('.js-rename-content-dialog .stdButton').on('click', function (e) {
                e.preventDefault();
                var checkedDocId = $('#workRooms input:checkbox:checked').map(function () {
                    return this.value;
                }).get();
                var target = $(".row").find("[data-id='" + checkedDocId + "']").find(".js-item-name");
                var name = $(this).closest("form").find("input[type=text]").val();
                var url = $(this).closest("form").attr("action");

                $.ajax({
                    type: "POST",
                    url: url,
                    data: { contentId: checkedDocId, name: name },
                    dataType: "json",
                    traditional: true,
                    success: function (data) {
                        if (data.newName.length > 0) {
                            target.html(data.newName);
                        }
                        $('.js-rename-content-dialog').modal("hide");
                    },
                    error: function (error) {
                        alert('error: ' + eval(error));
                    }
                });

            });

            if (typeof (showTimedPopup) !== 'undefined') {
                window.setTimeout(function () {
                    $('.js-pop-up-dialog').modal({
                        show: true
                    });
                }, delayInMs);
                $('.popButtons .or').on('click', function (e) {
                    $('.js-pop-up-dialog').modal('hide');
                    return false;
                });
                $('.popButtons .gr').on('click', function (e) {
                    window.setTimeout(function () {
                        $('.js-pop-up-dialog').modal('hide');
                    }, 700);
                    return true;
                });
            }

            $(".workRooms-documents :checkbox").change(function () {
                    var noItemsSelected = $('.workRooms-documents input:checked').length == 0;
                    var singleItemIsSelected = $('.workRooms-documents input:checked').length == 1;
                    var multipleItemsSelected = !noItemsSelected && !singleItemIsSelected;
                    var archiveItemIsSelected = $('.archive input:checked').length == 1;
                    var documentItemIsSelected = singleItemIsSelected && !archiveItemIsSelected;

                    var isMyDocument = $(this).data("owner") == "True";

                    disableAllOptions();

                    if (noItemsSelected) {
                        $(".js-add-folder-dialog-trigger").removeClass("buttonDisabled");
                        $(".js-add-document-dialog-trigger").removeClass("buttonDisabled");
                    }
                    if (multipleItemsSelected) {
                        $(".js-move-dialog-trigger").removeClass("buttonDisabled");
                        //Enable delete action just for owner/admin
                        if (isMyDocument || !$(".js-delete-content-dialog-trigger").hasClass("restricted")) {
                            $(".js-delete-content-dialog-trigger").removeClass("buttonDisabled");
                        }
                    }
                    if (singleItemIsSelected) {
                        $(".js-move-dialog-trigger").removeClass("buttonDisabled");
                        //Enable rename action just for owner/admin
                        if (isMyDocument || !$(".js-rename-content-dialog-trigger").hasClass("restricted")) {
                            $(".js-rename-content-dialog-trigger").removeClass("buttonDisabled");
                        }
                        //Enable delete action just for owner/admin
                        if (isMyDocument || !$(".js-delete-content-dialog-trigger").hasClass("restricted")) {
                            $(".js-delete-content-dialog-trigger").removeClass("buttonDisabled");
                        }
                    }
                    if (documentItemIsSelected) {
                        $(".js-add-version-dialog-trigger").removeClass("buttonDisabled");
                        $(".js-view-versions-dialog-trigger").removeClass("buttonDisabled");
                    }
                }
            );

            function disableAllOptions() {
                $("#news .actions-nav .light-button").addClass("buttonDisabled");
            }

            function actionIsNotDisabled(target) {
                return !target.hasClass("buttonDisabled");
            }

            // News(Blog)
            $('.js-edit-newsentry-dialog-trigger').on('click', function (e) {
                $(this).closest(".news-entry").find('.js-edit-newsentry-dialog').modal({
                    show: true
                });
            });

            $('.js-edit-newsentry-dialog .stdButton').on('click', function (e) {
                e.preventDefault();
                var url = $(this).data("url"),
                    topicId = $(this).data("rid"),
                    body = tinyMCE.activeEditor.getContent(),
                    target = $(this).closest(".news-entry"),
                    title = $(".editTitle").val();
                editBlogNewsEntry(url, topicId, body, title, target);
            });

            $('.js-edit-comment-dialog-trigger').on('click', function (e) {
                var actionUrl = $(this).data("url");
                var itemId = $(this).data("id");
                $(this).closest("li").find('.js-edit-comment-dialog').modal({
                    show: true,
                    url: actionUrl,
                    id: itemId
                });
            });

            $('.js-edit-comment-dialog .stdButton').on('click', function(e) {
                e.preventDefault();
                var url = $('.js-edit-comment-dialog.in').data("bs.modal").options.url,
                    commentId = $('.js-edit-comment-dialog.in').data("bs.modal").options.id,
                    replyContent = $('.js-edit-comment-dialog.in').find("textarea").val(),
                    targetReply = $(this).closest("li");
                editComment(url, commentId, replyContent, targetReply);
            });

            $('.js-delete-comment-dialog-trigger').on('click', function (e) {
                e.preventDefault();
                var actionUrl = $(this).data("url");
                var itemId = $(this).data("id");
                var target = $(this).closest("li");
                var redirectUrl = null;
                //check if href is not just "#"
                if (!/#/.test(this.href)) {
                    redirectUrl = $(this).attr("href");
                }
                $('.js-delete-comment-dialog').modal({
                    show: true,
                    url: actionUrl,
                    id: itemId,
                    redirectUrl: redirectUrl,
                    target: target
                });
            });

            $('.js-delete-comment-dialog').on('hidden.bs.modal', function () {
                $(this).data('bs.modal', null);
            });

            $('.js-delete-comment-dialog .stdButton').on('click', function (e) {
                e.preventDefault();
                var url = $('.js-delete-comment-dialog.in').data("bs.modal").options.url,
                    commentId = $('.js-delete-comment-dialog.in').data("bs.modal").options.id,
                    redirectUrl = $('.js-delete-comment-dialog.in').data("bs.modal").options.redirectUrl,
                    target = $('.js-delete-comment-dialog.in').data("bs.modal").options.target;
                deleteComment(url, commentId, redirectUrl, target);
            });

            $('.js-remove-topic-dialog-trigger').on('click', function (e) {
                e.preventDefault();
                var actionUrl = $(this).data("url"),
                    itemId = $(this).data("id"),
                    redirectUrl = $(this).data("back-link"),
                    target = $(this).closest("li");
                $('.js-remove-topic-dialog').modal({
                    show: true,
                    url: actionUrl,
                    id: itemId,
                    target: target,
                    redirectUrl: redirectUrl
                });
            });

            $('.js-remove-topic-dialog').on('hidden.bs.modal', function () {
                $(this).data('bs.modal', null);
            });

            $('.js-remove-topic-dialog .stdButton').on('click', function (e) {
                e.preventDefault();
                var url = $('.js-remove-topic-dialog.in').data("bs.modal").options.url,
                    topicId = $('.js-remove-topic-dialog.in').data("bs.modal").options.id,
                    redirectUrl = $('.js-remove-topic-dialog.in').data("bs.modal").options.redirectUrl;
                removeForumTopic(url, topicId, redirectUrl);
            });

            $('.js-close-topic-dialog-trigger').on('click', function (e) {
                e.preventDefault();
                var actionUrl = $(this).data("url"),
                    itemId = $(this).data("id"),
                    target = $(this).closest("li");
                $('.js-close-topic-dialog').modal({
                    show: true,
                    url: actionUrl,
                    id: itemId,
                    target: target
                });
            });

            $('.js-close-topic-dialog').on('hidden.bs.modal', function () {
                $(this).data('bs.modal', null);
            });

            $('.js-close-topic-dialog .stdButton').on('click', function (e) {
                e.preventDefault();
                var url = $('.js-close-topic-dialog.in').data("bs.modal").options.url,
                    commentId = $('.js-close-topic-dialog.in').data("bs.modal").options.id;
                lockOrUnlockForumTopic(url, commentId);
            });

        },
        removeForumTopic = function (url, topicId, redirectUrl) {
            $.ajax({
                type: "POST",
                url: url,
                data: { topicId: topicId },
                dataType: "json",
                success: function (data) {
                    if (data.success == true) {
                        $('.js-close-topic-dialog.in').modal("hide");
                        window.location = redirectUrl;
                    }
                },
                error: function (error) {
                    alert('error: ' + eval(error));
                }
            });
        },
        lockOrUnlockForumTopic = function (url, commentId) {
            $.ajax({
                type: "POST",
                url: url,
                data: { commentId: commentId },
                dataType: "json",
                success: function (data) {
                    if (data.success == true) {
                        $('.js-close-topic-dialog.in').modal("hide");
                        window.location.reload();
                    }
                },
                error: function (error) {
                    alert('error: ' + eval(error));
                }
            });
        },
        editComment = function (url, commentId, replyContent, targetReply) {
            $.ajax({
                type: "POST",
                url: url,
                data: { message: replyContent, commentId: commentId },
                dataType: "json",
                success: function (data) {
                    if (data.message.length > 0) {
                        $(targetReply).find('.js-body').html(data.message);
                        $(targetReply).find('textarea').html(data.message);
                        $('.js-edit-comment-dialog.in').modal("hide");
                    }
                },
                error: function (error) {
                    alert('error: ' + eval(error));
                }
            });
        },
        deleteComment = function (url, commentId, redirectUrl, target) {
            $.ajax({
                type: "POST",
                url: url,
                data: { commentId: commentId },
                dataType: "json",
                success: function (data) {
                    if (data.success == true) {
                        $('.js-delete-comment-dialog.in').modal("hide");

                        if (redirectUrl != null) {
                            window.location = redirectUrl;
                        } else {
                            $(target).slideUp();
                        }
                    }
                },
                error: function (error) {
                    alert('error: ' + eval(error));
                }
            });
        },
        editBlogNewsEntry = function (url, topicId, body, title, target) {
            $.ajax({
                type: "POST",
                url: url,
                data: { topicId: topicId, title: title, message: body },
                dataType: "json",
                success: function (data) {
                    if (data.entry != null) {
                        $(target).find('.js-title').html(data.entry.EntryTitle);
                        $(target).find('.js-html-text-area').html(data.entry.EntryBody);
                        $(target).find('.js-body').html(data.entry.EntryBody);
                    }
                    $('.js-edit-newsentry-dialog').modal("hide");
                },
                error: function (error) {
                    alert('error: ' + eval(error));
                }
            });
        },
        formSubmit = function (element, target) {
            var url = $(element).attr('action');
            var workRoomId = element.attr("id");
            var currentUserIsMemberOf = $(element).find("input#CurrentUserIsMemberOf").val();
            var isOpenWorkRoom = $(element).find("input#IsOpenWorkRoom").val();
            var removeOnLeave = false;
            if ($("#FilteringOption").length > 0) {
                removeOnLeave = $("#FilteringOption").val().toLowerCase() == "my";
            }

            $.ajax({
                type: "POST",
                url: url,
                data: { workRoomId: workRoomId, currentUserIsMemberOf: currentUserIsMemberOf, isOpenWorkRoom: isOpenWorkRoom },
                dataType: "json",
                success: function(data) {
                    if (removeOnLeave) {
                        target.closest("li").slideUp();
                    } else {
                        target.find("input:submit").val(data.buttonText);
                        target.find("input#CurrentUserIsMemberOf").val(data.isMember);
                        //Membership added
                        if (data.isMember == true) {
                            target.find("i.fa-plus").removeClass("fa-plus").addClass("fa-sign-in");
                        } //Membership removed
                        else if (data.isMember == false) {
                            target.find("i.fa-sign-in").removeClass("fa-sign-in").addClass("fa-plus");
                        }
                    }
                },
                error: function(error) {
                    alert('error: ' + eval(error));
                }
            });
        };

    /*show/hide tags*/
    //$(".tags div").not(':lt(4)').addClass('hidden');
    //$("a.show-more").click(function () {
    //    $(".tags div:lt(50)").removeClass('hidden');
    //    $("a.show-more").hide();
    //});

    var defaultRangeValidator = $.validator.methods.range;
    $.validator.methods.range = function (value, element, param) {
        if (element.type === 'checkbox') {
            // if it's a checkbox return true if it is checked
            return element.checked;
        } else {
            // otherwise run the default validation function
            return defaultRangeValidator.call(this, value, element, param);
        }
    }

    return {
        initialize: initialize
    };
}();;livsmedelsverket = livsmedelsverket || {};

livsmedelsverket.xformblock = function () {

    var initialize =
        function() {
            var btn = $('.formBlock table tr td input[type="submit"]');

            var parent = $(btn).closest('form');

            btn.click(
                function() {
                    var input = $(this);
                    input.addClass("disabled");
                    if (parent.hasClass('swe')) {
                        input.attr("value", "Skickar");
                    } else {
                        input.attr("value", "Sending");
                    }
                });

        };
    return {
        initialize: initialize
    };
}();;/*!
 * jQuery Cookie Plugin v1.4.1
 * https://github.com/carhartl/jquery-cookie
 *
 * Copyright 2006, 2014 Klaus Hartl
 * Released under the MIT license
 */
(function (factory) {
	if (typeof define === 'function' && define.amd) {
		// AMD (Register as an anonymous module)
		define(['jquery'], factory);
	} else if (typeof exports === 'object') {
		// Node/CommonJS
		module.exports = factory(require('jquery'));
	} else {
		// Browser globals
		factory(jQuery);
	}
}(function ($) {

	var pluses = /\+/g;

	function encode(s) {
		return config.raw ? s : encodeURIComponent(s);
	}

	function decode(s) {
		return config.raw ? s : decodeURIComponent(s);
	}

	function stringifyCookieValue(value) {
		return encode(config.json ? JSON.stringify(value) : String(value));
	}

	function parseCookieValue(s) {
		if (s.indexOf('"') === 0) {
			// This is a quoted cookie as according to RFC2068, unescape...
			s = s.slice(1, -1).replace(/\\"/g, '"').replace(/\\\\/g, '\\');
		}

		try {
			// Replace server-side written pluses with spaces.
			// If we can't decode the cookie, ignore it, it's unusable.
			// If we can't parse the cookie, ignore it, it's unusable.
			s = decodeURIComponent(s.replace(pluses, ' '));
			return config.json ? JSON.parse(s) : s;
		} catch (e) { }
	}

	function read(s, converter) {
		var value = config.raw ? s : parseCookieValue(s);
		return $.isFunction(converter) ? converter(value) : value;
	}

	var config = $.cookie = function (key, value, options) {

		// Write

		if (arguments.length > 1 && !$.isFunction(value)) {
			options = $.extend({}, config.defaults, options);

			if (typeof options.expires === 'number') {
				var days = options.expires, t = options.expires = new Date();
				t.setMilliseconds(t.getMilliseconds() + days * 864e+5);
			}

			return (document.cookie = [
				encode(key), '=', stringifyCookieValue(value),
				options.expires ? '; expires=' + options.expires.toUTCString() : '', // use expires attribute, max-age is not supported by IE
				options.path ? '; path=' + options.path : '',
				options.domain ? '; domain=' + options.domain : '',
				options.secure ? '; secure' : ''
			].join(''));
		}

		// Read

		var result = key ? undefined : {},
			// To prevent the for loop in the first place assign an empty array
			// in case there are no cookies at all. Also prevents odd result when
			// calling $.cookie().
			cookies = document.cookie ? document.cookie.split('; ') : [],
			i = 0,
			l = cookies.length;

		for (; i < l; i++) {
			var parts = cookies[i].split('='),
				name = decode(parts.shift()),
				cookie = parts.join('=');

			if (key === name) {
				// If second argument (value) is a function it's a converter...
				result = read(cookie, value);
				break;
			}

			// Prevent storing a cookie that we couldn't decode.
			if (!key && (cookie = read(cookie)) !== undefined) {
				result[name] = cookie;
			}
		}

		return result;
	};

	config.defaults = {};

	$.removeCookie = function (key, options) {
		// Must not alter options, thus extending a fresh object...
		$.cookie(key, '', $.extend({}, options, { expires: -1 }));
		return !$.cookie(key);
	};

}));;/**!
 * url-search-params-polyfill
 *    
 * @author Jerry Bendy (https://github.com/jerrybendy)
 * @licence MIT
 */
(function(self) {
    'use strict';

    var nativeURLSearchParams = (function() {
            // #41 Fix issue in RN
            try {
                if (self.URLSearchParams && (new self.URLSearchParams('foo=bar')).get('foo') === 'bar') {
                    return self.URLSearchParams;
                }
            } catch (e) {}
            return null;
        })(),
        isSupportObjectConstructor = nativeURLSearchParams && (new nativeURLSearchParams({a: 1})).toString() === 'a=1',
        // There is a bug in safari 10.1 (and earlier) that incorrectly decodes `%2B` as an empty space and not a plus.
        decodesPlusesCorrectly = nativeURLSearchParams && (new nativeURLSearchParams('s=%2B').get('s') === '+'),
        __URLSearchParams__ = "__URLSearchParams__",
        // Fix bug in Edge which cannot encode ' &' correctly
        encodesAmpersandsCorrectly = nativeURLSearchParams ? (function() {
            var ampersandTest = new nativeURLSearchParams();
            ampersandTest.append('s', ' &');
            return ampersandTest.toString() === 's=+%26';
        })() : true,
        prototype = URLSearchParamsPolyfill.prototype,
        iterable = !!(self.Symbol && self.Symbol.iterator);

    if (nativeURLSearchParams && isSupportObjectConstructor && decodesPlusesCorrectly && encodesAmpersandsCorrectly) {
        return;
    }


    /**
     * Make a URLSearchParams instance
     *
     * @param {object|string|URLSearchParams} search
     * @constructor
     */
    function URLSearchParamsPolyfill(search) {
        search = search || "";

        // support construct object with another URLSearchParams instance
        if (search instanceof URLSearchParams || search instanceof URLSearchParamsPolyfill) {
            search = search.toString();
        }
        this [__URLSearchParams__] = parseToDict(search);
    }


    /**
     * Appends a specified key/value pair as a new search parameter.
     *
     * @param {string} name
     * @param {string} value
     */
    prototype.append = function(name, value) {
        appendTo(this [__URLSearchParams__], name, value);
    };

    /**
     * Deletes the given search parameter, and its associated value,
     * from the list of all search parameters.
     *
     * @param {string} name
     */
    prototype['delete'] = function(name) {
        delete this [__URLSearchParams__] [name];
    };

    /**
     * Returns the first value associated to the given search parameter.
     *
     * @param {string} name
     * @returns {string|null}
     */
    prototype.get = function(name) {
        var dict = this [__URLSearchParams__];
        return this.has(name) ? dict[name][0] : null;
    };

    /**
     * Returns all the values association with a given search parameter.
     *
     * @param {string} name
     * @returns {Array}
     */
    prototype.getAll = function(name) {
        var dict = this [__URLSearchParams__];
        return this.has(name) ? dict [name].slice(0) : [];
    };

    /**
     * Returns a Boolean indicating if such a search parameter exists.
     *
     * @param {string} name
     * @returns {boolean}
     */
    prototype.has = function(name) {
        return hasOwnProperty(this [__URLSearchParams__], name);
    };

    /**
     * Sets the value associated to a given search parameter to
     * the given value. If there were several values, delete the
     * others.
     *
     * @param {string} name
     * @param {string} value
     */
    prototype.set = function set(name, value) {
        this [__URLSearchParams__][name] = ['' + value];
    };

    /**
     * Returns a string containg a query string suitable for use in a URL.
     *
     * @returns {string}
     */
    prototype.toString = function() {
        var dict = this[__URLSearchParams__], query = [], i, key, name, value;
        for (key in dict) {
            name = encode(key);
            for (i = 0, value = dict[key]; i < value.length; i++) {
                query.push(name + '=' + encode(value[i]));
            }
        }
        return query.join('&');
    };

    // There is a bug in Safari 10.1 and `Proxy`ing it is not enough.
    var forSureUsePolyfill = !decodesPlusesCorrectly;
    var useProxy = (!forSureUsePolyfill && nativeURLSearchParams && !isSupportObjectConstructor && self.Proxy);
    var propValue; 
    if (useProxy) {
        // Safari 10.0 doesn't support Proxy, so it won't extend URLSearchParams on safari 10.0
        propValue = new Proxy(nativeURLSearchParams, {
            construct: function (target, args) {
                return new target((new URLSearchParamsPolyfill(args[0]).toString()));
            }
        })
        // Chrome <=60 .toString() on a function proxy got error "Function.prototype.toString is not generic"
        propValue.toString = Function.prototype.toString.bind(URLSearchParamsPolyfill);
    } else {
        propValue = URLSearchParamsPolyfill;
    }
    /*
     * Apply polifill to global object and append other prototype into it
     */
    Object.defineProperty(self, 'URLSearchParams', {
        value: propValue
    });

    var USPProto = self.URLSearchParams.prototype;

    USPProto.polyfill = true;

    /**
     *
     * @param {function} callback
     * @param {object} thisArg
     */
    USPProto.forEach = USPProto.forEach || function(callback, thisArg) {
        var dict = parseToDict(this.toString());
        Object.getOwnPropertyNames(dict).forEach(function(name) {
            dict[name].forEach(function(value) {
                callback.call(thisArg, value, name, this);
            }, this);
        }, this);
    };

    /**
     * Sort all name-value pairs
     */
    USPProto.sort = USPProto.sort || function() {
        var dict = parseToDict(this.toString()), keys = [], k, i, j;
        for (k in dict) {
            keys.push(k);
        }
        keys.sort();

        for (i = 0; i < keys.length; i++) {
            this['delete'](keys[i]);
        }
        for (i = 0; i < keys.length; i++) {
            var key = keys[i], values = dict[key];
            for (j = 0; j < values.length; j++) {
                this.append(key, values[j]);
            }
        }
    };

    /**
     * Returns an iterator allowing to go through all keys of
     * the key/value pairs contained in this object.
     *
     * @returns {function}
     */
    USPProto.keys = USPProto.keys || function() {
        var items = [];
        this.forEach(function(item, name) {
            items.push(name);
        });
        return makeIterator(items);
    };

    /**
     * Returns an iterator allowing to go through all values of
     * the key/value pairs contained in this object.
     *
     * @returns {function}
     */
    USPProto.values = USPProto.values || function() {
        var items = [];
        this.forEach(function(item) {
            items.push(item);
        });
        return makeIterator(items);
    };

    /**
     * Returns an iterator allowing to go through all key/value
     * pairs contained in this object.
     *
     * @returns {function}
     */
    USPProto.entries = USPProto.entries || function() {
        var items = [];
        this.forEach(function(item, name) {
            items.push([name, item]);
        });
        return makeIterator(items);
    };


    if (iterable) {
        USPProto[self.Symbol.iterator] = USPProto[self.Symbol.iterator] || USPProto.entries;
    }


    function encode(str) {
        var replace = {
            '!': '%21',
            "'": '%27',
            '(': '%28',
            ')': '%29',
            '~': '%7E',
            '%20': '+',
            '%00': '\x00'
        };
        return encodeURIComponent(str).replace(/[!'\(\)~]|%20|%00/g, function(match) {
            return replace[match];
        });
    }

    function decode(str) {
        return str
            .replace(/[ +]/g, '%20')
            .replace(/(%[a-f0-9]{2})+/ig, function(match) {
                return decodeURIComponent(match);
            });
    }

    function makeIterator(arr) {
        var iterator = {
            next: function() {
                var value = arr.shift();
                return {done: value === undefined, value: value};
            }
        };

        if (iterable) {
            iterator[self.Symbol.iterator] = function() {
                return iterator;
            };
        }

        return iterator;
    }

    function parseToDict(search) {
        var dict = {};

        if (typeof search === "object") {
            // if `search` is an array, treat it as a sequence
            if (isArray(search)) {
                for (var i = 0; i < search.length; i++) {
                    var item = search[i];
                    if (isArray(item) && item.length === 2) {
                        appendTo(dict, item[0], item[1]);
                    } else {
                        throw new TypeError("Failed to construct 'URLSearchParams': Sequence initializer must only contain pair elements");
                    }
                }

            } else {
                for (var key in search) {
                    if (search.hasOwnProperty(key)) {
                        appendTo(dict, key, search[key]);
                    }
                }
            }

        } else {
            // remove first '?'
            if (search.indexOf("?") === 0) {
                search = search.slice(1);
            }

            var pairs = search.split("&");
            for (var j = 0; j < pairs.length; j++) {
                var value = pairs [j],
                    index = value.indexOf('=');

                if (-1 < index) {
                    appendTo(dict, decode(value.slice(0, index)), decode(value.slice(index + 1)));

                } else {
                    if (value) {
                        appendTo(dict, decode(value), '');
                    }
                }
            }
        }

        return dict;
    }

    function appendTo(dict, name, value) {
        var val = typeof value === 'string' ? value : (
            value !== null && value !== undefined && typeof value.toString === 'function' ? value.toString() : JSON.stringify(value)
        );

        // #47 Prevent using `hasOwnProperty` as a property name
        if (hasOwnProperty(dict, name)) {
            dict[name].push(val);
        } else {
            dict[name] = [val];
        }
    }

    function isArray(val) {
        return !!val && '[object Array]' === Object.prototype.toString.call(val);
    }

    function hasOwnProperty(obj, prop) {
        return Object.prototype.hasOwnProperty.call(obj, prop);
    }

})(typeof global !== 'undefined' ? global : (typeof window !== 'undefined' ? window : this));
;