text:
// Script: jScrollPane - cross browser customisable scrollbars
//
// *Version: 2.2.0, Last updated: 2018-05-16*
//
// Project Home - http://jscrollpane.kelvinluck.com/
// GitHub       - http://github.com/vitch/jScrollPane
// CND          - https://cdnjs.com/libraries/jScrollPane
// Source       - https://cdnjs.cloudflare.com/ajax/libs/jScrollPane/2.2.0/script/jquery.jscrollpane.min.js
// (Minified)   - https://cdnjs.cloudflare.com/ajax/libs/jScrollPane/2.2.0/script/jquery.jscrollpane.js
// CSS          - https://cdnjs.cloudflare.com/ajax/libs/jScrollPane/2.2.0/style/jquery.jscrollpane.css
// (Minified)   - https://cdnjs.cloudflare.com/ajax/libs/jScrollPane/2.2.0/style/jquery.jscrollpane.min.css
//
// About: License
//
// Copyright (c) 2017 Kelvin Luck
// Copyright (c) 2017-2018 Tuukka Pasanen
// Dual licensed under the MIT or GPL Version 2 licenses.
// http://jscrollpane.kelvinluck.com/MIT-LICENSE.txt
// http://jscrollpane.kelvinluck.com/GPL-LICENSE.txt
//
// About: Examples
//
// All examples and demos are available through the jScrollPane example site at:
// http://jscrollpane.kelvinluck.com/
//
// About: Support and Testing
//
// This plugin is tested on the browsers below and has been found to work reliably on them. If you run
// into a problem on one of the supported browsers then please visit the support section on the jScrollPane
// website (http://jscrollpane.kelvinluck.com/) for more information on getting support. You are also
// welcome to fork the project on GitHub if you can contribute a fix for a given issue.
//
// jQuery Versions - jQuery 3.x. Although script should work from jQuery 1.1 and up but no promises are made.
// Browsers Tested - See jQuery browser support page: https://jquery.com/browser-support/. Only modern
//                   browsers are supported.
//
// About: Release History
//
// 2.2.0       - (2018-05-16) No changes to RC1
// 2.2.0-rc.1  - (2018-04-28) Merged resize sensor to find out size changes of screen and
//                            again little bit tuned this to support more npm goodies.
//                            * Merged:
//                            - #361 Event based reinitialising - Resize Sensor
//                            - #359 Use npm scripts and local dev dependencies to build the project
// 2.1.3       - (2018-04-04) No changes from Release Candidate 2 so making release
// 2.1.3-rc.2  - (2018-03-13) Now using 'script/jquery.jscrollpane.min.js' main
//                            in package.json rather than 'Gruntfile.js'
// 2.1.3-rc.1  - (2018-03-05) Moving Gruntfile.js to root and example HTML
//                            to subdirectory examples
// 2.1.2       - (2018-02-16) Just on console.log remove and Release!
//                            This version should play nicely with NPM
// 2.1.2-rc.2  - (2018-02-03) Update package.json main-tag
// 2.1.2-rc.1  - (2018-01-18) Release on NPM.
// 2.1.1       - (2018-01-12) As everyone stays silent then we just release! No changes from RC.1
// 2.1.1-rc.1  - (2017-12-23) Started to slowly merge stuff (HO HO HO Merry Christmas!)
//             * Merged
//             - #349 - ScrollPane reinitialization should adapt to changed container size
//             - #335 Set drag bar width/height with .css instead of .width/.height
//             - #297 added two settings: always show HScroll and VScroll
//             * Bugs
//             - #8 Make it possible to tell a scrollbar to be "always on"
// 2.1.0  - (2017-12-16) Update jQuery to version 3.x

