src/ztfy/myams/resources/js/ext/jquery-mCustomScrollbar.js
changeset 0 8a19e25e39e4
equal deleted inserted replaced
-1:000000000000 0:8a19e25e39e4
       
     1 /*
       
     2  == malihu jquery custom scrollbars plugin ==
       
     3  version: 2.8.3
       
     4  author: malihu (http://manos.malihu.gr)
       
     5  plugin home: http://manos.malihu.gr/jquery-custom-content-scroller
       
     6  */
       
     7 
       
     8 /*
       
     9  Copyright 2010-2013 Manos Malihutsakis
       
    10 
       
    11  This program is free software: you can redistribute it and/or modify
       
    12  it under the terms of the GNU Lesser General Public License as published by
       
    13  the Free Software Foundation, either version 3 of the License, or
       
    14  any later version.
       
    15 
       
    16  This program is distributed in the hope that it will be useful,
       
    17  but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    18  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
       
    19  GNU Lesser General Public License for more details.
       
    20 
       
    21  You should have received a copy of the GNU Lesser General Public License
       
    22  along with this program.  If not, see http://www.gnu.org/licenses/lgpl.html.
       
    23  */
       
    24 (function ($) {
       
    25 	/*plugin script*/
       
    26 	var methods = {
       
    27 			init: function (options) {
       
    28 				var defaults = {
       
    29 						set_width: false, /*optional element width: boolean, pixels, percentage*/
       
    30 						set_height: false, /*optional element height: boolean, pixels, percentage*/
       
    31 						horizontalScroll: false, /*scroll horizontally: boolean*/
       
    32 						scrollInertia: 950, /*scrolling inertia: integer (milliseconds)*/
       
    33 						mouseWheel: true, /*mousewheel support: boolean*/
       
    34 						mouseWheelPixels: "auto", /*mousewheel pixels amount: integer, "auto"*/
       
    35 						autoDraggerLength: true, /*auto-adjust scrollbar dragger length: boolean*/
       
    36 						autoHideScrollbar: false, /*auto-hide scrollbar when idle*/
       
    37 						alwaysShowScrollbar: false, /*always show scrollbar even when there's nothing to scroll (disables autoHideScrollbar): boolean*/
       
    38 						snapAmount: null, /* optional element always snaps to a multiple of this number in pixels */
       
    39 						snapOffset: 0, /* when snapping, snap with this number in pixels as an offset */
       
    40 						scrollButtons: { /*scroll buttons*/
       
    41 							enable: false, /*scroll buttons support: boolean*/
       
    42 							scrollType: "continuous", /*scroll buttons scrolling type: "continuous", "pixels"*/
       
    43 							scrollSpeed: "auto", /*scroll buttons continuous scrolling speed: integer, "auto"*/
       
    44 							scrollAmount: 40 /*scroll buttons pixels scroll amount: integer (pixels)*/
       
    45 						},
       
    46 						advanced: {
       
    47 							updateOnBrowserResize: true, /*update scrollbars on browser resize (for layouts based on percentages): boolean*/
       
    48 							updateOnContentResize: false, /*auto-update scrollbars on content resize (for dynamic content): boolean*/
       
    49 							autoExpandHorizontalScroll: false, /*auto-expand width for horizontal scrolling: boolean*/
       
    50 							autoScrollOnFocus: true, /*auto-scroll on focused elements: boolean*/
       
    51 							normalizeMouseWheelDelta: false /*normalize mouse-wheel delta (-1/1)*/
       
    52 						},
       
    53 						contentTouchScroll: true, /*scrolling by touch-swipe content: boolean*/
       
    54 						callbacks: {
       
    55 							onScrollStart: function () {
       
    56 							}, /*user custom callback function on scroll start event*/
       
    57 							onScroll: function () {
       
    58 							}, /*user custom callback function on scroll event*/
       
    59 							onTotalScroll: function () {
       
    60 							}, /*user custom callback function on scroll end reached event*/
       
    61 							onTotalScrollBack: function () {
       
    62 							}, /*user custom callback function on scroll begin reached event*/
       
    63 							onTotalScrollOffset: 0, /*scroll end reached offset: integer (pixels)*/
       
    64 							onTotalScrollBackOffset: 0, /*scroll begin reached offset: integer (pixels)*/
       
    65 							whileScrolling: function () {
       
    66 							} /*user custom callback function on scrolling event*/
       
    67 						},
       
    68 						theme: "light" /*"light", "dark", "light-2", "dark-2", "light-thick", "dark-thick", "light-thin", "dark-thin"*/
       
    69 					},
       
    70 					options = $.extend(true, defaults, options);
       
    71 				return this.each(function () {
       
    72 					var $this = $(this);
       
    73 					/*set element width/height, create markup for custom scrollbars, add classes*/
       
    74 					if (options.set_width) {
       
    75 						$this.css("width", options.set_width);
       
    76 					}
       
    77 					if (options.set_height) {
       
    78 						$this.css("height", options.set_height);
       
    79 					}
       
    80 					if (!$(document).data("mCustomScrollbar-index")) {
       
    81 						$(document).data("mCustomScrollbar-index", "1");
       
    82 					} else {
       
    83 						var mCustomScrollbarIndex = parseInt($(document).data("mCustomScrollbar-index"));
       
    84 						$(document).data("mCustomScrollbar-index", mCustomScrollbarIndex + 1);
       
    85 					}
       
    86 					$this.wrapInner("<div class='mCustomScrollBox" + " mCS-" + options.theme + "' id='mCSB_" + $(document).data("mCustomScrollbar-index") + "' style='position:relative; height:100%; overflow:hidden; max-width:100%;' />").addClass("mCustomScrollbar _mCS_" + $(document).data("mCustomScrollbar-index"));
       
    87 					var mCustomScrollBox = $this.children(".mCustomScrollBox");
       
    88 					if (options.horizontalScroll) {
       
    89 						mCustomScrollBox.addClass("mCSB_horizontal").wrapInner("<div class='mCSB_h_wrapper' style='position:relative; left:0; width:999999px;' />");
       
    90 						var mCSB_h_wrapper = mCustomScrollBox.children(".mCSB_h_wrapper");
       
    91 						mCSB_h_wrapper.wrapInner("<div class='mCSB_container' style='position:absolute; left:0;' />").children(".mCSB_container").css({"width": mCSB_h_wrapper.children().outerWidth(), "position": "relative"}).unwrap();
       
    92 					} else {
       
    93 						mCustomScrollBox.wrapInner("<div class='mCSB_container' style='position:relative; top:0;' />");
       
    94 					}
       
    95 					var mCSB_container = mCustomScrollBox.children(".mCSB_container");
       
    96 					if ($.support.touch) {
       
    97 						mCSB_container.addClass("mCS_touch");
       
    98 					}
       
    99 					mCSB_container.after("<div class='mCSB_scrollTools' style='position:absolute;'><div class='mCSB_draggerContainer'><div class='mCSB_dragger' style='position:absolute;' oncontextmenu='return false;'><div class='mCSB_dragger_bar' style='position:relative;'></div></div><div class='mCSB_draggerRail'></div></div></div>");
       
   100 					var mCSB_scrollTools = mCustomScrollBox.children(".mCSB_scrollTools"),
       
   101 						mCSB_draggerContainer = mCSB_scrollTools.children(".mCSB_draggerContainer"),
       
   102 						mCSB_dragger = mCSB_draggerContainer.children(".mCSB_dragger");
       
   103 					if (options.horizontalScroll) {
       
   104 						mCSB_dragger.data("minDraggerWidth", mCSB_dragger.width());
       
   105 					} else {
       
   106 						mCSB_dragger.data("minDraggerHeight", mCSB_dragger.height());
       
   107 					}
       
   108 					if (options.scrollButtons.enable) {
       
   109 						if (options.horizontalScroll) {
       
   110 							mCSB_scrollTools.prepend("<a class='mCSB_buttonLeft' oncontextmenu='return false;'></a>").append("<a class='mCSB_buttonRight' oncontextmenu='return false;'></a>");
       
   111 						} else {
       
   112 							mCSB_scrollTools.prepend("<a class='mCSB_buttonUp' oncontextmenu='return false;'></a>").append("<a class='mCSB_buttonDown' oncontextmenu='return false;'></a>");
       
   113 						}
       
   114 					}
       
   115 					/*mCustomScrollBox scrollTop and scrollLeft is always 0 to prevent browser focus scrolling*/
       
   116 					mCustomScrollBox.bind("scroll", function () {
       
   117 						if (!$this.is(".mCS_disabled")) { /*native focus scrolling for disabled scrollbars*/
       
   118 							mCustomScrollBox.scrollTop(0).scrollLeft(0);
       
   119 						}
       
   120 					});
       
   121 					/*store options, global vars/states, intervals*/
       
   122 					$this.data({
       
   123 								   /*init state*/
       
   124 								   "mCS_Init": true,
       
   125 								   /*instance index*/
       
   126 								   "mCustomScrollbarIndex": $(document).data("mCustomScrollbar-index"),
       
   127 								   /*option parameters*/
       
   128 								   "horizontalScroll": options.horizontalScroll,
       
   129 								   "scrollInertia": options.scrollInertia,
       
   130 								   "scrollEasing": "mcsEaseOut",
       
   131 								   "mouseWheel": options.mouseWheel,
       
   132 								   "mouseWheelPixels": options.mouseWheelPixels,
       
   133 								   "autoDraggerLength": options.autoDraggerLength,
       
   134 								   "autoHideScrollbar": options.autoHideScrollbar,
       
   135 								   "alwaysShowScrollbar": options.alwaysShowScrollbar,
       
   136 								   "snapAmount": options.snapAmount,
       
   137 								   "snapOffset": options.snapOffset,
       
   138 								   "scrollButtons_enable": options.scrollButtons.enable,
       
   139 								   "scrollButtons_scrollType": options.scrollButtons.scrollType,
       
   140 								   "scrollButtons_scrollSpeed": options.scrollButtons.scrollSpeed,
       
   141 								   "scrollButtons_scrollAmount": options.scrollButtons.scrollAmount,
       
   142 								   "autoExpandHorizontalScroll": options.advanced.autoExpandHorizontalScroll,
       
   143 								   "autoScrollOnFocus": options.advanced.autoScrollOnFocus,
       
   144 								   "normalizeMouseWheelDelta": options.advanced.normalizeMouseWheelDelta,
       
   145 								   "contentTouchScroll": options.contentTouchScroll,
       
   146 								   "onScrollStart_Callback": options.callbacks.onScrollStart,
       
   147 								   "onScroll_Callback": options.callbacks.onScroll,
       
   148 								   "onTotalScroll_Callback": options.callbacks.onTotalScroll,
       
   149 								   "onTotalScrollBack_Callback": options.callbacks.onTotalScrollBack,
       
   150 								   "onTotalScroll_Offset": options.callbacks.onTotalScrollOffset,
       
   151 								   "onTotalScrollBack_Offset": options.callbacks.onTotalScrollBackOffset,
       
   152 								   "whileScrolling_Callback": options.callbacks.whileScrolling,
       
   153 								   /*events binding state*/
       
   154 								   "bindEvent_scrollbar_drag": false,
       
   155 								   "bindEvent_content_touch": false,
       
   156 								   "bindEvent_scrollbar_click": false,
       
   157 								   "bindEvent_mousewheel": false,
       
   158 								   "bindEvent_buttonsContinuous_y": false,
       
   159 								   "bindEvent_buttonsContinuous_x": false,
       
   160 								   "bindEvent_buttonsPixels_y": false,
       
   161 								   "bindEvent_buttonsPixels_x": false,
       
   162 								   "bindEvent_focusin": false,
       
   163 								   "bindEvent_autoHideScrollbar": false,
       
   164 								   /*buttons intervals*/
       
   165 								   "mCSB_buttonScrollRight": false,
       
   166 								   "mCSB_buttonScrollLeft": false,
       
   167 								   "mCSB_buttonScrollDown": false,
       
   168 								   "mCSB_buttonScrollUp": false
       
   169 							   });
       
   170 					/*max-width/max-height*/
       
   171 					if (options.horizontalScroll) {
       
   172 						if ($this.css("max-width") !== "none") {
       
   173 							if (!options.advanced.updateOnContentResize) { /*needs updateOnContentResize*/
       
   174 								options.advanced.updateOnContentResize = true;
       
   175 							}
       
   176 						}
       
   177 					} else {
       
   178 						if ($this.css("max-height") !== "none") {
       
   179 							var percentage = false, maxHeight = parseInt($this.css("max-height"));
       
   180 							if ($this.css("max-height").indexOf("%") >= 0) {
       
   181 								percentage = maxHeight,
       
   182 									maxHeight = $this.parent().height() * percentage / 100;
       
   183 							}
       
   184 							$this.css("overflow", "hidden");
       
   185 							mCustomScrollBox.css("max-height", maxHeight);
       
   186 						}
       
   187 					}
       
   188 					$this.mCustomScrollbar("update");
       
   189 					/*window resize fn (for layouts based on percentages)*/
       
   190 					if (options.advanced.updateOnBrowserResize) {
       
   191 						var mCSB_resizeTimeout, currWinWidth = $(window).width(), currWinHeight = $(window).height();
       
   192 						$(window).bind("resize." + $this.data("mCustomScrollbarIndex"), function () {
       
   193 							if (mCSB_resizeTimeout) {
       
   194 								clearTimeout(mCSB_resizeTimeout);
       
   195 							}
       
   196 							mCSB_resizeTimeout = setTimeout(function () {
       
   197 								if (!$this.is(".mCS_disabled") && !$this.is(".mCS_destroyed")) {
       
   198 									var winWidth = $(window).width(), winHeight = $(window).height();
       
   199 									if (currWinWidth !== winWidth || currWinHeight !== winHeight) { /*ie8 fix*/
       
   200 										if ($this.css("max-height") !== "none" && percentage) {
       
   201 											mCustomScrollBox.css("max-height", $this.parent().height() * percentage / 100);
       
   202 										}
       
   203 										$this.mCustomScrollbar("update");
       
   204 										currWinWidth = winWidth;
       
   205 										currWinHeight = winHeight;
       
   206 									}
       
   207 								}
       
   208 							}, 150);
       
   209 						});
       
   210 					}
       
   211 					/*content resize fn (for dynamically generated content)*/
       
   212 					if (options.advanced.updateOnContentResize) {
       
   213 						var mCSB_onContentResize;
       
   214 						if (options.horizontalScroll) {
       
   215 							var mCSB_containerOldSize = mCSB_container.outerWidth();
       
   216 						} else {
       
   217 							var mCSB_containerOldSize = mCSB_container.outerHeight();
       
   218 						}
       
   219 						mCSB_onContentResize = setInterval(function () {
       
   220 							if (options.horizontalScroll) {
       
   221 								if (options.advanced.autoExpandHorizontalScroll) {
       
   222 									mCSB_container.css({"position": "absolute", "width": "auto"}).wrap("<div class='mCSB_h_wrapper' style='position:relative; left:0; width:999999px;' />").css({"width": mCSB_container.outerWidth(), "position": "relative"}).unwrap();
       
   223 								}
       
   224 								var mCSB_containerNewSize = mCSB_container.outerWidth();
       
   225 							} else {
       
   226 								var mCSB_containerNewSize = mCSB_container.outerHeight();
       
   227 							}
       
   228 							if (mCSB_containerNewSize != mCSB_containerOldSize) {
       
   229 								$this.mCustomScrollbar("update");
       
   230 								mCSB_containerOldSize = mCSB_containerNewSize;
       
   231 							}
       
   232 						}, 300);
       
   233 					}
       
   234 				});
       
   235 			},
       
   236 			update: function () {
       
   237 				var $this = $(this),
       
   238 					mCustomScrollBox = $this.children(".mCustomScrollBox"),
       
   239 					mCSB_container = mCustomScrollBox.children(".mCSB_container");
       
   240 				mCSB_container.removeClass("mCS_no_scrollbar");
       
   241 				$this.removeClass("mCS_disabled mCS_destroyed");
       
   242 				mCustomScrollBox.scrollTop(0).scrollLeft(0);
       
   243 				/*reset scrollTop/scrollLeft to prevent browser focus scrolling*/
       
   244 				var mCSB_scrollTools = mCustomScrollBox.children(".mCSB_scrollTools"),
       
   245 					mCSB_draggerContainer = mCSB_scrollTools.children(".mCSB_draggerContainer"),
       
   246 					mCSB_dragger = mCSB_draggerContainer.children(".mCSB_dragger");
       
   247 				if ($this.data("horizontalScroll")) {
       
   248 					var mCSB_buttonLeft = mCSB_scrollTools.children(".mCSB_buttonLeft"),
       
   249 						mCSB_buttonRight = mCSB_scrollTools.children(".mCSB_buttonRight"),
       
   250 						mCustomScrollBoxW = mCustomScrollBox.width();
       
   251 					if ($this.data("autoExpandHorizontalScroll")) {
       
   252 						mCSB_container.css({"position": "absolute", "width": "auto"}).wrap("<div class='mCSB_h_wrapper' style='position:relative; left:0; width:999999px;' />").css({"width": mCSB_container.outerWidth(), "position": "relative"}).unwrap();
       
   253 					}
       
   254 					var mCSB_containerW = mCSB_container.outerWidth();
       
   255 				} else {
       
   256 					var mCSB_buttonUp = mCSB_scrollTools.children(".mCSB_buttonUp"),
       
   257 						mCSB_buttonDown = mCSB_scrollTools.children(".mCSB_buttonDown"),
       
   258 						mCustomScrollBoxH = mCustomScrollBox.height(),
       
   259 						mCSB_containerH = mCSB_container.outerHeight();
       
   260 				}
       
   261 				if (mCSB_containerH > mCustomScrollBoxH && !$this.data("horizontalScroll")) { /*content needs vertical scrolling*/
       
   262 					mCSB_scrollTools.css("display", "block");
       
   263 					var mCSB_draggerContainerH = mCSB_draggerContainer.height();
       
   264 					/*auto adjust scrollbar dragger length analogous to content*/
       
   265 					if ($this.data("autoDraggerLength")) {
       
   266 						var draggerH = Math.round(mCustomScrollBoxH / mCSB_containerH * mCSB_draggerContainerH),
       
   267 							minDraggerH = mCSB_dragger.data("minDraggerHeight");
       
   268 						if (draggerH <= minDraggerH) { /*min dragger height*/
       
   269 							mCSB_dragger.css({"height": minDraggerH});
       
   270 						} else if (draggerH >= mCSB_draggerContainerH - 10) { /*max dragger height*/
       
   271 							var mCSB_draggerContainerMaxH = mCSB_draggerContainerH - 10;
       
   272 							mCSB_dragger.css({"height": mCSB_draggerContainerMaxH});
       
   273 						} else {
       
   274 							mCSB_dragger.css({"height": draggerH});
       
   275 						}
       
   276 						mCSB_dragger.children(".mCSB_dragger_bar").css({"line-height": mCSB_dragger.height() + "px"});
       
   277 					}
       
   278 					var mCSB_draggerH = mCSB_dragger.height(),
       
   279 					/*calculate and store scroll amount, add scrolling*/
       
   280 						scrollAmount = (mCSB_containerH - mCustomScrollBoxH) / (mCSB_draggerContainerH - mCSB_draggerH);
       
   281 					$this.data("scrollAmount", scrollAmount).mCustomScrollbar("scrolling", mCustomScrollBox, mCSB_container, mCSB_draggerContainer, mCSB_dragger, mCSB_buttonUp, mCSB_buttonDown, mCSB_buttonLeft, mCSB_buttonRight);
       
   282 					/*scroll*/
       
   283 					var mCSB_containerP = Math.abs(mCSB_container.position().top);
       
   284 					$this.mCustomScrollbar("scrollTo", mCSB_containerP, {scrollInertia: 0, trigger: "internal"});
       
   285 				} else if (mCSB_containerW > mCustomScrollBoxW && $this.data("horizontalScroll")) { /*content needs horizontal scrolling*/
       
   286 					mCSB_scrollTools.css("display", "block");
       
   287 					var mCSB_draggerContainerW = mCSB_draggerContainer.width();
       
   288 					/*auto adjust scrollbar dragger length analogous to content*/
       
   289 					if ($this.data("autoDraggerLength")) {
       
   290 						var draggerW = Math.round(mCustomScrollBoxW / mCSB_containerW * mCSB_draggerContainerW),
       
   291 							minDraggerW = mCSB_dragger.data("minDraggerWidth");
       
   292 						if (draggerW <= minDraggerW) { /*min dragger height*/
       
   293 							mCSB_dragger.css({"width": minDraggerW});
       
   294 						} else if (draggerW >= mCSB_draggerContainerW - 10) { /*max dragger height*/
       
   295 							var mCSB_draggerContainerMaxW = mCSB_draggerContainerW - 10;
       
   296 							mCSB_dragger.css({"width": mCSB_draggerContainerMaxW});
       
   297 						} else {
       
   298 							mCSB_dragger.css({"width": draggerW});
       
   299 						}
       
   300 					}
       
   301 					var mCSB_draggerW = mCSB_dragger.width(),
       
   302 					/*calculate and store scroll amount, add scrolling*/
       
   303 						scrollAmount = (mCSB_containerW - mCustomScrollBoxW) / (mCSB_draggerContainerW - mCSB_draggerW);
       
   304 					$this.data("scrollAmount", scrollAmount).mCustomScrollbar("scrolling", mCustomScrollBox, mCSB_container, mCSB_draggerContainer, mCSB_dragger, mCSB_buttonUp, mCSB_buttonDown, mCSB_buttonLeft, mCSB_buttonRight);
       
   305 					/*scroll*/
       
   306 					var mCSB_containerP = Math.abs(mCSB_container.position().left);
       
   307 					$this.mCustomScrollbar("scrollTo", mCSB_containerP, {scrollInertia: 0, trigger: "internal"});
       
   308 				} else { /*content does not need scrolling*/
       
   309 					/*unbind events, reset content position, hide scrollbars, remove classes*/
       
   310 					mCustomScrollBox.unbind("mousewheel focusin");
       
   311 					if ($this.data("horizontalScroll")) {
       
   312 						mCSB_dragger.add(mCSB_container).css("left", 0);
       
   313 					} else {
       
   314 						mCSB_dragger.add(mCSB_container).css("top", 0);
       
   315 					}
       
   316 					if ($this.data("alwaysShowScrollbar")) {
       
   317 						if (!$this.data("horizontalScroll")) { /*vertical scrolling*/
       
   318 							mCSB_dragger.css({"height": mCSB_draggerContainer.height()});
       
   319 						} else if ($this.data("horizontalScroll")) { /*horizontal scrolling*/
       
   320 							mCSB_dragger.css({"width": mCSB_draggerContainer.width()});
       
   321 						}
       
   322 					} else {
       
   323 						mCSB_scrollTools.css("display", "none");
       
   324 						mCSB_container.addClass("mCS_no_scrollbar");
       
   325 					}
       
   326 					$this.data({"bindEvent_mousewheel": false, "bindEvent_focusin": false});
       
   327 				}
       
   328 			},
       
   329 			scrolling: function (mCustomScrollBox, mCSB_container, mCSB_draggerContainer, mCSB_dragger, mCSB_buttonUp, mCSB_buttonDown, mCSB_buttonLeft, mCSB_buttonRight) {
       
   330 				var $this = $(this);
       
   331 				/*scrollbar drag scrolling*/
       
   332 				if (!$this.data("bindEvent_scrollbar_drag")) {
       
   333 					var mCSB_draggerDragY, mCSB_draggerDragX,
       
   334 						mCSB_dragger_downEvent, mCSB_dragger_moveEvent, mCSB_dragger_upEvent;
       
   335 					if ($.support.pointer) { /*pointer*/
       
   336 						mCSB_dragger_downEvent = "pointerdown";
       
   337 						mCSB_dragger_moveEvent = "pointermove";
       
   338 						mCSB_dragger_upEvent = "pointerup";
       
   339 					} else if ($.support.msPointer) { /*MSPointer*/
       
   340 						mCSB_dragger_downEvent = "MSPointerDown";
       
   341 						mCSB_dragger_moveEvent = "MSPointerMove";
       
   342 						mCSB_dragger_upEvent = "MSPointerUp";
       
   343 					}
       
   344 					if ($.support.pointer || $.support.msPointer) { /*pointer, MSPointer*/
       
   345 						mCSB_dragger.bind(mCSB_dragger_downEvent, function (e) {
       
   346 							e.preventDefault();
       
   347 							$this.data({"on_drag": true});
       
   348 							mCSB_dragger.addClass("mCSB_dragger_onDrag");
       
   349 							var elem = $(this),
       
   350 								elemOffset = elem.offset(),
       
   351 								x = e.originalEvent.pageX - elemOffset.left,
       
   352 								y = e.originalEvent.pageY - elemOffset.top;
       
   353 							if (x < elem.width() && x > 0 && y < elem.height() && y > 0) {
       
   354 								mCSB_draggerDragY = y;
       
   355 								mCSB_draggerDragX = x;
       
   356 							}
       
   357 						});
       
   358 						$(document).bind(mCSB_dragger_moveEvent + "." + $this.data("mCustomScrollbarIndex"),function (e) {
       
   359 							e.preventDefault();
       
   360 							if ($this.data("on_drag")) {
       
   361 								var elem = mCSB_dragger,
       
   362 									elemOffset = elem.offset(),
       
   363 									x = e.originalEvent.pageX - elemOffset.left,
       
   364 									y = e.originalEvent.pageY - elemOffset.top;
       
   365 								scrollbarDrag(mCSB_draggerDragY, mCSB_draggerDragX, y, x);
       
   366 							}
       
   367 						}).bind(mCSB_dragger_upEvent + "." + $this.data("mCustomScrollbarIndex"), function (e) {
       
   368 							$this.data({"on_drag": false});
       
   369 							mCSB_dragger.removeClass("mCSB_dragger_onDrag");
       
   370 						});
       
   371 					} else { /*mouse/touch*/
       
   372 						mCSB_dragger.bind("mousedown touchstart",function (e) {
       
   373 							e.preventDefault();
       
   374 							e.stopImmediatePropagation();
       
   375 							var elem = $(this), elemOffset = elem.offset(), x, y;
       
   376 							if (e.type === "touchstart") {
       
   377 								var touch = e.originalEvent.touches[0] || e.originalEvent.changedTouches[0];
       
   378 								x = touch.pageX - elemOffset.left;
       
   379 								y = touch.pageY - elemOffset.top;
       
   380 							} else {
       
   381 								$this.data({"on_drag": true});
       
   382 								mCSB_dragger.addClass("mCSB_dragger_onDrag");
       
   383 								x = e.pageX - elemOffset.left;
       
   384 								y = e.pageY - elemOffset.top;
       
   385 							}
       
   386 							if (x < elem.width() && x > 0 && y < elem.height() && y > 0) {
       
   387 								mCSB_draggerDragY = y;
       
   388 								mCSB_draggerDragX = x;
       
   389 							}
       
   390 						}).bind("touchmove", function (e) {
       
   391 							e.preventDefault();
       
   392 							e.stopImmediatePropagation();
       
   393 							var touch = e.originalEvent.touches[0] || e.originalEvent.changedTouches[0],
       
   394 								elem = $(this),
       
   395 								elemOffset = elem.offset(),
       
   396 								x = touch.pageX - elemOffset.left,
       
   397 								y = touch.pageY - elemOffset.top;
       
   398 							scrollbarDrag(mCSB_draggerDragY, mCSB_draggerDragX, y, x);
       
   399 						});
       
   400 						$(document).bind("mousemove." + $this.data("mCustomScrollbarIndex"),function (e) {
       
   401 							if ($this.data("on_drag")) {
       
   402 								var elem = mCSB_dragger,
       
   403 									elemOffset = elem.offset(),
       
   404 									x = e.pageX - elemOffset.left,
       
   405 									y = e.pageY - elemOffset.top;
       
   406 								scrollbarDrag(mCSB_draggerDragY, mCSB_draggerDragX, y, x);
       
   407 							}
       
   408 						}).bind("mouseup." + $this.data("mCustomScrollbarIndex"), function (e) {
       
   409 							$this.data({"on_drag": false});
       
   410 							mCSB_dragger.removeClass("mCSB_dragger_onDrag");
       
   411 						});
       
   412 					}
       
   413 					$this.data({"bindEvent_scrollbar_drag": true});
       
   414 				}
       
   415 				function scrollbarDrag(mCSB_draggerDragY, mCSB_draggerDragX, y, x) {
       
   416 					if ($this.data("horizontalScroll")) {
       
   417 						$this.mCustomScrollbar("scrollTo", (mCSB_dragger.position().left - (mCSB_draggerDragX)) + x, {moveDragger: true, trigger: "internal"});
       
   418 					} else {
       
   419 						$this.mCustomScrollbar("scrollTo", (mCSB_dragger.position().top - (mCSB_draggerDragY)) + y, {moveDragger: true, trigger: "internal"});
       
   420 					}
       
   421 				}
       
   422 
       
   423 				/*content touch-drag*/
       
   424 				if ($.support.touch && $this.data("contentTouchScroll")) {
       
   425 					if (!$this.data("bindEvent_content_touch")) {
       
   426 						var touch,
       
   427 							elem, elemOffset, y, x, mCSB_containerTouchY, mCSB_containerTouchX;
       
   428 						mCSB_container.bind("touchstart", function (e) {
       
   429 							e.stopImmediatePropagation();
       
   430 							touch = e.originalEvent.touches[0] || e.originalEvent.changedTouches[0];
       
   431 							elem = $(this);
       
   432 							elemOffset = elem.offset();
       
   433 							x = touch.pageX - elemOffset.left;
       
   434 							y = touch.pageY - elemOffset.top;
       
   435 							mCSB_containerTouchY = y;
       
   436 							mCSB_containerTouchX = x;
       
   437 						});
       
   438 						mCSB_container.bind("touchmove", function (e) {
       
   439 							e.preventDefault();
       
   440 							e.stopImmediatePropagation();
       
   441 							touch = e.originalEvent.touches[0] || e.originalEvent.changedTouches[0];
       
   442 							elem = $(this).parent();
       
   443 							elemOffset = elem.offset();
       
   444 							x = touch.pageX - elemOffset.left;
       
   445 							y = touch.pageY - elemOffset.top;
       
   446 							if ($this.data("horizontalScroll")) {
       
   447 								$this.mCustomScrollbar("scrollTo", mCSB_containerTouchX - x, {trigger: "internal"});
       
   448 							} else {
       
   449 								$this.mCustomScrollbar("scrollTo", mCSB_containerTouchY - y, {trigger: "internal"});
       
   450 							}
       
   451 						});
       
   452 					}
       
   453 				}
       
   454 				/*dragger rail click scrolling*/
       
   455 				if (!$this.data("bindEvent_scrollbar_click")) {
       
   456 					mCSB_draggerContainer.bind("click", function (e) {
       
   457 						var scrollToPos = (e.pageY - mCSB_draggerContainer.offset().top) * $this.data("scrollAmount"), target = $(e.target);
       
   458 						if ($this.data("horizontalScroll")) {
       
   459 							scrollToPos = (e.pageX - mCSB_draggerContainer.offset().left) * $this.data("scrollAmount");
       
   460 						}
       
   461 						if (target.hasClass("mCSB_draggerContainer") || target.hasClass("mCSB_draggerRail")) {
       
   462 							$this.mCustomScrollbar("scrollTo", scrollToPos, {trigger: "internal", scrollEasing: "draggerRailEase"});
       
   463 						}
       
   464 					});
       
   465 					$this.data({"bindEvent_scrollbar_click": true});
       
   466 				}
       
   467 				/*mousewheel scrolling*/
       
   468 				if ($this.data("mouseWheel")) {
       
   469 					if (!$this.data("bindEvent_mousewheel")) {
       
   470 						mCustomScrollBox.bind("mousewheel", function (e, delta) {
       
   471 							var scrollTo, mouseWheelPixels = $this.data("mouseWheelPixels"), absPos = Math.abs(mCSB_container.position().top),
       
   472 								draggerPos = mCSB_dragger.position().top, limit = mCSB_draggerContainer.height() - mCSB_dragger.height();
       
   473 							if ($this.data("normalizeMouseWheelDelta")) {
       
   474 								if (delta < 0) {
       
   475 									delta = -1;
       
   476 								} else {
       
   477 									delta = 1;
       
   478 								}
       
   479 							}
       
   480 							if (mouseWheelPixels === "auto") {
       
   481 								mouseWheelPixels = 100 + Math.round($this.data("scrollAmount") / 2);
       
   482 							}
       
   483 							if ($this.data("horizontalScroll")) {
       
   484 								draggerPos = mCSB_dragger.position().left;
       
   485 								limit = mCSB_draggerContainer.width() - mCSB_dragger.width();
       
   486 								absPos = Math.abs(mCSB_container.position().left);
       
   487 							}
       
   488 							if ((delta > 0 && draggerPos !== 0) || (delta < 0 && draggerPos !== limit)) {
       
   489 								e.preventDefault();
       
   490 								e.stopImmediatePropagation();
       
   491 							}
       
   492 							scrollTo = absPos - (delta * mouseWheelPixels);
       
   493 							$this.mCustomScrollbar("scrollTo", scrollTo, {trigger: "internal"});
       
   494 						});
       
   495 						$this.data({"bindEvent_mousewheel": true});
       
   496 					}
       
   497 				}
       
   498 				/*buttons scrolling*/
       
   499 				if ($this.data("scrollButtons_enable")) {
       
   500 					if ($this.data("scrollButtons_scrollType") === "pixels") { /*scroll by pixels*/
       
   501 						if ($this.data("horizontalScroll")) {
       
   502 							mCSB_buttonRight.add(mCSB_buttonLeft).unbind("mousedown touchstart MSPointerDown pointerdown mouseup MSPointerUp pointerup mouseout MSPointerOut pointerout touchend", mCSB_buttonRight_stop, mCSB_buttonLeft_stop);
       
   503 							$this.data({"bindEvent_buttonsContinuous_x": false});
       
   504 							if (!$this.data("bindEvent_buttonsPixels_x")) {
       
   505 								/*scroll right*/
       
   506 								mCSB_buttonRight.bind("click", function (e) {
       
   507 									e.preventDefault();
       
   508 									PixelsScrollTo(Math.abs(mCSB_container.position().left) + $this.data("scrollButtons_scrollAmount"));
       
   509 								});
       
   510 								/*scroll left*/
       
   511 								mCSB_buttonLeft.bind("click", function (e) {
       
   512 									e.preventDefault();
       
   513 									PixelsScrollTo(Math.abs(mCSB_container.position().left) - $this.data("scrollButtons_scrollAmount"));
       
   514 								});
       
   515 								$this.data({"bindEvent_buttonsPixels_x": true});
       
   516 							}
       
   517 						} else {
       
   518 							mCSB_buttonDown.add(mCSB_buttonUp).unbind("mousedown touchstart MSPointerDown pointerdown mouseup MSPointerUp pointerup mouseout MSPointerOut pointerout touchend", mCSB_buttonRight_stop, mCSB_buttonLeft_stop);
       
   519 							$this.data({"bindEvent_buttonsContinuous_y": false});
       
   520 							if (!$this.data("bindEvent_buttonsPixels_y")) {
       
   521 								/*scroll down*/
       
   522 								mCSB_buttonDown.bind("click", function (e) {
       
   523 									e.preventDefault();
       
   524 									PixelsScrollTo(Math.abs(mCSB_container.position().top) + $this.data("scrollButtons_scrollAmount"));
       
   525 								});
       
   526 								/*scroll up*/
       
   527 								mCSB_buttonUp.bind("click", function (e) {
       
   528 									e.preventDefault();
       
   529 									PixelsScrollTo(Math.abs(mCSB_container.position().top) - $this.data("scrollButtons_scrollAmount"));
       
   530 								});
       
   531 								$this.data({"bindEvent_buttonsPixels_y": true});
       
   532 							}
       
   533 						}
       
   534 						function PixelsScrollTo(to) {
       
   535 							if (!mCSB_dragger.data("preventAction")) {
       
   536 								mCSB_dragger.data("preventAction", true);
       
   537 								$this.mCustomScrollbar("scrollTo", to, {trigger: "internal"});
       
   538 							}
       
   539 						}
       
   540 					} else { /*continuous scrolling*/
       
   541 						if ($this.data("horizontalScroll")) {
       
   542 							mCSB_buttonRight.add(mCSB_buttonLeft).unbind("click");
       
   543 							$this.data({"bindEvent_buttonsPixels_x": false});
       
   544 							if (!$this.data("bindEvent_buttonsContinuous_x")) {
       
   545 								/*scroll right*/
       
   546 								mCSB_buttonRight.bind("mousedown touchstart MSPointerDown pointerdown", function (e) {
       
   547 									e.preventDefault();
       
   548 									var scrollButtonsSpeed = ScrollButtonsSpeed();
       
   549 									$this.data({"mCSB_buttonScrollRight": setInterval(function () {
       
   550 										$this.mCustomScrollbar("scrollTo", Math.abs(mCSB_container.position().left) + scrollButtonsSpeed, {trigger: "internal", scrollEasing: "easeOutCirc"});
       
   551 									}, 17)});
       
   552 								});
       
   553 								var mCSB_buttonRight_stop = function (e) {
       
   554 									e.preventDefault();
       
   555 									clearInterval($this.data("mCSB_buttonScrollRight"));
       
   556 								}
       
   557 								mCSB_buttonRight.bind("mouseup touchend MSPointerUp pointerup mouseout MSPointerOut pointerout", mCSB_buttonRight_stop);
       
   558 								/*scroll left*/
       
   559 								mCSB_buttonLeft.bind("mousedown touchstart MSPointerDown pointerdown", function (e) {
       
   560 									e.preventDefault();
       
   561 									var scrollButtonsSpeed = ScrollButtonsSpeed();
       
   562 									$this.data({"mCSB_buttonScrollLeft": setInterval(function () {
       
   563 										$this.mCustomScrollbar("scrollTo", Math.abs(mCSB_container.position().left) - scrollButtonsSpeed, {trigger: "internal", scrollEasing: "easeOutCirc"});
       
   564 									}, 17)});
       
   565 								});
       
   566 								var mCSB_buttonLeft_stop = function (e) {
       
   567 									e.preventDefault();
       
   568 									clearInterval($this.data("mCSB_buttonScrollLeft"));
       
   569 								}
       
   570 								mCSB_buttonLeft.bind("mouseup touchend MSPointerUp pointerup mouseout MSPointerOut pointerout", mCSB_buttonLeft_stop);
       
   571 								$this.data({"bindEvent_buttonsContinuous_x": true});
       
   572 							}
       
   573 						} else {
       
   574 							mCSB_buttonDown.add(mCSB_buttonUp).unbind("click");
       
   575 							$this.data({"bindEvent_buttonsPixels_y": false});
       
   576 							if (!$this.data("bindEvent_buttonsContinuous_y")) {
       
   577 								/*scroll down*/
       
   578 								mCSB_buttonDown.bind("mousedown touchstart MSPointerDown pointerdown", function (e) {
       
   579 									e.preventDefault();
       
   580 									var scrollButtonsSpeed = ScrollButtonsSpeed();
       
   581 									$this.data({"mCSB_buttonScrollDown": setInterval(function () {
       
   582 										$this.mCustomScrollbar("scrollTo", Math.abs(mCSB_container.position().top) + scrollButtonsSpeed, {trigger: "internal", scrollEasing: "easeOutCirc"});
       
   583 									}, 17)});
       
   584 								});
       
   585 								var mCSB_buttonDown_stop = function (e) {
       
   586 									e.preventDefault();
       
   587 									clearInterval($this.data("mCSB_buttonScrollDown"));
       
   588 								}
       
   589 								mCSB_buttonDown.bind("mouseup touchend MSPointerUp pointerup mouseout MSPointerOut pointerout", mCSB_buttonDown_stop);
       
   590 								/*scroll up*/
       
   591 								mCSB_buttonUp.bind("mousedown touchstart MSPointerDown pointerdown", function (e) {
       
   592 									e.preventDefault();
       
   593 									var scrollButtonsSpeed = ScrollButtonsSpeed();
       
   594 									$this.data({"mCSB_buttonScrollUp": setInterval(function () {
       
   595 										$this.mCustomScrollbar("scrollTo", Math.abs(mCSB_container.position().top) - scrollButtonsSpeed, {trigger: "internal", scrollEasing: "easeOutCirc"});
       
   596 									}, 17)});
       
   597 								});
       
   598 								var mCSB_buttonUp_stop = function (e) {
       
   599 									e.preventDefault();
       
   600 									clearInterval($this.data("mCSB_buttonScrollUp"));
       
   601 								}
       
   602 								mCSB_buttonUp.bind("mouseup touchend MSPointerUp pointerup mouseout MSPointerOut pointerout", mCSB_buttonUp_stop);
       
   603 								$this.data({"bindEvent_buttonsContinuous_y": true});
       
   604 							}
       
   605 						}
       
   606 						function ScrollButtonsSpeed() {
       
   607 							var speed = $this.data("scrollButtons_scrollSpeed");
       
   608 							if ($this.data("scrollButtons_scrollSpeed") === "auto") {
       
   609 								speed = Math.round(($this.data("scrollInertia") + 100) / 40);
       
   610 							}
       
   611 							return speed;
       
   612 						}
       
   613 					}
       
   614 				}
       
   615 				/*scrolling on element focus (e.g. via TAB key)*/
       
   616 				if ($this.data("autoScrollOnFocus")) {
       
   617 					if (!$this.data("bindEvent_focusin")) {
       
   618 						mCustomScrollBox.bind("focusin", function () {
       
   619 							mCustomScrollBox.scrollTop(0).scrollLeft(0);
       
   620 							var focusedElem = $(document.activeElement);
       
   621 							if (focusedElem.is("input,textarea,select,button,a[tabindex],area,object")) {
       
   622 								var mCSB_containerPos = mCSB_container.position().top,
       
   623 									focusedElemPos = focusedElem.position().top,
       
   624 									visibleLimit = mCustomScrollBox.height() - focusedElem.outerHeight();
       
   625 								if ($this.data("horizontalScroll")) {
       
   626 									mCSB_containerPos = mCSB_container.position().left;
       
   627 									focusedElemPos = focusedElem.position().left;
       
   628 									visibleLimit = mCustomScrollBox.width() - focusedElem.outerWidth();
       
   629 								}
       
   630 								if (mCSB_containerPos + focusedElemPos < 0 || mCSB_containerPos + focusedElemPos > visibleLimit) {
       
   631 									$this.mCustomScrollbar("scrollTo", focusedElemPos, {trigger: "internal"});
       
   632 								}
       
   633 							}
       
   634 						});
       
   635 						$this.data({"bindEvent_focusin": true});
       
   636 					}
       
   637 				}
       
   638 				/*auto-hide scrollbar*/
       
   639 				if ($this.data("autoHideScrollbar") && !$this.data("alwaysShowScrollbar")) {
       
   640 					if (!$this.data("bindEvent_autoHideScrollbar")) {
       
   641 						mCustomScrollBox.bind("mouseenter",function (e) {
       
   642 							mCustomScrollBox.addClass("mCS-mouse-over");
       
   643 							functions.showScrollbar.call(mCustomScrollBox.children(".mCSB_scrollTools"));
       
   644 						}).bind("mouseleave touchend", function (e) {
       
   645 							mCustomScrollBox.removeClass("mCS-mouse-over");
       
   646 							if (e.type === "mouseleave") {
       
   647 								functions.hideScrollbar.call(mCustomScrollBox.children(".mCSB_scrollTools"));
       
   648 							}
       
   649 						});
       
   650 						$this.data({"bindEvent_autoHideScrollbar": true});
       
   651 					}
       
   652 				}
       
   653 			},
       
   654 			scrollTo: function (scrollTo, options) {
       
   655 				var $this = $(this),
       
   656 					defaults = {
       
   657 						moveDragger: false,
       
   658 						trigger: "external",
       
   659 						callbacks: true,
       
   660 						scrollInertia: $this.data("scrollInertia"),
       
   661 						scrollEasing: $this.data("scrollEasing")
       
   662 					},
       
   663 					options = $.extend(defaults, options),
       
   664 					draggerScrollTo,
       
   665 					mCustomScrollBox = $this.children(".mCustomScrollBox"),
       
   666 					mCSB_container = mCustomScrollBox.children(".mCSB_container"),
       
   667 					mCSB_scrollTools = mCustomScrollBox.children(".mCSB_scrollTools"),
       
   668 					mCSB_draggerContainer = mCSB_scrollTools.children(".mCSB_draggerContainer"),
       
   669 					mCSB_dragger = mCSB_draggerContainer.children(".mCSB_dragger"),
       
   670 					contentSpeed = draggerSpeed = options.scrollInertia,
       
   671 					scrollBeginning, scrollBeginningOffset, totalScroll, totalScrollOffset;
       
   672 				if (!mCSB_container.hasClass("mCS_no_scrollbar")) {
       
   673 					$this.data({"mCS_trigger": options.trigger});
       
   674 					if ($this.data("mCS_Init")) {
       
   675 						options.callbacks = false;
       
   676 					}
       
   677 					if (scrollTo || scrollTo === 0) {
       
   678 						if (typeof(scrollTo) === "number") { /*if integer, scroll by number of pixels*/
       
   679 							if (options.moveDragger) { /*scroll dragger*/
       
   680 								draggerScrollTo = scrollTo;
       
   681 								if ($this.data("horizontalScroll")) {
       
   682 									scrollTo = mCSB_dragger.position().left * $this.data("scrollAmount");
       
   683 								} else {
       
   684 									scrollTo = mCSB_dragger.position().top * $this.data("scrollAmount");
       
   685 								}
       
   686 								draggerSpeed = 0;
       
   687 							} else { /*scroll content by default*/
       
   688 								draggerScrollTo = scrollTo / $this.data("scrollAmount");
       
   689 							}
       
   690 						} else if (typeof(scrollTo) === "string") { /*if string, scroll by element position*/
       
   691 							var target;
       
   692 							if (scrollTo === "top") { /*scroll to top*/
       
   693 								target = 0;
       
   694 							} else if (scrollTo === "bottom" && !$this.data("horizontalScroll")) { /*scroll to bottom*/
       
   695 								target = mCSB_container.outerHeight() - mCustomScrollBox.height();
       
   696 							} else if (scrollTo === "left") { /*scroll to left*/
       
   697 								target = 0;
       
   698 							} else if (scrollTo === "right" && $this.data("horizontalScroll")) { /*scroll to right*/
       
   699 								target = mCSB_container.outerWidth() - mCustomScrollBox.width();
       
   700 							} else if (scrollTo === "first") { /*scroll to first element position*/
       
   701 								target = $this.find(".mCSB_container").find(":first");
       
   702 							} else if (scrollTo === "last") { /*scroll to last element position*/
       
   703 								target = $this.find(".mCSB_container").find(":last");
       
   704 							} else { /*scroll to element position*/
       
   705 								target = $this.find(scrollTo);
       
   706 							}
       
   707 							if (target.length === 1) { /*if such unique element exists, scroll to it*/
       
   708 								if ($this.data("horizontalScroll")) {
       
   709 									scrollTo = target.position().left;
       
   710 								} else {
       
   711 									scrollTo = target.position().top;
       
   712 								}
       
   713 								draggerScrollTo = scrollTo / $this.data("scrollAmount");
       
   714 							} else {
       
   715 								draggerScrollTo = scrollTo = target;
       
   716 							}
       
   717 						}
       
   718 						/*scroll to*/
       
   719 						if ($this.data("horizontalScroll")) {
       
   720 							if ($this.data("onTotalScrollBack_Offset")) { /*scroll beginning offset*/
       
   721 								scrollBeginningOffset = -$this.data("onTotalScrollBack_Offset");
       
   722 							}
       
   723 							if ($this.data("onTotalScroll_Offset")) { /*total scroll offset*/
       
   724 								totalScrollOffset = mCustomScrollBox.width() - mCSB_container.outerWidth() + $this.data("onTotalScroll_Offset");
       
   725 							}
       
   726 							if (draggerScrollTo < 0) { /*scroll start position*/
       
   727 								draggerScrollTo = scrollTo = 0;
       
   728 								clearInterval($this.data("mCSB_buttonScrollLeft"));
       
   729 								if (!scrollBeginningOffset) {
       
   730 									scrollBeginning = true;
       
   731 								}
       
   732 							} else if (draggerScrollTo >= mCSB_draggerContainer.width() - mCSB_dragger.width()) { /*scroll end position*/
       
   733 								draggerScrollTo = mCSB_draggerContainer.width() - mCSB_dragger.width();
       
   734 								scrollTo = mCustomScrollBox.width() - mCSB_container.outerWidth();
       
   735 								clearInterval($this.data("mCSB_buttonScrollRight"));
       
   736 								if (!totalScrollOffset) {
       
   737 									totalScroll = true;
       
   738 								}
       
   739 							} else {
       
   740 								scrollTo = -scrollTo;
       
   741 							}
       
   742 							var snapAmount = $this.data("snapAmount");
       
   743 							if (snapAmount) {
       
   744 								scrollTo = Math.round(scrollTo / snapAmount) * snapAmount - $this.data("snapOffset");
       
   745 							}
       
   746 							/*scrolling animation*/
       
   747 							functions.mTweenAxis.call(this, mCSB_dragger[0], "left", Math.round(draggerScrollTo), draggerSpeed, options.scrollEasing);
       
   748 							functions.mTweenAxis.call(this, mCSB_container[0], "left", Math.round(scrollTo), contentSpeed, options.scrollEasing, {
       
   749 								onStart: function () {
       
   750 									if (options.callbacks && !$this.data("mCS_tweenRunning")) {
       
   751 										callbacks("onScrollStart");
       
   752 									}
       
   753 									if ($this.data("autoHideScrollbar") && !$this.data("alwaysShowScrollbar")) {
       
   754 										functions.showScrollbar.call(mCSB_scrollTools);
       
   755 									}
       
   756 								},
       
   757 								onUpdate: function () {
       
   758 									if (options.callbacks) {
       
   759 										callbacks("whileScrolling");
       
   760 									}
       
   761 								},
       
   762 								onComplete: function () {
       
   763 									if (options.callbacks) {
       
   764 										callbacks("onScroll");
       
   765 										if (scrollBeginning || (scrollBeginningOffset && mCSB_container.position().left >= scrollBeginningOffset)) {
       
   766 											callbacks("onTotalScrollBack");
       
   767 										}
       
   768 										if (totalScroll || (totalScrollOffset && mCSB_container.position().left <= totalScrollOffset)) {
       
   769 											callbacks("onTotalScroll");
       
   770 										}
       
   771 									}
       
   772 									mCSB_dragger.data("preventAction", false);
       
   773 									$this.data("mCS_tweenRunning", false);
       
   774 									if ($this.data("autoHideScrollbar") && !$this.data("alwaysShowScrollbar")) {
       
   775 										if (!mCustomScrollBox.hasClass("mCS-mouse-over")) {
       
   776 											functions.hideScrollbar.call(mCSB_scrollTools);
       
   777 										}
       
   778 									}
       
   779 								}
       
   780 							});
       
   781 						} else {
       
   782 							if ($this.data("onTotalScrollBack_Offset")) { /*scroll beginning offset*/
       
   783 								scrollBeginningOffset = -$this.data("onTotalScrollBack_Offset");
       
   784 							}
       
   785 							if ($this.data("onTotalScroll_Offset")) { /*total scroll offset*/
       
   786 								totalScrollOffset = mCustomScrollBox.height() - mCSB_container.outerHeight() + $this.data("onTotalScroll_Offset");
       
   787 							}
       
   788 							if (draggerScrollTo < 0) { /*scroll start position*/
       
   789 								draggerScrollTo = scrollTo = 0;
       
   790 								clearInterval($this.data("mCSB_buttonScrollUp"));
       
   791 								if (!scrollBeginningOffset) {
       
   792 									scrollBeginning = true;
       
   793 								}
       
   794 							} else if (draggerScrollTo >= mCSB_draggerContainer.height() - mCSB_dragger.height()) { /*scroll end position*/
       
   795 								draggerScrollTo = mCSB_draggerContainer.height() - mCSB_dragger.height();
       
   796 								scrollTo = mCustomScrollBox.height() - mCSB_container.outerHeight();
       
   797 								clearInterval($this.data("mCSB_buttonScrollDown"));
       
   798 								if (!totalScrollOffset) {
       
   799 									totalScroll = true;
       
   800 								}
       
   801 							} else {
       
   802 								scrollTo = -scrollTo;
       
   803 							}
       
   804 							var snapAmount = $this.data("snapAmount");
       
   805 							if (snapAmount) {
       
   806 								scrollTo = Math.round(scrollTo / snapAmount) * snapAmount - $this.data("snapOffset");
       
   807 							}
       
   808 							/*scrolling animation*/
       
   809 							functions.mTweenAxis.call(this, mCSB_dragger[0], "top", Math.round(draggerScrollTo), draggerSpeed, options.scrollEasing);
       
   810 							functions.mTweenAxis.call(this, mCSB_container[0], "top", Math.round(scrollTo), contentSpeed, options.scrollEasing, {
       
   811 								onStart: function () {
       
   812 									if (options.callbacks && !$this.data("mCS_tweenRunning")) {
       
   813 										callbacks("onScrollStart");
       
   814 									}
       
   815 									if ($this.data("autoHideScrollbar") && !$this.data("alwaysShowScrollbar")) {
       
   816 										functions.showScrollbar.call(mCSB_scrollTools);
       
   817 									}
       
   818 								},
       
   819 								onUpdate: function () {
       
   820 									if (options.callbacks) {
       
   821 										callbacks("whileScrolling");
       
   822 									}
       
   823 								},
       
   824 								onComplete: function () {
       
   825 									if (options.callbacks) {
       
   826 										callbacks("onScroll");
       
   827 										if (scrollBeginning || (scrollBeginningOffset && mCSB_container.position().top >= scrollBeginningOffset)) {
       
   828 											callbacks("onTotalScrollBack");
       
   829 										}
       
   830 										if (totalScroll || (totalScrollOffset && mCSB_container.position().top <= totalScrollOffset)) {
       
   831 											callbacks("onTotalScroll");
       
   832 										}
       
   833 									}
       
   834 									mCSB_dragger.data("preventAction", false);
       
   835 									$this.data("mCS_tweenRunning", false);
       
   836 									if ($this.data("autoHideScrollbar") && !$this.data("alwaysShowScrollbar")) {
       
   837 										if (!mCustomScrollBox.hasClass("mCS-mouse-over")) {
       
   838 											functions.hideScrollbar.call(mCSB_scrollTools);
       
   839 										}
       
   840 									}
       
   841 								}
       
   842 							});
       
   843 						}
       
   844 						if ($this.data("mCS_Init")) {
       
   845 							$this.data({"mCS_Init": false});
       
   846 						}
       
   847 					}
       
   848 				}
       
   849 				/*callbacks*/
       
   850 				function callbacks(cb) {
       
   851 					if ($this.data("mCustomScrollbarIndex")) {
       
   852 						this.mcs = {
       
   853 							top: mCSB_container.position().top, left: mCSB_container.position().left,
       
   854 							draggerTop: mCSB_dragger.position().top, draggerLeft: mCSB_dragger.position().left,
       
   855 							topPct: Math.round((100 * Math.abs(mCSB_container.position().top)) / Math.abs(mCSB_container.outerHeight() - mCustomScrollBox.height())),
       
   856 							leftPct: Math.round((100 * Math.abs(mCSB_container.position().left)) / Math.abs(mCSB_container.outerWidth() - mCustomScrollBox.width()))
       
   857 						};
       
   858 						switch (cb) {
       
   859 							/*start scrolling callback*/
       
   860 							case "onScrollStart":
       
   861 								$this.data("mCS_tweenRunning", true).data("onScrollStart_Callback").call($this, this.mcs);
       
   862 								break;
       
   863 							case "whileScrolling":
       
   864 								$this.data("whileScrolling_Callback").call($this, this.mcs);
       
   865 								break;
       
   866 							case "onScroll":
       
   867 								$this.data("onScroll_Callback").call($this, this.mcs);
       
   868 								break;
       
   869 							case "onTotalScrollBack":
       
   870 								$this.data("onTotalScrollBack_Callback").call($this, this.mcs);
       
   871 								break;
       
   872 							case "onTotalScroll":
       
   873 								$this.data("onTotalScroll_Callback").call($this, this.mcs);
       
   874 								break;
       
   875 						}
       
   876 					}
       
   877 				}
       
   878 			},
       
   879 			stop: function () {
       
   880 				var $this = $(this),
       
   881 					mCSB_container = $this.children().children(".mCSB_container"),
       
   882 					mCSB_dragger = $this.children().children().children().children(".mCSB_dragger");
       
   883 				functions.mTweenAxisStop.call(this, mCSB_container[0]);
       
   884 				functions.mTweenAxisStop.call(this, mCSB_dragger[0]);
       
   885 			},
       
   886 			disable: function (resetScroll) {
       
   887 				var $this = $(this),
       
   888 					mCustomScrollBox = $this.children(".mCustomScrollBox"),
       
   889 					mCSB_container = mCustomScrollBox.children(".mCSB_container"),
       
   890 					mCSB_scrollTools = mCustomScrollBox.children(".mCSB_scrollTools"),
       
   891 					mCSB_dragger = mCSB_scrollTools.children().children(".mCSB_dragger");
       
   892 				mCustomScrollBox.unbind("mousewheel focusin mouseenter mouseleave touchend");
       
   893 				mCSB_container.unbind("touchstart touchmove")
       
   894 				if (resetScroll) {
       
   895 					if ($this.data("horizontalScroll")) {
       
   896 						mCSB_dragger.add(mCSB_container).css("left", 0);
       
   897 					} else {
       
   898 						mCSB_dragger.add(mCSB_container).css("top", 0);
       
   899 					}
       
   900 				}
       
   901 				mCSB_scrollTools.css("display", "none");
       
   902 				mCSB_container.addClass("mCS_no_scrollbar");
       
   903 				$this.data({"bindEvent_mousewheel": false, "bindEvent_focusin": false, "bindEvent_content_touch": false, "bindEvent_autoHideScrollbar": false}).addClass("mCS_disabled");
       
   904 			},
       
   905 			destroy: function () {
       
   906 				var $this = $(this);
       
   907 				$this.removeClass("mCustomScrollbar _mCS_" + $this.data("mCustomScrollbarIndex")).addClass("mCS_destroyed").children().children(".mCSB_container").unwrap().children().unwrap().siblings(".mCSB_scrollTools").remove();
       
   908 				$(document).unbind("mousemove." + $this.data("mCustomScrollbarIndex") + " mouseup." + $this.data("mCustomScrollbarIndex") + " MSPointerMove." + $this.data("mCustomScrollbarIndex") + " MSPointerUp." + $this.data("mCustomScrollbarIndex"));
       
   909 				$(window).unbind("resize." + $this.data("mCustomScrollbarIndex"));
       
   910 			}
       
   911 		},
       
   912 		functions = {
       
   913 			/*hide/show scrollbar*/
       
   914 			showScrollbar: function () {
       
   915 				this.stop().animate({opacity: 1}, "fast");
       
   916 			},
       
   917 			hideScrollbar: function () {
       
   918 				this.stop().animate({opacity: 0}, "fast");
       
   919 			},
       
   920 			/*js animation tween*/
       
   921 			mTweenAxis: function (el, prop, to, duration, easing, callbacks) {
       
   922 				var callbacks = callbacks || {},
       
   923 					onStart = callbacks.onStart || function () {
       
   924 					}, onUpdate = callbacks.onUpdate || function () {
       
   925 					}, onComplete = callbacks.onComplete || function () {
       
   926 					};
       
   927 				var startTime = _getTime(), _delay, progress = 0, from = el.offsetTop, elStyle = el.style;
       
   928 				if (prop === "left") {
       
   929 					from = el.offsetLeft;
       
   930 				}
       
   931 				var diff = to - from;
       
   932 				_cancelTween();
       
   933 				_startTween();
       
   934 				function _getTime() {
       
   935 					if (window.performance && window.performance.now) {
       
   936 						return window.performance.now();
       
   937 					} else {
       
   938 						if (window.performance && window.performance.webkitNow) {
       
   939 							return window.performance.webkitNow();
       
   940 						} else {
       
   941 							if (Date.now) {
       
   942 								return Date.now();
       
   943 							} else {
       
   944 								return new Date().getTime();
       
   945 							}
       
   946 						}
       
   947 					}
       
   948 				}
       
   949 
       
   950 				function _step() {
       
   951 					if (!progress) {
       
   952 						onStart.call();
       
   953 					}
       
   954 					progress = _getTime() - startTime;
       
   955 					_tween();
       
   956 					if (progress >= el._time) {
       
   957 						el._time = (progress > el._time) ? progress + _delay - (progress - el._time) : progress + _delay - 1;
       
   958 						if (el._time < progress + 1) {
       
   959 							el._time = progress + 1;
       
   960 						}
       
   961 					}
       
   962 					if (el._time < duration) {
       
   963 						el._id = _request(_step);
       
   964 					} else {
       
   965 						onComplete.call();
       
   966 					}
       
   967 				}
       
   968 
       
   969 				function _tween() {
       
   970 					if (duration > 0) {
       
   971 						el.currVal = _ease(el._time, from, diff, duration, easing);
       
   972 						elStyle[prop] = Math.round(el.currVal) + "px";
       
   973 					} else {
       
   974 						elStyle[prop] = to + "px";
       
   975 					}
       
   976 					onUpdate.call();
       
   977 				}
       
   978 
       
   979 				function _startTween() {
       
   980 					_delay = 1000 / 60;
       
   981 					el._time = progress + _delay;
       
   982 					_request = (!window.requestAnimationFrame) ? function (f) {
       
   983 						_tween();
       
   984 						return setTimeout(f, 0.01);
       
   985 					} : window.requestAnimationFrame;
       
   986 					el._id = _request(_step);
       
   987 				}
       
   988 
       
   989 				function _cancelTween() {
       
   990 					if (el._id == null) {
       
   991 						return;
       
   992 					}
       
   993 					if (!window.requestAnimationFrame) {
       
   994 						clearTimeout(el._id);
       
   995 					} else {
       
   996 						window.cancelAnimationFrame(el._id);
       
   997 					}
       
   998 					el._id = null;
       
   999 				}
       
  1000 
       
  1001 				function _ease(t, b, c, d, type) {
       
  1002 					switch (type) {
       
  1003 						case "linear":
       
  1004 							return c * t / d + b;
       
  1005 							break;
       
  1006 						case "easeOutQuad":
       
  1007 							t /= d;
       
  1008 							return -c * t * (t - 2) + b;
       
  1009 							break;
       
  1010 						case "easeInOutQuad":
       
  1011 							t /= d / 2;
       
  1012 							if (t < 1) return c / 2 * t * t + b;
       
  1013 							t--;
       
  1014 							return -c / 2 * (t * (t - 2) - 1) + b;
       
  1015 							break;
       
  1016 						case "easeOutCubic":
       
  1017 							t /= d;
       
  1018 							t--;
       
  1019 							return c * (t * t * t + 1) + b;
       
  1020 							break;
       
  1021 						case "easeOutQuart":
       
  1022 							t /= d;
       
  1023 							t--;
       
  1024 							return -c * (t * t * t * t - 1) + b;
       
  1025 							break;
       
  1026 						case "easeOutQuint":
       
  1027 							t /= d;
       
  1028 							t--;
       
  1029 							return c * (t * t * t * t * t + 1) + b;
       
  1030 							break;
       
  1031 						case "easeOutCirc":
       
  1032 							t /= d;
       
  1033 							t--;
       
  1034 							return c * Math.sqrt(1 - t * t) + b;
       
  1035 							break;
       
  1036 						case "easeOutSine":
       
  1037 							return c * Math.sin(t / d * (Math.PI / 2)) + b;
       
  1038 							break;
       
  1039 						case "easeOutExpo":
       
  1040 							return c * ( -Math.pow(2, -10 * t / d) + 1 ) + b;
       
  1041 							break;
       
  1042 						case "mcsEaseOut":
       
  1043 							var ts = (t /= d) * t, tc = ts * t;
       
  1044 							return b + c * (0.499999999999997 * tc * ts + -2.5 * ts * ts + 5.5 * tc + -6.5 * ts + 4 * t);
       
  1045 							break;
       
  1046 						case "draggerRailEase":
       
  1047 							t /= d / 2;
       
  1048 							if (t < 1) return c / 2 * t * t * t + b;
       
  1049 							t -= 2;
       
  1050 							return c / 2 * (t * t * t + 2) + b;
       
  1051 							break;
       
  1052 					}
       
  1053 				}
       
  1054 			},
       
  1055 			/*stop js animation tweens*/
       
  1056 			mTweenAxisStop: function (el) {
       
  1057 				if (el._id == null) {
       
  1058 					return;
       
  1059 				}
       
  1060 				if (!window.requestAnimationFrame) {
       
  1061 					clearTimeout(el._id);
       
  1062 				} else {
       
  1063 					window.cancelAnimationFrame(el._id);
       
  1064 				}
       
  1065 				el._id = null;
       
  1066 			},
       
  1067 			/*detect requestAnimationFrame and polyfill*/
       
  1068 			rafPolyfill: function () {
       
  1069 				var pfx = ["ms", "moz", "webkit", "o"], i = pfx.length;
       
  1070 				while (--i > -1 && !window.requestAnimationFrame) {
       
  1071 					window.requestAnimationFrame = window[pfx[i] + "RequestAnimationFrame"];
       
  1072 					window.cancelAnimationFrame = window[pfx[i] + "CancelAnimationFrame"] || window[pfx[i] + "CancelRequestAnimationFrame"];
       
  1073 				}
       
  1074 			}
       
  1075 		}
       
  1076 	/*detect features*/
       
  1077 	functions.rafPolyfill.call();
       
  1078 	/*requestAnimationFrame*/
       
  1079 	$.support.touch = !!('ontouchstart' in window);
       
  1080 	/*touch*/
       
  1081 	$.support.pointer = window.navigator.pointerEnabled;
       
  1082 	/*pointer support*/
       
  1083 	$.support.msPointer = window.navigator.msPointerEnabled;
       
  1084 	/*MSPointer support*/
       
  1085 	/*plugin dependencies*/
       
  1086 	var _dlp = ("https:" == document.location.protocol) ? "https:" : "http:";
       
  1087 	$.event.special.mousewheel || document.write('<script src="' + _dlp + '//cdnjs.cloudflare.com/ajax/libs/jquery-mousewheel/3.0.6/jquery.mousewheel.min.js"><\/script>');
       
  1088 	/*plugin fn*/
       
  1089 	$.fn.mCustomScrollbar = function (method) {
       
  1090 		if (methods[method]) {
       
  1091 			return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
       
  1092 		} else if (typeof method === "object" || !method) {
       
  1093 			return methods.init.apply(this, arguments);
       
  1094 		} else {
       
  1095 			$.error("Method " + method + " does not exist");
       
  1096 		}
       
  1097 	};
       
  1098 })(jQuery);