text: /*!
   * Theia Sticky Sidebar v1.3.0
   * https://github.com/WeCodePixels/theia-sticky-sidebar
   *
   * Glues your website's sidebars, making them permanently visible while scrolling.
   *
   * Copyright 2013-2014 WeCodePixels and other contributors
   * Released under the MIT license
   */
  
  (function ($) {
  	$.fn.theiaStickySidebar = function (options) {
  		var defaults = {
  			'containerSelector': '',
  			'additionalMarginTop': 0,
  			'additionalMarginBottom': 0,
  			'updateSidebarHeight': true,
  			'minWidth': 0,
  			'sidebarBehavior': 'modern'
  		};
  		options = $.extend(defaults, options);
  
  		// Validate options
  		options.additionalMarginTop = parseInt(options.additionalMarginTop) || 0;
  		options.additionalMarginBottom = parseInt(options.additionalMarginBottom) || 0;
  
  		tryInitOrHookIntoEvents(options, this);
  
  		// Try doing init, otherwise hook into window.resize and document.scroll and try again then.
  		function tryInitOrHookIntoEvents(options, $that) {
  			var success = tryInit(options, $that);
  
  			if (!success) {
  				console.log('TST: Body width smaller than options.minWidth. Init is delayed.');
  
  				$(document).scroll(function (options, $that) {
  					return function (evt) {
  						var success = tryInit(options, $that);
  
  						if (success) {
  							$(this).unbind(evt);
  						}
  					};
  				}(options, $that));
  				$(window).resize(function (options, $that) {
  					return function (evt) {
  						var success = tryInit(options, $that);
  
  						if (success) {
  							$(this).unbind(evt);
  						}
  					};
  				}(options, $that))
  			}
  		}
  
  		// Try doing init if proper conditions are met.
  		function tryInit(options, $that) {
  			if (options.initialized === true) {
  				return true;
  			}
  
  			if ($('body').width() < options.minWidth) {
  				return false;
  			}
  
  			init(options, $that);
  
  			return true;
  		}
  
  		// Init the sticky sidebar(s).
  		function init(options, $that) {
  			options.initialized = true;
  
  			// Add CSS
  			$('head').append($('<style>.theiaStickySidebar:after {content: ""; display: table; clear: both;}</style>'));
  
  			$that.each(function () {
  				console.log('TST: Doing init.');
  
  				var o = {};
  
  				o.sidebar = $(this);
  
  				// Save options
  				o.options = options || {};
  
  				// Get container
  				o.container = $(o.options.containerSelector);
  				if (o.container.size() == 0) {
  					o.container = o.sidebar.parent();
  				}
  
  				// Create sticky sidebar
  				o.sidebar.parents().css('-webkit-transform', 'none'); // Fix for WebKit bug - https://code.google.com/p/chromium/issues/detail?id=20574
  				o.sidebar.css({
  					'position': 'relative',
  					'overflow': 'visible',
  					// The "box-sizing" must be set to "content-box" because we set a fixed height to this element when the sticky sidebar has a fixed position.
  					'-webkit-box-sizing': 'border-box',
  					'-moz-box-sizing': 'border-box',
  					'box-sizing': 'border-box'
  				});
  
  				// Get the sticky sidebar element. If none has been found, then create one.
  				o.stickySidebar = o.sidebar.find('.theiaStickySidebar');
  				if (o.stickySidebar.length == 0) {
  					o.sidebar.find('script').remove(); // Remove <script> tags, otherwise they will be run again on the next line.
  					o.stickySidebar = $('<div>').addClass('theiaStickySidebar').append(o.sidebar.children());
  					o.sidebar.append(o.stickySidebar);
  				}
  
  				// Get existing top and bottom margins and paddings
  				o.marginTop = parseInt(o.sidebar.css('margin-top'));
  				o.marginBottom = parseInt(o.sidebar.css('margin-bottom'));
  				o.paddingTop = parseInt(o.sidebar.css('padding-top'));
  				o.paddingBottom = parseInt(o.sidebar.css('padding-bottom'));
  
  				// Add a temporary padding rule to check for collapsable margins.
  				var collapsedTopHeight = o.stickySidebar.offset().top;
  				var collapsedBottomHeight = o.stickySidebar.outerHeight();
  				o.stickySidebar.css('padding-top', 1);
  				o.stickySidebar.css('padding-bottom', 1);
  				collapsedTopHeight -= o.stickySidebar.offset().top;
  				collapsedBottomHeight = o.stickySidebar.outerHeight() - collapsedBottomHeight - collapsedTopHeight;
  				if (collapsedTopHeight == 0) {
  					o.stickySidebar.css('padding-top', 0);
  					o.stickySidebarPaddingTop = 0;
  				}
  				else {
  					o.stickySidebarPaddingTop = 1;
  				}
  
  				if (collapsedBottomHeight == 0) {
  					o.stickySidebar.css('padding-bottom', 0);
  					o.stickySidebarPaddingBottom = 0;
  				}
  				else {
  					o.stickySidebarPaddingBottom = 1;
  				}
  
  				// We use this to know whether the user is scrolling up or down.
  				o.previousScrollTop = null;
  
  				// Scroll top (value) when the sidebar has fixed position.
  				o.fixedScrollTop = 0;
  
  				// Set sidebar to default values.
  				resetSidebar();
  
  				o.onScroll = function (o) {
  					// Stop if the sidebar isn't visible.
  					if (!o.stickySidebar.is(":visible")) {
  						return;
  					}
  
  					// Stop if the window is too small.
  					if ($('body').width() < o.options.minWidth) {
  						resetSidebar();
  						return;
  					}
  
  					// Stop if the sidebar width is larger than the container width (e.g. the theme is responsive and the sidebar is now below the content)
  					if (o.sidebar.outerWidth(true) + 50 > o.container.width()) {
  						resetSidebar();
  						return;
  					}
  
  					var scrollTop = $(document).scrollTop();
  					var position = 'static';
  
  					// If the user has scrolled down enough for the sidebar to be clipped at the top, then we can consider changing its position.
  					if (scrollTop >= o.container.offset().top + (o.paddingTop + o.marginTop - o.options.additionalMarginTop)) {
  						// The top and bottom offsets, used in various calculations.
  						var offsetTop = o.paddingTop + o.marginTop + options.additionalMarginTop;
  						var offsetBottom = o.paddingBottom + o.marginBottom + options.additionalMarginBottom;
  
  						// All top and bottom positions are relative to the window, not to the parent elemnts.
  						var containerTop = o.container.offset().top;
  						var containerBottom = o.container.offset().top + getClearedHeight(o.container);
  
  						// The top and bottom offsets relative to the window screen top (zero) and bottom (window height).
  						var windowOffsetTop = 0 + options.additionalMarginTop;
  						var windowOffsetBottom;
  
  						var sidebarSmallerThanWindow = (o.stickySidebar.outerHeight() + offsetTop + offsetBottom) < $(window).height();
  						if (sidebarSmallerThanWindow) {
  							windowOffsetBottom = windowOffsetTop + o.stickySidebar.outerHeight();
  						}
  						else {
  							windowOffsetBottom = $(window).height() - o.marginBottom - o.paddingBottom - options.additionalMarginBottom;
  						}
  
  						var staticLimitTop = containerTop - scrollTop + o.paddingTop + o.marginTop;
  						var staticLimitBottom = containerBottom - scrollTop - o.paddingBottom - o.marginBottom;
  
  						var top = o.stickySidebar.offset().top - scrollTop;
  						var scrollTopDiff = o.previousScrollTop - scrollTop;
  
  						// If the sidebar position is fixed, then it won't move up or down by itself. So, we manually adjust the top coordinate.
  						if (o.stickySidebar.css('position') == 'fixed') {
  							if (o.options.sidebarBehavior == 'modern') {
  								top += scrollTopDiff;
  							}
  						}
  
  						if (o.options.sidebarBehavior == 'legacy') {
  							top = windowOffsetBottom - o.stickySidebar.outerHeight();
  							top = Math.max(top, windowOffsetBottom - o.stickySidebar.outerHeight());
  						}
  
  						if (scrollTopDiff > 0) { // If the user is scrolling up.
  							top = Math.min(top, windowOffsetTop);
  						}
  						else { // If the user is scrolling down.
  							top = Math.max(top, windowOffsetBottom - o.stickySidebar.outerHeight());
  						}
  
  						top = Math.max(top, staticLimitTop);
  
  						top = Math.min(top, staticLimitBottom - o.stickySidebar.outerHeight());
  
  						// If the sidebar is the same height as the container, we won't use fixed positioning.
  						var sidebarSameHeightAsContainer = o.container.height() == o.stickySidebar.outerHeight();
  
  						if (!sidebarSameHeightAsContainer && top == windowOffsetTop) {
  							position = 'fixed';
  						}
  						else if (!sidebarSameHeightAsContainer && top == windowOffsetBottom - o.stickySidebar.outerHeight()) {
  							position = 'fixed';
  						}
  						else if (scrollTop + top - o.sidebar.offset().top - o.paddingTop <= options.additionalMarginTop) {
  							// Stuck to the top of the page. No special behavior.
  							position = 'static';
  						}
  						else {
  							// Stuck to the bottom of the page.
  							position = 'absolute';
  						}
  					}
  
  					/*
  					 * Performance notice: It's OK to set these CSS values at each resize/scroll, even if they don't change.
  					 * It's way slower to first check if the values have changed.
  					 */
  					if (position == 'fixed') {
  						o.stickySidebar.css({
  							'position': 'fixed',
  							'width': o.sidebar.width(),
  							'top': top,
  							'left': o.sidebar.offset().left + parseInt(o.sidebar.css('padding-left'))
  						});
  					}
  					else if (position == 'absolute') {
  						var css = {};
  
  						if (o.stickySidebar.css('position') != 'absolute') {
  							css.position = 'absolute';
  							css.top = scrollTop + top - o.sidebar.offset().top - o.stickySidebarPaddingTop - o.stickySidebarPaddingBottom;
  						}
  
  						css.width = o.sidebar.width();
  						css.left = '';
  
  						o.stickySidebar.css(css);
  					}
  					else if (position == 'static') {
  						resetSidebar();
  					}
  
  					if (position != 'static') {
  						if (o.options.updateSidebarHeight == true) {
  							o.sidebar.css({
  								'min-height': o.stickySidebar.outerHeight() + o.stickySidebar.offset().top - o.sidebar.offset().top + o.paddingBottom
  							});
  						}
  					}
  
  					o.previousScrollTop = scrollTop;
  				};
  
  				// Initialize the sidebar's position.
  				o.onScroll(o);
  
  				// Recalculate the sidebar's position on every scroll and resize.
  				$(document).scroll(function (o) {
  					return function () {
  						o.onScroll(o);
  					};
  				}(o));
  				$(window).resize(function (o) {
  					return function () {
  						o.stickySidebar.css({'position': 'static'});
  						o.onScroll(o);
  					};
  				}(o));
  
  				// Reset the sidebar to its default state
  				function resetSidebar() {
  					o.fixedScrollTop = 0;
  					o.sidebar.css({
  						'min-height': '1px'
  					});
  					o.stickySidebar.css({
  						'position': 'static',
  						'width': ''
  					});
  				}
  
  				// Get the height of a div as if its floated children were cleared. Note that this function fails if the floats are more than one level deep.
  				function getClearedHeight(e) {
  					var height = e.height();
  
  					e.children().each(function () {
  						height = Math.max(height, $(this).height());
  					});
  
  					return height;
  				}
  			});
  		}
  	}
  })(jQuery);