(function (factory) {
  if ( typeof define === 'function' && define.amd ) {
      // AMD. Register as an anonymous module.
      define(['jquery'], factory);
  } else if (typeof exports === 'object') {
      // Node/CommonJS style for Browserify
      module.exports = factory(require('jquery'));
  } else {
      // Browser globals
      factory(jQuery);
  }
}(function($){

	$.fn.jScrollPane = function(settings)
	{
		// JScrollPane "class" - public methods are available through $('selector').data('jsp')
		function JScrollPane(elem, s)
		{
			var settings, jsp = this, pane, paneWidth, paneHeight, container, contentWidth, contentHeight,
				percentInViewH, percentInViewV, isScrollableV, isScrollableH, verticalDrag, dragMaxY,
				verticalDragPosition, horizontalDrag, dragMaxX, horizontalDragPosition,
				verticalBar, verticalTrack, scrollbarWidth, verticalTrackHeight, verticalDragHeight, arrowUp, arrowDown,
				horizontalBar, horizontalTrack, horizontalTrackWidth, horizontalDragWidth, arrowLeft, arrowRight,
				reinitialiseInterval, originalPadding, originalPaddingTotalWidth, previousContentWidth,
				wasAtTop = true, wasAtLeft = true, wasAtBottom = false, wasAtRight = false,
				originalElement = elem.clone(false, false).empty(), resizeEventsAdded = false,
				mwEvent = $.fn.mwheelIntent ? 'mwheelIntent.jsp' : 'mousewheel.jsp';

			var reinitialiseFn = function() {
				// if size has changed then reinitialise
				if (settings.resizeSensorDelay > 0) {
					setTimeout(function() {
						initialise(settings);
					}, settings.resizeSensorDelay);
				}
				else {
					initialise(settings);
				}
			};

			if (elem.css('box-sizing') === 'border-box') {
				originalPadding = 0;
				originalPaddingTotalWidth = 0;
			} else {
				originalPadding = elem.css('paddingTop') + ' ' +
									elem.css('paddingRight') + ' ' +
									elem.css('paddingBottom') + ' ' +
									elem.css('paddingLeft');
				originalPaddingTotalWidth = (parseInt(elem.css('paddingLeft'), 10) || 0) +
											(parseInt(elem.css('paddingRight'), 10) || 0);
			}

			function initialise(s)
			{

				var /*firstChild, lastChild, */isMaintainingPositon, lastContentX, lastContentY,
						hasContainingSpaceChanged, originalScrollTop, originalScrollLeft,
						newPaneWidth, newPaneHeight, maintainAtBottom = false, maintainAtRight = false;

				settings = s;

				if (pane === undefined) {
					originalScrollTop = elem.scrollTop();
					originalScrollLeft = elem.scrollLeft();

					elem.css(
						{
							overflow: 'hidden',
							padding: 0
						}
					);
					// TODO: Deal with where width/ height is 0 as it probably means the element is hidden and we should
					// come back to it later and check once it is unhidden...
					paneWidth = elem.innerWidth() + originalPaddingTotalWidth;
					paneHeight = elem.innerHeight();

					elem.width(paneWidth);

					pane = $('
').css('padding', originalPadding).append(elem.children());
					container = $('
')
						.css({
							'width': paneWidth + 'px',
							'height': paneHeight + 'px'
						}
					).append(pane).appendTo(elem);

					/*
					// Move any margins from the first and last children up to the container so they can still
					// collapse with neighbouring elements as they would before jScrollPane
					firstChild = pane.find(':first-child');
					lastChild = pane.find(':last-child');
					elem.css(
						{
							'margin-top': firstChild.css('margin-top'),
							'margin-bottom': lastChild.css('margin-bottom')
						}
					);
					firstChild.css('margin-top', 0);
					lastChild.css('margin-bottom', 0);
					*/
				} else {
					elem.css('width', '');

					// To measure the required dimensions accurately, temporarily override the CSS positioning
					// of the container and pane.
					container.css({width: 'auto', height: 'auto'});
					pane.css('position', 'static');

					newPaneWidth = elem.innerWidth() + originalPaddingTotalWidth;
					newPaneHeight = elem.innerHeight();
					pane.css('position', 'absolute');

					maintainAtBottom = settings.stickToBottom && isCloseToBottom();
					maintainAtRight  = settings.stickToRight  && isCloseToRight();

					hasContainingSpaceChanged = newPaneWidth !== paneWidth || newPaneHeight !== paneHeight;

					paneWidth = newPaneWidth;
					paneHeight = newPaneHeight;
					container.css({width: paneWidth, height: paneHeight});

					// If nothing changed since last check...
					if (!hasContainingSpaceChanged && previousContentWidth == contentWidth && pane.outerHeight() == contentHeight) {
						elem.width(paneWidth);
						return;
					}
					previousContentWidth = contentWidth;

					pane.css('width', '');
					elem.width(paneWidth);

					container.find('>.jspVerticalBar,>.jspHorizontalBar').remove().end();
				}

				pane.css('overflow', 'auto');
				if (s.contentWidth) {
					contentWidth = s.contentWidth;
				} else {
					contentWidth = pane[0].scrollWidth;
				}
				contentHeight = pane[0].scrollHeight;
				pane.css('overflow', '');

				percentInViewH = contentWidth / paneWidth;
				percentInViewV = contentHeight / paneHeight;
				isScrollableV = percentInViewV > 1 || settings.alwaysShowVScroll;
				isScrollableH = percentInViewH > 1 || settings.alwaysShowHScroll;

				if (!(isScrollableH || isScrollableV)) {
					elem.removeClass('jspScrollable');
					pane.css({
            top: 0,
            left: 0,
						width: container.width() - originalPaddingTotalWidth
					});
					removeMousewheel();
					removeFocusHandler();
					removeKeyboardNav();
					removeClickOnTrack();
				} else {
					elem.addClass('jspScrollable');

					isMaintainingPositon = settings.maintainPosition && (verticalDragPosition || horizontalDragPosition);
					if (isMaintainingPositon) {
						lastContentX = contentPositionX();
						lastContentY = contentPositionY();
					}

					initialiseVerticalScroll();
					initialiseHorizontalScroll();
					resizeScrollbars();

					if (isMaintainingPositon) {
						scrollToX(maintainAtRight  ? (contentWidth  - paneWidth ) : lastContentX, false);
						scrollToY(maintainAtBottom ? (contentHeight - paneHeight) : lastContentY, false);
					}

					initFocusHandler();
					initMousewheel();
					initTouch();

					if (settings.enableKeyboardNavigation) {
						initKeyboardNav();
					}
					if (settings.clickOnTrack) {
						initClickOnTrack();
					}

					observeHash();
					if (settings.hijackInternalLinks) {
						hijackInternalLinks();
					}
				}

				if (!settings.resizeSensor && settings.autoReinitialise && !reinitialiseInterval) {
					reinitialiseInterval = setInterval(
						function()
						{
							initialise(settings);
						},
						settings.autoReinitialiseDelay
					);
				} else if (!settings.resizeSensor && !settings.autoReinitialise && reinitialiseInterval) {
					clearInterval(reinitialiseInterval);
				}

				if(settings.resizeSensor && !resizeEventsAdded) {

					// detect size change in content
					detectSizeChanges(pane, reinitialiseFn);

					// detect size changes of scroll element
					detectSizeChanges(elem, reinitialiseFn);

					// detect size changes of container
					detectSizeChanges(elem.parent(), reinitialiseFn);

					// add a reinit on window resize also for safety
					window.addEventListener('resize', reinitialiseFn);

					resizeEventsAdded = true;
				}

        if(originalScrollTop && elem.scrollTop(0)) {
          scrollToY(originalScrollTop, false);
        }

				if(originalScrollLeft && elem.scrollLeft(0)) {
          scrollToX(originalScrollLeft, false);
        }

				elem.trigger('jsp-initialised', [isScrollableH || isScrollableV]);
			}

			function detectSizeChanges(element, callback) {

				// create resize event elements - based on resize sensor: https://github.com/flowkey/resize-sensor/
				var resizeWidth, resizeHeight;
				var resizeElement = document.createElement('div');
				var resizeGrowElement = document.createElement('div');
				var resizeGrowChildElement = document.createElement('div');
				var resizeShrinkElement = document.createElement('div');
				var resizeShrinkChildElement = document.createElement('div');

				// add necessary styling
				resizeElement.style.cssText = 'position: absolute; left: 0; top: 0; right: 0; bottom: 0; overflow: scroll; z-index: -1; visibility: hidden;';
				resizeGrowElement.style.cssText = 'position: absolute; left: 0; top: 0; right: 0; bottom: 0; overflow: scroll; z-index: -1; visibility: hidden;';
				resizeShrinkElement.style.cssText = 'position: absolute; left: 0; top: 0; right: 0; bottom: 0; overflow: scroll; z-index: -1; visibility: hidden;';

				resizeGrowChildElement.style.cssText = 'position: absolute; left: 0; top: 0;';
				resizeShrinkChildElement.style.cssText = 'position: absolute; left: 0; top: 0; width: 200%; height: 200%;';

				// Create a function to programmatically update sizes
				var updateSizes = function() {

					resizeGrowChildElement.style.width = resizeGrowElement.offsetWidth + 10 + 'px';
					resizeGrowChildElement.style.height = resizeGrowElement.offsetHeight + 10 + 'px';

					resizeGrowElement.scrollLeft = resizeGrowElement.scrollWidth;
					resizeGrowElement.scrollTop = resizeGrowElement.scrollHeight;

					resizeShrinkElement.scrollLeft = resizeShrinkElement.scrollWidth;
					resizeShrinkElement.scrollTop = resizeShrinkElement.scrollHeight;

					resizeWidth = element.width();
					resizeHeight = element.height();
				};

				// create functions to call when content grows
				var onGrow = function() {

					// check to see if the content has change size
					if (element.width() > resizeWidth || element.height() > resizeHeight) {

						// if size has changed then reinitialise
						callback.apply(this, []);
					}
					// after reinitialising update sizes
					updateSizes();
				};

				// create functions to call when content shrinks
				var onShrink = function() {

					// check to see if the content has change size
					if (element.width() < resizeWidth || element.height() < resizeHeight) {

						// if size has changed then reinitialise
						callback.apply(this, []);
					}
					// after reinitialising update sizes
					updateSizes();
				};

				// bind to scroll events
				resizeGrowElement.addEventListener('scroll', onGrow.bind(this));
				resizeShrinkElement.addEventListener('scroll', onShrink.bind(this));

				// nest elements before adding to pane
				resizeGrowElement.appendChild(resizeGrowChildElement);
				resizeShrinkElement.appendChild(resizeShrinkChildElement);

				resizeElement.appendChild(resizeGrowElement);
				resizeElement.appendChild(resizeShrinkElement);

				element.append(resizeElement);

				// ensure parent element is not statically positioned
				if(window.getComputedStyle(element[0], null).getPropertyValue('position') === 'static') {
					element[0].style.position = 'relative';
				}

				// update sizes initially
				updateSizes();
			}

			function initialiseVerticalScroll()
			{
				if (isScrollableV) {

					container.append(
						$('
').append(
							$('
'),
							$('
').append(
								$('
').append(
									$('
'),
									$('
')
								)
							),
							$('
')
						)
					);

					verticalBar = container.find('>.jspVerticalBar');
					verticalTrack = verticalBar.find('>.jspTrack');
					verticalDrag = verticalTrack.find('>.jspDrag');

					if (settings.showArrows) {
						arrowUp = $('').on(
							'mousedown.jsp', getArrowScroll(0, -1)
						).on('click.jsp', nil);
						arrowDown = $('').on(
							'mousedown.jsp', getArrowScroll(0, 1)
						).on('click.jsp', nil);
						if (settings.arrowScrollOnHover) {
							arrowUp.on('mouseover.jsp', getArrowScroll(0, -1, arrowUp));
							arrowDown.on('mouseover.jsp', getArrowScroll(0, 1, arrowDown));
						}

						appendArrows(verticalTrack, settings.verticalArrowPositions, arrowUp, arrowDown);
					}

					verticalTrackHeight = paneHeight;
					container.find('>.jspVerticalBar>.jspCap:visible,>.jspVerticalBar>.jspArrow').each(
						function()
						{
							verticalTrackHeight -= $(this).outerHeight();
						}
					);

					verticalDrag.on(
                                                "mouseenter",
						function()
						{
							verticalDrag.addClass('jspHover');
						}
                                        ).on(
                                                "mouseleave",
						function()
						{
							verticalDrag.removeClass('jspHover');
						}
					).on(
						'mousedown.jsp',
						function(e)
						{
							// Stop IE from allowing text selection
							$('html').on('dragstart.jsp selectstart.jsp', nil);

							verticalDrag.addClass('jspActive');

							var startY = e.pageY - verticalDrag.position().top;

							$('html').on(
								'mousemove.jsp',
								function(e)
								{
									positionDragY(e.pageY - startY, false);
								}
							).on('mouseup.jsp mouseleave.jsp', cancelDrag);
							return false;
						}
					);
					sizeVerticalScrollbar();
				}
			}

			function sizeVerticalScrollbar()
			{
				verticalTrack.height(verticalTrackHeight + 'px');
				verticalDragPosition = 0;
				scrollbarWidth = settings.verticalGutter + verticalTrack.outerWidth();

				// Make the pane thinner to allow for the vertical scrollbar
				pane.width(paneWidth - scrollbarWidth - originalPaddingTotalWidth);

				// Add margin to the left of the pane if scrollbars are on that side (to position
				// the scrollbar on the left or right set it's left or right property in CSS)
				try {
					if (verticalBar.position().left === 0) {
						pane.css('margin-left', scrollbarWidth + 'px');
					}
				} catch (err) {
				}
			}

			function initialiseHorizontalScroll()
			{
				if (isScrollableH) {

					container.append(
						$('
').append(
							$('
'),
							$('
').append(
								$('
').append(
									$('
'),
									$('
')
								)
							),
							$('
')
						)
					);

					horizontalBar = container.find('>.jspHorizontalBar');
					horizontalTrack = horizontalBar.find('>.jspTrack');
					horizontalDrag = horizontalTrack.find('>.jspDrag');

					if (settings.showArrows) {
						arrowLeft = $('').on(
							'mousedown.jsp', getArrowScroll(-1, 0)
						).on('click.jsp', nil);
						arrowRight = $('').on(
							'mousedown.jsp', getArrowScroll(1, 0)
						).on('click.jsp', nil);
						if (settings.arrowScrollOnHover) {
							arrowLeft.on('mouseover.jsp', getArrowScroll(-1, 0, arrowLeft));
							arrowRight.on('mouseover.jsp', getArrowScroll(1, 0, arrowRight));
						}
						appendArrows(horizontalTrack, settings.horizontalArrowPositions, arrowLeft, arrowRight);
					}

					horizontalDrag.on(
                                                "mouseenter",
						function()
						{
							horizontalDrag.addClass('jspHover');
						}
                                        ).on(
                                                "mouseleave",
						function()
						{
							horizontalDrag.removeClass('jspHover');
						}
					).on(
						'mousedown.jsp',
						function(e)
						{
							// Stop IE from allowing text selection
							$('html').on('dragstart.jsp selectstart.jsp', nil);

							horizontalDrag.addClass('jspActive');

							var startX = e.pageX - horizontalDrag.position().left;

							$('html').on(
								'mousemove.jsp',
								function(e)
								{
									positionDragX(e.pageX - startX, false);
								}
							).on('mouseup.jsp mouseleave.jsp', cancelDrag);
							return false;
						}
					);
					horizontalTrackWidth = container.innerWidth();
					sizeHorizontalScrollbar();
				}
			}

			function sizeHorizontalScrollbar()
			{
				container.find('>.jspHorizontalBar>.jspCap:visible,>.jspHorizontalBar>.jspArrow').each(
					function()
					{
						horizontalTrackWidth -= $(this).outerWidth();
					}
				);

				horizontalTrack.width(horizontalTrackWidth + 'px');
				horizontalDragPosition = 0;
			}

			function resizeScrollbars()
			{
				if (isScrollableH && isScrollableV) {
					var horizontalTrackHeight = horizontalTrack.outerHeight(),
						verticalTrackWidth = verticalTrack.outerWidth();
					verticalTrackHeight -= horizontalTrackHeight;
					$(horizontalBar).find('>.jspCap:visible,>.jspArrow').each(
						function()
						{
							horizontalTrackWidth += $(this).outerWidth();
						}
					);
					horizontalTrackWidth -= verticalTrackWidth;
					paneHeight -= verticalTrackWidth;
					paneWidth -= horizontalTrackHeight;
					horizontalTrack.parent().append(
						$('
').css('width', horizontalTrackHeight + 'px')
					);
					sizeVerticalScrollbar();
					sizeHorizontalScrollbar();
				}
				// reflow content
				if (isScrollableH) {
					pane.width((container.outerWidth() - originalPaddingTotalWidth) + 'px');
				}
				contentHeight = pane.outerHeight();
				percentInViewV = contentHeight / paneHeight;

				if (isScrollableH) {
					horizontalDragWidth = Math.ceil(1 / percentInViewH * horizontalTrackWidth);
					if (horizontalDragWidth > settings.horizontalDragMaxWidth) {
						horizontalDragWidth = settings.horizontalDragMaxWidth;
					} else if (horizontalDragWidth < settings.horizontalDragMinWidth) {
						horizontalDragWidth = settings.horizontalDragMinWidth;
					}
					horizontalDrag.css('width', horizontalDragWidth + 'px');
					dragMaxX = horizontalTrackWidth - horizontalDragWidth;
					_positionDragX(horizontalDragPosition); // To update the state for the arrow buttons
				}
				if (isScrollableV) {
					verticalDragHeight = Math.ceil(1 / percentInViewV * verticalTrackHeight);
					if (verticalDragHeight > settings.verticalDragMaxHeight) {
						verticalDragHeight = settings.verticalDragMaxHeight;
					} else if (verticalDragHeight < settings.verticalDragMinHeight) {
						verticalDragHeight = settings.verticalDragMinHeight;
					}
					verticalDrag.css('height', verticalDragHeight + 'px');
					dragMaxY = verticalTrackHeight - verticalDragHeight;
					_positionDragY(verticalDragPosition); // To update the state for the arrow buttons
				}
			}

			function appendArrows(ele, p, a1, a2)
			{
				var p1 = "before", p2 = "after", aTemp;

				// Sniff for mac... Is there a better way to determine whether the arrows would naturally appear
				// at the top or the bottom of the bar?
				if (p == "os") {
					p = /Mac/.test(navigator.platform) ? "after" : "split";
				}
				if (p == p1) {
					p2 = p;
				} else if (p == p2) {
					p1 = p;
					aTemp = a1;
					a1 = a2;
					a2 = aTemp;
				}

				ele[p1](a1)[p2](a2);
			}

			function getArrowScroll(dirX, dirY, ele)
			{
				return function()
				{
					arrowScroll(dirX, dirY, this, ele);
					this.blur();
					return false;
				};
			}

			function arrowScroll(dirX, dirY, arrow, ele)
			{
				arrow = $(arrow).addClass('jspActive');

				var eve,
					scrollTimeout,
					isFirst = true,
					doScroll = function()
					{
						if (dirX !== 0) {
							jsp.scrollByX(dirX * settings.arrowButtonSpeed);
						}
						if (dirY !== 0) {
							jsp.scrollByY(dirY * settings.arrowButtonSpeed);
						}
						scrollTimeout = setTimeout(doScroll, isFirst ? settings.initialDelay : settings.arrowRepeatFreq);
						isFirst = false;
					};

				doScroll();

				eve = ele ? 'mouseout.jsp' : 'mouseup.jsp';
				ele = ele || $('html');
				ele.on(
					eve,
					function()
					{
						arrow.removeClass('jspActive');
						if(scrollTimeout) {
              clearTimeout(scrollTimeout);
            }
						scrollTimeout = null;
						ele.off(eve);
					}
				);
			}

			function initClickOnTrack()
			{
				removeClickOnTrack();
				if (isScrollableV) {
					verticalTrack.on(
						'mousedown.jsp',
						function(e)
						{
							if (e.originalTarget === undefined || e.originalTarget == e.currentTarget) {
								var clickedTrack = $(this),
									offset = clickedTrack.offset(),
									direction = e.pageY - offset.top - verticalDragPosition,
									scrollTimeout,
									isFirst = true,
									doScroll = function()
									{
										var offset = clickedTrack.offset(),
											pos = e.pageY - offset.top - verticalDragHeight / 2,
											contentDragY = paneHeight * settings.scrollPagePercent,
											dragY = dragMaxY * contentDragY / (contentHeight - paneHeight);
										if (direction < 0) {
											if (verticalDragPosition - dragY > pos) {
												jsp.scrollByY(-contentDragY);
											} else {
												positionDragY(pos);
											}
										} else if (direction > 0) {
											if (verticalDragPosition + dragY < pos) {
												jsp.scrollByY(contentDragY);
											} else {
												positionDragY(pos);
											}
										} else {
											cancelClick();
											return;
										}
										scrollTimeout = setTimeout(doScroll, isFirst ? settings.initialDelay : settings.trackClickRepeatFreq);
										isFirst = false;
									},
									cancelClick = function()
									{
										if(scrollTimeout) {
                      clearTimeout(scrollTimeout);
                    }
										scrollTimeout = null;
										$(document).off('mouseup.jsp', cancelClick);
									};
								doScroll();
								$(document).on('mouseup.jsp', cancelClick);
								return false;
							}
						}
					);
				}

				if (isScrollableH) {
					horizontalTrack.on(
						'mousedown.jsp',
						function(e)
						{
							if (e.originalTarget === undefined || e.originalTarget == e.currentTarget) {
								var clickedTrack = $(this),
									offset = clickedTrack.offset(),
									direction = e.pageX - offset.left - horizontalDragPosition,
									scrollTimeout,
									isFirst = true,
									doScroll = function()
									{
										var offset = clickedTrack.offset(),
											pos = e.pageX - offset.left - horizontalDragWidth / 2,
											contentDragX = paneWidth * settings.scrollPagePercent,
											dragX = dragMaxX * contentDragX / (contentWidth - paneWidth);
										if (direction < 0) {
											if (horizontalDragPosition - dragX > pos) {
												jsp.scrollByX(-contentDragX);
											} else {
												positionDragX(pos);
											}
										} else if (direction > 0) {
											if (horizontalDragPosition + dragX < pos) {
												jsp.scrollByX(contentDragX);
											} else {
												positionDragX(pos);
											}
										} else {
											cancelClick();
											return;
										}
										scrollTimeout = setTimeout(doScroll, isFirst ? settings.initialDelay : settings.trackClickRepeatFreq);
										isFirst = false;
									},
									cancelClick = function()
									{
										if(scrollTimeout) {
                      clearTimeout(scrollTimeout);
                    }
										scrollTimeout = null;
										$(document).off('mouseup.jsp', cancelClick);
									};
								doScroll();
								$(document).on('mouseup.jsp', cancelClick);
								return false;
							}
						}
					);
				}
			}

			function removeClickOnTrack()
			{
				if (horizontalTrack) {
					horizontalTrack.off('mousedown.jsp');
				}
				if (verticalTrack) {
					verticalTrack.off('mousedown.jsp');
				}
			}

			function cancelDrag()
			{
				$('html').off('dragstart.jsp selectstart.jsp mousemove.jsp mouseup.jsp mouseleave.jsp');

				if (verticalDrag) {
					verticalDrag.removeClass('jspActive');
				}
				if (horizontalDrag) {
					horizontalDrag.removeClass('jspActive');
				}
			}

			function positionDragY(destY, animate)
			{
				if (!isScrollableV) {
					return;
				}
				if (destY < 0) {
					destY = 0;
				} else if (destY > dragMaxY) {
					destY = dragMaxY;
				}

				// allow for devs to prevent the JSP from being scrolled
				var willScrollYEvent = new $.Event("jsp-will-scroll-y");
				elem.trigger(willScrollYEvent, [destY]);

				if (willScrollYEvent.isDefaultPrevented()) {
					return;
				}

				var tmpVerticalDragPosition = destY || 0;

				var isAtTop = tmpVerticalDragPosition === 0,
					isAtBottom = tmpVerticalDragPosition == dragMaxY,
					percentScrolled = destY/ dragMaxY,
					destTop = -percentScrolled * (contentHeight - paneHeight);

				// can't just check if(animate) because false is a valid value that could be passed in...
				if (animate === undefined) {
					animate = settings.animateScroll;
				}
				if (animate) {
					jsp.animate(verticalDrag, 'top', destY,	_positionDragY, function() {
						elem.trigger('jsp-user-scroll-y', [-destTop, isAtTop, isAtBottom]);
					});
				} else {
					verticalDrag.css('top', destY);
					_positionDragY(destY);
					elem.trigger('jsp-user-scroll-y', [-destTop, isAtTop, isAtBottom]);
				}

			}

			function _positionDragY(destY)
			{
				if (destY === undefined) {
					destY = verticalDrag.position().top;
				}

				container.scrollTop(0);
				verticalDragPosition = destY || 0;

				var isAtTop = verticalDragPosition === 0,
					isAtBottom = verticalDragPosition == dragMaxY,
					percentScrolled = destY/ dragMaxY,
					destTop = -percentScrolled * (contentHeight - paneHeight);

				if (wasAtTop != isAtTop || wasAtBottom != isAtBottom) {
					wasAtTop = isAtTop;
					wasAtBottom = isAtBottom;
					elem.trigger('jsp-arrow-change', [wasAtTop, wasAtBottom, wasAtLeft, wasAtRight]);
				}

				updateVerticalArrows(isAtTop, isAtBottom);
				pane.css('top', destTop);
				elem.trigger('jsp-scroll-y', [-destTop, isAtTop, isAtBottom]).trigger('scroll');
			}

			function positionDragX(destX, animate)
			{
				if (!isScrollableH) {
					return;
				}
				if (destX < 0) {
					destX = 0;
				} else if (destX > dragMaxX) {
					destX = dragMaxX;
				}

				// allow for devs to prevent the JSP from being scrolled
				var willScrollXEvent = new $.Event("jsp-will-scroll-x");
				elem.trigger(willScrollXEvent, [destX]);

				if (willScrollXEvent.isDefaultPrevented()) {
					return;
				}

				var tmpHorizontalDragPosition = destX ||0;

				var isAtLeft = tmpHorizontalDragPosition === 0,
					isAtRight = tmpHorizontalDragPosition == dragMaxX,
					percentScrolled = destX / dragMaxX,
					destLeft = -percentScrolled * (contentWidth - paneWidth);

				if (animate === undefined) {
					animate = settings.animateScroll;
				}
				if (animate) {
					jsp.animate(horizontalDrag, 'left', destX,	_positionDragX, function() {
						elem.trigger('jsp-user-scroll-x', [-destLeft, isAtLeft, isAtRight]);
					});
				} else {
					horizontalDrag.css('left', destX);
					_positionDragX(destX);
					elem.trigger('jsp-user-scroll-x', [-destLeft, isAtLeft, isAtRight]);
				}
			}

			function _positionDragX(destX)
			{
				if (destX === undefined) {
					destX = horizontalDrag.position().left;
				}

				container.scrollTop(0);
				horizontalDragPosition = destX ||0;

				var isAtLeft = horizontalDragPosition === 0,
					isAtRight = horizontalDragPosition == dragMaxX,
					percentScrolled = destX / dragMaxX,
					destLeft = -percentScrolled * (contentWidth - paneWidth);

				if (wasAtLeft != isAtLeft || wasAtRight != isAtRight) {
					wasAtLeft = isAtLeft;
					wasAtRight = isAtRight;
					elem.trigger('jsp-arrow-change', [wasAtTop, wasAtBottom, wasAtLeft, wasAtRight]);
				}

				updateHorizontalArrows(isAtLeft, isAtRight);
				pane.css('left', destLeft);
				elem.trigger('jsp-scroll-x', [-destLeft, isAtLeft, isAtRight]).trigger('scroll');
			}

			function updateVerticalArrows(isAtTop, isAtBottom)
			{
				if (settings.showArrows) {
					arrowUp[isAtTop ? 'addClass' : 'removeClass']('jspDisabled');
					arrowDown[isAtBottom ? 'addClass' : 'removeClass']('jspDisabled');
				}
			}

			function updateHorizontalArrows(isAtLeft, isAtRight)
			{
				if (settings.showArrows) {
					arrowLeft[isAtLeft ? 'addClass' : 'removeClass']('jspDisabled');
					arrowRight[isAtRight ? 'addClass' : 'removeClass']('jspDisabled');
				}
			}

			function scrollToY(destY, animate)
			{
				var percentScrolled = destY / (contentHeight - paneHeight);
				positionDragY(percentScrolled * dragMaxY, animate);
			}

			function scrollToX(destX, animate)
			{
				var percentScrolled = destX / (contentWidth - paneWidth);
				positionDragX(percentScrolled * dragMaxX, animate);
			}

			function scrollToElement(ele, stickToTop, animate)
			{
				var e, eleHeight, eleWidth, eleTop = 0, eleLeft = 0, viewportTop, viewportLeft, maxVisibleEleTop, maxVisibleEleLeft, destY, destX;

				// Legal hash values aren't necessarily legal jQuery selectors so we need to catch any
				// errors from the lookup...
				try {
					e = $(ele);
				} catch (err) {
					return;
				}
				eleHeight = e.outerHeight();
				eleWidth= e.outerWidth();

				container.scrollTop(0);
				container.scrollLeft(0);

				// loop through parents adding the offset top of any elements that are relatively positioned between
				// the focused element and the jspPane so we can get the true distance from the top
				// of the focused element to the top of the scrollpane...
				while (!e.is('.jspPane')) {
					eleTop += e.position().top;
					eleLeft += e.position().left;
					e = e.offsetParent();
					if (/^body|html$/i.test(e[0].nodeName)) {
						// we ended up too high in the document structure. Quit!
						return;
					}
				}

				viewportTop = contentPositionY();
				maxVisibleEleTop = viewportTop + paneHeight;
				if (eleTop < viewportTop || stickToTop) { // element is above viewport
					destY = eleTop - settings.horizontalGutter;
				} else if (eleTop + eleHeight > maxVisibleEleTop) { // element is below viewport
					destY = eleTop - paneHeight + eleHeight + settings.horizontalGutter;
				}
				if (!isNaN(destY)) {
					scrollToY(destY, animate);
				}

				viewportLeft = contentPositionX();
	            maxVisibleEleLeft = viewportLeft + paneWidth;
	            if (eleLeft < viewportLeft || stickToTop) { // element is to the left of viewport
	                destX = eleLeft - settings.horizontalGutter;
	            } else if (eleLeft + eleWidth > maxVisibleEleLeft) { // element is to the right viewport
	                destX = eleLeft - paneWidth + eleWidth + settings.horizontalGutter;
	            }
	            if (!isNaN(destX)) {
	                scrollToX(destX, animate);
	            }

			}

			function contentPositionX()
			{
				return -pane.position().left;
			}

			function contentPositionY()
			{
				return -pane.position().top;
			}

			function isCloseToBottom()
			{
				var scrollableHeight = contentHeight - paneHeight;
				return (scrollableHeight > 20) && (scrollableHeight - contentPositionY() < 10);
			}

			function isCloseToRight()
			{
				var scrollableWidth = contentWidth - paneWidth;
				return (scrollableWidth > 20) && (scrollableWidth - contentPositionX() < 10);
			}

			function initMousewheel()
			{
				container.off(mwEvent).on(
					mwEvent,
					function (event, delta, deltaX, deltaY) {

                        if (!horizontalDragPosition) horizontalDragPosition = 0;
                        if (!verticalDragPosition) verticalDragPosition = 0;

						var dX = horizontalDragPosition, dY = verticalDragPosition, factor = event.deltaFactor || settings.mouseWheelSpeed;
						jsp.scrollBy(deltaX * factor, -deltaY * factor, false);
						// return true if there was no movement so rest of screen can scroll
						return dX == horizontalDragPosition && dY == verticalDragPosition;
					}
				);
			}

			function removeMousewheel()
			{
				container.off(mwEvent);
			}

			function nil()
			{
				return false;
			}

			function initFocusHandler()
			{
				pane.find(':input,a').off('focus.jsp').on(
					'focus.jsp',
					function(e)
					{
						scrollToElement(e.target, false);
					}
				);
			}

			function removeFocusHandler()
			{
				pane.find(':input,a').off('focus.jsp');
			}

			function initKeyboardNav()
			{
				var keyDown, elementHasScrolled, validParents = [];
				if(isScrollableH) {
          validParents.push(horizontalBar[0]);
        }

				if(isScrollableV) {
          validParents.push(verticalBar[0]);
        }

				// IE also focuses elements that don't have tabindex set.
				pane.on(
					'focus.jsp',
					function()
					{
						elem.focus();
					}
				);

				elem.attr('tabindex', 0)
					.off('keydown.jsp keypress.jsp')
					.on(
						'keydown.jsp',
						function(e)
						{
							if (e.target !== this && !(validParents.length && $(e.target).closest(validParents).length)){
								return;
							}
							var dX = horizontalDragPosition, dY = verticalDragPosition;
							switch(e.keyCode) {
								case 40: // down
								case 38: // up
								case 34: // page down
								case 32: // space
								case 33: // page up
								case 39: // right
								case 37: // left
									keyDown = e.keyCode;
									keyDownHandler();
									break;
								case 35: // end
									scrollToY(contentHeight - paneHeight);
									keyDown = null;
									break;
								case 36: // home
									scrollToY(0);
									keyDown = null;
									break;
							}

							elementHasScrolled = e.keyCode == keyDown && dX != horizontalDragPosition || dY != verticalDragPosition;
							return !elementHasScrolled;
						}
					).on(
						'keypress.jsp', // For FF/ OSX so that we can cancel the repeat key presses if the JSP scrolls...
						function(e)
						{
							if (e.keyCode == keyDown) {
								keyDownHandler();
							}
							// If the keypress is not related to the area, ignore it. Fixes problem with inputs inside scrolled area. Copied from line 955.
							if (e.target !== this && !(validParents.length && $(e.target).closest(validParents).length)){
								return;
							}
							return !elementHasScrolled;
						}
					);

				if (settings.hideFocus) {
					elem.css('outline', 'none');
					if ('hideFocus' in container[0]){
						elem.attr('hideFocus', true);
					}
				} else {
					elem.css('outline', '');
					if ('hideFocus' in container[0]){
						elem.attr('hideFocus', false);
					}
				}

				function keyDownHandler()
				{
					var dX = horizontalDragPosition, dY = verticalDragPosition;
					switch(keyDown) {
						case 40: // down
							jsp.scrollByY(settings.keyboardSpeed, false);
							break;
						case 38: // up
							jsp.scrollByY(-settings.keyboardSpeed, false);
							break;
						case 34: // page down
						case 32: // space
							jsp.scrollByY(paneHeight * settings.scrollPagePercent, false);
							break;
						case 33: // page up
							jsp.scrollByY(-paneHeight * settings.scrollPagePercent, false);
							break;
						case 39: // right
							jsp.scrollByX(settings.keyboardSpeed, false);
							break;
						case 37: // left
							jsp.scrollByX(-settings.keyboardSpeed, false);
							break;
					}

					elementHasScrolled = dX != horizontalDragPosition || dY != verticalDragPosition;
					return elementHasScrolled;
				}
			}

			function removeKeyboardNav()
			{
				elem.attr('tabindex', '-1')
					.removeAttr('tabindex')
					.off('keydown.jsp keypress.jsp');

				pane.off('.jsp');
			}

			function observeHash()
			{
				if (location.hash && location.hash.length > 1) {
					var e,
						retryInt,
						hash = escape(location.hash.substr(1)) // hash must be escaped to prevent XSS
						;
					try {
						e = $('#' + hash + ', a[name="' + hash + '"]');
					} catch (err) {
						return;
					}

					if (e.length && pane.find(hash)) {
						// nasty workaround but it appears to take a little while before the hash has done its thing
						// to the rendered page so we just wait until the container's scrollTop has been messed up.
						if (container.scrollTop() === 0) {
							retryInt = setInterval(
								function()
								{
									if (container.scrollTop() > 0) {
										scrollToElement(e, true);
										$(document).scrollTop(container.position().top);
										clearInterval(retryInt);
									}
								},
								50
							);
						} else {
							scrollToElement(e, true);
							$(document).scrollTop(container.position().top);
						}
					}
				}
			}

			function hijackInternalLinks()
			{
				// only register the link handler once
				if ($(document.body).data('jspHijack')) {
					return;
				}

				// remember that the handler was bound
				$(document.body).data('jspHijack', true);

				// use live handler to also capture newly created links
				$(document.body).delegate('a[href*="#"]', 'click', function(event) {
					// does the link point to the same page?
					// this also takes care of cases with a <base>-Tag or Links not starting with the hash #
					// e.g.  when the current url already is index.html
					var href = this.href.substr(0, this.href.indexOf('#')),
						locationHref = location.href,
						hash,
						element,
						container,
						jsp,
						scrollTop,
						elementTop;
					if (location.href.indexOf('#') !== -1) {
						locationHref = location.href.substr(0, location.href.indexOf('#'));
					}
					if (href !== locationHref) {
						// the link points to another page
						return;
					}

					// check if jScrollPane should handle this click event
					hash = escape(this.href.substr(this.href.indexOf('#') + 1));

					// find the element on the page
					try {
						element = $('#' + hash + ', a[name="' + hash + '"]');
					} catch (e) {
						// hash is not a valid jQuery identifier
						return;
					}

					if (!element.length) {
						// this link does not point to an element on this page
						return;
					}

					container = element.closest('.jspScrollable');
					jsp = container.data('jsp');

					// jsp might be another jsp instance than the one, that bound this event
					// remember: this event is only bound once for all instances.
					jsp.scrollToElement(element, true);

					if (container[0].scrollIntoView) {
						// also scroll to the top of the container (if it is not visible)
						scrollTop = $(window).scrollTop();
						elementTop = element.offset().top;
						if (elementTop < scrollTop || elementTop > scrollTop + $(window).height()) {
							container[0].scrollIntoView();
						}
					}

					// jsp handled this event, prevent the browser default (scrolling :P)
					event.preventDefault();
				});
			}

			// Init touch on iPad, iPhone, iPod, Android
			function initTouch()
			{
				var startX,
					startY,
					touchStartX,
					touchStartY,
					moved,
					moving = false;

				container.off('touchstart.jsp touchmove.jsp touchend.jsp click.jsp-touchclick').on(
					'touchstart.jsp',
					function(e)
					{
						var touch = e.originalEvent.touches[0];
						startX = contentPositionX();
						startY = contentPositionY();
						touchStartX = touch.pageX;
						touchStartY = touch.pageY;
						moved = false;
						moving = true;
					}
				).on(
					'touchmove.jsp',
					function(ev)
					{
						if(!moving) {
							return;
						}

						var touchPos = ev.originalEvent.touches[0],
							dX = horizontalDragPosition, dY = verticalDragPosition;

						jsp.scrollTo(startX + touchStartX - touchPos.pageX, startY + touchStartY - touchPos.pageY);

						moved = moved || Math.abs(touchStartX - touchPos.pageX) > 5 || Math.abs(touchStartY - touchPos.pageY) > 5;

						// return true if there was no movement so rest of screen can scroll
						return dX == horizontalDragPosition && dY == verticalDragPosition;
					}
				).on(
					'touchend.jsp',
					function(e)
					{
						moving = false;
						/*if(moved) {
							return false;
						}*/
					}
				).on(
					'click.jsp-touchclick',
					function(e)
					{
						if(moved) {
							moved = false;
							return false;
						}
					}
				);
			}

			function destroy(){
				var currentY = contentPositionY(),
					currentX = contentPositionX();
				elem.removeClass('jspScrollable').off('.jsp');
				pane.off('.jsp');
				elem.replaceWith(originalElement.append(pane.children()));
				originalElement.scrollTop(currentY);
				originalElement.scrollLeft(currentX);

				// clear reinitialize timer if active
				if (reinitialiseInterval) {
					clearInterval(reinitialiseInterval);
				}
			}

			// Public API
			$.extend(
				jsp,
				{
					// Reinitialises the scroll pane (if it's internal dimensions have changed since the last time it
					// was initialised). The settings object which is passed in will override any settings from the
					// previous time it was initialised - if you don't pass any settings then the ones from the previous
					// initialisation will be used.
					reinitialise: function(s)
					{
						s = $.extend({}, settings, s);
						initialise(s);
					},
					// Scrolls the specified element (a jQuery object, DOM node or jQuery selector string) into view so
					// that it can be seen within the viewport. If stickToTop is true then the element will appear at
					// the top of the viewport, if it is false then the viewport will scroll as little as possible to
					// show the element. You can also specify if you want animation to occur. If you don't provide this
					// argument then the animateScroll value from the settings object is used instead.
					scrollToElement: function(ele, stickToTop, animate)
					{
						scrollToElement(ele, stickToTop, animate);
					},
					// Scrolls the pane so that the specified co-ordinates within the content are at the top left
					// of the viewport. animate is optional and if not passed then the value of animateScroll from
					// the settings object this jScrollPane was initialised with is used.
					scrollTo: function(destX, destY, animate)
					{
						scrollToX(destX, animate);
						scrollToY(destY, animate);
					},
					// Scrolls the pane so that the specified co-ordinate within the content is at the left of the
					// viewport. animate is optional and if not passed then the value of animateScroll from the settings
					// object this jScrollPane was initialised with is used.
					scrollToX: function(destX, animate)
					{
						scrollToX(destX, animate);
					},
					// Scrolls the pane so that the specified co-ordinate within the content is at the top of the
					// viewport. animate is optional and if not passed then the value of animateScroll from the settings
					// object this jScrollPane was initialised with is used.
					scrollToY: function(destY, animate)
					{
						scrollToY(destY, animate);
					},
					// Scrolls the pane to the specified percentage of its maximum horizontal scroll position. animate
					// is optional and if not passed then the value of animateScroll from the settings object this
					// jScrollPane was initialised with is used.
					scrollToPercentX: function(destPercentX, animate)
					{
						scrollToX(destPercentX * (contentWidth - paneWidth), animate);
					},
					// Scrolls the pane to the specified percentage of its maximum vertical scroll position. animate
					// is optional and if not passed then the value of animateScroll from the settings object this
					// jScrollPane was initialised with is used.
					scrollToPercentY: function(destPercentY, animate)
					{
						scrollToY(destPercentY * (contentHeight - paneHeight), animate);
					},
					// Scrolls the pane by the specified amount of pixels. animate is optional and if not passed then
					// the value of animateScroll from the settings object this jScrollPane was initialised with is used.
					scrollBy: function(deltaX, deltaY, animate)
					{
						jsp.scrollByX(deltaX, animate);
						jsp.scrollByY(deltaY, animate);
					},
					// Scrolls the pane by the specified amount of pixels. animate is optional and if not passed then
					// the value of animateScroll from the settings object this jScrollPane was initialised with is used.
					scrollByX: function(deltaX, animate)
					{
						var destX = contentPositionX() + Math[deltaX<0 ? 'floor' : 'ceil'](deltaX),
							percentScrolled = destX / (contentWidth - paneWidth);
						positionDragX(percentScrolled * dragMaxX, animate);
					},
					// Scrolls the pane by the specified amount of pixels. animate is optional and if not passed then
					// the value of animateScroll from the settings object this jScrollPane was initialised with is used.
					scrollByY: function(deltaY, animate)
					{
						var destY = contentPositionY() + Math[deltaY<0 ? 'floor' : 'ceil'](deltaY),
							percentScrolled = destY / (contentHeight - paneHeight);
						positionDragY(percentScrolled * dragMaxY, animate);
					},
					// Positions the horizontal drag at the specified x position (and updates the viewport to reflect
					// this). animate is optional and if not passed then the value of animateScroll from the settings
					// object this jScrollPane was initialised with is used.
					positionDragX: function(x, animate)
					{
						positionDragX(x, animate);
					},
					// Positions the vertical drag at the specified y position (and updates the viewport to reflect
					// this). animate is optional and if not passed then the value of animateScroll from the settings
					// object this jScrollPane was initialised with is used.
					positionDragY: function(y, animate)
					{
						positionDragY(y, animate);
					},
					// This method is called when jScrollPane is trying to animate to a new position. You can override
					// it if you want to provide advanced animation functionality. It is passed the following arguments:
					//  * ele          - the element whose position is being animated
					//  * prop         - the property that is being animated
					//  * value        - the value it's being animated to
					//  * stepCallback - a function that you must execute each time you update the value of the property
					//  * completeCallback - a function that will be executed after the animation had finished
					// You can use the default implementation (below) as a starting point for your own implementation.
					animate: function(ele, prop, value, stepCallback, completeCallback)
					{
						var params = {};
						params[prop] = value;
						ele.animate(
							params,
							{
								'duration'	: settings.animateDuration,
								'easing'	: settings.animateEase,
								'queue'		: false,
								'step'		: stepCallback,
								'complete'	: completeCallback
							}
						);
					},
					// Returns the current x position of the viewport with regards to the content pane.
					getContentPositionX: function()
					{
						return contentPositionX();
					},
					// Returns the current y position of the viewport with regards to the content pane.
					getContentPositionY: function()
					{
						return contentPositionY();
					},
					// Returns the width of the content within the scroll pane.
					getContentWidth: function()
					{
						return contentWidth;
					},
					// Returns the height of the content within the scroll pane.
					getContentHeight: function()
					{
						return contentHeight;
					},
					// Returns the horizontal position of the viewport within the pane content.
					getPercentScrolledX: function()
					{
						return contentPositionX() / (contentWidth - paneWidth);
					},
					// Returns the vertical position of the viewport within the pane content.
					getPercentScrolledY: function()
					{
						return contentPositionY() / (contentHeight - paneHeight);
					},
					// Returns whether or not this scrollpane has a horizontal scrollbar.
					getIsScrollableH: function()
					{
						return isScrollableH;
					},
					// Returns whether or not this scrollpane has a vertical scrollbar.
					getIsScrollableV: function()
					{
						return isScrollableV;
					},
					// Gets a reference to the content pane. It is important that you use this method if you want to
					// edit the content of your jScrollPane as if you access the element directly then you may have some
					// problems (as your original element has had additional elements for the scrollbars etc added into
					// it).
					getContentPane: function()
					{
						return pane;
					},
					// Scrolls this jScrollPane down as far as it can currently scroll. If animate isn't passed then the
					// animateScroll value from settings is used instead.
					scrollToBottom: function(animate)
					{
						positionDragY(dragMaxY, animate);
					},
					// Hijacks the links on the page which link to content inside the scrollpane. If you have changed
					// the content of your page (e.g. via AJAX) and want to make sure any new anchor links to the
					// contents of your scroll pane will work then call this function.
					hijackInternalLinks: $.noop,
					// Removes the jScrollPane and returns the page to the state it was in before jScrollPane was
					// initialised.
					destroy: function()
					{
							destroy();
					}
				}
			);

			initialise(s);
		}

		// Pluginifying code...
		settings = $.extend({}, $.fn.jScrollPane.defaults, settings);

		// Apply default speed
		$.each(['arrowButtonSpeed', 'trackClickSpeed', 'keyboardSpeed'], function() {
			settings[this] = settings[this] || settings.speed;
		});

		return this.each(
			function()
			{
				var elem = $(this), jspApi = elem.data('jsp');
				if (jspApi) {
					jspApi.reinitialise(settings);
				} else {
					$("script",elem).filter('[type="text/javascript"],:not([type])').remove();
					jspApi = new JScrollPane(elem, settings);
					elem.data('jsp', jspApi);
				}
			}
		);
	};

	$.fn.jScrollPane.defaults = {
		showArrows					: false,
		maintainPosition			: true,
		stickToBottom				: false,
		stickToRight				: false,
		clickOnTrack				: true,
		autoReinitialise			: false,
		autoReinitialiseDelay		: 500,
		verticalDragMinHeight		: 0,
		verticalDragMaxHeight		: 99999,
		horizontalDragMinWidth		: 0,
		horizontalDragMaxWidth		: 99999,
		contentWidth				: undefined,
		animateScroll				: false,
		animateDuration				: 300,
		animateEase					: 'linear',
		hijackInternalLinks			: false,
		verticalGutter				: 4,
		horizontalGutter			: 4,
		mouseWheelSpeed				: 3,
		arrowButtonSpeed			: 0,
		arrowRepeatFreq				: 50,
		arrowScrollOnHover			: false,
		trackClickSpeed				: 0,
		trackClickRepeatFreq		: 70,
		verticalArrowPositions		: 'split',
		horizontalArrowPositions	: 'split',
		enableKeyboardNavigation	: true,
		hideFocus					: false,
		keyboardSpeed				: 0,
		initialDelay                : 300,        // Delay before starting repeating
		speed						: 30,		// Default speed when others falsey
		scrollPagePercent			: 0.8,		// Percent of visible area scrolled when pageUp/Down or track area pressed
		alwaysShowVScroll			: false,
		alwaysShowHScroll			: false,
		resizeSensor				: false,
		resizeSensorDelay			: 0,
	};

}));


text:
This repository contains code for various programming assignments of B551: Elements of Artificial Intelligence course taken in Fall 2016 at Indiana University.

[Course Description](https://www.soic.indiana.edu/graduate/courses/index.html?number=B551&department=CSCI).

redpajama_set_name: RedPajamaGithub


text:
package org.apache.myfaces.view.facelets.tag.composite;

import java.beans.BeanDescriptor;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

import javax.faces.component.UINamingContainer;

import junit.framework.TestCase;

public class SerializableAttributesTestCase extends TestCase
{

    @Override
    protected void setUp() throws Exception
    {
        super.setUp();
    }

    @Override
    protected void tearDown() throws Exception
    {
        super.tearDown();
    }

    public void testSerializeCompositeResourceWrapper() throws Exception
    {
        CompositeResouceWrapper subject = new CompositeResouceWrapper();
        subject.setResourceName("testRes");
        subject.setLibraryName("testLib");
        subject.setContentType(null);

        ByteArrayOutputStream baos = new ByteArrayOutputStream(128);
        ObjectOutputStream oos = new ObjectOutputStream(baos);
        oos.writeObject(subject);
        oos.flush();
        baos.flush();
        ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
        ObjectInputStream ois = new ObjectInputStream(bais);
        CompositeResouceWrapper blorg = (CompositeResouceWrapper) ois.readObject();
        assertEquals(blorg.getResourceName(), subject.getResourceName());
        assertEquals(blorg.getLibraryName(), subject.getLibraryName());
        assertEquals(blorg.getContentType(), subject.getContentType());
        oos.close();
        ois.close();
    }

    public void testSerializeCompositeComponentBeanInfo() throws Exception
    {
        BeanDescriptor descriptor = new BeanDescriptor(UINamingContainer.class);
        CompositeComponentBeanInfo subject = new CompositeComponentBeanInfo(descriptor);
        CompositeComponentPropertyDescriptor pd = new CompositeComponentPropertyDescriptor("attrName");
        pd.setValue("type","someClass");
        subject.getPropertyDescriptorsList().add(pd);
        ByteArrayOutputStream baos = new ByteArrayOutputStream(128);
        ObjectOutputStream oos = new ObjectOutputStream(baos);
        oos.writeObject(subject);
        oos.flush();
        baos.flush();
        ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
        ObjectInputStream ois = new ObjectInputStream(bais);
        CompositeComponentBeanInfo blorg = (CompositeComponentBeanInfo) ois.readObject();

        assertEquals(UINamingContainer.class, blorg.getBeanDescriptor().getBeanClass());
        assertEquals(pd.getName(), blorg.getPropertyDescriptorsList().get(0).getName());
        oos.close();
        ois.close();
    }
}


text:
<!DOCTYPE html>
<html>
<head>
    <title>LiveReload Test</title>
    <link rel="stylesheet" href="test.css">
</head>
<body>
    <script src="../../../dist/livereload.js?host=localhost" async defer></script>
</body>
</html>


text:
ACCEPTED

#### According to
Index Fungorum

#### Published in
Mycol. Pap. 171: 144 (1996)

#### Original name
Polycoccum serusiauxii Matzer

### Remarks
null


text:
layout: docs
title: Mu
section: docs
permalink: /
---

# Mu-Scala

[Mu] is a suite of libraries and tools that help you build and maintain
microservices and clients in a functional style.

## Getting Started

If you're new to Mu-Scala, check out the [Getting Started
guide](getting-started) and the [tutorials](tutorials).

## Features

While you focus on implementing the business logic for your service, let Mu take
care of the boilerplate and non-functional requirements, including:

* generation of model classes, service interfaces and clients from [Avro],
  or [Protobuf] <abbr title="Interface definition language">IDL</abbr>
  files
* serialization of requests and responses into Avro/Protobuf
* building high-performance [gRPC] servers and clients
* handling of [streaming requests and responses](guides/grpc-streaming) using [FS2] Stream
* [accessing metadata on services](guides/accessing-metadata)
* [distributed tracing](guides/distributed-tracing)
* [metrics reporting](guides/metrics-reporting)
* ... and plenty more features on the way!

Specifically, Mu helps you to build [gRPC] servers and clients based on either
[Avro] or [Protobuf] protocol definitions.

## Scala versions

Mu is available for Scala 2.13 and 3.x.

However, Avro support for Scala 3 should be considered *experimental* because
the Scala 3 version of Avro4s is not yet feature-complete. For example, fields
with default values are not supported properly.

Most code samples in this documentation site use Scala 3 syntax.

[Avro]: https://avro.apache.org/
[FS2]: https://github.com/typelevel/fs2
[gRPC]: https://grpc.io/
[Mu]: https://github.com/higherkindness/mu-scala
[Protobuf]: https://developers.google.com/protocol-buffers


text:
<!DOCTYPE html>

        <link rel="stylesheet" href="style.css">
        <title>Alper Unal - Software Engineer</title>

                        Alper Unal

                        Software Engineer

                Linkedin


text:
class Module:
    def __init__(self):
        self.name = ""
        self.type = ""
        self.version = ""
        self.artefactos = [];
        self.checked = False;

class BuildConf:
    def __init__(self,build_conf_file):
        self.modules = [];
        self.load_from_buildconf(build_conf_file);

    def get_module(self,module_name):
        for m in self.modules:
            if m.name == module_name:
                m.checked = True;
                return m;
        return None;

    def load_from_buildconf(self,buildconffile):
        with open(buildconffile) as f:
            process_line = False;
            for l in f:
                if process_line:
                    line = l.lstrip(" ");
                    line = line.rstrip("\n");
                    if len(line) == 0:
                        continue;
                    if line[0] == "#":
                        continue;
                    if line[0] == ")":
                        break;
                    lsplit = line.split(":")
                    module = Module();
                    module.type = lsplit[0];
                    namespli = lsplit[1].split("-")
                    if len(namespli) == 1:
                        module.name = namespli[0]
                        module.version = "0";
                    elif len(namespli) == 2:
                        module.name = namespli[0]
                        module.version = namespli[1]
                    else:
                        print("Line:"+line+" has something weird");
                    if len(lsplit)==3:
                        module.artefactos = lsplit[2].split(",");
                    self.modules.append(module);
                if "MODULE_LIST" in l:
                    process_line = True;
                    continue;


text:
package Q2_02_Return_Kth_To_Last;

import CtCILibrary.AssortedMethods;

public class Tester {

	public static void main(String[] args) {

	}

}


text:
Public NotInheritable Class AboutCodeLadder

    Private Sub AboutCodeLadder_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        ' Set the title of the form.
        Dim ApplicationTitle As String
        If My.Application.Info.Title <> "" Then
            ApplicationTitle = My.Application.Info.Title
        Else
            ApplicationTitle = System.IO.Path.GetFileNameWithoutExtension(My.Application.Info.AssemblyName)
        End If
        Me.Text = String.Format("About {0}", ApplicationTitle)
        ' Initialize all of the text displayed on the About Box.
        ' TODO: Customize the application's assembly information in the "Application" pane of the project
        '    properties dialog (under the "Project" menu).
        Me.LabelProductName.Text = My.Application.Info.ProductName
        Me.LabelVersion.Text = String.Format("Version {0}", My.Application.Info.Version.ToString)
        Me.LabelCopyright.Text = My.Application.Info.Copyright
        Me.LabelCompanyName.Text = My.Application.Info.CompanyName
        Me.TextBoxDescription.Text = My.Application.Info.Description _
                                   & vbNewLine & vbNewLine _
                                   & "The content provided relates to CISC-181 as taught at San Diego Mesa College " _
                                   & "using material drawn from the first six chapters of " _
                                   & "Gaddis, 'Starting out with Visual Basic 2010', Addison Wesley, 2011."
    End Sub

    Private Sub OKButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles OKButton.Click
        Me.Close()
    End Sub

End Class


text:
//-----------------------------------------------------------------------
// <copyright file="Serialization.cs" company="Akka.NET Project">
//     Copyright (C) 2009-2020 Lightbend Inc. <http://www.lightbend.com>
//     Copyright (C) 2013-2020 .NET Foundation <https://github.com/akkadotnet/akka.net>
// </copyright>
//-----------------------------------------------------------------------

using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Reflection;
using System.Runtime.Serialization;
using Akka.Actor;
using Akka.Annotations;
using Akka.Util;
using Akka.Util.Internal;
using Akka.Util.Reflection;
using Akka.Configuration;

namespace Akka.Serialization
{
    /// <summary>
    /// INTERNAL API.
    ///
    /// Serialization information needed for serializing local actor refs.
    /// </summary>
    [InternalApi]
    public sealed class Information : IEquatable<Information>
    {
        public Information(Address address, ActorSystem system)
        {
            Address = address;
            System = system;
        }

        public Address Address { get; }

        public ActorSystem System { get; }

        public bool Equals(Information other)
        {
            if (ReferenceEquals(null, other)) return false;
            if (ReferenceEquals(this, other)) return true;
            return Address.Equals(other.Address);
        }

        public override bool Equals(object obj)
        {
            if (ReferenceEquals(null, obj)) return false;
            if (ReferenceEquals(this, obj)) return true;
            if (obj.GetType() != this.GetType()) return false;
            return Equals((Information)obj);
        }

        public override int GetHashCode()
        {
            unchecked
            {
                return (Address.GetHashCode() * 397);
            }
        }

        public static bool operator ==(Information left, Information right)
        {
            return Equals(left, right);
        }

        public static bool operator !=(Information left, Information right)
        {
            return !Equals(left, right);
        }
    }

    /// <summary>
    /// The serialization system used by Akka.NET to serialize and deserialize objects
    /// per the <see cref="ActorSystem"/>'s serialization configuration.
    /// </summary>
    public class Serialization
    {
        /// <summary>
        /// Used to determine the manifest for a message, if applicable.
        /// </summary>
        /// <param name="s">The serializer we want to use on the message.</param>
        /// <param name="msg">The message payload.</param>
        /// <returns>A populated string is applicable; <see cref="string.Empty"/> otherwise.</returns>
        /// <remarks>
        /// WARNING: if you change this method it's likely that the DaemonMsgCreateSerializer and other calls will need changes too.
        /// </remarks>
        public static string ManifestFor(Serializer s, object msg)
        {
            switch (s)
            {
                case SerializerWithStringManifest s2:
                    return s2.Manifest(msg);
                case Serializer s3 when s3.IncludeManifest:
                    return msg.GetType().TypeQualifiedName();
                default:
                    return string.Empty;
            }
        }

        /// <summary>
        /// Needs to be INTERNAL so it can be accessed from tests. Should never be set directly.
        /// </summary>
        [ThreadStatic]
        internal static Information CurrentTransportInformation;

        /// <summary>
        ///  Retrieves the <see cref="Information"/> used for serializing and deserializing
        /// <see cref="IActorRef"/> instances in all serializers.
        /// </summary>
        public static Information GetCurrentTransportInformation()
        {
            if (CurrentTransportInformation == null)
            {
                throw new InvalidOperationException(
                    "CurrentTransportInformation is not set. Use Serialization.WithTransport<T>.");
            }

            return CurrentTransportInformation;
        }

        /// <summary>
        /// TBD
        /// </summary>
        /// <typeparam name="T">TBD</typeparam>
        /// <param name="system">TBD</param>
        /// <param name="address">TBD</param>
        /// <param name="action">TBD</param>
        /// <returns>TBD</returns>
        [Obsolete("Obsolete. Use the SerializeWithTransport<T>(ExtendedActorSystem) method instead.")]
        public static T WithTransport<T>(ActorSystem system, Address address, Func<T> action)
        {
            CurrentTransportInformation = new Information(address, system);
            var res = action();
            CurrentTransportInformation = null;
            return res;
        }

        private readonly Serializer _nullSerializer;

        private readonly ConcurrentDictionary<Type, Serializer> _serializerMap = new ConcurrentDictionary<Type, Serializer>();
        private readonly Dictionary<int, Serializer> _serializersById = new Dictionary<int, Serializer>();
        private readonly Dictionary<string, Serializer> _serializersByName = new Dictionary<string, Serializer>();

        private readonly ImmutableHashSet<SerializerDetails> _serializerDetails;

        /// <summary>
        /// Serialization module. Contains methods for serialization and deserialization as well as
        /// locating a Serializer for a particular class as defined in the mapping in the configuration.
        /// </summary>
        /// <param name="system">The ActorSystem to which this serializer belongs.</param>
        public Serialization(ExtendedActorSystem system)
        {
            System = system;
            _nullSerializer = new NullSerializer(system);
            AddSerializer("null", _nullSerializer);

            var serializersConfig = system.Settings.Config.GetConfig("akka.actor.serializers").AsEnumerable().ToList();
            var serializerBindingConfig = system.Settings.Config.GetConfig("akka.actor.serialization-bindings").AsEnumerable().ToList();
            var serializerSettingsConfig = system.Settings.Config.GetConfig("akka.actor.serialization-settings");

            _serializerDetails = system.Settings.Setup.Get<SerializationSetup>()
                .Select(x => x.CreateSerializers(system)).GetOrElse(ImmutableHashSet<SerializerDetails>.Empty);

            foreach (var kvp in serializersConfig)
            {
                var serializerTypeName = kvp.Value.GetString();
                var serializerType = Type.GetType(serializerTypeName);
                if (serializerType == null)
                {
                    system.Log.Warning("The type name for serializer '{0}' did not resolve to an actual Type: '{1}'", kvp.Key, serializerTypeName);
                    continue;
                }

                var serializerConfig = serializerSettingsConfig.GetConfig(kvp.Key);

                var serializer = !serializerConfig.IsNullOrEmpty()
                    ? (Serializer)Activator.CreateInstance(serializerType, system, serializerConfig)
                    : (Serializer)Activator.CreateInstance(serializerType, system);

                AddSerializer(kvp.Key, serializer);
            }

            // Add any serializers that are registered via the SerializationSetup
            foreach (var details in _serializerDetails)
            {
                AddSerializer(details.Alias, details.Serializer);

                // populate the serialization map
                foreach (var t in details.UseFor)
                {
                    AddSerializationMap(t, details.Serializer);
                }
            }

            foreach (var kvp in serializerBindingConfig)
            {
                var typename = kvp.Key;
                var serializerName = kvp.Value.GetString();
                var messageType = Type.GetType(typename);

                if (messageType == null)
                {

                    system.Log.Warning("The type name for message/serializer binding '{0}' did not resolve to an actual Type: '{1}'", serializerName, typename);
                    continue;
                }

                if (!_serializersByName.TryGetValue(serializerName, out var serializer))
                {
                    system.Log.Warning("Serialization binding to non existing serializer: '{0}'", serializerName);
                    continue;
                }

                AddSerializationMap(messageType, serializer);
            }

        }

        private Information SerializationInfo => System.Provider.SerializationInformation;

        /// <summary>
        /// Performs the requested serialization function while also setting
        /// the <see cref="CurrentTransportInformation"/> based on available data
        /// from the <see cref="ActorSystem"/>. Useful when serializing <see cref="IActorRef"/>s.
        /// </summary>
        /// <typeparam name="T">The type of message being serialized.</typeparam>
        /// <param name="system">The <see cref="ActorSystem"/> performing serialization.</param>
        /// <param name="action">The serialization function.</param>
        /// <returns>The serialization output.</returns>
        public static T WithTransport<T>(ExtendedActorSystem system, Func<T> action)
        {
            var info = system.Provider.SerializationInformation;
            if (CurrentTransportInformation == info)
            {
                // already set
                return action();
            }

            var oldInfo = CurrentTransportInformation;
            try
            {
                CurrentTransportInformation = info;
                return action();
            }
            finally
            {
                CurrentTransportInformation = oldInfo;
            }
        }

        private T WithTransport<T>(Func<T> action)
        {
            var oldInfo = CurrentTransportInformation;
            try
            {
                if (oldInfo == null)
                    CurrentTransportInformation = SerializationInfo;
                return action();
            }
            finally
            {
                CurrentTransportInformation = oldInfo;
            }
        }

        private Serializer GetSerializerByName(string name)
        {
            if (name == null)
                return null;

            _serializersByName.TryGetValue(name, out Serializer serializer);
            return serializer;
        }

        /// <summary>
        /// The ActorSystem to which <see cref="Serialization"/> is bound.
        /// </summary>
        public ExtendedActorSystem System { get; }

        /// <summary>
        /// Adds the serializer to the internal state of the serialization subsystem
        /// </summary>
        /// <param name="serializer">Serializer instance</param>
        [Obsolete("No longer supported. Use the AddSerializer(name, serializer) overload instead.", true)]
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public void AddSerializer(Serializer serializer)
        {
            _serializersById.Add(serializer.Identifier, serializer);
        }

        /// <summary>
        /// Adds the serializer to the internal state of the serialization subsystem
        /// </summary>
        /// <param name="name">Configuration name of the serializer</param>
        /// <param name="serializer">Serializer instance</param>
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public void AddSerializer(string name, Serializer serializer)
        {
            _serializersById.Add(serializer.Identifier, serializer);
            _serializersByName.Add(name, serializer);
        }

        /// <summary>
        /// TBD
        /// </summary>
        /// <param name="type">TBD</param>
        /// <param name="serializer">TBD</param>
        /// <returns>TBD</returns>
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public void AddSerializationMap(Type type, Serializer serializer)
        {
            _serializerMap[type] = serializer;
        }

        /// <summary>
        /// Serializes the given message into an array of bytes using whatever serializer is currently configured.
        /// </summary>
        /// <param name="o">The message being serialized.</param>
        /// <returns>A byte array containing the serialized message.</returns>
        public byte[] Serialize(object o)
        {
            return WithTransport(() => FindSerializerFor(o).ToBinary(o));
        }

        /// <summary>
        /// Deserializes the given array of bytes using the specified serializer id, using the optional type hint to the Serializer.
        /// </summary>
        /// <param name="bytes">TBD</param>
        /// <param name="serializerId">TBD</param>
        /// <param name="type">TBD</param>
        /// <exception cref="SerializationException">
        /// This exception is thrown if the system cannot find the serializer with the given <paramref name="serializerId"/>.
        /// </exception>
        /// <returns>The resulting object</returns>
        public object Deserialize(byte[] bytes, int serializerId, Type type)
        {
            return WithTransport(() =>
            {
                if (!_serializersById.TryGetValue(serializerId, out var serializer))
                    throw new SerializationException(
                        $"Cannot find serializer with id [{serializerId}] (class [{type?.Name}]). The most probable reason" +
                        " is that the configuration entry 'akka.actor.serializers' is not in sync between the two systems.");

                return serializer.FromBinary(bytes, type);
            });
        }

        /// <summary>
        /// Deserializes the given array of bytes using the specified serializer id, using the optional type hint to the Serializer.
        /// </summary>
        /// <param name="bytes">TBD</param>
        /// <param name="serializerId">TBD</param>
        /// <param name="manifest">TBD</param>
        /// <exception cref="SerializationException">
        /// This exception is thrown if the system cannot find the serializer with the given <paramref name="serializerId"/>
        /// or it couldn't find the given <paramref name="manifest"/> with the given <paramref name="serializerId"/>.
        /// </exception>
        /// <returns>The resulting object</returns>
        public object Deserialize(byte[] bytes, int serializerId, string manifest)
        {
            if (!_serializersById.TryGetValue(serializerId, out var serializer))
                throw new SerializationException(
                    $"Cannot find serializer with id [{serializerId}] (manifest [{manifest}]). The most probable reason" +
                    " is that the configuration entry 'akka.actor.serializers' is not in sync between the two systems.");

            // not using `withTransportInformation { () =>` because deserializeByteBuffer is supposed to be the
            // possibility for allocation free serialization
            var oldInfo = Serialization.CurrentTransportInformation;
            try
            {
                if (oldInfo == null)
                    Serialization.CurrentTransportInformation = SerializationInfo;

                if (serializer is SerializerWithStringManifest stringManifest)
                    return stringManifest.FromBinary(bytes, manifest);
                if (string.IsNullOrEmpty(manifest))
                    return serializer.FromBinary(bytes, null);
                Type type;
                try
                {
                    type = TypeCache.GetType(manifest);
                }
                catch (Exception ex)
                {
                    throw new SerializationException(
                        $"Cannot find manifest class [{manifest}] for serializer with id [{serializerId}].", ex);
                }

                return serializer.FromBinary(bytes, type);
            }
            finally
            {
                Serialization.CurrentTransportInformation = oldInfo;
            }
        }

        /// <summary>
        /// Returns the Serializer configured for the given object, returns the NullSerializer if it's null.
        /// </summary>
        /// <param name="obj">The object that needs to be serialized</param>
        /// <param name="defaultSerializerName">The config name of the serializer to use when no specific binding config is present</param>
        /// <returns>The serializer configured for the given object type</returns>
        public Serializer FindSerializerFor(object obj, string defaultSerializerName = null)
        {
            return obj == null ? _nullSerializer : FindSerializerForType(obj.GetType(), defaultSerializerName);
        }

        //cache to eliminate lots of typeof operator calls
        private readonly Type _objectType = typeof(object);

        /// <summary>
        /// Returns the configured Serializer for the given Class. The configured Serializer
        /// is used if the configured class `IsAssignableFrom` from the <see cref="Type">type</see>, i.e.
        /// the configured class is a super class or implemented interface. In case of
        /// ambiguity it is primarily using the most specific configured class,
        /// and secondly the entry configured first.
        /// </summary>
        /// <param name="objectType">TBD</param>
        /// <param name="defaultSerializerName">The config name of the serializer to use when no specific binding config is present</param>
        /// <exception cref="SerializationException">
        /// This exception is thrown if the serializer of the given <paramref name="objectType"/> could not be found.
        /// </exception>
        /// <returns>The serializer configured for the given object type</returns>
        public Serializer FindSerializerForType(Type objectType, string defaultSerializerName = null)
        {
            if (_serializerMap.TryGetValue(objectType, out var fullMatchSerializer))
                return fullMatchSerializer;

            Serializer serializer = null;
            Type type = objectType;

            // TODO: see if we can do a better job with proper type sorting here - most specific to least specific (object serializer goes last)
            foreach (var serializerType in _serializerMap)
            {
                // force deferral of the base "object" serializer until all other higher-level types have been evaluated
                if (serializerType.Key.IsAssignableFrom(type) && serializerType.Key != _objectType)
                {
                    serializer = serializerType.Value;
                    break;
                }
            }

            if (serializer == null)
                serializer = GetSerializerByName(defaultSerializerName);

            // do a final check for the "object" serializer
            if (serializer == null)
                _serializerMap.TryGetValue(_objectType, out serializer);

            if (serializer == null)
                throw new SerializationException($"Serializer not found for type {objectType.Name}");

            AddSerializationMap(type, serializer);
            return serializer;
        }

        /// <summary>
        /// The serialized path of an actorRef, based on the current transport serialization information.
        /// If there is no external address available for the requested address then the systems default
        /// address will be used.
        ///
        /// If there is no external address available in the given <see cref="IActorRef"/> then the systems default
        /// address will be used and that is retrieved from the ThreadLocal <see cref="Information"/>
        /// that was set with <see cref="Serialization.WithTransportInformation{T}"/>
        /// </summary>
        /// <param name="actorRef">The <see cref="IActorRef"/> to be serialized.</param>
        /// <returns>Absolute path to the serialized actor.</returns>
        public static string SerializedActorPath(IActorRef actorRef)
        {
            if (Equals(actorRef, ActorRefs.NoSender))
                return String.Empty;

            var path = actorRef.Path;
            ExtendedActorSystem originalSystem = null;
            if (actorRef is ActorRefWithCell)
            {
                originalSystem = actorRef.AsInstanceOf<ActorRefWithCell>().Underlying.System.AsInstanceOf<ExtendedActorSystem>();
            }

            if (CurrentTransportInformation == null)
            {
                if (originalSystem == null)
                {
                    var res = path.ToSerializationFormat();
                    return res;
                }

                try
                {
                    var defaultAddress = originalSystem.Provider.DefaultAddress;
                    var res = path.ToSerializationFormatWithAddress(defaultAddress);
                    return res;
                }
                catch
                {
                    return path.ToSerializationFormat();
                }
            }

            //CurrentTransportInformation exists
            var system = CurrentTransportInformation.System;
            var address = CurrentTransportInformation.Address;
            if (originalSystem == null || originalSystem == system)
            {
                var res = path.ToSerializationFormatWithAddress(address);
                return res;
            }
            else
            {
                var provider = originalSystem.Provider;
                var res =
                    path.ToSerializationFormatWithAddress(provider.GetExternalAddressFor(address) ?? provider.DefaultAddress);
                return res;
            }
        }

        internal Serializer GetSerializerById(int serializerId)
        {
            return _serializersById[serializerId];
        }
    }
}


text:
package mesosphere.marathon.client;

import feign.*;
import feign.Feign.Builder;
import feign.auth.BasicAuthRequestInterceptor;
import feign.codec.ErrorDecoder;
import feign.gson.GsonDecoder;
import feign.gson.GsonEncoder;
import feign.slf4j.Slf4jLogger;
import mesosphere.client.common.ModelUtils;
import mesosphere.marathon.client.auth.TokenAuthRequestInterceptor;

import static java.util.Arrays.asList;

public class MarathonClient {

	public static final String DEBUG_JSON_OUTPUT = "DEBUG_JSON_OUTPUT";

	static class MarathonHeadersInterceptor implements RequestInterceptor {
		@Override
		public void apply(RequestTemplate template) {
			template.header("Accept", "application/json");
			template.header("Content-Type", "application/json");
		}
	}

	static class MarathonErrorDecoder implements ErrorDecoder {
		@Override
		public Exception decode(String methodKey, Response response) {
			return new MarathonException(response.status(), response.reason());
		}
	}

	public static Marathon getInstance(String endpoint) {
		return getInstance(endpoint, null);
	}

	/**
	 * The generalized version of the method that allows more in-depth customizations via
	 * {@link RequestInterceptor}s.
	 *
	 * @param endpoint
	 * 		URL of Marathon
	 * @param interceptors optional request interceptors
	 * @return Marathon client
	 */
	public static Marathon getInstance(String endpoint, RequestInterceptor... interceptors) {

		Builder b = Feign.builder()
				.encoder(new GsonEncoder(ModelUtils.GSON))
				.decoder(new GsonDecoder(ModelUtils.GSON))
				.errorDecoder(new MarathonErrorDecoder());
		if (interceptors != null)
			b.requestInterceptors(asList(interceptors));
		String debugOutput = System.getenv(DEBUG_JSON_OUTPUT);
		if ("System.out".equals(debugOutput)) {
			System.setProperty("org.slf4j.simpleLogger.logFile", "System.out");
			System.setProperty("org.slf4j.simpleLogger.defaultLogLevel", "debug");
			b.logger(new Slf4jLogger()).logLevel(Logger.Level.FULL);
		} else if (debugOutput != null) {
			b.logger(new Logger.JavaLogger().appendToFile(debugOutput)).logLevel(Logger.Level.FULL);
		}
		b.requestInterceptor(new MarathonHeadersInterceptor());
		return b.target(Marathon.class, endpoint);
	}

	/**
	 * Creates a Marathon client proxy that performs HTTP basic authentication.
	 *
	 * @param endpoint URL for Marathon
	 * @param username basic auth username
	 * @param password basic auth password
	 * @return Marathon client
	 */
	public static Marathon getInstanceWithBasicAuth(String endpoint, String username, String password) {
		return getInstance(endpoint,new BasicAuthRequestInterceptor(username,password));
	}

	/**
	 * Creates a Marathon client proxy that uses a token for authentication.
	 *
	 * @param endpoint URL of Marathon
	 * @param token token
     * @return Marathon client
     */
	public static Marathon getInstanceWithTokenAuth(String endpoint, String token) {
		return getInstance(endpoint, new TokenAuthRequestInterceptor(token));
	}
}


text:
import React, { Component } from 'react';
import { Modal, Button, Table, Tabs, Tab } from 'react-bootstrap';
import ModalStore from '../stores/ModalStore';
import ModalActions from '../actions/ModalActions';
import JSFeatureTable from './JSFeatureTable';
import FirewallModuleHealthTable from './FirewallModuleHealthTable';
import ServerReleaseVersionTable from './ServerReleaseVersionTable';
import { componentLogger } from '../utils/logger';

const componentName = 'ServerStatsModal';

class ServerStatsModal extends Component {
    constructor(params) {
        super(params);

        this.state = ModalStore.getState();

        this.onChange = this.onChange.bind(this);
        this.close = this.close.bind(this);
    }

    componentWillMount() {
        componentLogger(componentName, 'componentcomponentWillMount');
    }

    componentDidMount() {
        ModalStore.listen(this.onChange);
        componentLogger(componentName, 'componentDidMount');
    }

    componentWillUnmount() {
        ModalStore.unlisten(this.onChange);
        componentLogger(componentName, 'componentWillUnmount');
    }

    onChange(state) {
        this.setState(state);
    }

    close() {
        ModalActions.hideServerStatsModal();
    }

    render() {
        // TODO: refactor this for this clarity
        let serverStats = (this.state.serverStats ? 1 : 0) ? this.state.serverStats : null,
            jsFeatures = serverStats ? (serverStats.js.jsFeatures ? serverStats.js.jsFeatures : null) : null,
            firewallModuleHealthData = serverStats ? (serverStats.health ? (serverStats.health.data ? serverStats.health.data : null) : null) : null,
            releaseVersions = serverStats ? (serverStats.version ? (serverStats.version.data ? serverStats.version.data : null) : null) : null;

        return (
            <Modal bsSize="large" show={this.state.showModal} onHide={this.close}>
                <Modal.Header closeButton>
                    <Modal.Title>{serverStats ? serverStats.name : ''} Server Stats</Modal.Title>
                </Modal.Header>
                <Modal.Body>
                    <Tabs defaultActiveKey={1}>
                        <Tab eventKey={1} title="JavaScript Features">

                            {jsFeatures ? <JSFeatureTable jsFeatures={jsFeatures} /> : null}
                        </Tab>
                        <Tab eventKey={2} title="Firewall Module Health">

                            {firewallModuleHealthData ? <FirewallModuleHealthTable firewallModuleHealthData={firewallModuleHealthData}/> : null}
                        </Tab>
                        <Tab eventKey={3} title="Release Versions">

                            {releaseVersions ? <ServerReleaseVersionTable releaseVersions={releaseVersions} /> : null}
                        </Tab>
                    </Tabs>
                </Modal.Body>
                <Modal.Footer>
                    <Button onClick={this.close}>Close</Button>
                </Modal.Footer>
            </Modal>
        )
    }
}

export default ServerStatsModal;


text:
<?php

class M_user_group_access extends MY_Model
{
	public $table = 'user_group_access'; // you MUST mention the table name
	public $primary_key = 'group_access_id'; // you MUST mention the primary key
	public function __construct()
	{
        $this->soft_deletes = TRUE;
		$this->return_as = 'array';
		parent::__construct();
	}
}