PageSourceSearch

https://westonerz.com/wp-content/themes/zoxpress/js/scripts.js?ver=7.1.2

js westonerz.com collected 2026-09-28 14:45:18 UTC 113,963 bytes, 3,265 lines download raw bytes

1jQuery(document).ready(function($) {
2"use strict";
3
4  	// Fly-Out Navigation
5	$(".zox-fly-but-click").on('click', function(){
6		$("#zox-fly-wrap").toggleClass("zox-fly-menu");
7		$("#zox-fly-wrap").toggleClass("zox-fly-shadow");
8  		$(".zox-fly-but-wrap").toggleClass("zox-fly-open");
9  		$(".zox-fly-fade").toggleClass("zox-fly-fade-trans");
10		$("#zox-site-main").toggleClass("zox-body-blur");
11	});
12
13	// Back to Top Button
14    	var duration = 500;
15    	$('.back-to-top').on('click', function(event) {
16          event.preventDefault();
17          $('html, body').animate({scrollTop: 0}, duration);
18          return false;
19    	});
20
21    document.querySelectorAll('a[href^="#"]').forEach(anchor => {
22	    anchor.addEventListener('click', function (e) {
23	        e.preventDefault();
24
25	        document.querySelector(this.getAttribute('href')).scrollIntoView({
26	            behavior: 'smooth'
27	        });
28	    });
29	});
30
31	// Copy To Clipboard
32	var dummy = document.createElement('input');
33    var text = window.location.href;
34	$('.zox-post-soc-copy').click(function() {
35		document.body.appendChild(dummy);
36		dummy.value = text;
37		dummy.select();
38		document.execCommand('copy');
39		document.body.removeChild(dummy);
40		alert("URL Copied.");
41	});
42
43 	// Search Toggle
44 	$(".zox-search-click").on('click', function(){
45 	  	$("#zox-search-wrap").toggleClass("zox-search-toggle");
46		$("#zox-site-main").toggleClass("zox-body-blur");
47		$("#zox-search-input").focus();
48  	});
49
50 	// Social Toggle
51 	$(".zox-soc-stat-click").on('click', function(){
52 	$(".zox-soc-more-stat").toggleClass("zox-soc-more-open");
53  	});
54
55  	$(".zox-soc-scroll-click").on('click', function(){
56	$(".zox-soc-more-scroll").toggleClass("zox-soc-more-open");
57  	});
58
59   	// Comments Toggle
60   	$(".zox-com-click").on('click', function(){
61	  $("#comments").show();
62  	  $("#disqus_thread").show();
63  	  $("#zox-comments-button").hide();
64  	});
65
66	// Widget Columns Toggle
67	$('.zox-widget-tab-wrap').each(function() {
68		$(this).find(".zox-tab-col-cont").hide(); //Hide all content
69		$(this).find("ul.zox-widget-tab-head li.zox-widget-tab-act").addClass("active").show(); //Activate first tab
70		$(this).find(".zox-tab-col-cont:first").show(); //Show first tab content
71	});
72
73	$("ul.zox-widget-tab-head li").on('click', function(e) {
74		$(this).parents('.zox-widget-tab-wrap').find("ul.zox-widget-tab-head li").removeClass("active"); //Remove any "active" class
75		$(this).addClass("active"); //Add "active" class to selected tab
76		$(this).parents('.zox-widget-tab-wrap').find(".zox-tab-col-cont").hide(); //Hide all tab content
77
78		var activeTab = $(this).find("a").attr("href"); //Find the href attribute value to identify the active tab + content
79		$(this).parents('.zox-widget-tab-wrap').find(activeTab).fadeIn(); //Fade in the active ID content
80
81		e.preventDefault();
82	});
83
84	$("ul.zox-widget-tab-head li a").on('click', function(e) {
85		e.preventDefault();
86	});
87
88});
89
90
91	// Nicescroll
92
93(function(jQuery){
94
95  // globals
96  var domfocus = false;
97  var mousefocus = false;
98  var zoomactive = false;
99  var tabindexcounter = 5000;
100  var ascrailcounter = 2000;
101  var globalmaxzindex = 0;
102
103  var $ = jQuery;  // sandbox
104
105  // http://stackoverflow.com/questions/2161159/get-script-path
106  function getScriptPath() {
107    var scripts=document.getElementsByTagName('script');
108    var path=scripts[scripts.length-1].src.split('?')[0];
109    return (path.split('/').length>0) ? path.split('/').slice(0,-1).join('/')+'/' : '';
110  }
111  var scriptpath = getScriptPath();
112
113  var vendors = ['ms','moz','webkit','o'];
114
115  var setAnimationFrame = window.requestAnimationFrame||false;
116  var clearAnimationFrame = window.cancelAnimationFrame||false;
117
118  if (!setAnimationFrame) {
119    for(var vx in vendors) {
120      var v = vendors[vx];
121      if (!setAnimationFrame) setAnimationFrame = window[v+'RequestAnimationFrame'];
122      if (!clearAnimationFrame) clearAnimationFrame = window[v+'CancelAnimationFrame']||window[v+'CancelRequestAnimationFrame'];
123    }
124  }
125
126  var clsMutationObserver = window.MutationObserver || window.WebKitMutationObserver || false;
127
128  var _globaloptions = {
129      zindex:"auto",
130      cursoropacitymin:0,
131      cursoropacitymax:1,
132      cursorcolor:"#424242",
133      cursorwidth:"5px",
134      cursorborder:"1px solid #fff",
135      cursorborderradius:"5px",
136      scrollspeed:60,
137      mousescrollstep:8*3,
138      touchbehavior:false,
139      hwacceleration:true,
140      usetransition:true,
141      boxzoom:false,
142      dblclickzoom:true,
143      gesturezoom:true,
144      grabcursorenabled:true,
145      autohidemode:true,
146      background:"",
147      iframeautoresize:true,
148      cursorminheight:32,
149      preservenativescrolling:true,
150      railoffset:false,
151      bouncescroll:true,
152      spacebarenabled:true,
153      railpadding:{top:0,right:0,left:0,bottom:0},
154      disableoutline:true,
155      horizrailenabled:true,
156      railalign:"right",
157      railvalign:"bottom",
158      enabletranslate3d:true,
159      enablemousewheel:true,
160      enablekeyboard:true,
161      smoothscroll:true,
162      sensitiverail:true,
163      enablemouselockapi:true,
164//      cursormaxheight:false,
165      cursorfixedheight:false,
166      directionlockdeadzone:6,
167      hidecursordelay:400,
168      nativeparentscrolling:true,
169      enablescrollonselection:true,
170      overflowx:true,
171      overflowy:true,
172      cursordragspeed:0.3,
173      rtlmode:false,
174      cursordragontouch:false,
175      oneaxismousemode:"auto"
176  }
177
178  var browserdetected = false;
179
180  var getBrowserDetection = function() {
181
182    if (browserdetected) return browserdetected;
183
184    var domtest = document.createElement('DIV');
185
186    var d = {};
187
188		d.haspointerlock = "pointerLockElement" in document || "mozPointerLockElement" in document || "webkitPointerLockElement" in document;
189
190    d.isopera = ("opera" in window);
191    d.isopera12 = (d.isopera&&("getUserMedia" in navigator));
192    d.isoperamini = (Object.prototype.toString.call(window.operamini) === "[object OperaMini]");
193
194    d.isie = (("all" in document) && ("attachEvent" in domtest) && !d.isopera);
195    d.isieold = (d.isie && !("msInterpolationMode" in domtest.style));  // IE6 and older
196    d.isie7 = d.isie&&!d.isieold&&(!("documentMode" in document)||(document.documentMode==7));
197    d.isie8 = d.isie&&("documentMode" in document)&&(document.documentMode==8);
198    d.isie9 = d.isie&&("performance" in window)&&(document.documentMode>=9);
199    d.isie10 = d.isie&&("performance" in window)&&(document.documentMode>=10);
200
201    d.isie9mobile = /iemobile.9/i.test(navigator.userAgent);  //wp 7.1 mango
202    if (d.isie9mobile) d.isie9 = false;
203    d.isie7mobile = (!d.isie9mobile&&d.isie7) && /iemobile/i.test(navigator.userAgent);  //wp 7.0
204
205    d.ismozilla = ("MozAppearance" in domtest.style);
206
207    d.iswebkit = ("WebkitAppearance" in domtest.style);
208
209    d.ischrome = ("chrome" in window);
210		d.ischrome22 = (d.ischrome&&d.haspointerlock);
211    d.ischrome26 = (d.ischrome&&("transition" in domtest.style));  // issue with transform detection (maintain prefix)
212
213    d.cantouch = ("ontouchstart" in document.documentElement)||("ontouchstart" in window);  // detection for Chrome Touch Emulation
214    d.hasmstouch = (window.navigator.msPointerEnabled||false);  // IE10+ pointer events
215
216    d.ismac = /^mac$/i.test(navigator.platform);
217
218    d.isios = (d.cantouch && /iphone|ipad|ipod/i.test(navigator.platform));
219    d.isios4 = ((d.isios)&&!("seal" in Object));
220
221    d.isandroid = (/android/i.test(navigator.userAgent));
222
223    d.trstyle = false;
224    d.hastransform = false;
225    d.hastranslate3d = false;
226    d.transitionstyle = false;
227    d.hastransition = false;
228    d.transitionend = false;
229
230    var check = ['transform','msTransform','webkitTransform','MozTransform','OTransform'];
231    for(var a=0;a<check.length;a++){
232      if (typeof domtest.style[check[a]] != "undefined") {
233        d.trstyle = check[a];
234        break;
235      }
236    }
237    d.hastransform = (d.trstyle != false);
238    if (d.hastransform) {
239      domtest.style[d.trstyle] = "translate3d(1px,2px,3px)";
240      d.hastranslate3d = /translate3d/.test(domtest.style[d.trstyle]);
241    }
242
243    d.transitionstyle = false;
244    d.prefixstyle = '';
245    d.transitionend = false;
246    var check = ['transition','webkitTransition','MozTransition','OTransition','OTransition','msTransition','KhtmlTransition'];
247    var prefix = ['','-webkit-','-moz-','-o-','-o','-ms-','-khtml-'];
248    var evs = ['transitionend','webkitTransitionEnd','transitionend','otransitionend','oTransitionEnd','msTransitionEnd','KhtmlTransitionEnd'];
249    for(var a=0;a<check.length;a++) {
250      if (check[a] in domtest.style) {
251        d.transitionstyle = check[a];
252        d.prefixstyle = prefix[a];
253        d.transitionend = evs[a];
254        break;
255      }
256    }
257    if (d.ischrome26) {  // use always prefix
258      d.prefixstyle = prefix[1];
259    }
260
261    d.hastransition = (d.transitionstyle);
262
263    function detectCursorGrab() {
264      var lst = ['-moz-grab','-webkit-grab','grab'];
265      if ((d.ischrome&&!d.ischrome22)||d.isie) lst=[];  // force setting for IE returns false positive and chrome cursor bug
266      for(var a=0;a<lst.length;a++) {
267        var p = lst[a];
268        domtest.style['cursor']=p;
269        if (domtest.style['cursor']==p) return p;
270      }
271      return 'url(http://www.google.com/intl/en_ALL/mapfiles/openhand.cur),n-resize';  // thank you google for custom cursor!
272    }
273    d.cursorgrabvalue = detectCursorGrab();
274
275    d.hasmousecapture = ("setCapture" in domtest);
276
277    d.hasMutationObserver = (clsMutationObserver !== false);
278
279    domtest = null;  //memory released
280
281    browserdetected = d;
282
283    return d;
284  }
285
286  var NiceScrollClass = function(myopt,me) {
287
288    var self = this;
289
290    this.version = '3.5.0 BETA5';
291    this.name = 'nicescroll';
292
293    this.me = me;
294
295    this.opt = {
296      doc:$("body"),
297      win:false
298    };
299
300    $.extend(this.opt,_globaloptions);
301
302// Options for internal use
303    this.opt.snapbackspeed = 80;
304
305    if (myopt||false) {
306      for(var a in self.opt) {
307        if (typeof myopt[a] != "undefined") self.opt[a] = myopt[a];
308      }
309    }
310
311    this.doc = self.opt.doc;
312    this.iddoc = (this.doc&&this.doc[0])?this.doc[0].id||'':'';
313    this.ispage = /BODY|HTML/.test((self.opt.win)?self.opt.win[0].nodeName:this.doc[0].nodeName);
314    this.haswrapper = (self.opt.win!==false);
315    this.win = self.opt.win||(this.ispage?$(window):this.doc);
316    this.docscroll = (this.ispage&&!this.haswrapper)?$(window):this.win;
317    this.body = $("body");
318    this.viewport = false;
319
320    this.isfixed = false;
321
322    this.iframe = false;
323    this.isiframe = ((this.doc[0].nodeName == 'IFRAME') && (this.win[0].nodeName == 'IFRAME'));
324
325    this.istextarea = (this.win[0].nodeName == 'TEXTAREA');
326
327    this.forcescreen = false; //force to use screen position on events
328
329    this.canshowonmouseevent = (self.opt.autohidemode!="scroll");
330
331// Events jump table
332    this.onmousedown = false;
333    this.onmouseup = false;
334    this.onmousemove = false;
335    this.onmousewheel = false;
336    this.onkeypress = false;
337    this.ongesturezoom = false;
338    this.onclick = false;
339
340// Nicescroll custom events
341    this.onscrollstart = false;
342    this.onscrollend = false;
343    this.onscrollcancel = false;
344
345    this.onzoomin = false;
346    this.onzoomout = false;
347
348// Let's start!
349    this.view = false;
350    this.page = false;
351
352    this.scroll = {x:0,y:0};
353    this.scrollratio = {x:0,y:0};
354    this.cursorheight = 20;
355    this.scrollvaluemax = 0;
356
357    this.checkrtlmode = false;
358
359    this.scrollrunning = false;
360
361    this.scrollmom = false;
362
363    this.observer = false;
364    this.observerremover = false;  // observer on parent for remove detection
365
366    do {
367      this.id = "ascrail"+(ascrailcounter++);
368    } while (document.getElementById(this.id));
369
370    this.rail = false;
371    this.cursor = false;
372    this.cursorfreezed = false;
373    this.selectiondrag = false;
374
375    this.zoom = false;
376    this.zoomactive = false;
377
378    this.hasfocus = false;
379    this.hasmousefocus = false;
380
381    this.visibility = true;
382    this.locked = false;
383    this.hidden = false; // rails always hidden
384    this.cursoractive = true; // user can interact with cursors
385
386    this.overflowx = self.opt.overflowx;
387    this.overflowy = self.opt.overflowy;
388
389    this.nativescrollingarea = false;
390    this.checkarea = 0;
391
392    this.events = [];  // event list for unbind
393
394    this.saved = {};
395
396    this.delaylist = {};
397    this.synclist = {};
398
399    this.lastdeltax = 0;
400    this.lastdeltay = 0;
401
402    this.detected = getBrowserDetection();
403
404    var cap = $.extend({},this.detected);
405
406    this.canhwscroll = (cap.hastransform&&self.opt.hwacceleration);
407    this.ishwscroll = (this.canhwscroll&&self.haswrapper);
408
409    this.istouchcapable = false;  // desktop devices with touch screen support
410
411//## Check Chrome desktop with touch support
412    if (cap.cantouch&&cap.ischrome&&!cap.isios&&!cap.isandroid) {
413      this.istouchcapable = true;
414      cap.cantouch = false;  // parse normal desktop events
415    }
416
417//## Firefox 18 nightly build (desktop) false positive (or desktop with touch support)
418    if (cap.cantouch&&cap.ismozilla&&!cap.isios&&!cap.isandroid) {
419      this.istouchcapable = true;
420      cap.cantouch = false;  // parse normal desktop events
421    }
422
423//## disable MouseLock API on user request
424
425    if (!self.opt.enablemouselockapi) {
426      cap.hasmousecapture = false;
427      cap.haspointerlock = false;
428    }
429
430    this.delayed = function(name,fn,tm,lazy) {
431      var dd = self.delaylist[name];
432      var nw = (new Date()).getTime();
433      if (!lazy&&dd&&dd.tt) return false;
434      if (dd&&dd.tt) clearTimeout(dd.tt);
435      if (dd&&dd.last+tm>nw&&!dd.tt) {
436        self.delaylist[name] = {
437          last:nw+tm,
438          tt:setTimeout(function(){self.delaylist[name].tt=0;fn.call();},tm)
439        }
440      }
441      else if (!dd||!dd.tt) {
442        self.delaylist[name] = {
443          last:nw,
444          tt:0
445        }
446        setTimeout(function(){fn.call();},0);
447      }
448    };
449
450    this.debounced = function(name,fn,tm) {
451      var dd = self.delaylist[name];
452      var nw = (new Date()).getTime();
453      self.delaylist[name] = fn;
454      if (!dd) {
455        setTimeout(function(){var fn=self.delaylist[name];self.delaylist[name]=false;fn.call();},tm);
456      }
457    }
458
459    this.synched = function(name,fn) {
460
461      function requestSync() {
462        if (self.onsync) return;
463        setAnimationFrame(function(){
464          self.onsync = false;
465          for(name in self.synclist){
466            var fn = self.synclist[name];
467            if (fn) fn.call(self);
468            self.synclist[name] = false;
469          }
470        });
471        self.onsync = true;
472      };
473
474      self.synclist[name] = fn;
475      requestSync();
476      return name;
477    };
478
479    this.unsynched = function(name) {
480      if (self.synclist[name]) self.synclist[name] = false;
481    }
482
483    this.css = function(el,pars) {  // save & set
484      for(var n in pars) {
485        self.saved.css.push([el,n,el.css(n)]);
486        el.css(n,pars[n]);
487      }
488    };
489
490    this.scrollTop = function(val) {
491      return (typeof val == "undefined") ? self.getScrollTop() : self.setScrollTop(val);
492    };
493
494    this.scrollLeft = function(val) {
495      return (typeof val == "undefined") ? self.getScrollLeft() : self.setScrollLeft(val);
496    };
497
498// derived by by Dan Pupius www.pupius.net
499    BezierClass = function(st,ed,spd,p1,p2,p3,p4) {
500      this.st = st;
501      this.ed = ed;
502      this.spd = spd;
503
504      this.p1 = p1||0;
505      this.p2 = p2||1;
506      this.p3 = p3||0;
507      this.p4 = p4||1;
508
509      this.ts = (new Date()).getTime();
510      this.df = this.ed-this.st;
511    };
512    BezierClass.prototype = {
513      B2:function(t){ return 3*t*t*(1-t) },
514      B3:function(t){ return 3*t*(1-t)*(1-t) },
515      B4:function(t){ return (1-t)*(1-t)*(1-t) },
516      getNow:function(){
517        var nw = (new Date()).getTime();
518        var pc = 1-((nw-this.ts)/this.spd);
519        var bz = this.B2(pc) + this.B3(pc) + this.B4(pc);
520        return (pc<0) ? this.ed : this.st+Math.round(this.df*bz);
521      },
522      update:function(ed,spd){
523        this.st = this.getNow();
524        this.ed = ed;
525        this.spd = spd;
526        this.ts = (new Date()).getTime();
527        this.df = this.ed-this.st;
528        return this;
529      }
530    };
531
532    if (this.ishwscroll) {
533    // hw accelerated scroll
534      this.doc.translate = {x:0,y:0,tx:"0px",ty:"0px"};
535
536      //this one can help to enable hw accel on ios6 http://indiegamr.com/ios6-html-hardware-acceleration-changes-and-how-to-fix-them/
537      if (cap.hastranslate3d&&cap.isios) this.doc.css("-webkit-backface-visibility","hidden");  // prevent flickering http://stackoverflow.com/questions/3461441/
538
539      //derived from http://stackoverflow.com/questions/11236090/
540      function getMatrixValues() {
541        var tr = self.doc.css(cap.trstyle);
542        if (tr&&(tr.substr(0,6)=="matrix")) {
543          return tr.replace(/^.*\((.*)\)$/g, "$1").replace(/px/g,'').split(/, +/);
544        }
545        return false;
546      }
547
548      this.getScrollTop = function(last) {
549        if (!last) {
550          var mtx = getMatrixValues();
551          if (mtx) return (mtx.length==16) ? -mtx[13] : -mtx[5];  //matrix3d 16 on IE10
552          if (self.timerscroll&&self.timerscroll.bz) return self.timerscroll.bz.getNow();
553        }
554        return self.doc.translate.y;
555      };
556
557      this.getScrollLeft = function(last) {
558        if (!last) {
559          var mtx = getMatrixValues();
560          if (mtx) return (mtx.length==16) ? -mtx[12] : -mtx[4];  //matrix3d 16 on IE10
561          if (self.timerscroll&&self.timerscroll.bh) return self.timerscroll.bh.getNow();
562        }
563        return self.doc.translate.x;
564      };
565
566      if (document.createEvent) {
567        this.notifyScrollEvent = function(el) {
568          var e = document.createEvent("UIEvents");
569          e.initUIEvent("scroll", false, true, window, 1);
570          el.dispatchEvent(e);
571        };
572      }
573      else if (document.fireEvent) {
574        this.notifyScrollEvent = function(el) {
575          var e = document.createEventObject();
576          el.fireEvent("onscroll");
577          e.cancelBubble = true;
578        };
579      }
580      else {
581        this.notifyScrollEvent = function(el,add) {}; //NOPE
582      }
583
584      if (cap.hastranslate3d&&self.opt.enabletranslate3d) {
585        this.setScrollTop = function(val,silent) {
586          self.doc.translate.y = val;
587          self.doc.translate.ty = (val*-1)+"px";
588          self.doc.css(cap.trstyle,"translate3d("+self.doc.translate.tx+","+self.doc.translate.ty+",0px)");
589          if (!silent) self.notifyScrollEvent(self.win[0]);
590        };
591        this.setScrollLeft = function(val,silent) {
592          self.doc.translate.x = val;
593          self.doc.translate.tx = (val*-1)+"px";
594          self.doc.css(cap.trstyle,"translate3d("+self.doc.translate.tx+","+self.doc.translate.ty+",0px)");
595          if (!silent) self.notifyScrollEvent(self.win[0]);
596        };
597      } else {
598        this.setScrollTop = function(val,silent) {
599          self.doc.translate.y = val;
600          self.doc.translate.ty = (val*-1)+"px";
601          self.doc.css(cap.trstyle,"translate("+self.doc.translate.tx+","+self.doc.translate.ty+")");
602          if (!silent) self.notifyScrollEvent(self.win[0]);
603        };
604        this.setScrollLeft = function(val,silent) {
605          self.doc.translate.x = val;
606          self.doc.translate.tx = (val*-1)+"px";
607          self.doc.css(cap.trstyle,"translate("+self.doc.translate.tx+","+self.doc.translate.ty+")");
608          if (!silent) self.notifyScrollEvent(self.win[0]);
609        };
610      }
611    } else {
612    // native scroll
613      this.getScrollTop = function() {
614        return self.docscroll.scrollTop();
615      };
616      this.setScrollTop = function(val) {
617        return self.docscroll.scrollTop(val);
618      };
619      this.getScrollLeft = function() {
620        return self.docscroll.scrollLeft();
621      };
622      this.setScrollLeft = function(val) {
623        return self.docscroll.scrollLeft(val);
624      };
625    }
626
627    this.getTarget = function(e) {
628      if (!e) return false;
629      if (e.target) return e.target;
630      if (e.srcElement) return e.srcElement;
631      return false;
632    };
633
634    this.hasParent = function(e,id) {
635      if (!e) return false;
636      var el = e.target||e.srcElement||e||false;
637      while (el && el.id != id) {
638        el = el.parentNode||false;
639      }
640      return (el!==false);
641    };
642
643    function getZIndex() {
644      var dom = self.win;
645      if ("zIndex" in dom) return dom.zIndex();  // use jQuery UI method when available
646      while (dom.length>0) {
647        if (dom[0].nodeType==9) return false;
648        var zi = dom.css('zIndex');
649        if (!isNaN(zi)&&zi!=0) return parseInt(zi);
650        dom = dom.parent();
651      }
652      return false;
653    };
654
655//inspired by http://forum.jquery.com/topic/width-includes-border-width-when-set-to-thin-medium-thick-in-ie
656    var _convertBorderWidth = {"thin":1,"medium":3,"thick":5};
657    function getWidthToPixel(dom,prop,chkheight) {
658      var wd = dom.css(prop);
659      var px = parseFloat(wd);
660      if (isNaN(px)) {
661        px = _convertBorderWidth[wd]||0;
662        var brd = (px==3) ? ((chkheight)?(self.win.outerHeight() - self.win.innerHeight()):(self.win.outerWidth() - self.win.innerWidth())) : 1; //DON'T TRUST CSS
663        if (self.isie8&&px) px+=1;
664        return (brd) ? px : 0;
665      }
666      return px;
667    };
668
669    this.getOffset = function() {
670      if (self.isfixed) return {top:parseFloat(self.win.css('top')),left:parseFloat(self.win.css('left'))};
671      if (!self.viewport) return self.win.offset();
672      var ww = self.win.offset();
673      var vp = self.viewport.offset();
674      return {top:ww.top-vp.top+self.viewport.scrollTop(),left:ww.left-vp.left+self.viewport.scrollLeft()};
675    };
676
677    this.updateScrollBar = function(len) {
678      if (self.ishwscroll) {
679        self.rail.css({height:self.win.innerHeight()});
680        if (self.railh) self.railh.css({width:self.win.innerWidth()});
681      } else {
682        var wpos = self.getOffset();
683        var pos = {top:wpos.top,left:wpos.left};
684        pos.top+= getWidthToPixel(self.win,'border-top-width',true);
685        var brd = (self.win.outerWidth() - self.win.innerWidth())/2;
686        pos.left+= (self.rail.align) ? self.win.outerWidth() - getWidthToPixel(self.win,'border-right-width') - self.rail.width : getWidthToPixel(self.win,'border-left-width');
687
688        var off = self.opt.railoffset;
689        if (off) {
690          if (off.top) pos.top+=off.top;
691          if (self.rail.align&&off.left) pos.left+=off.left;
692        }
693
694				if (!self.locked) self.rail.css({top:pos.top,left:pos.left,height:(len)?len.h:self.win.innerHeight()});
695
696				if (self.zoom) {
697				  self.zoom.css({top:pos.top+1,left:(self.rail.align==1) ? pos.left-20 : pos.left+self.rail.width+4});
698			  }
699
700				if (self.railh&&!self.locked) {
701					var pos = {top:wpos.top,left:wpos.left};
702					var y = (self.railh.align) ? pos.top + getWidthToPixel(self.win,'border-top-width',true) + self.win.innerHeight() - self.railh.height : pos.top + getWidthToPixel(self.win,'border-top-width',true);
703					var x = pos.left + getWidthToPixel(self.win,'border-left-width');
704					self.railh.css({top:y,left:x,width:self.railh.width});
705				}
706
707
708      }
709    };
710
711    this.doRailClick = function(e,dbl,hr) {
712
713      var fn,pg,cur,pos;
714
715//      if (self.rail.drag&&self.rail.drag.pt!=1) return;
716      if (self.locked) return;
717//      if (self.rail.drag) return;
718
719//      self.cancelScroll();
720
721      self.cancelEvent(e);
722
723      if (dbl) {
724        fn = (hr) ? self.doScrollLeft : self.doScrollTop;
725        cur = (hr) ? ((e.pageX - self.railh.offset().left - (self.cursorwidth/2)) * 
725self.scrollratio.x) : ((e.pageY - self.rail.offset().top - (self.cursorheight/2)) * self.scrollratio.y);
726        fn(cur);
727      } else {
728//        console.log(e.pageY);
729        fn = (hr) ? self.doScrollLeftBy : self.doScrollBy;
730        cur = (hr) ? self.scroll.x : self.scroll.y;
731        pos = (hr) ? e.pageX - self.railh.offset().left : e.pageY - self.rail.offset().top;
732        pg = (hr) ? self.view.w : self.view.h;
733        (cur>=pos) ? fn(pg) : fn(-pg);
734      }
735
736    }
737
738    self.hasanimationframe = (setAnimationFrame);
739    self.hascancelanimationframe = (clearAnimationFrame);
740
741    if (!self.hasanimationframe) {
742      setAnimationFrame=function(fn){return setTimeout(fn,15-Math.floor((+new Date)/1000)%16)}; // 1000/60)};
743      clearAnimationFrame=clearInterval;
744    }
745    else if (!self.hascancelanimationframe) clearAnimationFrame=function(){self.cancelAnimationFrame=true};
746
747    this.init = function() {
748
749      self.saved.css = [];
750
751      if (cap.isie7mobile) return true; // SORRY, DO NOT WORK!
752      if (cap.isoperamini) return true; // SORRY, DO NOT WORK!
753
754      if (cap.hasmstouch) self.css((self.ispage)?$("html"):self.win,{'-ms-touch-action':'none'});
755
756      self.zindex = "auto";
757      if (!self.ispage&&self.opt.zindex=="auto") {
758        self.zindex = getZIndex()||"auto";
759      } else {
760        self.zindex = self.opt.zindex;
761      }
762
763      if (!self.ispage&&self.zindex!="auto") {
764        if (self.zindex>globalmaxzindex) globalmaxzindex=self.zindex;
765      }
766
767      if (self.isie&&self.zindex==0&&self.opt.zindex=="auto") {  // fix IE auto == 0
768        self.zindex="auto";
769      }
770
771/*
772      self.ispage = true;
773      self.haswrapper = true;
774//      self.win = $(window);
775      self.docscroll = $("body");
776//      self.doc = $("body");
777*/
778
779      if (!self.ispage || (!cap.cantouch && !cap.isieold && !cap.isie9mobile)) {
780
781        var cont = self.docscroll;
782        if (self.ispage) cont = (self.haswrapper)?self.win:self.doc;
783
784        if (!cap.isie9mobile) self.css(cont,{'overflow-y':'hidden'});
785
786        if (self.ispage&&cap.isie7) {
787          if (self.doc[0].nodeName=='BODY') self.css($("html"),{'overflow-y':'hidden'});  //IE7 double scrollbar issue
788          else if (self.doc[0].nodeName=='HTML') self.css($("body"),{'overflow-y':'hidden'});  //IE7 double scrollbar issue
789        }
790
791        if (cap.isios&&!self.ispage&&!self.haswrapper) self.css($("body"),{"-webkit-overflow-scrolling":"touch"});  //force hw acceleration
792
793        var cursor = $(document.createElement('div'));
794        cursor.css({
795          position:"relative",top:0,"float":"right",width:self.opt.cursorwidth,height:"0px",
796          'background-color':self.opt.cursorcolor,
797          border:self.opt.cursorborder,
798          'background-clip':'padding-box',
799          '-webkit-border-radius':self.opt.cursorborderradius,
800          '-moz-border-radius':self.opt.cursorborderradius,
801          'border-radius':self.opt.cursorborderradius
802        });
803
804        cursor.hborder = parseFloat(cursor.outerHeight() - cursor.innerHe
804ight());
805        self.cursor = cursor;
806
807        var rail = $(document.createElement('div'));
808        rail.attr('id',self.id);
809        rail.addClass('nicescroll-rails');
810
811        var v,a,kp = ["left","right"];  //"top","bottom"
812        for(var n in kp) {
813          a=kp[n];
814          v = self.opt.railpadding[a];
815          (v) ? rail.css("padding-"+a,v+"px") : self.opt.railpadding[a] = 0;
816        }
817
818        rail.append(cursor);
819
820        rail.width = Math.max(parseFloat(self.opt.cursorwidth),cursor.outerWidth()) + self.opt.railpadding['left'] + self.opt.railpadding['right'];
821        rail.css({width:rail.width+"px",'zIndex':self.zindex,"background":self.opt.background,cursor:"default"});
822
823        rail.visibility = true;
824        rail.scrollable = true;
825
826        rail.align = (self.opt.railalign=="left") ? 0 : 1;
827
828        self.rail = rail;
829
830        self.rail.drag = false;
831
832        var zoom = false;
833        if (self.opt.boxzoom&&!self.ispage&&!cap.isieold) {
834          zoom = document.createElement('div');
835          self.bind(zoom,"click",self.doZoom);
836          self.zoom = $(zoom);
837          self.zoom.css({"cursor":"pointer",'z-index':self.zindex,'backgroundImage':'url('+scriptpath+'zoomico.png)','height':18,'width':18,'backgroundPosition':'0px 0px'});
838          if (self.opt.dblclickzoom) self.bind(self.win,"dblclick",self.doZoom);
839          if (cap.cantouch&&self.opt.gesturezoom) {
840            self.ongesturezoom = function(e) {
841              if (e.scale>1.5) self.doZoomIn(e);
842              if (e.scale<0.8) self.doZoomOut(e);
843              return self.cancelEvent(e);
844            };
845            self.bind(self.win,"gestureend",self.ongesturezoom);
846          }
847        }
848
849// init HORIZ
850
851        self.railh = false;
852
853        if (self.opt.horizrailenabled) {
854
855          self.css(cont,{'overflow-x':'hidden'});
856
857          var cursor = $(document.createElement('div'));
858          cursor.css({
859            position:"relative",top:0,height:self.opt.cursorwidth,width:"0px",
860            'background-color':self.opt.cursorcolor,
861            border:self.opt.cursorborder,
862            'background-clip':'padding-box',
863            '-webkit-border-radius':self.opt.cursorborderradius,
864            '-moz-border-radius':self.opt.cursorborderradius,
865            'border-radius':self.opt.cursorborderradius
866          });
867
868          cursor.wborder = parseFloat(cursor.outerWidth() - cursor.innerWidth());
869          self.cursorh = cursor;
870
871          var railh = $(document.createElement('div'));
872          railh.attr('id',self.id+'-hr');
873          railh.addClass('nicescroll-rails');
874          railh.height = Math.max(parseFloat(self.opt.cursorwidth),cursor.outerHeight());
875          railh.css({height:railh.height+"px",'zIndex':self.zindex,"background":self.opt.background});
876
877          railh.append(cursor);
878
879          railh.visibility = true;
880          railh.scrollable = true;
881
882          railh.align = (self.opt.railvalign=="top") ? 0 : 1;
883
884          self.railh = railh;
885
886          self.railh.drag = false;
887
888        }
889
890//
891
892        if (self.ispage) {
893          rail.css({position:"fixed",top:"0px",height:"100%"});
894          (rail.align) ? rail.css({right:"0px"}) : rail.css({left:"0px"});
895          self.body.append(rail);
896          if (self.railh) {
897            railh.css({position:"fixed",left:"0px",width:"100%"});
898            (railh.align) ? railh.css({bottom:"0px"}) : railh.css({top:"0px"});
899            self.body.append(railh);
900          }
901        } else {
902          if (self.ishwscroll) {
903            if (self.win.css('position')=='static') self.css(self.win,{'position':'relative'});
904            var bd = (self.win[0].nodeName == 'HTML') ? self.body : self.win;
905            if (self.zoom) {
906              self.zoom.css({position:"absolute",top:1,right:0,"margin-right":rail.width+4});
907              bd.append(self.zoom);
908            }
909            rail.css({position:"absolute",top:0});
910            (rail.align) ? rail.css({right:0}) : rail.css({left:0});
911            bd.append(rail);
912            if (railh) {
913              railh.css({position:"absolute",left:0,bottom:0});
914              (railh.align) ? railh.css({bottom:0}) : railh.css({top:0});
915              bd.append(railh);
916            }
917          } else {
918            self.isfixed = (self.win.css("position")=="fixed");
919            var rlpos = (self.isfixed) ? "fixed" : "absolute";
920
921            if (!self.isfixed) self.viewport = self.getViewport(self.win[0]);
922            if (self.viewport) {
923              self.body = self.viewport;
924              if ((/relative|absolute/.test(self.viewport.css("position")))==false) self.css(self.viewport,{"position":"relative"});
925            }
926
927            rail.css({position:rlpos});
928            if (self.zoom) self.zoom.css({position:rlpos});
929            self.updateScrollBar();
930            self.body.append(rail);
931            if (self.zoom) self.body.append(self.zoom);
932            if (self.railh) {
933              railh.css({position:rlpos});
934              self.body.append(railh);
935            }
936          }
937
938          if (cap.isios) self.css(self.win,{'-webkit-tap-highlight-color':'rgba(0,0,0,0)','-webkit-touch-callout':'none'});  // prevent grey layer on click
939
940					if (cap.isie&&self.opt.disableoutline) self.win.attr("hideFocus","true");  // IE, prevent dotted rectangle on focused div
941					if (cap.iswebkit&&self.opt.disableoutline) self.win.css({"outline":"none"});
942//          if (cap.isopera&&self.opt.disableoutline) self.win.css({"outline":"0"});  // Opera to test [TODO]
943
944        }
945
946        if (self.opt.autohidemode===false) {
947          self.autohidedom = false;
948          self.rail.css({opacity:self.opt.cursoropacitymax});
949          if (self.railh) self.railh.css({opacity:self.opt.cursoropacitymax});
950        }
951        else if (self.opt.autohidemode===true) {
952          self.autohidedom = $().add(self.rail);
953          if (cap.isie8) self.autohidedom=self.autohidedom.add(self.cursor);
954          if (self.railh) self.autohidedom=self.autohidedom.add(self.railh);
955          if (self.railh&&cap.isie8) self.autohidedom=self.autohidedom.add(self.cursorh);
956        }
957        else if (self.opt.autohidemode=="scroll") {
958          self.autohidedom = $().add(self.rail);
959          if (self.railh) self.autohidedom=self.autohidedom.add(self.railh);
960        }
961        else if (self.opt.autohidemode=="cursor") {
962          self.autohidedom = $().add(self.cursor);
963          if (self.railh) self.autohidedom=self.autohidedom.add(self.cursorh);
964        }
965        else if (self.opt.autohidemode=="hidden") {
966          self.autohidedom = false;
967          self.hide();
968          self.locked = false;
969        }
970
971        if (cap.isie9mobile) {
972
973          self.scrollmom = new ScrollMomentumClass2D(self);
974
975          /*
976          var trace = function(msg) {
977            var db = $("#debug");
978            if (isNaN(msg)&&(typeof msg != "string")) {
979              var x = [];
980              for(var a in msg) {
981                x.push(a+":"+msg[a]);
982              }
983              msg ="{"+x.join(",")+"}";
984            }
985            if (db.children().length>0) {
986              db.children().eq(0).before("<div>"+msg+"</div>");
987            } else {
988              db.append("<div>"+msg+"</div>");
989            }
990          }
991          window.onerror = function(msg,url,ln) {
992            trace("ERR: "+msg+" at "+ln);
993          }
994*/
995
996          self.onmangotouch = function(e) {
997            var py = self.getScrollTop();
998            var px = self.getScrollLeft();
999
1000            if ((py == self.scrollmom.lastscrolly)&&(px == self.scrollmom.lastscrollx)) return true;
1001//            $("#debug").html('DRAG:'+py);
1002
1003            var dfy = py-self.mangotouch.sy;
1004            var dfx = px-self.mangotouch.sx;
1005            var df = Math.round(Math.sqrt(Math.pow(dfx,2)+Math.pow(dfy,2)));
1006            if (df==0) return;
1007
1008            var dry = (dfy<0)?-1:1;
1009            var drx = (dfx<0)?-1:1;
1010
1011            var tm = +new Date();
1012            if (self.mangotouch.lazy) clearTimeout(self.mangotouch.lazy);
1013
1014            if (((tm-self.mangotouch.tm)>80)||(self.mangotouch.dry!=dry)||(self.mangotouch.drx!=drx)) {
1015//              trace('RESET+'+(tm-self.mangotouch.tm));
1016              self.scrollmom.stop();
1017              self.scrollmom.reset(px,py);
1018              self.mangotouch.sy = py;
1019              self.mangotouch.ly = py;
1020              self.mangotouch.sx = px;
1021              self.mangotouch.lx = px;
1022              self.mangotouch.dry = dry;
1023              self.mangotouch.drx = drx;
1024              self.mangotouch.tm = tm;
1025            } else {
1026
1027              self.scrollmom.stop();
1028              self.scrollmom.update(self.mangotouch.sx-dfx,self.mangotouch.sy-dfy);
1029              var gap = tm - self.mangotouch.tm;
1030              self.mangotouch.tm = tm;
1031
1032//              trace('MOVE:'+df+" - "+gap);
1033
1034              var ds = Math.max(Math.abs(self.mangotouch.ly-py),Math.abs(self.mangotouch.lx-px));
1035              self.mangotouch.ly = py;
1036              self.mangotouch.lx = px;
1037
1038              if (ds>2) {
1039                self.mangotouch.lazy = setTimeout(function(){
1040//                  trace('END:'+ds+'+'+gap);
1041                  self.mangotouch.lazy = false;
1042                  self.mangotouch.dry = 0;
1043                  self.mangotouch.drx = 0;
1044                  self.mangotouch.tm = 0;
1045                  self.scrollmom.doMomentum(30);
1046                },100);
1047              }
1048            }
1049          }
1050
1051          var top = self.getScrollTop();
1052          var lef = self.getScrollLeft();
1053          self.mangotouch = {sy:top,ly:top,dry:0,sx:lef,lx:lef,drx:0,lazy:false,tm:0};
1054
1055          self.bind(self.docscroll,"scroll",self.onmangotouch);
1056
1057        } else {
1058
1059          if (cap.cantouch||self.istouchcapable||self.opt.touchbehavior||cap.hasmstouch) {
1060
1061            self.scrollmom = new ScrollMomentumClass2D(self);
1062
1063            self.ontouchstart = function(e) {
1064              if (e.pointerType&&e.pointerType!=2) return false;
1065
1066              if (!self.locked) {
1067
1068                if (cap.hasmstouch) {
1069                  var tg = (e.target) ? e.target : false;
1070                  while (tg) {
1071                    var nc = $(tg).getNiceScroll();
1072                    if ((nc.length>0)&&(nc[0].me == self.me)) break;
1073                    if (nc.length>0) return false;
1074                    if ((tg.nodeName=='DIV')&&(tg.id==self.id)) break;
1075                    tg = (tg.parentNode) ? tg.parentNode : false;
1076                  }
1077                }
1078
1079                self.cancelScroll();
1080
1081                var tg = self.getTarget(e);
1082
1083                if (tg) {
1084                  var skp = (/INPUT/i.test(tg.nodeName))&&(/range/i.test(tg.type));
1085                  if (skp) return self.stopPropagation(e);
1086                }
1087
1088                if (!("clientX" in e) && ("changedTouches" in e)) {
1089                  e.clientX = e.changedTouches[0].clientX;
1090                  e.clientY = e.changedTouches[0].clientY;
1091                }
1092
1093                if (self.forcescreen) {
1094                  var le = e;
1095                  var e = {"original":(e.original)?e.original:e};
1096                  e.clientX = le.screenX;
1097                  e.clientY = le.screenY;
1098                }
1099
1100                self.rail.drag = {x:e.clientX,y:e.clientY,sx:self.scroll.x,sy:self.scroll.y,st:self.getScrollTop(),sl:self.getScrollLeft(),pt:2,dl:false};
1101
1102                if (self.ispage||!self.opt.directionlockdeadzone) {
1103                  self.rail.drag.dl = "f";
1104                } else {
1105
1106                  var view = {
1107                    w:$(window).width(),
1108                    h:$(window).height()
1109                  };
1110
1111                  var page = {
1112                    w:Math.max(document.body.scrollWidth,document.documentElement.scrollWidth),
1113                    h:Math.max(document.body.scrollHeight,document.documentElement.scrollHeight)
1114                  }
1115
1116                  var maxh = Math.max(0,page.h - view.h);
1117                  var maxw = Math.max(0,page.w - view.w);
1118
1119                  if (!self.rail.scrollable&&self.railh.scrollable) self.rail.drag.ck = (maxh>0) ? "v" : false;
1120                  else if (self.rail.scrollable&&!self.railh.scrollable) self.rail.drag.ck = (maxw>0) ? "h" : false;
1121                  else self.rail.drag.ck = false;
1122                  if (!self.rail.drag.ck) self.rail.drag.dl = "f";
1123                }
1124
1125                if (self.opt.touchbehavior&&self.isiframe&&cap.isie) {
1126                  var wp = self.win.position();
1127                  self.rail.drag.x+=wp.left;
1128                  self.rail.drag.y+=wp.top;
1129                }
1130
1131                self.hasmoving = false;
1132                self.lastmouseup = false;
1133                self.scrollmom.reset(e.clientX,e.clientY);
1134                if (!cap.cantouch&&!this.istouchcapable&&!cap.hasmstouch) {
1135
1136                  var ip = (tg)?/INPUT|SELECT|TEXTAREA/i.test(tg.nodeName):false;
1137                  if (!ip) {
1138                    if (!self.ispage&&cap.hasmousecapture) tg.setCapture();
1139//                  return self.cancelEvent(e);
1140                    return (self.opt.touchbehavior) ? self.cancelEvent(e) : self.stopPropagation(e);
1141                  }
1142                  if (/SUBMIT|CANCEL|BUTTON/i.test($(tg).attr('type'))) {
1143                    pc = {"tg":tg,"click":false};
1144                    self.preventclick = pc;
1145                  }
1146
1147                }
1148              }
1149
1150            };
1151
1152            self.ontouchend = function(e) {
1153              if (e.pointerType&&e.pointerType!=2) return false;
1154              if (self.rail.drag&&(self.rail.drag.pt==2)) {
1155                self.scrollmom.doMomentum();
1156                self.rail.drag = false;
1157                if (self.hasmoving) {
1158                  self.hasmoving = false;
1159                  self.lastmouseup = true;
1160                  self.hideCursor();
1161                  if (cap.hasmousecapture) document.releaseCapture();
1162                  if (!cap.cantouch) return self.cancelEvent(e);
1163                }
1164              }
1165
1166            };
1167
1168            var moveneedoffset = (self.opt.touchbehavior&&self.isiframe&&!cap.hasmousecapture);
1169
1170            self.ontouchmove = function(e,byiframe) {
1171
1172              if (e.pointerType&&e.pointerType!=2) return false;
1173
1174              if (self.rail.drag&&(self.rail.drag.pt==2)) {
1175                if (cap.cantouch&&(typeof e.original == "undefined")) return true;  // prevent ios "ghost" events by clickable elements
1176
1177                self.hasmoving = true;
1178
1179                if (self.preventclick&&!self.preventclick.click) {
1180                  self.preventclick.click = self.preventclick.tg.oncl
1180ick||false;
1181                  self.preventclick.tg.onclick = self.onpreventclick;
1182                }
1183
1184                var ev = $.extend({"original":e},e);
1185                e = ev;
1186
1187                if (("changedTouches" in e)) {
1188                  e.clientX = e.changedTouches[0].clientX;
1189                  e.clientY = e.changedTouches[0].clientY;
1190                }
1191
1192                if (self.forcescreen) {
1193                  var le = e;
1194                  var e = {"original":(e.original)?e.original:e};
1195                  e.clientX = le.screenX;
1196                  e.clientY = le.screenY;
1197                }
1198
1199                var ofx = ofy = 0;
1200
1201                if (moveneedoffset&&!byiframe) {
1202                  var wp = self.win.position();
1203                  ofx=-wp.left;
1204                  ofy=-wp.top;
1205                }
1206
1207                var fy = e.clientY + ofy;
1208                var my = (fy-self.rail.drag.y);
1209                var fx = e.clientX + ofx;
1210                var mx = (fx-self.rail.drag.x);
1211
1212                var ny = self.rail.drag.st-my;
1213
1214                if (self.ishwscroll&&self.opt.bouncescroll) {
1215                  if (ny<0) {
1216                    ny = Math.round(ny/2);
1217//                    fy = 0;
1218                  }
1219                  else if (ny>self.page.maxh) {
1220                    ny = self.page.maxh+Math.round((ny-self.page.maxh)/2);
1221//                    fy = 0;
1222                  }
1223                } else {
1224                  if (ny<0) {ny=0;fy=0}
1225                  if (ny>self.page.maxh) {ny=self.page.maxh;fy=0}
1226                }
1227
1228                if (self.railh&&self.railh.scrollable) {
1229                  var nx = self.rail.drag.sl-mx;
1230
1231                  if (self.ishwscroll&&self.opt.bouncescroll) {
1232                    if (nx<0) {
1233                      nx = Math.round(nx/2);
1234//                      fx = 0;
1235                    }
1236                    else if (nx>self.page.maxw) {
1237                      nx = self.page.maxw+Math.round((nx-self.page.maxw)/2);
1238//                      fx = 0;
1239                    }
1240                  } else {
1241                    if (nx<0) {nx=0;fx=0}
1242                    if (nx>self.page.maxw) {nx=self.page.maxw;fx=0}
1243                  }
1244
1245                }
1246
1247                var grabbed = false;
1248                if (self.rail.drag.dl) {
1249                  grabbed = true;
1250                  if (self.rail.drag.dl=="v") nx = self.rail.drag.sl;
1251                  else if (self.rail.drag.dl=="h") ny = self.rail.drag.st;
1252                } else {
1253                  var ay = Math.abs(my);
1254                  var ax = Math.abs(mx);
1255                  var dz = self.opt.directionlockdeadzone;
1256                  if (self.rail.drag.ck=="v") {
1257                    if (ay>dz&&(ax<=(ay*0.3))) {
1258                      self.rail.drag = false;
1259                      return true;
1260                    }
1261                    else if (ax>dz) {
1262                      self.rail.drag.dl="f";
1263                      $("body").scrollTop($("body").scrollTop());  // stop iOS native scrolling (when active javascript has blocked)
1264                    }
1265                  }
1266                  else if (self.rail.drag.ck=="h") {
1267                    if (ax>dz&&(ay<=(ax*0.3))) {
1268                      self.rail.drag = false;
1269                      return true;
1270                    }
1271                    else if (ay>dz) {
1272                      self.rail.drag.dl="f";
1273                      $("body").scrollLeft($("body").scrollLeft());  // stop iOS native scrolling (when active javascript has blocked)
1274                    }
1275                  }
1276                }
1277
1278                self.synched("touchmove",function(){
1279                  if (self.rail.drag&&(self.rail.drag.pt==2)) {
1280                    if (self.prepareTransition) self.prepareTransition(0);
1281                    if (self.rail.scrollable) self.setScrollTop(ny);
1282                    self.scrollmom.update(fx,fy);
1283                    if (self.railh&&self.railh.scrollable) {
1284                      self.setScrollLeft(nx);
1285                      self.showCursor(ny,nx);
1286                    } else {
1287                      self.showCursor(ny);
1288                    }
1289                    if (cap.isie10) document.selection.clear();
1290                  }
1291                });
1292
1293                if (cap.ischrome&&self.istouchcapable) grabbed=false;  //chrome touch emulation doesn't like!
1294                if (grabbed) return self.cancelEvent(e);
1295              }
1296
1297            };
1298
1299          }
1300
1301          self.onmousedown = function(e,hronly) {
1302            if (self.rail.drag&&self.rail.drag.pt!=1) return;
1303            if (self.locked) return self.cancelEvent(e);
1304            self.cancelScroll();
1305            self.rail.drag = {x:e.clientX,y:e.clientY,sx:self.scroll.x,sy:self.scroll.y,pt:1,hr:(!!hronly)};
1306            var tg = self.getTarget(e);
1307            if (!self.ispage&&cap.hasmousecapture) tg.setCapture();
1308            if (self.isiframe&&!cap.hasmousecapture) {
1309              self.saved["csspointerevents"] = self.doc.css("pointer-events");
1310              self.css(self.doc,{"pointer-events":"none"});
1311            }
1312            return self.cancelEvent(e);
1313          };
1314
1315          self.onmouseup = function(e) {
1316            if (self.rail.drag) {
1317              if (cap.hasmousecapture) document.releaseCapture();
1318              if (self.isiframe&&!cap.hasmousecapture) self.doc.css("pointer-events",self.saved["csspointerevents"]);
1319              if(self.rail.drag.pt!=1)return;
1320              self.rail.drag = false;
1321              //if (!self.rail.active) self.hideCursor();
1322              return self.cancelEvent(e);
1323            }
1324          };
1325
1326          self.onmousemove = function(e) {
1327            if (self.rail.drag) {
1328              if(self.rail.drag.pt!=1)return;
1329
1330              if (cap.ischrome&&e.which==0) return self.onmouseup(e);
1331
1332              self.cursorfreezed = true;
1333
1334              if (self.rail.drag.hr) {
1335                self.scroll.x = self.rail.drag.sx + (e.clientX-self.rail.drag.x);
1336                if (self.scroll.x<0) self.scroll.x=0;
1337                var mw = self.scrollvaluemaxw;
1338                if (self.scroll.x>mw) self.scroll.x=mw;
1339              } else {
1340                self.scroll.y = self.rail.drag.sy + (e.clientY-self.rail.drag.y);
1341                if (self.scroll.y<0) self.scroll.y=0;
1342                var my = self.scrollvaluemax;
1343                if (self.scroll.y>my) self.scroll.y=my;
1344              }
1345
1346              self.synched('mousemove',function(){
1347                if (self.rail.drag&&(self.rail.drag.pt==1)) {
1348                  self.showCursor();
1349                  if (self.rail.drag.hr) self.doScrollLeft(Math.round(self.scroll.x*self.scrollratio.x),self.opt.cursordragspeed);
1350                  else self.doScrollTop(Math.round(self.scroll.y*self.scrollratio.y),self.opt.cursordragspeed);
1351                }
1352              });
1353
1354              return self.cancelEvent(e);
1355            }
1356/*
1357            else {
1358              self.checkarea = true;
1359            }
1360*/
1361          };
1362
1363          if (cap.cantouch||self.opt.touchbehavior) {
1364
1365            self.onpreventclick = function(e) {
1366              if (self.preventclick) {
1367                self.preventclick.tg.onclick = self.preventclick.click;
1368                self.preventclick = false;
1369                return self.cancelEvent(e);
1370              }
1371            }
1372
1373//            self.onmousedown = self.ontouchstart;
1374//            self.onmouseup = self.ontouchend;
1375//            self.onmousemove = self.ontouchmove;
1376
1377            self.bind(self.win,"mousedown",self.ontouchstart);  // control content dragging
1378
1379            self.onclick = (cap.isios) ? false : function(e) {
1380              if (self.lastmouseup) {
1381                self.lastmouseup = false;
1382                return self.cancelEvent(e);
1383              } else {
1384                return true;
1385              }
1386            };
1387
1388            if (self.opt.grabcursorenabled&&cap.cursorgrabvalue) {
1389              self.css((self.ispage)?self.doc:self.win,{'cursor':cap.cursorgrabvalue});
1390              self.css(self.rail,{'cursor':cap.cursorgrabvalue});
1391            }
1392
1393          } else {
1394
1395            function checkSelectionScroll(e) {
1396              if (!self.selectiondrag) return;
1397
1398              if (e) {
1399                var ww = self.win.outerHeight();
1400                var df = (e.pageY - self.selectiondrag.top);
1401                if (df>0&&df<ww) df=0;
1402                if (df>=ww) df-=ww;
1403                self.selectiondrag.df = df;
1404              }
1405              if (self.selectiondrag.df==0) return;
1406
1407              var rt = -Math.floor(self.selectiondrag.df/6)*2;
1408//              self.doScrollTop(self.getScrollTop(true)+rt);
1409              self.doScrollBy(rt);
1410
1411              self.debounced("doselectionscroll",function(){checkSelectionScroll()},50);
1412            }
1413
1414            if ("getSelection" in document) {  // A grade - Major browsers
1415              self.hasTextSelected = function() {
1416                return (document.getSelection().rangeCount>0);
1417              }
1418            }
1419            else if ("selection" in document) {  //IE9-
1420              self.hasTextSelected = function() {
1421                return (document.selection.type != "None");
1422              }
1423            }
1424            else {
1425              self.hasTextSelected = function() {  // no support
1426                return false;
1427              }
1428            }
1429
1430            self.onselectionstart = function(e) {
1431              if (self.ispage) return;
1432              self.selectiondrag = self.win.offset();
1433            }
1434            self.onselectionend = function(e) {
1435              self.selectiondrag = false;
1436            }
1437            self.onselectiondrag = function(e) {
1438              if (!self.selectiondrag) return;
1439              if (self.hasTextSelected()) self.debounced("selectionscroll",function(){checkSelectionScroll(e)},250);
1440            }
1441
1442
1443          }
1444
1445          if (cap.hasmstouch) {
1446            self.css(self.rail,{'-ms-touch-action':'none'});
1447            self.css(self.cursor,{'-ms-touch-action':'none'});
1448
1449            self.bind(self.win,"MSPointerDown",self.ontouchstart);
1450            self.bind(document,"MSPointerUp",self.ontouchend);
1451            self.bind(document,"MSPointerMove",self.ontouchmove);
1452            self.bind(self.cursor,"MSGestureHold",function(e){e.preventDefault()});
1453            self.bind(self.cursor,"contextmenu",function(e){e.preventDefault()});
1454          }
1455
1456          if (this.istouchcapable) {  //desktop with screen touch enabled
1457            self.bind(self.win,"touchstart",self.ontouchstart);
1458            self.bind(document,"touchend",self.ontouchend);
1459            self.bind(document,"touchcancel",self.ontouchend);
1460            self.bind(document,"touchmove",self.ontouchmove);
1461          }
1462
1463          self.bind(self.cursor,"mousedown",self.onmousedown);
1464          self.bind(self.cursor,"mouseup",self.onmouseup);
1465
1466          if (self.railh) {
1467            self.bind(self.cursorh,"mousedown",function(e){self.onmousedown(e,true)});
1468            self.bind(self.cursorh,"mouseup",function(e){
1469              if (self.rail.drag&&self.rail.drag.pt==2) return;
1470              self.rail.drag = false;
1471              self.hasmoving = false;
1472              self.hideCursor();
1473              if (cap.hasmousecapture) document.releaseCapture();
1474              return self.cancelEvent(e);
1475            });
1476          }
1477
1478          if (self.opt.cursordragontouch||!cap.cantouch&&!self.opt.touchbehavior) {
1479
1480            self.rail.css({"cursor":"default"});
1481            self.railh&&self.railh.css({"cursor":"default"});
1482
1483            self.jqbind(self.rail,"mouseenter",function() {
1484              if (self.canshowonmouseevent) self.showCursor();
1485              self.rail.active = true;
1486            });
1487            self.jqbind(self.rail,"mouseleave",function() {
1488              self.rail.active = false;
1489              if (!self.rail.drag) self.hideCursor();
1490            });
1491
1492            if (self.opt.sensitiverail) {
1493              self.bind(self.rail,"click",function(e){self.doRailClick(e,false,false)});
1494              self.bind(self.rail,"dblclick",function(e){self.doRailClick(e,true,false)});
1495              self.bind(self.cursor,"click",function(e){self.cancelEvent(e)});
1496              self.bind(self.cursor,"dblclick",function(e){self.cancelEvent(e)});
1497            }
1498
1499            if (self.railh) {
1500              self.jqbind(self.railh,"mouseenter",function() {
1501                if (self.canshowonmouseevent) self.showCursor();
1502                self.rail.active = true;
1503              });
1504              self.jqbind(self.railh,"mouseleave",function() {
1505                self.rail.active = false;
1506                if (!self.rail.drag) self.hideCursor();
1507              });
1508
1509              if (self.opt.sensitiverail) {
1510                self.bind(self.railh, "click", function(e){self.doRailClick(e,false,true)});
1511                self.bind(self.railh, "dblclick", function(e){self.doRailClick(e, true, true) });
1512                self.bind(self.cursorh, "click", function (e) { self.cancelEvent(e) });
1513                self.bind(self.cursorh, "dblclick", function (e) { self.cancelEvent(e) });
1514              }
1515
1516            }
1517
1518          }
1519
1520          if (!cap.cantouch&&!self.opt.touchbehavior) {
1521
1522            self.bind((cap.hasmousecapture)?self.win:document,"mouseup",self.onmouseup);
1523            self.bind(document,"mousemove",self.onmousemove);
1524            if (self.onclick) self.bind(document,"click",self.onclick);
1525
1526            if (!self.ispage&&self.opt.enablescrollonselection) {
1527              self.bind(self.win[0],"mousedown",self.onselectionstart);
1528              self.bind(document,"mouseup",self.onselectionend);
1529              self.bind(self.cursor,"mouseup",self.onselectionend);
1530              if (self.cursorh) self.bind(self.cursorh,"mouseup",self.onselectionend);
1531              self.bind(document,"mousemove",self.onselectiondrag);
1532            }
1533
1534						if (self.zoom) {
1535							self.jqbind(self.zoom,"mouseenter",function() {
1536								if (self.canshowonmouseevent) self.showCursor();
1537								self.rail.active = true;
1538							});
1539							self.jqbind(self.zoom,"mouseleave",function() {
1540								self.rail.active = false;
1541								if (!self.rail.drag) self.hideCursor();
1542							});
1543						}
1544
1545          } else {
1546
1547            self.bind((cap.hasmousecapture)?self.win:document,"mouseup",self.ontouchend);
1548            self.bind(document,"mousemove",self.ontouchmove);
1549            if (self.onclick) self.bind(document,"click",self.onclick);
1550
1551            if (self.opt.cursordragontouch) {
1552              self.bind(self.cursor,"mousedown",self.onmousedown);
1553              self.bind(self.cursor,"mousemove",self.onmousemove);
1554              self.cursorh&&self.bind(self.cursorh,"mousedown",self.onmousedown);
1555              self.cursorh&&self.bind(self.cursorh,"mousemove",self.onmousemove);
1556            }
1557
1558          }
1559
1560					if (self.opt.enablemousewheel) {
1561						if (!self.isiframe) self.bind((cap.isie&&self.ispage) ? document : self.win /*self.docscroll*/ ,"mousewheel",self.onmousewheel);
1562						self.bind(self.rail,"mousewheel",self.onmousewheel);
1563						if (self.railh) self.bind(self.railh,"mousewheel",self.onmousewheelhr);
1564					}
1565
1566          if (!self.ispage&&!cap.cantouch&&!(/HTML|BODY/.test(self.win[0].nodeName))) {
1567            if (!self.win.attr("tabindex")) self.win.attr({"tabindex":tabindexcounter++});
1568
1569            self.jqbind(self.win,"focus",function(e) {
1570              domfocus = (self.getTarget(e)).id||true;
1571              self.hasfocus = true;
1572              if (self.canshowonmouseevent) self.noticeCursor();
1573            });
1574            self.jqbind(self.win,"blur",function(e) {
1575              domfocus = false;
1576              self.hasfocus = false;
1577            });
1578
1579            self.jqbind(self.win,"mouseenter",function(e) {
1580              mousefocus = (self.getTarget(e)).id||true;
1581              self.hasmousefocus = true;
1582              if (self.canshowonmouseevent) self.noticeCursor();
1583            });
1584            self.jqbind(self.win,"mouseleave",function() {
1585              mousefocus = false;
1586              self.hasmousefocus = false;
1587            });
1588
1589          };
1590
1591        }  // !ie9mobile
1592
1593        //Thanks to http://www.quirksmode.org !!
1594        self.onkeypress = function(e) {
1595          if (self.locked&&self.page.maxh==0) return true;
1596
1597          e = (e) ? e : window.e;
1598          var tg = self.getTarget(e);
1599          if (tg&&/INPUT|TEXTAREA|SELECT|OPTION/.test(tg.nodeName)) {
1600            var tp = tg.getAttribute('type')||tg.type||false;
1601            if ((!tp)||!(/submit|button|cancel/i.tp)) return true;
1602          }
1603
1604          if (self.hasfocus||(self.hasmousefocus&&!domfocus)||(self.ispage&&!domfocus&&!mousefocus)) {
1605            var key = e.keyCode;
1606
1607            if (self.locked&&key!=27) return self.cancelEvent(e);
1608
1609            var ctrl = e.ctrlKey||false;
1610            var shift = e.shiftKey || false;
1611
1612            var ret = false;
1613            switch (key) {
1614              case 38:
1615              case 63233: //safari
1616                self.doScrollBy(24*3);
1617                ret = true;
1618                break;
1619              case 40:
1620              case 63235: //safari
1621                self.doScrollBy(-24*3);
1622                ret = true;
1623                break;
1624              case 37:
1625              case 63232: //safari
1626                if (self.railh) {
1627                  (ctrl) ? self.doScrollLeft(0) : self.doScrollLeftBy(24*3);
1628                  ret = true;
1629                }
1630                break;
1631              case 39:
1632              case 63234: //safari
1633                if (self.railh) {
1634                  (ctrl) ? self.doScrollLeft(self.page.maxw) : self.doScrollLeftBy(-24*3);
1635                  ret = true;
1636                }
1637                break;
1638              case 33:
1639              case 63276: // safari
1640                self.doScrollBy(self.view.h);
1641                ret = true;
1642                break;
1643              case 34:
1644              case 63277: // safari
1645                self.doScrollBy(-self.view.h);
1646                ret = true;
1647                break;
1648              case 36:
1649              case 63273: // safari
1650                (self.railh&&ctrl) ? self.doScrollPos(0,0) : self.doScrollTo(0);
1651                ret = true;
1652                break;
1653              case 35:
1654              case 63275: // safari
1655                (self.railh&&ctrl) ? self.doScrollPos(self.page.maxw,self.page.maxh) : self.doScrollTo(self.page.maxh);
1656                ret = true;
1657                break;
1658              case 32:
1659                if (self.opt.spacebarenabled) {
1660                  (shift) ? self.doScrollBy(self.view.h) : self.doScrollBy(-self.view.h);
1661                  ret = true;
1662                }
1663                break;
1664              case 27: // ESC
1665                if (self.zoomactive) {
1666                  self.doZoom();
1667                  ret = true;
1668                }
1669                break;
1670            }
1671            if (ret) return self.cancelEvent(e);
1672          }
1673        };
1674
1675        if (self.opt.enablekeyboard) self.bind(document,(cap.isopera&&!cap.isopera12)?"keypress":"keydown",self.onkeypress);
1676
1677        self.bind(window,'resize',self.lazyResize);
1678        self.bind(window,'orientationchange',self.lazyResize);
1679
1680        self.bind(window,"load",self.lazyResize);
1681
1682        if (cap.ischrome&&!self.ispage&&!self.haswrapper) { //chrome void scrollbar bug - it persists in version 26
1683          var tmp=self.win.attr("style");
1684					var ww = parseFloat(self.win.css("width"))+1;
1685          self.win.css('width',ww);
1686          self.synched("chromefix",function(){self.win.attr("style",tmp)});
1687        }
1688
1689
1690// Trying a cross-browser implementation - good luck!
1691
1692        self.onAttributeChange = function(e) {
1693          self.lazyResize(250);
1694        }
1695
1696        if (!self.ispage&&!self.haswrapper) {
1697          // redesigned MutationObserver for Chrome18+/Firefox14+/iOS6+ with support for: remove div, add/remove content
1698          if (clsMutationObserver !== false) {
1699            self.observer = new clsMutationObserver(function(mutations) {
1700              mutations.forEach(self.onAttributeChange);
1701            });
1702            self.observer.observe(self.win[0],{childList: true, characterData: false, attributes: true, subtree: false});
1703
1704            self.observerremover = new clsMutationObserver(function(mutations) {
1705               mutations.forEach(function(mo){
1706                 if (mo.removedNodes.length>0) {
1707                   for (var dd in mo.removedNodes) {
1708                     if (mo.removedNodes[dd]==self.win[0]) return self.remove();
1709                   }
1710                 }
1711               });
1712            });
1713            self.observerremover.observe(self.win[0].parentNode,{childList: true, characterData: false, attributes: false, subtree: false});
1714
1715          } else {
1716            self.bind(self.win,(cap.isie&&!cap.isie9)?"propertychange":"DOMAttrModified",self.onAttributeChange);
1717            if (cap.isie9) self.win[0].attachEvent("onpropertychange",self.onAttributeChange); //IE9 DOMAttrModified bug
1718            self.bind(self.win,"DOMNodeRemoved",function(e){
1719              if (e.target==self.win[0]) self.remove();
1720            });
1721          }
1722        }
1723
1724//
1725
1726        if (!self.ispage&&self.opt.boxzoom) self.bind(window,"resize",self.resizeZoom);
1727        if (self.istextarea) self.bind(self.win,"mouseup",self.lazyResize);
1728
1729        self.checkrtlmode = true;
1730        self.lazyResize(30);
1731
1732      }
1733
1734      if (this.doc[0].nodeName == 'IFRAME') {
1735        function oniframeload(e) {
1736          self.iframexd = false;
1737          try {
1738            var doc = 'contentDocument' in this ? this.contentDocument : this.contentWindow.document;
1739            var a = doc.domain;
1740          } catch(e){self.iframexd = true;doc=false};
1741
1742          if (self.iframexd) {
1743            if ("console" in window) console.log('NiceScroll error: policy restriced iframe');
1744            return true;  //cross-domain - I can't manage this
1745          }
1746
1747          self.forcescreen = true;
1748
1749          if (self.isiframe) {
1750            self.iframe = {
1751              "doc":$(doc),
1752              "html":self.doc.contents().find('html')[0],
1753              "body":self.doc.contents().find('body')[0]
1754            };
1755            self.getContentSize = function(){
1756              return {
1757                w:Math.max(self.iframe.html.scrollWidth,self.iframe.body.scrollWidth),
1758                h:Math.max(self.iframe.html.scrollHeight,self.iframe.body.scrollHeight)
1759              }
1760            }
1761            self.docscroll = $(self.iframe.body);//$(this.contentWindow);
1762          }
1763
1764          if (!cap.isios&&self.opt.iframeautoresize&&!self.isiframe) {
1765            self.win.scrollTop(0); // reset position
1766            self.doc.height("");  //reset height to fix browser bug
1767            var hh=Math.max(doc.getElementsByTagName('html')[0].scrollHeight,doc.body.scrollHeight);
1768            self.doc.height(hh);
1769          }
1770          self.lazyResize(30);
1771
1772          if (cap.isie7) self.css($(self.iframe.html),{'overflow-y':'hidden'});
1773          //self.css($(doc.body),{'overflow-y':'hidden'});
1774          self.css($(self.iframe.body),{'overflow-y':'hidden'});
1775
1776          if (cap.isios&&self.haswrapper) {
1777            self.css($(doc.body),{'-webkit-transform':'translate3d(0,0,0)'});  // avoid iFrame content clipping - thanks to http://blog.derraab.com/2012/04/02/avoid-iframe-content-clipping-with-css-transform-on-ios/
1778
1779            console.log(1);
1780
1781          }
1782
1783          if ('contentWindow' in this) {
1784            self.bind(this.contentWindow,"scroll",self.onscroll);  //IE8 & minor
1785          } else {
1786            self.bind(doc,"scroll",self.onscroll);
1787          }
1788
1789          if (self.opt.enablemousewheel) {
1790            self.bind(doc,"mousewheel",self.onmousewheel);
1791          }
1792
1793          if (self.opt.enablekeyboard) self.bind(doc,(cap.isopera)?"keypress":"keydown",self.onkeypress);
1794
1795          if (cap.cantouch||self.opt.touchbehavior) {
1796            self.bind(doc,"mousedown",self.ontouchstart);
1797            self.bind(doc,"mousemove",function(e){self.ontouchmove(e,true)});
1798            if (self.opt.grabcursorenabled&&cap.cursorgrabvalue) self.css($(doc.body),{'cursor':cap.cursorgrabvalue});
1799          }
1800
1801          self.bind(doc,"mouseup",self.ontouchend);
1802
1803          if (self.zoom) {
1804            if (self.opt.dblclickzoom) self.bind(doc,'dblclick',self.doZoom);
1805            if (self.ongesturezoom) self.bind(doc,"gestureend",self.ongesturezoom);
1806          }
1807        };
1808
1809        if (this.doc[0].readyState&&this.doc[0].readyState=="complete"){
1810          setTimeout(function(){oniframeload.call(self.doc[0],false)},500);
1811        }
1812        self.bind(this.doc,"load",oniframeload);
1813
1814      }
1815
1816    };
1817
1818    this.showCursor = function(py,px) {
1819      if (self.cursortimeout) {
1820        clearTimeout(self.cursortimeout);
1821        self.cursortimeout = 0;
1822      }
1823      if (!self.rail) return;
1824      if (self.autohidedom) {
1825        self.autohidedom.stop().css({opacity:self.opt.cursoropacitymax});
1826        self.cursoractive = true;
1827      }
1828
1829      if (!self.rail.drag||self.rail.drag.pt!=1) {
1830        if ((typeof py != "undefined")&&(py!==false)) {
1831          self.scroll.y = Math.round(py * 1/self.scrollratio.y);
1832        }
1833        if (typeof px != "undefined") {
1834          self.scroll.x = Math.round(px * 1/self.scrollratio.x);
1835        }
1836      }
1837
1838      self.cursor.css({height:self.cursorheight,top:self.scroll.y});
1839      if (self.cursorh) {
1840        (!self.rail.align&&self.rail.visibility) ? self.cursorh.css({width:self.cursorwidth,left:self.scroll.x+self.rail.width}) : self.cursorh.css({width:self.cursorwidth,left:self.scroll.x});
1841        self.cursoractive = true;
1842      }
1843
1844      if (self.zoom) self.zoom.stop().css({opacity:self.opt.cursoropacitymax});
1845    };
1846
1847    this.hideCursor = function(tm) {
1848      if (self.cursortimeout) return;
1849      if (!self.rail) return;
1850      if (!self.autohidedom) return;
1851      self.cursortimeout = setTimeout(function() {
1852         if (!self.rail.active||!self.showonmouseevent) {
1853           self.autohidedom.stop().animate({opacity:self.opt.cursoropacitymin});
1854           if (self.zoom) self.zoom.stop().animate({opacity:self.opt.cursoropacitymin});
1855           self.cursoractive = false;
1856         }
1857         self.cursortimeout = 0;
1858      }
1858,tm||self.opt.hidecursordelay);
1859    };
1860
1861    this.noticeCursor = function(tm,py,px) {
1862      self.showCursor(py,px);
1863      if (!self.rail.active) self.hideCursor(tm);
1864    };
1865
1866    this.getContentSize =
1867      (self.ispage) ?
1868        function(){
1869          return {
1870            w:Math.max(document.body.scrollWidth,document.documentElement.scrollWidth),
1871            h:Math.max(document.body.scrollHeight,document.documentElement.scrollHeight)
1872          }
1873        }
1874      : (self.haswrapper) ?
1875        function(){
1876          return {
1877            w:self.doc.outerWidth()+parseInt(self.win.css('paddingLeft'))+parseInt(self.win.css('paddingRight')),
1878            h:self.doc.outerHeight()+parseInt(self.win.css('paddingTop'))+parseInt(self.win.css('paddingBottom'))
1879          }
1880        }
1881      : function() {
1882        return {
1883          w:self.docscroll[0].scrollWidth,
1884          h:self.docscroll[0].scrollHeight
1885        }
1886      };
1887
1888    this.onResize = function(e,page) {
1889
1890	  if (!self.win) return false;
1891
1892      if (!self.haswrapper&&!self.ispage) {
1893        if (self.win.css('display')=='none') {
1894          if (self.visibility) self.hideRail().hideRailHr();
1895          return false;
1896        } else {
1897          if (!self.hidden&&!self.visibility) self.showRail().showRailHr();
1898        }
1899      }
1900
1901      var premaxh = self.page.maxh;
1902      var premaxw = self.page.maxw;
1903
1904      var preview = {h:self.view.h,w:self.view.w};
1905
1906      self.view = {
1907        w:(self.ispage) ? self.win.width() : parseInt(self.win[0].clientWidth),
1908        h:(self.ispage) ? self.win.height() : parseInt(self.win[0].clientHeight)
1909      };
1910
1911      self.page = (page) ? page : self.getContentSize();
1912
1913      self.page.maxh = Math.max(0,self.page.h - self.view.h);
1914      self.page.maxw = Math.max(0,self.page.w - self.view.w);
1915
1916      if ((self.page.maxh==premaxh)&&(self.page.maxw==premaxw)&&(self.view.w==preview.w)) {
1917        // test position
1918        if (!self.ispage) {
1919          var pos = self.win.offset();
1920          if (self.lastposition) {
1921            var lst = self.lastposition;
1922            if ((lst.top==pos.top)&&(lst.left==pos.left)) return self; //nothing to do
1923          }
1924          self.lastposition = pos;
1925        } else {
1926          return self; //nothing to do
1927        }
1928      }
1929
1930      if (self.page.maxh==0) {
1931        self.hideRail();
1932        self.scrollvaluemax = 0;
1933        self.scroll.y = 0;
1934        self.scrollratio.y = 0;
1935        self.cursorheight = 0;
1936        self.setScrollTop(0);
1937        self.rail.scrollable = false;
1938      } else {
1939        self.rail.scrollable = true;
1940      }
1941
1942      if (self.page.maxw==0) {
1943        self.hideRailHr();
1944        self.scrollvaluemaxw = 0;
1945        self.scroll.x = 0;
1946        self.scrollratio.x = 0;
1947        self.cursorwidth = 0;
1948        self.setScrollLeft(0);
1949        self.railh.scrollable = false;
1950      } else {
1951        self.railh.scrollable = true;
1952      }
1953
1954      self.locked = (self.page.maxh==0)&&(self.page.maxw==0);
1955      if (self.locked) {
1956				if (!self.ispage) self.updateScrollBar(self.view);
1957			  return false;
1958		  }
1959
1960      if (!self.hidden&&!self.visibility) {
1961        self.showRail().showRailHr();
1962      }
1963      else if (!self.hidden&&!self.railh.visibility) self.showRailHr();
1964
1965      if (self.istextarea&&self.win.css('resize')&&self.win.css('resize')!='none') self.view.h-=20;
1966
1967      self.cursorheight = Math.min(self.view.h,Math.round(self.view.h * (self.view.h / self.page.h)));
1968      self.cursorheight = (self.opt.cursorfixedheight) ? self.opt.cursorfixedheight : Math.max(self.opt.cursorminheight,self.cursorheight);
1969
1970      self.cursorwidth = Math.min(self.view.w,Math.round(self.view.w * (self.view.w / self.page.w)));
1971      self.cursorwidth = (self.opt.cursorfixedheight) ? self.opt.cursorfixedheight : Math.max(self.opt.cursorminheight,self.cursorwidth);
1972
1973      self.scrollvaluemax = self.view.h-self.cursorheight-self.cursor.hborder;
1974
1975      if (self.railh) {
1976        self.railh.width = (self.page.maxh>0) ? (self.view.w-self.rail.width) : self.view.w;
1977        self.scrollvaluemaxw = self.railh.width-self.cursorwidth-self.cursorh.wborder;
1978      }
1979
1980      if (self.checkrtlmode&&self.railh) {
1981        self.checkrtlmode = false;
1982        if (self.opt.rtlmode&&self.scroll.x==0) self.setScrollLeft(self.page.maxw);
1983      }
1984
1985      if (!self.ispage) self.updateScrollBar(self.view);
1986
1987      self.scrollratio = {
1988        x:(self.page.maxw/self.scrollvaluemaxw),
1989        y:(self.page.maxh/self.scrollvaluemax)
1990      };
1991
1992      var sy = self.getScrollTop();
1993      if (sy>self.page.maxh) {
1994        self.doScrollTop(self.page.maxh);
1995      } else {
1996        self.scroll.y = Math.round(self.getScrollTop() * (1/self.scrollratio.y));
1997        self.scroll.x = Math.round(self.getScrollLeft() * (1/self.scrollratio.x));
1998        if (self.cursoractive) self.noticeCursor();
1999      }
2000
2001      if (self.scroll.y&&(self.getScrollTop()==0)) self.doScrollTo(Math.floor(self.scroll.y*self.scrollratio.y));
2002
2003      return self;
2004    };
2005
2006    this.resize = self.onResize;
2007
2008    this.lazyResize = function(tm) {   // event debounce
2009      tm = (isNaN(tm)) ? 30 : tm;
2010      self.delayed('resize',self.resize,tm);
2011      return self;
2012    }
2013
2014// modified by MDN https://developer.mozilla.org/en-US/docs/DOM/Mozilla_event_reference/wheel
2015    function _modernWheelEvent(dom,name,fn,bubble) {
2016      self._bind(dom,name,function(e){
2017        var  e = (e) ? e : window.event;
2018        var event = {
2019          original: e,
2020          target: e.target || e.srcElement,
2021          type: "wheel",
2022          deltaMode: e.type == "MozMousePixelScroll" ? 0 : 1,
2023          deltaX: 0,
2024          deltaZ: 0,
2025          preventDefault: function() {
2026            e.preventDefault ? e.preventDefault() : e.returnValue = false;
2027            return false;
2028          },
2029          stopImmediatePropagation: function() {
2030            (e.stopImmediatePropagation) ? e.stopImmediatePropagation() : e.cancelBubble = true;
2031          }
2032        };
2033
2034        if (name=="mousewheel") {
2035          event.deltaY = - 1/40 * e.wheelDelta;
2036          e.wheelDeltaX && (event.deltaX = - 1/40 * e.wheelDeltaX);
2037        } else {
2038          event.deltaY = e.detail;
2039        }
2040
2041        return fn.call(dom,event);
2042      },bubble);
2043    };
2044
2045    this._bind = function(el,name,fn,bubble) {  // primitive bind
2046      self.events.push({e:el,n:name,f:fn,b:bubble,q:false});
2047      if (el.addEventListener) {
2048        el.addEventListener(name,fn,bubble||false);
2049      }
2050      else if (el.attachEvent) {
2051        el.attachEvent("on"+name,fn);
2052      }
2053      else {
2054        el["on"+name] = fn;
2055      }
2056    };
2057
2058    this.jqbind = function(dom,name,fn) {  // use jquery bind for non-native events (mouseenter/mouseleave)
2059      self.events.push({e:dom,n:name,f:fn,q:true});
2060      $(dom).bind(name,fn);
2061    }
2062
2063    this.bind = function(dom,name,fn,bubble) {  // touch-oriented & fixing jquery bind
2064      var el = ("jquery" in dom) ? dom[0] : dom;
2065
2066      if (name=='mousewheel') {
2067        if ("onwheel" in self.win) {
2068          self._bind(el,"wheel",fn,bubble||false);
2069        } else {
2070          var wname = (typeof document.onmousewheel != "undefined") ? "mousewheel" : "DOMMouseScroll";  // older IE/Firefox
2071          _modernWheelEvent(el,wname,fn,bubble||false);
2072          if (wname=="DOMMouseScroll") _modernWheelEvent(el,"MozMousePixelScroll",fn,bubble||false);  // Firefox legacy
2073        }
2074      }
2075      else if (el.addEventListener) {
2076        if (cap.cantouch && /mouseup|mousedown|mousemove/.test(name)) {  // touch device support
2077          var tt=(name=='mousedown')?'touchstart':(name=='mouseup')?'touchend':'touchmove';
2078          self._bind(el,tt,function(e){
2079            if (e.touches) {
2080              if (e.touches.length<2) {var ev=(e.touches.length)?e.touches[0]:e;ev.original=e;fn.call(this,ev);}
2081            }
2082            else if (e.changedTouches) {var ev=e.changedTouches[0];ev.original=e;fn.call(this,ev);}  //blackberry
2083          },bubble||false);
2084        }
2085        self._bind(el,name,fn,bubble||false);
2086        if (cap.cantouch && name=="mouseup") self._bind(el,"touchcancel",fn,bubble||false);
2087      }
2088      else {
2089        self._bind(el,name,function(e) {
2090          e = e||window.event||false;
2091          if (e) {
2092            if (e.srcElement) e.target=e.srcElement;
2093          }
2094          if (!("pageY" in e)) {
2095            e.pageX = e.clientX + document.documentElement.scrollLeft;
2096            e.pageY = e.clientY + document.documentElement.scrollTop;
2097          }
2098          return ((fn.call(el,e)===false)||bubble===false) ? self.cancelEvent(e) : true;
2099        });
2100      }
2101    };
2102
2103    this._unbind = function(el,name,fn,bub) {  // primitive unbind
2104      if (el.removeEventListener) {
2105        el.removeEventListener(name,fn,bub);
2106      }
2107      else if (el.detachEvent) {
2108        el.detachEvent('on'+name,fn);
2109      } else {
2110        el['on'+name] = false;
2111      }
2112    };
2113
2114    this.unbindAll = function() {
2115      for(var a=0;a<self.events.length;a++) {
2116        var r = self.events[a];
2117        (r.q) ? r.e.unbind(r.n,r.f) : self._unbind(r.e,r.n,r.f,r.b);
2118      }
2119    };
2120
2121    // Thanks to http://www.switchonthecode.com !!
2122    this.cancelEvent = function(e) {
2123      var e = (e.original) ? e.original : (e) ? e : window.event||false;
2124      if (!e) return false;
2125      if(e.preventDefault) e.preventDefault();
2126      if(e.stopPropagation) e.stopPropagation();
2127      if(e.preventManipulation) e.preventManipulation();  //IE10
2128      e.cancelBubble = true;
2129      e.cancel = true;
2130      e.returnValue = false;
2131      return false;
2132    };
2133
2134    this.stopPropagation = function(e) {
2135      var e = (e.original) ? e.original : (e) ? e : window.event||false;
2136      if (!e) return false;
2137      if (e.stopPropagation) return e.stopPropagation();
2138      if (e.cancelBubble) e.cancelBubble=true;
2139      return false;
2140    }
2141
2142    this.showRail = function() {
2143      if ((self.page.maxh!=0)&&(self.ispage||self.win.css('display')!='none')) {
2144        self.visibility = true;
2145        self.rail.visibility = true;
2146        self.rail.css('display','block');
2147      }
2148      return self;
2149    };
2150
2151    this.showRailHr = function() {
2152      if (!self.railh) return self;
2153      if ((self.page.maxw!=0)&&(self.ispage||self.win.css('display')!='none')) {
2154        self.railh.visibility = true;
2155        self.railh.css('display','block');
2156      }
2157      return self;
2158    };
2159
2160    this.hideRail = function() {
2161      self.visibility = false;
2162      self.rail.visibility = false;
2163      self.rail.css('display','none');
2164      return self;
2165    };
2166
2167    this.hideRailHr = function() {
2168      if (!self.railh) return self;
2169      self.railh.visibility = false;
2170      self.railh.css('display','none');
2171      return self;
2172    };
2173
2174    this.show = function() {
2175      self.hidden = false;
2176      self.locked = false;
2177      return self.showRail().showRailHr();
2178    };
2179
2180    this.hide = function() {
2181      self.hidden = true;
2182      self.locked = true;
2183      return self.hideRail().hideRailHr();
2184    };
2185
2186    this.toggle = function() {
2187      return (self.hidden) ? self.show() : self.hide();
2188    };
2189
2190    this.remove = function() {
2191      self.stop();
2192      if (self.cursortimeout) clearTimeout(self.cursortimeout);
2193      self.doZoomOut();
2194      self.unbindAll();
2195
2196      if (cap.isie9) self.win[0].detachEvent("onpropertychange",self.onAttributeChange); //IE9 DOMAttrModified bug
2197
2198      if (self.observer !== false) self.observer.disconnect();
2199      if (self.observerremover !== false) self.observerremover.disconnect();
2200
2201      self.events = null;
2202
2203      if (self.cursor) {
2204        self.cursor.remove();
2205      }
2206      if (self.cursorh) {
2207        self.cursorh.remove();
2208      }
2209      if (self.rail) {
2210        self.rail.remove();
2211      }
2212      if (self.railh) {
2213        self.railh.remove();
2214      }
2215      if (self.zoom) {
2216        self.zoom.remove();
2217      }
2218      for(var a=0;a<self.saved.css.length;a++) {
2219        var d=self.saved.css[a];
2220        d[0].css(d[1],(typeof d[2]=="undefined") ? '' : d[2]);
2221      }
2222      self.saved = false;
2223      self.me.data('__nicescroll',''); //erase all traces
2224
2225      // memory leak fixed by GianlucaGuarini - thanks a lot!
2226      // remove the current nicescroll from the $.nicescroll array & normalize array
2227      var lst = $.nicescroll;
2228      lst.each(function(i){
2229        if (!this) return;
2230        if(this.id === self.id) {
2231          delete lst[i];
2232          for(var b=++i;b<lst.length;b++,i++) lst[i]=lst[b];
2233          lst.length--;
2234          if (lst.length) delete lst[lst.length];
2235        }
2236      });
2237
2238      for (var i in self) {
2239        self[i] = null;
2240        delete self[i];
2241      }
2242
2243      self = null;
2244
2245    };
2246
2247    this.scrollstart = function(fn) {
2248      this.onscrollstart = fn;
2249      return self;
2250    }
2251    this.scrollend = function(fn) {
2252      this.onscrollend = fn;
2253      return self;
2254    }
2255    this.scrollcancel = function(fn) {
2256      this.onscrollcancel = fn;
2257      return self;
2258    }
2259
2260    this.zoomin = function(fn) {
2261      this.onzoomin = fn;
2262      return self;
2263    }
2264    this.zoomout = function(fn) {
2265      this.onzoomout = fn;
2266      return self;
2267    }
2268
2269    this.isScrollable = function(e) {
2270      var dom = (e.target) ? e.target : e;
2271      if (dom.nodeName == 'OPTION') return true;
2272      while (dom&&(dom.nodeType==1)&&!(/BODY|HTML/.test(dom.nodeName))) {
2273        var dd = $(dom);
2274        var ov = dd.css('overflowY')||dd.css('overflowX')||dd.css('overflow')||'';
2275        if (/scroll|auto/.test(ov)) return (dom.clientHeight!=dom.scrollHeight);
2276        dom = (dom.parentNode) ? dom.parentNode : false;
2277      }
2278      return false;
2279    };
2280
2281    this.getViewport = function(me) {
2282      var dom = (me&&me.parentNode) ? me.parentNode : false;
2283      while (dom&&(dom.nodeType==1)&&!(/BODY|HTML/.test(dom.nodeName))) {
2284        var dd = $(dom);
2285        var ov = dd.css('overflowY')||dd.css('overflowX')||dd.css('overflow')||'';
2286        if ((/scroll|auto/.test(ov))&&(dom.clientHeight!=dom.scrollHeight)) return dd;
2287        if (dd.getNiceScroll().length>0) return dd;
2288        dom = (dom.parentNode) ? dom.parentNode : false;
2289      }
2290      return false;
2291    };
2292
2293    function execScrollWheel(e,hr,chkscroll) {
2294      var px,py;
2295      var rt = 1;
2296
2297      if (e.deltaMode==0) {  // PIXEL
2298        px = -Math.floor(e.deltaX*(self.opt.mousescrollstep/(18*3)));
2299        py = -Math.floor(e.deltaY*(self.opt.mousescrollstep/(18*3)));
2300      }
2301      else if (e.deltaMode==1) {  // LINE
2302        px = -Math.floor(e.deltaX*self.opt.mousescrollstep);
2303        py = -Math.floor(e.deltaY*self.opt.mousescrollstep);
2304      }
2305
2306      if (hr&&self.opt.oneaxismousemode&&(px==0)&&py) {  // classic vertical-only mousewheel + browser with x/y support
2307        px = py;
2308        py = 0;
2309      }
2310
2311      if (px) {
2312        if (self.scrollmom) {self.scrollmom.stop()}
2313        self.lastdeltax+=px;
2314        self.debounced("mousewheelx",function(){var dt=self.lastdeltax;self.lastdeltax=0;if(!self.rail.drag){self.doScrollLeftBy(dt)}},120);
2315      }
2316      if (py) {
2317        if (self.opt.nativeparentscrolling&&chkscroll&&!self.ispage&&!self.zoomactive) {
2318          if (py<0) {
2319            if (self.getScrollTop()>=self.page.maxh) return true;
2320          } else {
2321            if (self.getScrollTop()<=0) return true;
2322          }
2323        }
2324        if (self.scrollmom) {self.scrollmom.stop()}
2325        self.lastdeltay+=py;
2326        self.debounced("mousewheely",function(){var dt=self.lastdeltay;self.lastdeltay=0;if(!self.rail.drag){self.doScrollBy(dt)}},120);
2327      }
2328
2329      e.stopImmediatePropagation();
2330      return e.preventDefault();
2331//      return self.cancelEvent(e);
2332    };
2333
2334    this.onmousewheel = function(e) {
2335      if (self.locked) {
2336        self.debounced("checkunlock",self.resize,250);
2337        return true;
2338      }
2339      if (self.rail.drag) return self.cancelEvent(e);
2340
2341      if (self.opt.oneaxismousemode=="auto"&&e.deltaX!=0) self.opt.oneaxismousemode = false;  // check two-axis mouse support (not very elegant)
2342
2343      if (self.opt.oneaxismousemode&&e.deltaX==0) {
2344        if (!self.rail.scrollable) {
2345          if (self.railh&&self.railh.scrollable) {
2346            return self.onmousewheelhr(e);
2347          } else {
2348            return true;
2349          }
2350        }
2351      }
2352
2353      var nw = +(new Date());
2354      var chk = false;
2355      if (self.opt.preservenativescrolling&&((self.checkarea+600)<nw)) {
2356//        self.checkarea = false;
2357        self.nativescrollingarea = self.isScrollable(e);
2358        chk = true;
2359      }
2360      self.checkarea = nw;
2361      if (self.nativescrollingarea) return true; // this isn't my business
2362//      if (self.locked) return self.cancelEvent(e);
2363      var ret = execScrollWheel(e,false,chk);
2364      if (ret) self.checkarea = 0;
2365      return ret;
2366    };
2367
2368    this.onmousewheelhr = function(e) {
2369      if (self.locked||!self.railh.scrollable) return true;
2370      if (self.rail.drag) return self.cancelEvent(e);
2371
2372      var nw = +(new Date());
2373      var chk = false;
2374      if (self.opt.preservenativescrolling&&((self.checkarea+600)<nw)) {
2375//        self.checkarea = false;
2376        self.nativescrollingarea = self.isScrollable(e);
2377        chk = true;
2378      }
2379      self.checkarea = nw;
2380      if (self.nativescrollingarea) return true; // this isn't my business
2381      if (self.locked) return self.cancelEvent(e);
2382
2383      return execScrollWheel(e,true,chk);
2384    };
2385
2386    this.stop = function() {
2387      self.cancelScroll();
2388      if (self.scrollmon) self.scrollmon.stop();
2389      self.cursorfreezed = false;
2390      self.scroll.y = Math.round(self.getScrollTop() * (1/self.scrollratio.y));
2391      self.noticeCursor();
2392      return self;
2393    };
2394
2395    this.getTransitionSpeed = function(dif) {
2396      var sp = Math.round(self.opt.scrollspeed*10);
2397      var ex = Math.min(sp,Math.round((dif / 20) * self.opt.scrollspeed));
2398      return (ex>
239820) ? ex : 0;
2399    }
2400
2401    if (!self.opt.smoothscroll) {
2402      this.doScrollLeft = function(x,spd) {  //direct
2403        var y = self.getScrollTop();
2404        self.doScrollPos(x,y,spd);
2405      }
2406      this.doScrollTop = function(y,spd) {   //direct
2407        var x = self.getScrollLeft();
2408        self.doScrollPos(x,y,spd);
2409      }
2410      this.doScrollPos = function(x,y,spd) {  //direct
2411        var nx = (x>self.page.maxw) ? self.page.maxw : x;
2412        if (nx<0) nx=0;
2413        var ny = (y>self.page.maxh) ? self.page.maxh : y;
2414        if (ny<0) ny=0;
2415        self.synched('scroll',function(){
2416          self.setScrollTop(ny);
2417          self.setScrollLeft(nx);
2418        });
2419      }
2420      this.cancelScroll = function() {}; // direct
2421    }
2422    else if (self.ishwscroll&&cap.hastransition&&self.opt.usetransition) {
2423      this.prepareTransition = function(dif,istime) {
2424        var ex = (istime) ? ((dif>20)?dif:0) : self.getTransitionSpeed(dif);
2425        var trans = (ex) ? cap.prefixstyle+'transform '+ex+'ms ease-out' : '';
2426        if (!self.lasttransitionstyle||self.lasttransitionstyle!=trans) {
2427          self.lasttransitionstyle = trans;
2428          self.doc.css(cap.transitionstyle,trans);
2429        }
2430        return ex;
2431      };
2432
2433      this.doScrollLeft = function(x,spd) {  //trans
2434        var y = (self.scrollrunning) ? self.newscrolly : self.getScrollTop();
2435        self.doScrollPos(x,y,spd);
2436      }
2437
2438      this.doScrollTop = function(y,spd) {   //trans
2439        var x = (self.scrollrunning) ? self.newscrollx : self.getScrollLeft();
2440        self.doScrollPos(x,y,spd);
2441      }
2442
2443      this.doScrollPos = function(x,y,spd) {  //trans
2444
2445        var py = self.getScrollTop();
2446        var px = self.getScrollLeft();
2447
2448        if (((self.newscrolly-py)*(y-py)<0)||((self.newscrollx-px)*(x-px)<0)) self.cancelScroll();  //inverted movement detection
2449
2450        if (self.opt.bouncescroll==false) {
2451          if (y<0) y=0;
2452          else if (y>self.page.maxh) y=self.page.maxh;
2453          if (x<0) x=0;
2454          else if (x>self.page.maxw) x=self.page.maxw;
2455        }
2456
2457        if (self.scrollrunning&&x==self.newscrollx&&y==self.newscrolly) return false;
2458
2459        self.newscrolly = y;
2460        self.newscrollx = x;
2461
2462        self.newscrollspeed = spd||false;
2463
2464        if (self.timer) return false;
2465
2466        self.timer = setTimeout(function(){
2467
2468          var top = self.getScrollTop();
2469          var lft = self.getScrollLeft();
2470
2471          var dst = {};
2472          dst.x = x-lft;
2473          dst.y = y-top;
2474          dst.px = lft;
2475          dst.py = top;
2476
2477          var dd = Math.round(Math.sqrt(Math.pow(dst.x,2)+Math.pow(dst.y,2)));
2478
2479//          var df = (self.newscrollspeed) ? self.newscrollspeed : dd;
2480
2481          var ms = (self.newscrollspeed && self.newscrollspeed>1) ? self.newscrollspeed : self.getTransitionSpeed(dd);
2482          if (self.newscrollspeed&&self.newscrollspeed<=1) ms*=self.newscrollspeed;
2483
2484          self.prepareTransition(ms,true);
2485
2486          if (self.timerscroll&&self.timerscroll.tm) clearInterval(self.timerscroll.tm);
2487
2488          if (ms>0) {
2489
2490            if (!self.scrollrunning&&self.onscrollstart) {
2491              var info = {"type":"scrollstart","current":{"x":lft,"y":top},"request":{"x":x,"y":y},"end":{"x":self.newscrollx,"y":self.newscrolly},"speed":ms};
2492              self.onscrollstart.call(self,info);
2493            }
2494
2495            if (cap.transitionend) {
2496              if (!self.scrollendtrapped) {
2497                self.scrollendtrapped = true;
2498                self.bind(self.doc,cap.transitionend,self.onScrollEnd,false); //I have got to do something usefull!!
2499              }
2500            } else {
2501              if (self.scrollendtrapped) clearTimeout(self.scrollendtrapped);
2502              self.scrollendtrapped = setTimeout(self.onScrollEnd,ms);  // simulate transitionend event
2503            }
2504
2505            var py = top;
2506            var px = lft;
2507            self.timerscroll = {
2508              bz: new BezierClass(py,self.newscrolly,ms,0,0,0.58,1),
2509              bh: new BezierClass(px,self.newscrollx,ms,0,0,0.58,1)
2510            };
2511            if (!self.cursorfreezed) self.timerscroll.tm=setInterval(function(){self.showCursor(self.getScrollTop(),self.getScrollLeft())},60);
2512
2513          }
2514
2515          self.synched("doScroll-set",function(){
2516            self.timer = 0;
2517            if (self.scrollendtrapped) self.scrollrunning = true;
2518            self.setScrollTop(self.newscrolly);
2519            self.setScrollLeft(self.newscrollx);
2520            if (!self.scrollendtrapped) self.onScrollEnd();
2521          });
2522
2523
2524        },50);
2525
2526      };
2527
2528      this.cancelScroll = function() {
2529        if (!self.scrollendtrapped) return true;
2530        var py = self.getScrollTop();
2531        var px = self.getScrollLeft();
2532        self.scrollrunning = false;
2533        if (!cap.transitionend) clearTimeout(cap.transitionend);
2534        self.scrollendtrapped = false;
2535        self._unbind(self.doc,cap.transitionend,self.onScrollEnd);
2536        self.prepareTransition(0);
2537        self.setScrollTop(py); // fire event onscroll
2538        if (self.railh) self.setScrollLeft(px);
2539        if (self.timerscroll&&self.timerscroll.tm) clearInterval(self.timerscroll.tm);
2540        self.timerscroll = false;
2541
2542        self.cursorfreezed = false;
2543
2544        //self.noticeCursor(false,py,px);
2545        self.showCursor(py,px);
2546        return self;
2547      };
2548      this.onScrollEnd = function() {
2549        if (self.scrollendtrapped) self._unbind(self.doc,cap.transitionend,self.onScrollEnd);
2550        self.scrollendtrapped = false;
2551        self.prepareTransition(0);
2552        if (self.timerscroll&&self.timerscroll.tm) clearInterval(self.timerscroll.tm);
2553        self.timerscroll = false;
2554        var py = self.getScrollTop();
2555        var px = self.getScrollLeft();
2556        self.setScrollTop(py);  // fire event onscroll
2557        if (self.railh) self.setScrollLeft(px);  // fire event onscroll left
2558
2559        self.noticeCursor(false,py,px);
2560
2561        self.cursorfreezed = false;
2562
2563        if (py<0) py=0
2564        else if (py>self.page.maxh) py=self.page.maxh;
2565        if (px<0) px=0
2566        else if (px>self.page.maxw) px=self.page.maxw;
2567        if((py!=self.newscrolly)||(px!=self.newscrollx)) return self.doScrollPos(px,py,self.opt.snapbackspeed);
2568
2569        if (self.onscrollend&&self.scrollrunning) {
2570          var info = {"type":"scrollend","current":{"x":px,"y":py},"end":{"x":self.newscrollx,"y":self.newscrolly}};
2571          self.onscrollend.call(self,info);
2572        }
2573        self.scrollrunning = false;
2574
2575      };
2576
2577    } else {
2578
2579      this.doScrollLeft = function(x,spd) {  //no-trans
2580        var y = (self.scrollrunning) ? self.newscrolly : self.getScrollTop();
2581        self.doScrollPos(x,y,spd);
2582      }
2583
2584      this.doScrollTop = function(y,spd) {  //no-trans
2585        var x = (self.scrollrunning) ? self.newscrollx : self.getScrollLeft();
2586        self.doScrollPos(x,y,spd);
2587      }
2588
2589      this.doScrollPos = function(x,y,spd) {  //no-trans
2590        var y = ((typeof y == "undefined")||(y===false)) ? self.getScrollTop(true) : y;
2591
2592        if  ((self.timer)&&(self.newscrolly==y)&&(self.newscrollx==x)) return true;
2593
2594        if (self.timer) clearAnimationFrame(self.timer);
2595        self.timer = 0;
2596
2597        var py = self.getScrollTop();
2598        var px = self.getScrollLeft();
2599
2600        if (((self.newscrolly-py)*(y-py)<0)||((self.newscrollx-px)*(x-px)<0)) self.cancelScroll();  //inverted movement detection
2601
2602        self.newscrolly = y;
2603        self.newscrollx = x;
2604
2605        if (!self.bouncescroll||!self.rail.visibility) {
2606          if (self.newscrolly<0) {
2607            self.newscrolly = 0;
2608          }
2609          else if (self.newscrolly>self.page.maxh) {
2610            self.newscrolly = self.page.maxh;
2611          }
2612        }
2613        if (!self.bouncescroll||!self.railh.visibility) {
2614          if (self.newscrollx<0) {
2615            self.newscrollx = 0;
2616          }
2617          else if (self.newscrollx>self.page.maxw) {
2618            self.newscrollx = self.page.maxw;
2619          }
2620        }
2621
2622        self.dst = {};
2623        self.dst.x = x-px;
2624        self.dst.y = y-py;
2625        self.dst.px = px;
2626        self.dst.py = py;
2627
2628        var dst = Math.round(Math.sqrt(Math.pow(self.dst.x,2)+Math.pow(self.dst.y,2)));
2629
2630        self.dst.ax = self.dst.x / dst;
2631        self.dst.ay = self.dst.y / dst;
2632
2633        var pa = 0;
2634        var pe = dst;
2635
2636        if (self.dst.x==0) {
2637          pa = py;
2638          pe = y;
2639          self.dst.ay = 1;
2640          self.dst.py = 0;
2641        } else if (self.dst.y==0) {
2642          pa = px;
2643          pe = x;
2644          self.dst.ax = 1;
2645          self.dst.px = 0;
2646        }
2647
2648        var ms = self.getTransitionSpeed(dst);
2649        if (spd&&spd<=1) ms*=spd;
2650        if (ms>0) {
2651          self.bzscroll = (self.bzscroll) ? self.bzscroll.update(pe,ms) : new BezierClass(pa,pe,ms,0,1,0,1);
2652        } else {
2653          self.bzscroll = false;
2654        }
2655
2656        if (self.timer) return;
2657
2658        if ((py==self.page.maxh&&y>=self.page.maxh)||(px==self.page.maxw&&x>=self.page.maxw)) self.checkContentSize();
2659
2660        var sync = 1;
2661
2662        function scrolling() {
2663          if (self.cancelAnimationFrame) return true;
2664
2665          self.scrollrunning = true;
2666
2667          sync = 1-sync;
2668          if (sync) return (self.timer = setAnimationFrame(scrolling)||1);
2669
2670          var done = 0;
2671
2672          var sc = sy = self.getScrollTop();
2673          if (self.dst.ay) {
2674            sc = (self.bzscroll) ? self.dst.py + (self.bzscroll.getNow()*self.dst.ay) : self.newscrolly;
2675            var dr=sc-sy;
2676            if ((dr<0&&sc<self.newscrolly)||(dr>0&&sc>self.newscrolly)) sc = self.newscrolly;
2677            self.setScrollTop(sc);
2678            if (sc == self.newscrolly) done=1;
2679          } else {
2680            done=1;
2681          }
2682
2683          var scx = sx = self.getScrollLeft();
2684          if (self.dst.ax) {
2685            scx = (self.bzscroll) ? self.dst.px + (self.bzscroll.getNow()*self.dst.ax) : self.newscrollx;
2686            var dr=scx-sx;
2687            if ((dr<0&&scx<self.newscrollx)||(dr>0&&scx>self.newscrollx)) scx = self.newscrollx;
2688            self.setScrollLeft(scx);
2689            if (scx == self.newscrollx) done+=1;
2690          } else {
2691            done+=1;
2692          }
2693
2694          if (done==2) {
2695            self.timer = 0;
2696            self.cursorfreezed = false;
2697            self.bzscroll = false;
2698            self.scrollrunning = false;
2699            if (sc<0) sc=0;
2700            else if (sc>self.page.maxh) sc=self.page.maxh;
2701            if (scx<0) scx=0;
2702            else if (scx>self.page.maxw) scx=self.page.maxw;
2703            if ((scx!=self.newscrollx)||(sc!=self.newscrolly)) self.doScrollPos(scx,sc);
2704            else {
2705              if (self.onscrollend) {
2706                var info = {"type":"scrollend","current":{"x":sx,"y":sy},"end":{"x":self.newscrollx,"y":self.newscrolly}};
2707                self.onscrollend.call(self,info);
2708              }
2709            }
2710          } else {
2711            self.timer = setAnimationFrame(scrolling)||1;
2712          }
2713        };
2714        self.cancelAnimationFrame=false;
2715        self.timer = 1;
2716
2717        if (self.onscrollstart&&!self.scrollrunning) {
2718          var info = {"type":"scrollstart","current":{"x":px,"y":py},"request":{"x":x,"y":y},"end":{"x":self.newscrollx,"y":self.newscrolly},"speed":ms};
2719          self.onscrollstart.call(self,info);
2720        }
2721
2722        scrolling();
2723
2724        if ((py==self.page.maxh&&y>=py)||(px==self.page.maxw&&x>=px)) self.checkContentSize();
2725
2726        self.noticeCursor();
2727      };
2728
2729      this.cancelScroll = function() {
2730        if (self.timer) clearAnimationFrame(self.timer);
2731        self.timer = 0;
2732        self.bzscroll = false;
2733        self.scrollrunning = false;
2734        return self;
2735      };
2736
2737    }
2738
2739    this.doScrollBy = function(stp,relative) {
2740      var ny = 0;
2741      if (relative) {
2742        ny = Math.floor((self.scroll.y-stp)*self.scrollratio.y)
2743      } else {
2744        var sy = (self.timer) ? self.newscrolly : self.getScrollTop(true);
2745        ny = sy-stp;
2746      }
2747      if (self.bouncescroll) {
2748        var haf = Math.round(self.view.h/2);
2749        if (ny<-haf) ny=-haf
2750        else if (ny>(self.page.maxh+haf)) ny = (self.page.maxh+haf);
2751      }
2752      self.cursorfreezed = false;
2753
2754      py = self.getScrollTop(true);
2755      if (ny<0&&py<=0) return self.noticeCursor();
2756      else if (ny>self.page.maxh&&py>=self.page.maxh) {
2757        self.checkContentSize();
2758        return self.noticeCursor();
2759      }
2760
2761      self.doScrollTop(ny);
2762    };
2763
2764    this.doScrollLeftBy = function(stp,relative) {
2765      var nx = 0;
2766      if (relative) {
2767        nx = Math.floor((self.scroll.x-stp)*self.scrollratio.x)
2768      } else {
2769        var sx = (self.timer) ? self.newscrollx : self.getScrollLeft(true);
2770        nx = sx-stp;
2771      }
2772      if (self.bouncescroll) {
2773        var haf = Math.round(self.view.w/2);
2774        if (nx<-haf) nx=-haf
2775        else if (nx>(self.page.maxw+haf)) nx = (self.page.maxw+haf);
2776      }
2777      self.cursorfreezed = false;
2778
2779      px = self.getScrollLeft(true);
2780      if (nx<0&&px<=0) return self.noticeCursor();
2781      else if (nx>self.page.maxw&&px>=self.page.maxw) return self.noticeCursor();
2782
2783      self.doScrollLeft(nx);
2784    };
2785
2786    this.doScrollTo = function(pos,relative) {
2787      var ny = (relative) ? Math.round(pos*self.scrollratio.y) : pos;
2788      if (ny<0) ny=0
2789      else if (ny>self.page.maxh) ny = self.page.maxh;
2790      self.cursorfreezed = false;
2791      self.doScrollTop(pos);
2792    };
2793
2794    this.checkContentSize = function() {
2795      var pg = self.getContentSize();
2796      if ((pg.h!=self.page.h)||(pg.w!=self.page.w)) self.resize(false,pg);
2797    };
2798
2799    self.onscroll = function(e) {
2800      if (self.rail.drag) return;
2801      if (!self.cursorfreezed) {
2802        self.synched('scroll',function(){
2803          self.scroll.y = Math.round(self.getScrollTop() * (1/self.scrollratio.y));
2804          if (self.railh) self.scroll.x = Math.round(self.getScrollLeft() * (1/self.scrollratio.x));
2805          self.noticeCursor();
2806        });
2807      }
2808    };
2809    self.bind(self.docscroll,"scroll",self.onscroll);
2810
2811    this.doZoomIn = function(e) {
2812      if (self.zoomactive) return;
2813      self.zoomactive = true;
2814
2815      self.zoomrestore = {
2816        style:{}
2817      };
2818      var lst = ['position','top','left','zIndex','backgroundColor','marginTop','marginBottom','marginLeft','marginRight'];
2819      var win = self.win[0].style;
2820      for(var a in lst) {
2821        var pp = lst[a];
2822        self.zoomrestore.style[pp] = (typeof win[pp] != "undefined") ? win[pp] : '';
2823      }
2824
2825      self.zoomrestore.style.width = self.win.css('width');
2826      self.zoomrestore.style.height = self.win.css('height');
2827
2828      self.zoomrestore.padding = {
2829        w:self.win.outerWidth()-self.win.width(),
2830        h:self.win.outerHeight()-self.win.height()
2831      };
2832
2833      if (cap.isios4) {
2834        self.zoomrestore.scrollTop = $(window).scrollTop();
2835        $(window).scrollTop(0);
2836      }
2837
2838      self.win.css({
2839        "position":(cap.isios4)?"absolute":"fixed",
2840        "top":0,
2841        "left":0,
2842        "z-index":globalmaxzindex+100,
2843        "margin":"0px"
2844      });
2845      var bkg = self.win.css("backgroundColor");
2846      if (bkg==""||/transparent|rgba\(0, 0, 0, 0\)|rgba\(0,0,0,0\)/.test(bkg)) self.win.css("backgroundColor","#fff");
2847      self.rail.css({"z-index":globalmaxzindex+101});
2848      self.zoom.css({"z-index":globalmaxzindex+102});
2849      self.zoom.css('backgroundPosition','0px -18px');
2850      self.resizeZoom();
2851
2852      if (self.onzoomin) self.onzoomin.call(self);
2853
2854      return self.cancelEvent(e);
2855    };
2856
2857    this.doZoomOut = function(e) {
2858      if (!self.zoomactive) return;
2859      self.zoomactive = false;
2860
2861      self.win.css("margin","");
2862      self.win.css(self.zoomrestore.style);
2863
2864      if (cap.isios4) {
2865        $(window).scrollTop(self.zoomrestore.scrollTop);
2866      }
2867
2868      self.rail.css({"z-index":self.zindex});
2869      self.zoom.css({"z-index":self.zindex});
2870      self.zoomrestore = false;
2871      self.zoom.css('backgroundPosition','0px 0px');
2872      self.onResize();
2873
2874      if (self.onzoomout) self.onzoomout.call(self);
2875
2876      return self.cancelEvent(e);
2877    };
2878
2879    this.doZoom = function(e) {
2880      return (self.zoomactive) ? self.doZoomOut(e) : self.doZoomIn(e);
2881    };
2882
2883    this.resizeZoom = function() {
2884      if (!self.zoomactive) return;
2885
2886      var py = self.getScrollTop(); //preserve scrolling position
2887      self.win.css({
2888        width:$(window).width()-self.zoomrestore.padding.w+"px",
2889        height:$(window).height()-self.zoomrestore.padding.h+"px"
2890      });
2891      self.onResize();
2892
2893      self.setScrollTop(Math.min(self.page.maxh,py));
2894    };
2895
2896    this.init();
2897
2898    $.nicescroll.push(this);
2899
2900  };
2901
2902// Inspired by the work of Kin Blas
2903// http://webpro.host.adobe.com/people/jblas/momentum/includes/jquery.momentum.0.7.js
2904
2905
2906  var ScrollMomentumClass2D = function(nc) {
2907    var self = this;
2908    this.nc = nc;
2909
2910    this.lastx = 0;
2911    this.lasty = 0;
2912    this.speedx = 0;
2913    this.speedy = 0;
2914    this.lasttime = 0;
2915    this.steptime = 0;
2916    this.snapx = false;
2917    this.snapy = false;
2918    this.demulx = 0;
2919    this.demuly = 0;
2920
2921    this.lastscrollx = -1;
2922    this.lastscrolly = -1;
2923
2924    this.chkx = 0;
2925    this.chky = 0;
2926
2927    this.timer = 0;
2928
2929    this.time = function() {
2930      return +new Date();//beautifull hack
2931    };
2932
2933    this.reset = function(px,py) {
2934      self.stop();
2935      var now = self.time();
2936      self.steptime = 0;
2937      self.lasttime = now;
2938      self.speedx = 0;
2939      self.speedy = 0;
2940      self.lastx = px;
2941      self.lasty = py;
2942      self.lastscrollx = -1;
2943      self.lastscrolly = -1;
2944    };
2945
2946    this.update = function(px,py) {
2947      var now = self.time();
vendor: 1,665 bytes, lines 2948-3011
2948      self.steptime = now - self.lasttime;
2949      self.lasttime = now;
2950      var dy = py - self.lasty;
2951      var dx = px - self.lastx;
2952      var sy = self.nc.getScrollTop();
2953      var sx = self.nc.getScrollLeft();
2954      var newy = sy + dy;
2955      var newx = sx + dx;
2956      self.snapx = (newx<0)||(newx>self.nc.page.maxw);
2957      self.snapy = (newy<0)||(newy>self.nc.page.maxh);
2958      self.speedx = dx;
2959      self.speedy = dy;
2960      self.lastx = px;
2961      self.lasty = py;
2962    };
2963
2964    this.stop = function() {
2965      self.nc.unsynched("domomentum2d");
2966      if (self.timer) clearTimeout(self.timer);
2967      self.timer = 0;
2968      self.lastscrollx = -1;
2969      self.lastscrolly = -1;
2970    };
2971
2972    this.doSnapy = function(nx,ny) {
2973      var snap = false;
2974
2975      if (ny<0) {
2976        ny=0;
2977        snap=true;
2978      }
2979      else if (ny>self.nc.page.maxh) {
2980        ny=self.nc.page.maxh;
2981        snap=true;
2982      }
2983
2984      if (nx<0) {
2985        nx=0;
2986        snap=true;
2987      }
2988      else if (nx>self.nc.page.maxw) {
2989        nx=self.nc.page.maxw;
2990        snap=true;
2991      }
2992
2993      if (snap) self.nc.doScrollPos(nx,ny,self.nc.opt.snapbackspeed);
2994    };
2995
2996    this.doMomentum = function(gp) {
2997      var t = self.time();
2998      var l = (gp) ? t+gp : self.lasttime;
2999
3000      var sl = self.nc.getScrollLeft();
3001      var st = self.nc.getScrollTop();
3002
3003      var pageh = self.nc.page.maxh;
3004      var pagew = self.nc.page.maxw;
3005
3006      self.speedx = (pagew>0) ? Math.min(60,self.speedx) : 0;
3007      self.speedy = (pageh>0) ? Math.min(60,self.speedy) : 0;
3008
3009      var chk = l && (t - l) <= 60;
3010
3011      if ((st<0)||(st>pageh)||(sl<0)||(sl>
3011pagew)) chk = false;
3012
3013      var sy = (self.speedy && chk) ? self.speedy : false;
3014      var sx = (self.speedx && chk) ? self.speedx : false;
3015
3016      if (sy||sx) {
3017        var tm = Math.max(16,self.steptime); //timeout granularity
3018
3019        if (tm>50) {  // do smooth
3020          var xm = tm/50;
3021          self.speedx*=xm;
3022          self.speedy*=xm;
3023          tm = 50;
3024        }
3025
3026        self.demulxy = 0;
3027
3028        self.lastscrollx = self.nc.getScrollLeft();
3029        self.chkx = self.lastscrollx;
3030        self.lastscrolly = self.nc.getScrollTop();
3031        self.chky = self.lastscrolly;
3032
3033        var nx = self.lastscrollx;
3034        var ny = self.lastscrolly;
3035
3036        var onscroll = function(){
3037          var df = ((self.time()-t)>600) ? 0.04 : 0.02;
3038
3039          if (self.speedx) {
3040            nx = Math.floor(self.lastscrollx - (self.speedx*(1-self.demulxy)));
3041            self.lastscrollx = nx;
3042            if ((nx<0)||(nx>pagew)) df=0.10;
3043          }
3044
3045          if (self.speedy) {
3046            ny = Math.floor(self.lastscrolly - (self.speedy*(1-self.demulxy)));
3047            self.lastscrolly = ny;
3048            if ((ny<0)||(ny>pageh)) df=0.10;
3049          }
3050
3051          self.demulxy = Math.min(1,self.demulxy+df);
3052
3053          self.nc.synched("domomentum2d",function(){
3054
3055            if (self.speedx) {
3056              var scx = self.nc.getScrollLeft();
3057              if (scx!=self.chkx) self.stop();
3058              self.chkx=nx;
3059              self.nc.setScrollLeft(nx);
3060            }
3061
3062            if (self.speedy) {
3063              var scy = self.nc.getScrollTop();
3064              if (scy!=self.chky) self.stop();
3065              self.chky=ny;
3066              self.nc.setScrollTop(ny);
3067            }
3068
3069            if(!self.timer) {
3070              self.nc.hideCursor();
3071              self.doSnapy(nx,ny);
3072            }
3073
3074          });
3075
3076          if (self.demulxy<1) {
3077            self.timer = setTimeout(onscroll,tm);
3078          } else {
3079            self.stop();
3080            self.nc.hideCursor();
3081            self.doSnapy(nx,ny);
3082          }
3083        };
3084
3085        onscroll();
3086
3087      } else {
3088        self.doSnapy(self.nc.getScrollLeft(),self.nc.getScrollTop());
3089      }
3090
3091    }
3092
3093  };
3094
3095
3096// override jQuery scrollTop
3097
3098  var _scrollTop = jQuery.fn.scrollTop; // preserve original function
3099
3100  jQuery.cssHooks["pageYOffset"] = {
3101    get: function(elem,computed,extra) {
3102      var nice = $.data(elem,'__nicescroll')||false;
3103      return (nice&&nice.ishwscroll) ? nice.getScrollTop() : _scrollTop.call(elem);
3104    },
3105    set: function(elem,value) {
3106      var nice = $.data(elem,'__nicescroll')||false;
3107      (nice&&nice.ishwscroll) ? nice.setScrollTop(parseInt(value)) : _scrollTop.call(elem,value);
3108      return this;
3109    }
3110  };
3111
3112/*
3113  $.fx.step["scrollTop"] = function(fx){
3114    $.cssHooks["scrollTop"].set( fx.elem, fx.now + fx.unit );
3115  };
3116*/
3117
3118  jQuery.fn.scrollTop = function(value) {
3119    if (typeof value == "undefined") {
3120      var nice = (this[0]) ? $.data(this[0],'__nicescroll')||false : false;
3121      return (nice&&nice.ishwscroll) ? nice.getScrollTop() : _scrollTop.call(this);
3122    } else {
3123      return this.each(function() {
3124        var nice = $.data(this,'__nicescroll')||false;
3125        (nice&&nice.ishwscroll) ? nice.setScrollTop(parseInt(value)) : _scrollTop.call($(this),value);
3126      });
3127    }
3128  }
3129
3130// override jQuery scrollLeft
3131
3132  var _scrollLeft = jQuery.fn.scrollLeft; // preserve original function
3133
3134  $.cssHooks.pageXOffset = {
3135    get: function(elem,computed,extra) {
3136      var nice = $.data(elem,'__nicescroll')||false;
3137      return (nice&&nice.ishwscroll) ? nice.getScrollLeft() : _scrollLeft.call(elem);
3138    },
3139    set: function(elem,value) {
3140      var nice = $.data(elem,'__nicescroll')||false;
3141      (nice&&nice.ishwscroll) ? nice.setScrollLeft(parseInt(value)) : _scrollLeft.call(elem,value);
3142      return this;
3143    }
3144  };
3145
3146/*
3147  $.fx.step["scrollLeft"] = function(fx){
3148    $.cssHooks["scrollLeft"].set( fx.elem, fx.now + fx.unit );
3149  };
3150*/
3151
3152  jQuery.fn.scrollLeft = function(value) {
3153    if (typeof value == "undefined") {
3154      var nice = (this[0]) ? $.data(this[0],'__nicescroll')||false : false;
3155      return (nice&&nice.ishwscroll) ? nice.getScrollLeft() : _scrollLeft.call(this);
3156    } else {
3157      return this.each(function() {
3158        var nice = $.data(this,'__nicescroll')||false;
3159        (nice&&nice.ishwscroll) ? nice.setScrollLeft(parseInt(value)) : _scrollLeft.call($(this),value);
3160      });
3161    }
3162  }
3163
3164  var NiceScrollArray = function(doms) {
3165    var self = this;
3166    this.length = 0;
3167    this.name = "nicescrollarray";
3168
3169    this.each = function(fn) {
3170      for(var a=0,i=0;a<self.length;a++) fn.call(self[a],i++);
3171      return self;
3172    };
3173
3174    this.push = function(nice) {
3175      self[self.length]=nice;
3176      self.length++;
3177    };
3178
3179    this.eq = function(idx) {
3180      return self[idx];
3181    };
3182
3183    if (doms) {
3184      for(a=0;a<doms.length;a++) {
3185        var nice = $.data(doms[a],'__nicescroll')||false;
3186        if (nice) {
3187          this[this.length]=nice;
3188          this.length++;
3189        }
3190      };
3191    }
3192
3193    return this;
3194  };
3195
3196  function mplex(el,lst,fn) {
3197    for(var a=0;a<lst.length;a++) fn(el,lst[a]);
3198  };
3199  mplex(
3200    NiceScrollArray.prototype,
3201    ['show','hide','toggle','onResize','resize','remove','stop','doScrollPos'],
3202    function(e,n) {
3203      e[n] = function(){
3204        var args = arguments;
3205        return this.each(function(){
3206          this[n].apply(this,args);
3207        });
3208      };
3209    }
3210  );
3211
3212  jQuery.fn.getNiceScroll = function(index) {
3213    if (typeof index == "undefined") {
3214      return new NiceScrollArray(this);
3215    } else {
3216      var nice = this[index]&&$.data(this[index],'__nicescroll')||false;
3217      return nice;
3218    }
3219  };
3220
3221  jQuery.extend(jQuery.expr[':'], {
3222    nicescroll: function(a) {
3223      return ($.data(a,'__nicescroll'))?true:false;
3224    }
3225  });
3226
3227  $.fn.niceScroll = function(wrapper,opt) {
3228    if (typeof opt=="undefined") {
3229      if ((typeof wrapper=="object")&&!("jquery" in wrapper)) {
3230        opt = wrapper;
3231        wrapper = false;
3232      }
3233    }
3234    var ret = new NiceScrollArray();
3235    if (typeof opt=="undefined") opt = {};
3236
3237    if (wrapper||false) {
3238      opt.doc = $(wrapper);
3239      opt.win = $(this);
3240    }
3241    var docundef = !("doc" in opt);
3242    if (!docundef&&!("win" in opt)) opt.win = $(this);
3243
3244    this.each(function() {
3245      var nice = $(this).data('__nicescroll')||false;
3246      if (!nice) {
3247        opt.doc = (docundef) ? $(this) : opt.doc;
3248        nice = new NiceScrollClass(opt,$(this));
3249        $(this).data('__nicescroll',nice);
3250      }
3251      ret.push(nice);
3252    });
3253    return (ret.length==1) ? ret[0] : ret;
3254  };
3255
3256  window.NiceScroll = {
3257    getjQuery:function(){return jQuery}
3258  };
3259
3260  if (!$.nicescroll) {
3261   $.nicescroll = new NiceScrollArray();
3262   $.nicescroll.options = _globaloptions;
3263  }
3264
3265})( jQuery );

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.