PageSourceSearch

https://hondacars-saitamanaka.co.jp/wp-content/themes/saitamanaka/common/js/iscroll.js

js hondacars-saitamanaka.co.jp collected 2026-10-07 13:38:25 UTC 75,677 bytes, 2,170 lines download raw bytes

vendor: 10,279 bytes, lines 1-282
1/*! iScroll v5.2.0-snapshot ~ (c) 2008-2017 Matteo Spinelli ~ http://cubiq.org/license */
2(function (window, document, Math) {
3    var rAF = window.requestAnimationFrame	||
4        window.webkitRequestAnimationFrame	||
5        window.mozRequestAnimationFrame		||
6        window.oRequestAnimationFrame		||
7        window.msRequestAnimationFrame		||
8        function (callback) { window.setTimeout(callback, 1000 / 60); };
9
10    var utils = (function () {
11        var me = {};
12
13        var _elementStyle = document.createElement('div').style;
14        var _vendor = (function () {
15            var vendors = ['t', 'webkitT', 'MozT', 'msT', 'OT'],
16                transform,
17                i = 0,
18                l = vendors.length;
19
20            for ( ; i < l; i++ ) {
21                transform = vendors[i] + 'ransform';
22                if ( transform in _elementStyle ) return vendors[i].substr(0, vendors[i].length-1);
23            }
24
25            return false;
26        })();
27
28        function _prefixStyle (style) {
29            if ( _vendor === false ) return false;
30            if ( _vendor === '' ) return style;
31            return _vendor + style.charAt(0).toUpperCase() + style.substr(1);
32        }
33
34        me.getTime = Date.now || function getTime () { return new Date().getTime(); };
35
36        me.extend = function (target, obj) {
37            for ( var i in obj ) {
38                target[i] = obj[i];
39            }
40        };
41
42        me.addEvent = function (el, type, fn, capture) {
43            el.addEventListener(type, fn, {passive: false});
44        };
45
46        me.removeEvent = function (el, type, fn, capture) {
47            el.removeEventListener(type, fn, !!capture);
48        };
49
50        me.prefixPointerEvent = function (pointerEvent) {
51            return window.MSPointerEvent ?
52                'MSPointer' + pointerEvent.charAt(7).toUpperCase() + pointerEvent.substr(8):
53                pointerEvent;
54        };
55
56        me.momentum = function (current, start, time, lowerMargin, wrapperSize, deceleration) {
57            var distance = current - start,
58                speed = Math.abs(distance) / time,
59                destination,
60                duration;
61
62            deceleration = deceleration === undefined ? 0.0006 : deceleration;
63
64            destination = current + ( speed * speed ) / ( 2 * deceleration ) * ( distance < 0 ? -1 : 1 );
65            duration = speed / deceleration;
66
67            if ( destination < lowerMargin ) {
68                destination = wrapperSize ? lowerMargin - ( wrapperSize / 2.5 * ( speed / 8 ) ) : lowerMargin;
69                distance = Math.abs(destination - current);
70                duration = distance / speed;
71            } else if ( destination > 0 ) {
72                destination = wrapperSize ? wrapperSize / 2.5 * ( speed / 8 ) : 0;
73                distance = Math.abs(current) + destination;
74                duration = distance / speed;
75            }
76
77            return {
78                destination: Math.round(destination),
79                duration: duration
80            };
81        };
82
83        var _transform = _prefixStyle('transform');
84
85        me.extend(me, {
86            hasTransform: _transform !== false,
87            hasPerspective: _prefixStyle('perspective') in _elementStyle,
88            hasTouch: 'ontouchstart' in window,
89            hasPointer: !!(window.PointerEvent || window.MSPointerEvent), // IE10 is prefixed
90            hasTransition: _prefixStyle('transition') in _elementStyle
91        });
92
93        /*
94        This should find all Android browsers lower than build 535.19 (both stock browser and webview)
95        - galaxy S2 is ok
96        - 2.3.6 : `AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1`
97        - 4.0.4 : `AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30`
98       - galaxy S3 is badAndroid (stock brower, webview)
99         `AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30`
100       - galaxy S4 is badAndroid (stock brower, webview)
101         `AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30`
102       - galaxy S5 is OK
103         `AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Mobile Safari/537.36 (Chrome/)`
104       - galaxy S6 is OK
105         `AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Mobile Safari/537.36 (Chrome/)`
106      */
107        me.isBadAndroid = (function() {
108            var appVersion = window.navigator.appVersion;
109            // Android browser is not a chrome browser.
110            if (/Android/.test(appVersion) && !(/Chrome\/\d/.test(appVersion))) {
111                var safariVersion = appVersion.match(/Safari\/(\d+.\d)/);
112                if(safariVersion && typeof safariVersion === "object" && safariVersion.length >= 2) {
113                    return parseFloat(safariVersion[1]) < 535.19;
114                } else {
115                    return true;
116                }
117            } else {
118                return false;
119            }
120        })();
121
122        me.extend(me.style = {}, {
123            transform: _transform,
124            transitionTimingFunction: _prefixStyle('transitionTimingFunction'),
125            transitionDuration: _prefixStyle('transitionDuration'),
126            transitionDelay: _prefixStyle('transitionDelay'),
127            transformOrigin: _prefixStyle('transformOrigin'),
128            touchAction: _prefixStyle('touchAction')
129        });
130
131        me.hasClass = function (e, c) {
132            var re = new RegExp("(^|\\s)" + c + "(\\s|$)");
133            return re.test(e.className);
134        };
135
136        me.addClass = function (e, c) {
137            if ( me.hasClass(e, c) ) {
138                return;
139            }
140
141            var newclass = e.className.split(' ');
142            newclass.push(c);
143            e.className = newclass.join(' ');
144        };
145
146        me.removeClass = function (e, c) {
147            if ( !me.hasClass(e, c) ) {
148                return;
149            }
150
151            var re = new RegExp("(^|\\s)" + c + "(\\s|$)", 'g');
152            e.className = e.className.replace(re, ' ');
153        };
154
155        me.offset = function (el) {
156            var left = -el.offsetLeft,
157                top = -el.offsetTop;
158
159            // jshint -W084
160            while (el = el.offsetParent) {
161                left -= el.offsetLeft;
162                top -= el.offsetTop;
163            }
164            // jshint +W084
165
166            return {
167                left: left,
168                top: top
169            };
170        };
171
172        me.preventDefaultException = function (el, exceptions) {
173            for ( var i in exceptions ) {
174                if ( exceptions[i].test(el[i]) ) {
175                    return true;
176                }
177            }
178
179            return false;
180        };
181
182        me.extend(me.eventType = {}, {
183            touchstart: 1,
184            touchmove: 1,
185            touchend: 1,
186
187            mousedown: 2,
188            mousemove: 2,
189            mouseup: 2,
190
191            pointerdown: 1,
192            pointermove: 1,
193            pointerup: 1,
194
195            MSPointerDown: 3,
196            MSPointerMove: 3,
197            MSPointerUp: 3
198        });
199
200        me.extend(me.ease = {}, {
201            quadratic: {
202                style: 'cubic-bezier(0.25, 0.46, 0.45, 0.94)',
203                fn: function (k) {
204                    return k * ( 2 - k );
205                }
206            },
207            circular: {
208                style: 'cubic-bezier(0.1, 0.57, 0.1, 1)',	// Not properly "circular" but this looks better, it should be (0.075, 0.82, 0.165, 1)
209                fn: function (k) {
210                    return Math.sqrt( 1 - ( --k * k ) );
211                }
212            },
213            back: {
214                style: 'cubic-bezier(0.175, 0.885, 0.32, 1.275)',
215                fn: function (k) {
216                    var b = 4;
217                    return ( k = k - 1 ) * k * ( ( b + 1 ) * k + b ) + 1;
218                }
219            },
220            bounce: {
221                style: '',
222                fn: function (k) {
223                    if ( ( k /= 1 ) < ( 1 / 2.75 ) ) {
224                        return 7.5625 * k * k;
225                    } else if ( k < ( 2 / 2.75 ) ) {
226                        return 7.5625 * ( k -= ( 1.5 / 2.75 ) ) * k + 0.75;
227                    } else if ( k < ( 2.5 / 2.75 ) ) {
228                        return 7.5625 * ( k -= ( 2.25 / 2.75 ) ) * k + 0.9375;
229                    } else {
230                        return 7.5625 * ( k -= ( 2.625 / 2.75 ) ) * k + 0.984375;
231                    }
232                }
233            },
234            elastic: {
235                style: '',
236                fn: function (k) {
237                    var f = 0.22,
238                        e = 0.4;
239
240                    if ( k === 0 ) { return 0; }
241                    if ( k == 1 ) { return 1; }
242
243                    return ( e * Math.pow( 2, - 10 * k ) * Math.sin( ( k - f / 4 ) * ( 2 * Math.PI ) / f ) + 1 );
244                }
245            }
246        });
247
248        me.tap = function (e, eventName) {
249            var ev = document.createEvent('Event');
250            ev.initEvent(eventName, true, true);
251            ev.pageX = e.pageX;
252            ev.pageY = e.pageY;
253            e.target.dispatchEvent(ev);
254        };
255
256        me.click = function (e) {
257            var target = e.target,
258                ev;
259
260            if ( !(/(SELECT|INPUT|TEXTAREA)/i).test(target.tagName) ) {
261                // https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/initMouseEvent
262                // initMouseEvent is deprecated.
263                ev = document.createEvent(window.MouseEvent ? 'MouseEvents' : 'Event');
264                ev.initEvent('click', true, true);
265                ev.view = e.view || window;
266                ev.detail = 1;
267                ev.screenX = target.screenX || 0;
268                ev.screenY = target.screenY || 0;
269                ev.clientX = target.clientX || 0;
270                ev.clientY = target.clientY || 0;
271                ev.ctrlKey = !!e.ctrlKey;
272                ev.altKey = !!e.altKey;
273                ev.shiftKey = !!e.shiftKey;
274                ev.metaKey = !!e.metaKey;
275                ev.button = 0;
276                ev.relatedTarget = null;
277                ev._constructed = true;
278                target.dispatchEvent(ev);
279            }
280        };
281
282        me.getTouchAction = function(eventPassthrough, addPinch) {
283            var touchAction = 'none';
284            if ( eventPassthrough === 'vertical' ) {
285                touchAction = 'pan-y';
286            } else if (eventPassthrough === 'horizontal' ) {
287                touchAction = 'pan-x';
288            }
289            if (addPinch && touchAction != 'none') {
290                // add pinch-zoom support if the browser supports it, but if not (eg. Chrome <55) do nothing
291                touchAction += ' pinch-zoom';
292            }
293            return touchAction;
294        };
295
296        me.getRect = function(el) {
297            if (el instanceof SVGElement) {
298                var rect = el.getBoundingClientRect();
299                return {
300                    top : rect.top,
301                    left : rect.left,
302                    width : rect.width,
303                    height : rect.height
304                };
305            } else {
306                return {
307                    top : el.offsetTop,
308                    left : el.offsetLeft,
309                    width : el.offsetWidth,
310                    height : el.offsetHeight
311                };
312            }
313        };
314
315        return me;
316    })();
317    function IScroll (el, options) {
318        this.wrapper = typeof el == 'string' ? document.querySelector(el) : el;
319        this.scroller = this.wrapper.children[0];
320        this.scrollerStyle = this.scroller.style;		// cache style for better performance
321
322        this.options = {
323
324            resizeScrollbars: true,
325
326            mouseWheelSpeed: 20,
327
328            snapThreshold: 0.334,
329
330// INSERT POINT: OPTIONS
331            disablePointer : false,
332            disableTouch : false,
333            disableMouse : false,
334            startX: 0,
335            startY: 0,
336            scrollY: true,
337            directionLockThreshold: 5,
338            momentum: true,
339
340            bounce: true,
341            bounceTime: 600,
342            bounceEasing: '',
343
344            preventDefault: true,
345            preventDefaultException: { tagName: /^(INPUT|TEXTAREA|BUTTON|SELECT)$/ },
346
347            HWCompositing: true,
348            useTransition: true,
349            useTransform: true,
350            bindToWrapper: typeof window.onmousedown === "undefined"
351        };
352
353        for ( var i in options ) {
354            this.options[i] = options[i];
355        }
356
357        // Normalize options
358        this.translateZ = this.options.HWCompositing && utils.hasPerspective ? ' translateZ(0)' : '';
359
360        this.options.useTransition = utils.hasTransition && this.options.useTransition;
361        this.options.useTransform = utils.hasTransform && this.options.useTransform;
362
363        this.options.eventPassthrough = this.options.eventPassthrough === true ? 'vertical' : this.options.eventPassthrough;
364        this.options.preventDefault = !this.options.eventPassthrough && this.options.preventDefault;
365
366        // If you want eventPassthrough I have to lock one of the axes
367        this.options.scrollY = this.options.eventPassthrough == 'vertical' ? false : this.options.scrollY;
368        this.options.scrollX = this.options.eventPassthrough == 'horizontal' ? false : this.options.scrollX;
369
370        // With eventPassthrough we also need lockDirection mechanism
371        this.options.freeScroll = this.options.freeScroll && !this.options.eventPassthrough;
372        this.options.directionLockThreshold = this.options.eventPassthrough ? 0 : this.options.directionLockThreshold;
373
374        this.options.bounceEasing = typeof this.options.bounceEasing == 'string' ? utils.ease[this.options.bounceEasing] || utils.ease.circular : this.options.bounceEasing;
375
376        this.options.resizePolling = this.options.resizePolling === undefined ? 60 : this.options.resizePolling;
377
378        if ( this.options.tap === true ) {
379            this.options.tap = 'tap';
380        }
381
382        // https://github.com/cubiq/iscroll/issues/1029
383        if (!this.options.useTransition && !this.options.useTransform) {
384            if(!(/relative|absolute/i).test(this.scrollerStyle.position)) {
385                this.scrollerStyle.position = "relative";
386            }
387        }
388
389        if ( this.options.shrinkScrollbars == 'scale' ) {
390            this.options.useTransition = false;
vendor: 4,984 bytes, lines 391-550
391        }
392
393        this.options.invertWheelDirection = this.options.invertWheelDirection ? -1 : 1;
394
395// INSERT POINT: NORMALIZATION
396
397        // Some defaults
398        this.x = 0;
399        this.y = 0;
400        this.directionX = 0;
401        this.directionY = 0;
402        this._events = {};
403
404// INSERT POINT: DEFAULTS
405
406        this._init();
407        this.refresh();
408
409        this.scrollTo(this.options.startX, this.options.startY);
410        this.enable();
411    }
412
413    IScroll.prototype = {
414        version: '5.2.0-snapshot',
415
416        _init: function () {
417            this._initEvents();
418
419            if ( this.options.scrollbars || this.options.indicators ) {
420                this._initIndicators();
421            }
422
423            if ( this.options.mouseWheel ) {
424                this._initWheel();
425            }
426
427            if ( this.options.snap ) {
428                this._initSnap();
429            }
430
431            if ( this.options.keyBindings ) {
432                this._initKeys();
433            }
434
435// INSERT POINT: _init
436
437        },
438
439        destroy: function () {
440            this._initEvents(true);
441            clearTimeout(this.resizeTimeout);
442            this.resizeTimeout = null;
443            this._execEvent('destroy');
444        },
445
446        _transitionEnd: function (e) {
447            if ( e.target != this.scroller || !this.isInTransition ) {
448                return;
449            }
450
451            this._transitionTime();
452            if ( !this.resetPosition(this.options.bounceTime) ) {
453                this.isInTransition = false;
454                this._execEvent('scrollEnd');
455            }
456        },
457
458        _start: function (e) {
459            // React to left mouse button only
460            if ( utils.eventType[e.type] != 1 ) {
461                // for button property
462                // http://unixpapa.com/js/mouse.html
463                var button;
464                if (!e.which) {
465                    /* IE case */
466                    button = (e.button < 2) ? 0 :
467                        ((e.button == 4) ? 1 : 2);
468                } else {
469                    /* All others */
470                    button = e.button;
471                }
472                if ( button !== 0 ) {
473                    return;
474                }
475            }
476
477            if ( !this.enabled || (this.initiated && utils.eventType[e.type] !== this.initiated) ) {
478                return;
479            }
480
481            if ( this.options.preventDefault && !utils.isBadAndroid && !utils.preventDefaultException(e.target, this.options.preventDefaultException) ) {
482                // e.preventDefault();
483            }
484
485            var point = e.touches ? e.touches[0] : e,
486                pos;
487
488            this.initiated	= utils.eventType[e.type];
489            this.moved		= false;
490            this.distX		= 0;
491            this.distY		= 0;
492            this.directionX = 0;
493            this.directionY = 0;
494            this.directionLocked = 0;
495
496            this.startTime = utils.getTime();
497
498            if ( this.options.useTransition && this.isInTransition ) {
499                this._transitionTime();
500                this.isInTransition = false;
501                pos = this.getComputedPosition();
502                this._translate(Math.round(pos.x), Math.round(pos.y));
503                this._execEvent('scrollEnd');
504            } else if ( !this.options.useTransition && this.isAnimating ) {
505                this.isAnimating = false;
506                this._execEvent('scrollEnd');
507            }
508
509            this.startX    = this.x;
510            this.startY    = this.y;
511            this.absStartX = this.x;
512            this.absStartY = this.y;
513            this.pointX    = point.pageX;
514            this.pointY    = point.pageY;
515
516            this._execEvent('beforeScrollStart');
517        },
518
519        _move: function (e) {
520            if ( !this.enabled || utils.eventType[e.type] !== this.initiated ) {
521                return;
522            }
523
524            if ( this.options.preventDefault ) {	// increases performance on Android? TODO: check!
525                e.preventDefault();
526            }
527
528            var point		= e.touches ? e.touches[0] : e,
529                deltaX		= point.pageX - this.pointX,
530                deltaY		= point.pageY - this.pointY,
531                timestamp	= utils.getTime(),
532                newX, newY,
533                absDistX, absDistY;
534
535            this.pointX		= point.pageX;
536            this.pointY		= point.pageY;
537
538            this.distX		+= deltaX;
539            this.distY		+= deltaY;
540            absDistX		= Math.abs(this.distX);
541            absDistY		= Math.abs(this.distY);
542
543            // We need to move at least 10 pixels for the scrolling to initiate
544            if ( timestamp - this.endTime > 300 && (absDistX < 10 && absDistY < 10) ) {
545                return;
546            }
547
548            // If you are scrolling in one direction lock the other
549            if ( !this.directionLocked && !this.options.freeScroll ) {
550                if ( absDistX > absDistY + this.options.directionLockThreshold ) {
vendor: 4,206 bytes, lines 551-668
551                    this.directionLocked = 'h';		// lock horizontally
552                } else if ( absDistY >= absDistX + this.options.directionLockThreshold ) {
553                    this.directionLocked = 'v';		// lock vertically
554                } else {
555                    this.directionLocked = 'n';		// no lock
556                }
557            }
558
559            if ( this.directionLocked == 'h' ) {
560                if ( this.options.eventPassthrough == 'vertical' ) {
561                    e.preventDefault();
562                } else if ( this.options.eventPassthrough == 'horizontal' ) {
563                    this.initiated = false;
564                    return;
565                }
566
567                deltaY = 0;
568            } else if ( this.directionLocked == 'v' ) {
569                if ( this.options.eventPassthrough == 'horizontal' ) {
570                    e.preventDefault();
571                } else if ( this.options.eventPassthrough == 'vertical' ) {
572                    this.initiated = false;
573                    return;
574                }
575
576                deltaX = 0;
577            }
578
579            deltaX = this.hasHorizontalScroll ? deltaX : 0;
580            deltaY = this.hasVerticalScroll ? deltaY : 0;
581
582            newX = this.x + deltaX;
583            newY = this.y + deltaY;
584
585            // Slow down if outside of the boundaries
586            if ( newX > 0 || newX < this.maxScrollX ) {
587                newX = this.options.bounce ? this.x + deltaX / 3 : newX > 0 ? 0 : this.maxScrollX;
588            }
589            if ( newY > 0 || newY < this.maxScrollY ) {
590                newY = this.options.bounce ? this.y + deltaY / 3 : newY > 0 ? 0 : this.maxScrollY;
591            }
592
593            this.directionX = deltaX > 0 ? -1 : deltaX < 0 ? 1 : 0;
594            this.directionY = deltaY > 0 ? -1 : deltaY < 0 ? 1 : 0;
595
596            if ( !this.moved ) {
597                this._execEvent('scrollStart');
598            }
599
600            this.moved = true;
601
602            this._translate(newX, newY);
603
604            /* REPLACE START: _move */
605
606            if ( timestamp - this.startTime > 300 ) {
607                this.startTime = timestamp;
608                this.startX = this.x;
609                this.startY = this.y;
610            }
611
612            /* REPLACE END: _move */
613
614        },
615
616        _end: function (e) {
617            if ( !this.enabled || utils.eventType[e.type] !== this.initiated ) {
618                return;
619            }
620
621            if ( this.options.preventDefault && !utils.preventDefaultException(e.target, this.options.preventDefaultException) ) {
622                // e.preventDefault();
623            }
624
625            var point = e.changedTouches ? e.changedTouches[0] : e,
626                momentumX,
627                momentumY,
628                duration = utils.getTime() - this.startTime,
629                newX = Math.round(this.x),
630                newY = Math.round(this.y),
631                distanceX = Math.abs(newX - this.startX),
632                distanceY = Math.abs(newY - this.startY),
633                time = 0,
634                easing = '';
635
636            this.isInTransition = 0;
637            this.initiated = 0;
638            this.endTime = utils.getTime();
639
640            // reset if we are outside of the boundaries
641            if ( this.resetPosition(this.options.bounceTime) ) {
642                return;
643            }
644
645            this.scrollTo(newX, newY);	// ensures that the last position is rounded
646
647            // we scrolled less than 10 pixels
648            if ( !this.moved ) {
649                if ( this.options.tap ) {
650                    utils.tap(e, this.options.tap);
651                }
652
653                if ( this.options.click ) {
654                    utils.click(e);
655                }
656
657                this._execEvent('scrollCancel');
658                return;
659            }
660
661            if ( this._events.flick && duration < 200 && distanceX < 100 && distanceY < 100 ) {
662                this._execEvent('flick');
663                return;
664            }
665
666            // start momentum animation if needed
667            if ( this.options.momentum && duration < 300 ) {
668                momentumX = this.hasHorizontalScroll ? utils.momentum(this.x, this.startX, duration, this.maxScrollX, this.options.bounce ? this.wrapperW
vendor: 4,675 bytes, lines 668-806
668idth : 0, this.options.deceleration) : { destination: newX, duration: 0 };
669                momentumY = this.hasVerticalScroll ? utils.momentum(this.y, this.startY, duration, this.maxScrollY, this.options.bounce ? this.wrapperHeight : 0, this.options.deceleration) : { destination: newY, duration: 0 };
670                newX = momentumX.destination;
671                newY = momentumY.destination;
672                time = Math.max(momentumX.duration, momentumY.duration);
673                this.isInTransition = 1;
674            }
675
676
677            if ( this.options.snap ) {
678                var snap = this._nearestSnap(newX, newY);
679                this.currentPage = snap;
680                time = this.options.snapSpeed || Math.max(
681                    Math.max(
682                        Math.min(Math.abs(newX - snap.x), 1000),
683                        Math.min(Math.abs(newY - snap.y), 1000)
684                    ), 300);
685                newX = snap.x;
686                newY = snap.y;
687
688                this.directionX = 0;
689                this.directionY = 0;
690                easing = this.options.bounceEasing;
691            }
692
693// INSERT POINT: _end
694
695            if ( newX != this.x || newY != this.y ) {
696                // change easing function when scroller goes out of the boundaries
697                if ( newX > 0 || newX < this.maxScrollX || newY > 0 || newY < this.maxScrollY ) {
698                    easing = utils.ease.quadratic;
699                }
700
701                this.scrollTo(newX, newY, time, easing);
702                return;
703            }
704
705            this._execEvent('scrollEnd');
706        },
707
708        _resize: function () {
709            var that = this;
710
711            clearTimeout(this.resizeTimeout);
712
713            this.resizeTimeout = setTimeout(function () {
714                that.refresh();
715            }, this.options.resizePolling);
716        },
717
718        resetPosition: function (time) {
719            var x = this.x,
720                y = this.y;
721
722            time = time || 0;
723
724            if ( !this.hasHorizontalScroll || this.x > 0 ) {
725                x = 0;
726            } else if ( this.x < this.maxScrollX ) {
727                x = this.maxScrollX;
728            }
729
730            if ( !this.hasVerticalScroll || this.y > 0 ) {
731                y = 0;
732            } else if ( this.y < this.maxScrollY ) {
733                y = this.maxScrollY;
734            }
735
736            if ( x == this.x && y == this.y ) {
737                return false;
738            }
739
740            this.scrollTo(x, y, time, this.options.bounceEasing);
741
742            return true;
743        },
744
745        disable: function () {
746            this.enabled = false;
747        },
748
749        enable: function () {
750            this.enabled = true;
751        },
752
753        refresh: function () {
754            utils.getRect(this.wrapper);		// Force reflow
755
756            this.wrapperWidth	= this.wrapper.clientWidth;
757            this.wrapperHeight	= this.wrapper.clientHeight;
758
759            var rect = utils.getRect(this.scroller);
760            /* REPLACE START: refresh */
761
762            this.scrollerWidth	= rect.width;
763            this.scrollerHeight	= rect.height;
764
765            this.maxScrollX		= this.wrapperWidth - this.scrollerWidth;
766            this.maxScrollY		= this.wrapperHeight - this.scrollerHeight;
767
768            /* REPLACE END: refresh */
769
770            this.hasHorizontalScroll	= this.options.scrollX && this.maxScrollX < 0;
771            this.hasVerticalScroll		= this.options.scrollY && this.maxScrollY < 0;
772
773            if ( !this.hasHorizontalScroll ) {
774                this.maxScrollX = 0;
775                this.scrollerWidth = this.wrapperWidth;
776            }
777
778            if ( !this.hasVerticalScroll ) {
779                this.maxScrollY = 0;
780                this.scrollerHeight = this.wrapperHeight;
781            }
782
783            this.endTime = 0;
784            this.directionX = 0;
785            this.directionY = 0;
786
787            if(utils.hasPointer && !this.options.disablePointer) {
788                // The wrapper should have `touchAction` property for using pointerEvent.
789                this.wrapper.style[utils.style.touchAction] = utils.getTouchAction(this.options.eventPassthrough, true);
790
791                // case. not support 'pinch-zoom'
792                // https://github.com/cubiq/iscroll/issues/1118#issuecomment-270057583
793                if (!this.wrapper.style[utils.style.touchAction]) {
794                    this.wrapper.style[utils.style.touchAction] = utils.getTouchAction(this.options.eventPassthrough, false);
795                }
796            }
797            this.wrapperOffset = utils.offset(this.wrapper);
798
799            this._execEvent('refresh');
800
801            this.resetPosition();
802
803// INSERT POINT: _refresh
804
805        },
806
vendor: 15,305 bytes, lines 807-1262
807        on: function (type, fn) {
808            if ( !this._events[type] ) {
809                this._events[type] = [];
810            }
811
812            this._events[type].push(fn);
813        },
814
815        off: function (type, fn) {
816            if ( !this._events[type] ) {
817                return;
818            }
819
820            var index = this._events[type].indexOf(fn);
821
822            if ( index > -1 ) {
823                this._events[type].splice(index, 1);
824            }
825        },
826
827        _execEvent: function (type) {
828            if ( !this._events[type] ) {
829                return;
830            }
831
832            var i = 0,
833                l = this._events[type].length;
834
835            if ( !l ) {
836                return;
837            }
838
839            for ( ; i < l; i++ ) {
840                this._events[type][i].apply(this, [].slice.call(arguments, 1));
841            }
842        },
843
844        scrollBy: function (x, y, time, easing) {
845            x = this.x + x;
846            y = this.y + y;
847            time = time || 0;
848
849            this.scrollTo(x, y, time, easing);
850        },
851
852        scrollTo: function (x, y, time, easing) {
853            easing = easing || utils.ease.circular;
854
855            this.isInTransition = this.options.useTransition && time > 0;
856            var transitionType = this.options.useTransition && easing.style;
857            if ( !time || transitionType ) {
858                if(transitionType) {
859                    this._transitionTimingFunction(easing.style);
860                    this._transitionTime(time);
861                }
862                this._translate(x, y);
863            } else {
864                this._animate(x, y, time, easing.fn);
865            }
866        },
867
868        scrollToElement: function (el, time, offsetX, offsetY, easing) {
869            el = el.nodeType ? el : this.scroller.querySelector(el);
870
871            if ( !el ) {
872                return;
873            }
874
875            var pos = utils.offset(el);
876
877            pos.left -= this.wrapperOffset.left;
878            pos.top  -= this.wrapperOffset.top;
879
880            // if offsetX/Y are true we center the element to the screen
881            var elRect = utils.getRect(el);
882            var wrapperRect = utils.getRect(this.wrapper);
883            if ( offsetX === true ) {
884                offsetX = Math.round(elRect.width / 2 - wrapperRect.width / 2);
885            }
886            if ( offsetY === true ) {
887                offsetY = Math.round(elRect.height / 2 - wrapperRect.height / 2);
888            }
889
890            pos.left -= offsetX || 0;
891            pos.top  -= offsetY || 0;
892
893            pos.left = pos.left > 0 ? 0 : pos.left < this.maxScrollX ? this.maxScrollX : pos.left;
894            pos.top  = pos.top  > 0 ? 0 : pos.top  < this.maxScrollY ? this.maxScrollY : pos.top;
895
896            time = time === undefined || time === null || time === 'auto' ? Math.max(Math.abs(this.x-pos.left), Math.abs(this.y-pos.top)) : time;
897
898            this.scrollTo(pos.left, pos.top, time, easing);
899        },
900
901        _transitionTime: function (time) {
902            if (!this.options.useTransition) {
903                return;
904            }
905            time = time || 0;
906            var durationProp = utils.style.transitionDuration;
907            if(!durationProp) {
908                return;
909            }
910
911            this.scrollerStyle[durationProp] = time + 'ms';
912
913            if ( !time && utils.isBadAndroid ) {
914                this.scrollerStyle[durationProp] = '0.0001ms';
915                // remove 0.0001ms
916                var self = this;
917                rAF(function() {
918                    if(self.scrollerStyle[durationProp] === '0.0001ms') {
919                        self.scrollerStyle[durationProp] = '0s';
920                    }
921                });
922            }
923
924
925            if ( this.indicators ) {
926                for ( var i = this.indicators.length; i--; ) {
927                    this.indicators[i].transitionTime(time);
928                }
929            }
930
931
932// INSERT POINT: _transitionTime
933
934        },
935
936        _transitionTimingFunction: function (easing) {
937            this.scrollerStyle[utils.style.transitionTimingFunction] = easing;
938
939
940            if ( this.indicators ) {
941                for ( var i = this.indicators.length; i--; ) {
942                    this.indicators[i].transitionTimingFunction(easing);
943                }
944            }
945
946
947// INSERT POINT: _transitionTimingFunction
948
949        },
950
951        _translate: function (x, y) {
952            if ( this.options.useTransform ) {
953
954                /* REPLACE START: _translate */
955
956                this.scrollerStyle[utils.style.transform] = 'translate(' + x + 'px,' + y + 'px)' + this.translateZ;
957
958                /* REPLACE END: _translate */
959
960            } else {
961                x = Math.round(x);
962                y = Math.round(y);
963                this.scrollerStyle.left = x + 'px';
964                this.scrollerStyle.top = y + 'px';
965            }
966
967            this.x = x;
968            this.y = y;
969
970
971            if ( this.indicators ) {
972                for ( var i = this.indicators.length; i--; ) {
973                    this.indicators[i].updatePosition();
974                }
975            }
976
977
978// INSERT POINT: _translate
979
980        },
981
982        _initEvents: function (remove) {
983            var eventType = remove ? utils.removeEvent : utils.addEvent,
984                target = this.options.bindToWrapper ? this.wrapper : window;
985
986            eventType(window, 'orientationchange', this);
987            eventType(window, 'resize', this);
988
989            if ( this.options.click ) {
990                eventType(this.wrapper, 'click', this, true);
991            }
992
993            if ( !this.options.disableMouse ) {
994                eventType(this.wrapper, 'mousedown', this);
995                eventType(target, 'mousemove', this);
996                eventType(target, 'mousecancel', this);
997                eventType(target, 'mouseup', this);
998            }
999
1000            if ( utils.hasPointer && !this.options.disablePointer ) {
1001                eventType(this.wrapper, utils.prefixPointerEvent('pointerdown'), this);
1002                eventType(target, utils.prefixPointerEvent('pointermove'), this);
1003                eventType(target, utils.prefixPointerEvent('pointercancel'), this);
1004                eventType(target, utils.prefixPointerEvent('pointerup'), this);
1005            }
1006
1007            if ( utils.hasTouch && !this.options.disableTouch ) {
1008                eventType(this.wrapper, 'touchstart', this);
1009                eventType(target, 'touchmove', this);
1010                eventType(target, 'touchcancel', this);
1011                eventType(target, 'touchend', this);
1012            }
1013
1014            eventType(this.scroller, 'transitionend', this);
1015            eventType(this.scroller, 'webkitTransitionEnd', this);
1016            eventType(this.scroller, 'oTransitionEnd', this);
1017            eventType(this.scroller, 'MSTransitionEnd', this);
1018        },
1019
1020        getComputedPosition: function () {
1021            var matrix = window.getComputedStyle(this.scroller, null),
1022                x, y;
1023
1024            if ( this.options.useTransform ) {
1025                matrix = matrix[utils.style.transform].split(')')[0].split(', ');
1026                x = +(matrix[12] || matrix[4]);
1027                y = +(matrix[13] || matrix[5]);
1028            } else {
1029                x = +matrix.left.replace(/[^-\d.]/g, '');
1030                y = +matrix.top.replace(/[^-\d.]/g, '');
1031            }
1032
1033            return { x: x, y: y };
1034        },
1035        _initIndicators: function () {
1036            var interactive = this.options.interactiveScrollbars,
1037                customStyle = typeof this.options.scrollbars != 'string',
1038                indicators = [],
1039                indicator;
1040
1041            var that = this;
1042
1043            this.indicators = [];
1044
1045            if ( this.options.scrollbars ) {
1046                // Vertical scrollbar
1047                if ( this.options.scrollY ) {
1048                    indicator = {
1049                        el: createDefaultScrollbar('v', interactive, this.options.scrollbars),
1050                        interactive: interactive,
1051                        defaultScrollbars: true,
1052                        customStyle: customStyle,
1053                        resize: this.options.resizeScrollbars,
1054                        shrink: this.options.shrinkScrollbars,
1055                        fade: this.options.fadeScrollbars,
1056                        listenX: false
1057                    };
1058
1059                    this.wrapper.appendChild(indicator.el);
1060                    indicators.push(indicator);
1061                }
1062
1063                // Horizontal scrollbar
1064                if ( this.options.scrollX ) {
1065                    indicator = {
1066                        el: createDefaultScrollbar('h', interactive, this.options.scrollbars),
1067                        interactive: interactive,
1068                        defaultScrollbars: true,
1069                        customStyle: customStyle,
1070                        resize: this.options.resizeScrollbars,
1071                        shrink: this.options.shrinkScrollbars,
1072                        fade: this.options.fadeScrollbars,
1073                        listenY: false
1074                    };
1075
1076                    this.wrapper.appendChild(indicator.el);
1077                    indicators.push(indicator);
1078                }
1079            }
1080
1081            if ( this.options.indicators ) {
1082                // TODO: check concat compatibility
1083                indicators = indicators.concat(this.options.indicators);
1084            }
1085
1086            for ( var i = indicators.length; i--; ) {
1087                this.indicators.push( new Indicator(this, indicators[i]) );
1088            }
1089
1090            // TODO: check if we can use array.map (wide compatibility and performance issues)
1091            function _indicatorsMap (fn) {
1092                if (that.indicators) {
1093                    for ( var i = that.indicators.length; i--; ) {
1094                        fn.call(that.indicators[i]);
1095                    }
1096                }
1097            }
1098
1099            if ( this.options.fadeScrollbars ) {
1100                this.on('scrollEnd', function () {
1101                    _indicatorsMap(function () {
1102                        this.fade();
1103                    });
1104                });
1105
1106                this.on('scrollCancel', function () {
1107                    _indicatorsMap(function () {
1108                        this.fade();
1109                    });
1110                });
1111
1112                this.on('scrollStart', function () {
1113                    _indicatorsMap(function () {
1114                        this.fade(1);
1115                    });
1116                });
1117
1118                this.on('beforeScrollStart', function () {
1119                    _indicatorsMap(function () {
1120                        this.fade(1, true);
1121                    });
1122                });
1123            }
1124
1125
1126            this.on('refresh', function () {
1127                _indicatorsMap(function () {
1128                    this.refresh();
1129                });
1130            });
1131
1132            this.on('destroy', function () {
1133                _indicatorsMap(function () {
1134                    this.destroy();
1135                });
1136
1137                delete this.indicators;
1138            });
1139        },
1140
1141        _initWheel: function () {
1142            utils.addEvent(this.wrapper, 'wheel', this);
1143            utils.addEvent(this.wrapper, 'mousewheel', this);
1144            utils.addEvent(this.wrapper, 'DOMMouseScroll', this);
1145
1146            this.on('destroy', function () {
1147                clearTimeout(this.wheelTimeout);
1148                this.wheelTimeout = null;
1149                utils.removeEvent(this.wrapper, 'wheel', this);
1150                utils.removeEvent(this.wrapper, 'mousewheel', this);
1151                utils.removeEvent(this.wrapper, 'DOMMouseScroll', this);
1152            });
1153        },
1154
1155        _wheel: function (e) {
1156            if ( !this.enabled ) {
1157                return;
1158            }
1159
1160            e.preventDefault();
1161
1162            var wheelDeltaX, wheelDeltaY,
1163                newX, newY,
1164                that = this;
1165
1166            if ( this.wheelTimeout === undefined ) {
1167                that._execEvent('scrollStart');
1168            }
1169
1170            // Execute the scrollEnd event after 400ms the wheel stopped scrolling
1171            clearTimeout(this.wheelTimeout);
1172            this.wheelTimeout = setTimeout(function () {
1173                if(!that.options.snap) {
1174                    that._execEvent('scrollEnd');
1175                }
1176                that.wheelTimeout = undefined;
1177            }, 400);
1178
1179            if ( 'deltaX' in e ) {
1180                if (e.deltaMode === 1) {
1181                    wheelDeltaX = -e.deltaX * this.options.mouseWheelSpeed;
1182                    wheelDeltaY = -e.deltaY * this.options.mouseWheelSpeed;
1183                } else {
1184                    wheelDeltaX = -e.deltaX;
1185                    wheelDeltaY = -e.deltaY;
1186                }
1187            } else if ( 'wheelDeltaX' in e ) {
1188                wheelDeltaX = e.wheelDeltaX / 120 * this.options.mouseWheelSpeed;
1189                wheelDeltaY = e.wheelDeltaY / 120 * this.options.mouseWheelSpeed;
1190            } else if ( 'wheelDelta' in e ) {
1191                wheelDeltaX = wheelDeltaY = e.wheelDelta / 120 * this.options.mouseWheelSpeed;
1192            } else if ( 'detail' in e ) {
1193                wheelDeltaX = wheelDeltaY = -e.detail / 3 * this.options.mouseWheelSpeed;
1194            } else {
1195                return;
1196            }
1197
1198            wheelDeltaX *= this.options.invertWheelDirection;
1199            wheelDeltaY *= this.options.invertWheelDirection;
1200
1201            if ( !this.hasVerticalScroll ) {
1202                wheelDeltaX = wheelDeltaY;
1203                wheelDeltaY = 0;
1204            }
1205
1206            if ( this.options.snap ) {
1207                newX = this.currentPage.pageX;
1208                newY = this.currentPage.pageY;
1209
1210                if ( wheelDeltaX > 0 ) {
1211                    newX--;
1212                } else if ( wheelDeltaX < 0 ) {
1213                    newX++;
1214                }
1215
1216                if ( wheelDeltaY > 0 ) {
1217                    newY--;
1218                } else if ( wheelDeltaY < 0 ) {
1219                    newY++;
1220                }
1221
1222                this.goToPage(newX, newY);
1223
1224                return;
1225            }
1226
1227            newX = this.x + Math.round(this.hasHorizontalScroll ? wheelDeltaX : 0);
1228            newY = this.y + Math.round(this.hasVerticalScroll ? wheelDeltaY : 0);
1229
1230            this.directionX = wheelDeltaX > 0 ? -1 : wheelDeltaX < 0 ? 1 : 0;
1231            this.directionY = wheelDeltaY > 0 ? -1 : wheelDeltaY < 0 ? 1 : 0;
1232
1233            if ( newX > 0 ) {
1234                newX = 0;
1235            } else if ( newX < this.maxScrollX ) {
1236                newX = this.maxScrollX;
1237            }
1238
1239            if ( newY > 0 ) {
1240                newY = 0;
1241            } else if ( newY < this.maxScrollY ) {
1242                newY = this.maxScrollY;
1243            }
1244
1245            this.scrollTo(newX, newY, 0);
1246
1247// INSERT POINT: _wheel
1248        },
1249
1250        _initSnap: function () {
1251            this.currentPage = {};
1252
1253            if ( typeof this.options.snap == 'string' ) {
1254                this.options.snap = this.scroller.querySelectorAll(this.options.snap);
1255            }
1256
1257            this.on('refresh', function () {
1258                var i = 0, l,
1259                    m = 0, n,
1260                    cx, cy,
1261                    x = 0, y,
1262                    stepX = this.options.snapStepX || this.wrapperW
vendor: 12,299 bytes, lines 1262-1635
1262idth,
1263                    stepY = this.options.snapStepY || this.wrapperHeight,
1264                    el,
1265                    rect;
1266
1267                this.pages = [];
1268
1269                if ( !this.wrapperWidth || !this.wrapperHeight || !this.scrollerWidth || !this.scrollerHeight ) {
1270                    return;
1271                }
1272
1273                if ( this.options.snap === true ) {
1274                    cx = Math.round( stepX / 2 );
1275                    cy = Math.round( stepY / 2 );
1276
1277                    while ( x > -this.scrollerWidth ) {
1278                        this.pages[i] = [];
1279                        l = 0;
1280                        y = 0;
1281
1282                        while ( y > -this.scrollerHeight ) {
1283                            this.pages[i][l] = {
1284                                x: Math.max(x, this.maxScrollX),
1285                                y: Math.max(y, this.maxScrollY),
1286                                width: stepX,
1287                                height: stepY,
1288                                cx: x - cx,
1289                                cy: y - cy
1290                            };
1291
1292                            y -= stepY;
1293                            l++;
1294                        }
1295
1296                        x -= stepX;
1297                        i++;
1298                    }
1299                } else {
1300                    el = this.options.snap;
1301                    l = el.length;
1302                    n = -1;
1303
1304                    for ( ; i < l; i++ ) {
1305                        rect = utils.getRect(el[i]);
1306                        if ( i === 0 || rect.left <= utils.getRect(el[i-1]).left ) {
1307                            m = 0;
1308                            n++;
1309                        }
1310
1311                        if ( !this.pages[m] ) {
1312                            this.pages[m] = [];
1313                        }
1314
1315                        x = Math.max(-rect.left, this.maxScrollX);
1316                        y = Math.max(-rect.top, this.maxScrollY);
1317                        cx = x - Math.round(rect.width / 2);
1318                        cy = y - Math.round(rect.height / 2);
1319
1320                        this.pages[m][n] = {
1321                            x: x,
1322                            y: y,
1323                            width: rect.width,
1324                            height: rect.height,
1325                            cx: cx,
1326                            cy: cy
1327                        };
1328
1329                        if ( x > this.maxScrollX ) {
1330                            m++;
1331                        }
1332                    }
1333                }
1334
1335                this.goToPage(this.currentPage.pageX || 0, this.currentPage.pageY || 0, 0);
1336
1337                // Update snap threshold if needed
1338                if ( this.options.snapThreshold % 1 === 0 ) {
1339                    this.snapThresholdX = this.options.snapThreshold;
1340                    this.snapThresholdY = this.options.snapThreshold;
1341                } else {
1342                    this.snapThresholdX = Math.round(this.pages[this.currentPage.pageX][this.currentPage.pageY].width * this.options.snapThreshold);
1343                    this.snapThresholdY = Math.round(this.pages[this.currentPage.pageX][this.currentPage.pageY].height * this.options.snapThreshold);
1344                }
1345            });
1346
1347            this.on('flick', function () {
1348                var time = this.options.snapSpeed || Math.max(
1349                    Math.max(
1350                        Math.min(Math.abs(this.x - this.startX), 1000),
1351                        Math.min(Math.abs(this.y - this.startY), 1000)
1352                    ), 300);
1353
1354                this.goToPage(
1355                    this.currentPage.pageX + this.directionX,
1356                    this.currentPage.pageY + this.directionY,
1357                    time
1358                );
1359            });
1360        },
1361
1362        _nearestSnap: function (x, y) {
1363            if ( !this.pages.length ) {
1364                return { x: 0, y: 0, pageX: 0, pageY: 0 };
1365            }
1366
1367            var i = 0,
1368                l = this.pages.length,
1369                m = 0;
1370
1371            // Check if we exceeded the snap threshold
1372            if ( Math.abs(x - this.absStartX) < this.snapThresholdX &&
1373                Math.abs(y - this.absStartY) < this.snapThresholdY ) {
1374                return this.currentPage;
1375            }
1376
1377            if ( x > 0 ) {
1378                x = 0;
1379            } else if ( x < this.maxScrollX ) {
1380                x = this.maxScrollX;
1381            }
1382
1383            if ( y > 0 ) {
1384                y = 0;
1385            } else if ( y < this.maxScrollY ) {
1386                y = this.maxScrollY;
1387            }
1388
1389            for ( ; i < l; i++ ) {
1390                if ( x >= this.pages[i][0].cx ) {
1391                    x = this.pages[i][0].x;
1392                    break;
1393                }
1394            }
1395
1396            l = this.pages[i].length;
1397
1398            for ( ; m < l; m++ ) {
1399                if ( y >= this.pages[0][m].cy ) {
1400                    y = this.pages[0][m].y;
1401                    break;
1402                }
1403            }
1404
1405            if ( i == this.currentPage.pageX ) {
1406                i += this.directionX;
1407
1408                if ( i < 0 ) {
1409                    i = 0;
1410                } else if ( i >= this.pages.length ) {
1411                    i = this.pages.length - 1;
1412                }
1413
1414                x = this.pages[i][0].x;
1415            }
1416
1417            if ( m == this.currentPage.pageY ) {
1418                m += this.directionY;
1419
1420                if ( m < 0 ) {
1421                    m = 0;
1422                } else if ( m >= this.pages[0].length ) {
1423                    m = this.pages[0].length - 1;
1424                }
1425
1426                y = this.pages[0][m].y;
1427            }
1428
1429            return {
1430                x: x,
1431                y: y,
1432                pageX: i,
1433                pageY: m
1434            };
1435        },
1436
1437        goToPage: function (x, y, time, easing) {
1438            easing = easing || this.options.bounceEasing;
1439
1440            if ( x >= this.pages.length ) {
1441                x = this.pages.length - 1;
1442            } else if ( x < 0 ) {
1443                x = 0;
1444            }
1445
1446            if ( y >= this.pages[x].length ) {
1447                y = this.pages[x].length - 1;
1448            } else if ( y < 0 ) {
1449                y = 0;
1450            }
1451
1452            var posX = this.pages[x][y].x,
1453                posY = this.pages[x][y].y;
1454
1455            time = time === undefined ? this.options.snapSpeed || Math.max(
1456                Math.max(
1457                    Math.min(Math.abs(posX - this.x), 1000),
1458                    Math.min(Math.abs(posY - this.y), 1000)
1459                ), 300) : time;
1460
1461            this.currentPage = {
1462                x: posX,
1463                y: posY,
1464                pageX: x,
1465                pageY: y
1466            };
1467
1468            this.scrollTo(posX, posY, time, easing);
1469        },
1470
1471        next: function (time, easing) {
1472            var x = this.currentPage.pageX,
1473                y = this.currentPage.pageY;
1474
1475            x++;
1476
1477            if ( x >= this.pages.length && this.hasVerticalScroll ) {
1478                x = 0;
1479                y++;
1480            }
1481
1482            this.goToPage(x, y, time, easing);
1483        },
1484
1485        prev: function (time, easing) {
1486            var x = this.currentPage.pageX,
1487                y = this.currentPage.pageY;
1488
1489            x--;
1490
1491            if ( x < 0 && this.hasVerticalScroll ) {
1492                x = 0;
1493                y--;
1494            }
1495
1496            this.goToPage(x, y, time, easing);
1497        },
1498
1499        _initKeys: function (e) {
1500            // default key bindings
1501            var keys = {
1502                pageUp: 33,
1503                pageDown: 34,
1504                end: 35,
1505                home: 36,
1506                left: 37,
1507                up: 38,
1508                right: 39,
1509                down: 40
1510            };
1511            var i;
1512
1513            // if you give me characters I give you keycode
1514            if ( typeof this.options.keyBindings == 'object' ) {
1515                for ( i in this.options.keyBindings ) {
1516                    if ( typeof this.options.keyBindings[i] == 'string' ) {
1517                        this.options.keyBindings[i] = this.options.keyBindings[i].toUpperCase().charCodeAt(0);
1518                    }
1519                }
1520            } else {
1521                this.options.keyBindings = {};
1522            }
1523
1524            for ( i in keys ) {
1525                this.options.keyBindings[i] = this.options.keyBindings[i] || keys[i];
1526            }
1527
1528            utils.addEvent(window, 'keydown', this);
1529
1530            this.on('destroy', function () {
1531                utils.removeEvent(window, 'keydown', this);
1532            });
1533        },
1534
1535        _key: function (e) {
1536            if ( !this.enabled ) {
1537                return;
1538            }
1539
1540            var snap = this.options.snap,	// we are using this alot, better to cache it
1541                newX = snap ? this.currentPage.pageX : this.x,
1542                newY = snap ? this.currentPage.pageY : this.y,
1543                now = utils.getTime(),
1544                prevTime = this.keyTime || 0,
1545                acceleration = 0.250,
1546                pos;
1547
1548            if ( this.options.useTransition && this.isInTransition ) {
1549                pos = this.getComputedPosition();
1550
1551                this._translate(Math.round(pos.x), Math.round(pos.y));
1552                this.isInTransition = false;
1553            }
1554
1555            this.keyAcceleration = now - prevTime < 200 ? Math.min(this.keyAcceleration + acceleration, 50) : 0;
1556
1557            switch ( e.keyCode ) {
1558                case this.options.keyBindings.pageUp:
1559                    if ( this.hasHorizontalScroll && !this.hasVerticalScroll ) {
1560                        newX += snap ? 1 : this.wrapperWidth;
1561                    } else {
1562                        newY += snap ? 1 : this.wrapperHeight;
1563                    }
1564                    break;
1565                case this.options.keyBindings.pageDown:
1566                    if ( this.hasHorizontalScroll && !this.hasVerticalScroll ) {
1567                        newX -= snap ? 1 : this.wrapperWidth;
1568                    } else {
1569                        newY -= snap ? 1 : this.wrapperHeight;
1570                    }
1571                    break;
1572                case this.options.keyBindings.end:
1573                    newX = snap ? this.pages.length-1 : this.maxScrollX;
1574                    newY = snap ? this.pages[0].length-1 : this.maxScrollY;
1575                    break;
1576                case this.options.keyBindings.home:
1577                    newX = 0;
1578                    newY = 0;
1579                    break;
1580                case this.options.keyBindings.left:
1581                    newX += snap ? -1 : 5 + this.keyAcceleration>>0;
1582                    break;
1583                case this.options.keyBindings.up:
1584                    newY += snap ? 1 : 5 + this.keyAcceleration>>0;
1585                    break;
1586                case this.options.keyBindings.right:
1587                    newX -= snap ? -1 : 5 + this.keyAcceleration>>0;
1588                    break;
1589                case this.options.keyBindings.down:
1590                    newY -= snap ? 1 : 5 + this.keyAcceleration>>0;
1591                    break;
1592                default:
1593                    return;
1594            }
1595
1596            if ( snap ) {
1597                this.goToPage(newX, newY);
1598                return;
1599            }
1600
1601            if ( newX > 0 ) {
1602                newX = 0;
1603                this.keyAcceleration = 0;
1604            } else if ( newX < this.maxScrollX ) {
1605                newX = this.maxScrollX;
1606                this.keyAcceleration = 0;
1607            }
1608
1609            if ( newY > 0 ) {
1610                newY = 0;
1611                this.keyAcceleration = 0;
1612            } else if ( newY < this.maxScrollY ) {
1613                newY = this.maxScrollY;
1614                this.keyAcceleration = 0;
1615            }
1616
1617            this.scrollTo(newX, newY, 0);
1618
1619            this.keyTime = now;
1620        },
1621
1622        _animate: function (destX, destY, duration, easingFn) {
1623            var that = this,
1624                startX = this.x,
1625                startY = this.y,
1626                startTime = utils.getTime(),
1627                destTime = startTime + duration;
1628
1629            function step () {
1630                var now = utils.getTime(),
1631                    newX, newY,
1632                    easing;
1633
1634                if ( now >= destTime ) {
1635                    that.isAnimating = false;
vendor: 8,178 bytes, lines 1636-1870
1636                    that._translate(destX, destY);
1637
1638                    if ( !that.resetPosition(that.options.bounceTime) ) {
1639                        that._execEvent('scrollEnd');
1640                    }
1641
1642                    return;
1643                }
1644
1645                now = ( now - startTime ) / duration;
1646                easing = easingFn(now);
1647                newX = ( destX - startX ) * easing + startX;
1648                newY = ( destY - startY ) * easing + startY;
1649                that._translate(newX, newY);
1650
1651                if ( that.isAnimating ) {
1652                    rAF(step);
1653                }
1654            }
1655
1656            this.isAnimating = true;
1657            step();
1658        },
1659        handleEvent: function (e) {
1660            switch ( e.type ) {
1661                case 'touchstart':
1662                case 'pointerdown':
1663                case 'MSPointerDown':
1664                case 'mousedown':
1665                    this._start(e);
1666                    break;
1667                case 'touchmove':
1668                case 'pointermove':
1669                case 'MSPointerMove':
1670                case 'mousemove':
1671                    this._move(e);
1672                    break;
1673                case 'touchend':
1674                case 'pointerup':
1675                case 'MSPointerUp':
1676                case 'mouseup':
1677                case 'touchcancel':
1678                case 'pointercancel':
1679                case 'MSPointerCancel':
1680                case 'mousecancel':
1681                    this._end(e);
1682                    break;
1683                case 'orientationchange':
1684                case 'resize':
1685                    this._resize();
1686                    break;
1687                case 'transitionend':
1688                case 'webkitTransitionEnd':
1689                case 'oTransitionEnd':
1690                case 'MSTransitionEnd':
1691                    this._transitionEnd(e);
1692                    break;
1693                case 'wheel':
1694                case 'DOMMouseScroll':
1695                case 'mousewheel':
1696                    this._wheel(e);
1697                    break;
1698                case 'keydown':
1699                    this._key(e);
1700                    break;
1701                case 'click':
1702                    if ( this.enabled && !e._constructed ) {
1703                        e.preventDefault();
1704                        e.stopPropagation();
1705                    }
1706                    break;
1707            }
1708        }
1709    };
1710    function createDefaultScrollbar (direction, interactive, type) {
1711        var scrollbar = document.createElement('div'),
1712            indicator = document.createElement('div');
1713
1714        if ( type === true ) {
1715            scrollbar.style.cssText = 'position:absolute;z-index:9999';
1716            indicator.style.cssText = '-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;position:absolute;background:rgba(0,0,0,0.5);border:1px solid rgba(255,255,255,0.9);border-radius:3px';
1717        }
1718
1719        indicator.className = 'iScrollIndicator';
1720
1721        if ( direction == 'h' ) {
1722            if ( type === true ) {
1723                scrollbar.style.cssText += ';height:7px;left:2px;right:2px;bottom:0';
1724                indicator.style.height = '100%';
1725            }
1726            scrollbar.className = 'iScrollHorizontalScrollbar';
1727        } else {
1728            if ( type === true ) {
1729                scrollbar.style.cssText += ';width:7px;bottom:2px;top:2px;right:1px';
1730                indicator.style.width = '100%';
1731            }
1732            scrollbar.className = 'iScrollVerticalScrollbar';
1733        }
1734
1735        scrollbar.style.cssText += ';overflow:hidden';
1736
1737        if ( !interactive ) {
1738            scrollbar.style.pointerEvents = 'none';
1739        }
1740
1741        scrollbar.appendChild(indicator);
1742
1743        return scrollbar;
1744    }
1745
1746    function Indicator (scroller, options) {
1747        this.wrapper = typeof options.el == 'string' ? document.querySelector(options.el) : options.el;
1748        this.wrapperStyle = this.wrapper.style;
1749        this.indicator = this.wrapper.children[0];
1750        this.indicatorStyle = this.indicator.style;
1751        this.scroller = scroller;
1752
1753        this.options = {
1754            listenX: true,
1755            listenY: true,
1756            interactive: false,
1757            resize: true,
1758            defaultScrollbars: false,
1759            shrink: false,
1760            fade: false,
1761            speedRatioX: 0,
1762            speedRatioY: 0
1763        };
1764
1765        for ( var i in options ) {
1766            this.options[i] = options[i];
1767        }
1768
1769        this.sizeRatioX = 1;
1770        this.sizeRatioY = 1;
1771        this.maxPosX = 0;
1772        this.maxPosY = 0;
1773
1774        if ( this.options.interactive ) {
1775            if ( !this.options.disableTouch ) {
1776                utils.addEvent(this.indicator, 'touchstart', this);
1777                utils.addEvent(window, 'touchend', this);
1778            }
1779            if ( !this.options.disablePointer ) {
1780                utils.addEvent(this.indicator, utils.prefixPointerEvent('pointerdown'), this);
1781                utils.addEvent(window, utils.prefixPointerEvent('pointerup'), this);
1782            }
1783            if ( !this.options.disableMouse ) {
1784                utils.addEvent(this.indicator, 'mousedown', this);
1785                utils.addEvent(window, 'mouseup', this);
1786            }
1787        }
1788
1789        if ( this.options.fade ) {
1790            this.wrapperStyle[utils.style.transform] = this.scroller.translateZ;
1791            var durationProp = utils.style.transitionDuration;
1792            if(!durationProp) {
1793                return;
1794            }
1795            this.wrapperStyle[durationProp] = utils.isBadAndroid ? '0.0001ms' : '0ms';
1796            // remove 0.0001ms
1797            var self = this;
1798            if(utils.isBadAndroid) {
1799                rAF(function() {
1800                    if(self.wrapperStyle[durationProp] === '0.0001ms') {
1801                        self.wrapperStyle[durationProp] = '0s';
1802                    }
1803                });
1804            }
1805            this.wrapperStyle.opacity = '0';
1806        }
1807    }
1808
1809    Indicator.prototype = {
1810        handleEvent: function (e) {
1811            switch ( e.type ) {
1812                case 'touchstart':
1813                case 'pointerdown':
1814                case 'MSPointerDown':
1815                case 'mousedown':
1816                    this._start(e);
1817                    break;
1818                case 'touchmove':
1819                case 'pointermove':
1820                case 'MSPointerMove':
1821                case 'mousemove':
1822                    this._move(e);
1823                    break;
1824                case 'touchend':
1825                case 'pointerup':
1826                case 'MSPointerUp':
1827                case 'mouseup':
1828                case 'touchcancel':
1829                case 'pointercancel':
1830                case 'MSPointerCancel':
1831                case 'mousecancel':
1832                    this._end(e);
1833                    break;
1834            }
1835        },
1836
1837        destroy: function () {
1838            if ( this.options.fadeScrollbars ) {
1839                clearTimeout(this.fadeTimeout);
1840                this.fadeTimeout = null;
1841            }
1842            if ( this.options.interactive ) {
1843                utils.removeEvent(this.indicator, 'touchstart', this);
1844                utils.removeEvent(this.indicator, utils.prefixPointerEvent('pointerdown'), this);
1845                utils.removeEvent(this.indicator, 'mousedown', this);
1846
1847                utils.removeEvent(window, 'touchmove', this);
1848                utils.removeEvent(window, utils.prefixPointerEvent('pointermove'), this);
1849                utils.removeEvent(window, 'mousemove', this);
1850
1851                utils.removeEvent(window, 'touchend', this);
1852                utils.removeEvent(window, utils.prefixPointerEvent('pointerup'), this);
1853                utils.removeEvent(window, 'mouseup', this);
1854            }
1855
1856            if ( this.options.defaultScrollbars && this.wrapper.parentNode ) {
1857                this.wrapper.parentNode.removeChild(this.wrapper);
1858            }
1859        },
1860
1861        _start: function (e) {
1862            var point = e.touches ? e.touches[0] : e;
1863
1864            e.preventDefault();
1865            e.stopPropagation();
1866
1867            this.transitionTime();
1868
1869            this.initiated = true;
1870            this.moved = false;
vendor: 11,605 bytes, lines 1871-2170
1871            this.lastPointX	= point.pageX;
1872            this.lastPointY	= point.pageY;
1873
1874            this.startTime	= utils.getTime();
1875
1876            if ( !this.options.disableTouch ) {
1877                utils.addEvent(window, 'touchmove', this);
1878            }
1879            if ( !this.options.disablePointer ) {
1880                utils.addEvent(window, utils.prefixPointerEvent('pointermove'), this);
1881            }
1882            if ( !this.options.disableMouse ) {
1883                utils.addEvent(window, 'mousemove', this);
1884            }
1885
1886            this.scroller._execEvent('beforeScrollStart');
1887        },
1888
1889        _move: function (e) {
1890            var point = e.touches ? e.touches[0] : e,
1891                deltaX, deltaY,
1892                newX, newY,
1893                timestamp = utils.getTime();
1894
1895            if ( !this.moved ) {
1896                this.scroller._execEvent('scrollStart');
1897            }
1898
1899            this.moved = true;
1900
1901            deltaX = point.pageX - this.lastPointX;
1902            this.lastPointX = point.pageX;
1903
1904            deltaY = point.pageY - this.lastPointY;
1905            this.lastPointY = point.pageY;
1906
1907            newX = this.x + deltaX;
1908            newY = this.y + deltaY;
1909
1910            this._pos(newX, newY);
1911
1912// INSERT POINT: indicator._move
1913
1914            e.preventDefault();
1915            e.stopPropagation();
1916        },
1917
1918        _end: function (e) {
1919            if ( !this.initiated ) {
1920                return;
1921            }
1922
1923            this.initiated = false;
1924
1925            e.preventDefault();
1926            e.stopPropagation();
1927
1928            utils.removeEvent(window, 'touchmove', this);
1929            utils.removeEvent(window, utils.prefixPointerEvent('pointermove'), this);
1930            utils.removeEvent(window, 'mousemove', this);
1931
1932            if ( this.scroller.options.snap ) {
1933                var snap = this.scroller._nearestSnap(this.scroller.x, this.scroller.y);
1934
1935                var time = this.options.snapSpeed || Math.max(
1936                    Math.max(
1937                        Math.min(Math.abs(this.scroller.x - snap.x), 1000),
1938                        Math.min(Math.abs(this.scroller.y - snap.y), 1000)
1939                    ), 300);
1940
1941                if ( this.scroller.x != snap.x || this.scroller.y != snap.y ) {
1942                    this.scroller.directionX = 0;
1943                    this.scroller.directionY = 0;
1944                    this.scroller.currentPage = snap;
1945                    this.scroller.scrollTo(snap.x, snap.y, time, this.scroller.options.bounceEasing);
1946                }
1947            }
1948
1949            if ( this.moved ) {
1950                this.scroller._execEvent('scrollEnd');
1951            }
1952        },
1953
1954        transitionTime: function (time) {
1955            time = time || 0;
1956            var durationProp = utils.style.transitionDuration;
1957            if(!durationProp) {
1958                return;
1959            }
1960
1961            this.indicatorStyle[durationProp] = time + 'ms';
1962
1963            if ( !time && utils.isBadAndroid ) {
1964                this.indicatorStyle[durationProp] = '0.0001ms';
1965                // remove 0.0001ms
1966                var self = this;
1967                rAF(function() {
1968                    if(self.indicatorStyle[durationProp] === '0.0001ms') {
1969                        self.indicatorStyle[durationProp] = '0s';
1970                    }
1971                });
1972            }
1973        },
1974
1975        transitionTimingFunction: function (easing) {
1976            this.indicatorStyle[utils.style.transitionTimingFunction] = easing;
1977        },
1978
1979        refresh: function () {
1980            this.transitionTime();
1981
1982            if ( this.options.listenX && !this.options.listenY ) {
1983                this.indicatorStyle.display = this.scroller.hasHorizontalScroll ? 'block' : 'none';
1984            } else if ( this.options.listenY && !this.options.listenX ) {
1985                this.indicatorStyle.display = this.scroller.hasVerticalScroll ? 'block' : 'none';
1986            } else {
1987                this.indicatorStyle.display = this.scroller.hasHorizontalScroll || this.scroller.hasVerticalScroll ? 'block' : 'none';
1988            }
1989
1990            if ( this.scroller.hasHorizontalScroll && this.scroller.hasVerticalScroll ) {
1991                utils.addClass(this.wrapper, 'iScrollBothScrollbars');
1992                utils.removeClass(this.wrapper, 'iScrollLoneScrollbar');
1993
1994                if ( this.options.defaultScrollbars && this.options.customStyle ) {
1995                    if ( this.options.listenX ) {
1996                        this.wrapper.style.right = '8px';
1997                    } else {
1998                        this.wrapper.style.bottom = '8px';
1999                    }
2000                }
2001            } else {
2002                utils.removeClass(this.wrapper, 'iScrollBothScrollbars');
2003                utils.addClass(this.wrapper, 'iScrollLoneScrollbar');
2004
2005                if ( this.options.defaultScrollbars && this.options.customStyle ) {
2006                    if ( this.options.listenX ) {
2007                        this.wrapper.style.right = '2px';
2008                    } else {
2009                        this.wrapper.style.bottom = '2px';
2010                    }
2011                }
2012            }
2013
2014            utils.getRect(this.wrapper);	// force refresh
2015
2016            if ( this.options.listenX ) {
2017                this.wrapperWidth = this.wrapper.clientWidth;
2018                if ( this.options.resize ) {
2019                    this.indicatorWidth = Math.max(Math.round(this.wrapperWidth * this.wrapperWidth / (this.scroller.scrollerWidth || this.wrapperWidth || 1)), 8);
2020                    this.indicatorStyle.width = this.indicatorWidth + 'px';
2021                } else {
2022                    this.indicatorWidth = this.indicator.clientWidth;
2023                }
2024
2025                this.maxPosX = this.wrapperWidth - this.indicatorWidth;
2026
2027                if ( this.options.shrink == 'clip' ) {
2028                    this.minBoundaryX = -this.indicatorWidth + 8;
2029                    this.maxBoundaryX = this.wrapperWidth - 8;
2030                } else {
2031                    this.minBoundaryX = 0;
2032                    this.maxBoundaryX = this.maxPosX;
2033                }
2034
2035                this.sizeRatioX = this.options.speedRatioX || (this.scroller.maxScrollX && (this.maxPosX / this.scroller.maxScrollX));
2036            }
2037
2038            if ( this.options.listenY ) {
2039                this.wrapperHeight = this.wrapper.clientHeight;
2040                if ( this.options.resize ) {
2041                    this.indicatorHeight = Math.max(Math.round(this.wrapperHeight * this.wrapperHeight / (this.scroller.scrollerHeight || this.wrapperHeight || 1)), 8);
2042                    this.indicatorStyle.height = this.indicatorHeight + 'px';
2043                } else {
2044                    this.indicatorHeight = this.indicator.clientHeight;
2045                }
2046
2047                this.maxPosY = this.wrapperHeight - this.indicatorHeight;
2048
2049                if ( this.options.shrink == 'clip' ) {
2050                    this.minBoundaryY = -this.indicatorHeight + 8;
2051                    this.maxBoundaryY = this.wrapperHeight - 8;
2052                } else {
2053                    this.minBoundaryY = 0;
2054                    this.maxBoundaryY = this.maxPosY;
2055                }
2056
2057                this.maxPosY = this.wrapperHeight - this.indicatorHeight;
2058                this.sizeRatioY = this.options.speedRatioY || (this.scroller.maxScrollY && (this.maxPosY / this.scroller.maxScrollY));
2059            }
2060
2061            this.updatePosition();
2062        },
2063
2064        updatePosition: function () {
2065            var x = this.options.listenX && Math.round(this.sizeRatioX * this.scroller.x) || 0,
2066                y = this.options.listenY && Math.round(this.sizeRatioY * this.scroller.y) || 0;
2067
2068            if ( !this.options.ignoreBoundaries ) {
2069                if ( x < this.minBoundaryX ) {
2070                    if ( this.options.shrink == 'scale' ) {
2071                        this.width = Math.max(this.indicatorWidth + x, 8);
2072                        this.indicatorStyle.width = this.width + 'px';
2073                    }
2074                    x = this.minBoundaryX;
2075                } else if ( x > this.maxBoundaryX ) {
2076                    if ( this.options.shrink == 'scale' ) {
2077                        this.width = Math.max(this.indicatorWidth - (x - this.maxPosX), 8);
2078                        this.indicatorStyle.width = this.width + 'px';
2079                        x = this.maxPosX + this.indicatorWidth - this.width;
2080                    } else {
2081                        x = this.maxBoundaryX;
2082                    }
2083                } else if ( this.options.shrink == 'scale' && this.width != this.indicatorWidth ) {
2084                    this.width = this.indicatorWidth;
2085                    this.indicatorStyle.width = this.width + 'px';
2086                }
2087
2088                if ( y < this.minBoundaryY ) {
2089                    if ( this.options.shrink == 'scale' ) {
2090                        this.height = Math.max(this.indicatorHeight + y * 3, 8);
2091                        this.indicatorStyle.height = this.height + 'px';
2092                    }
2093                    y = this.minBoundaryY;
2094                } else if ( y > this.maxBoundaryY ) {
2095                    if ( this.options.shrink == 'scale' ) {
2096                        this.height = Math.max(this.indicatorHeight - (y - this.maxPosY) * 3, 8);
2097                        this.indicatorStyle.height = this.height + 'px';
2098                        y = this.maxPosY + this.indicatorHeight - this.height;
2099                    } else {
2100                        y = this.maxBoundaryY;
2101                    }
2102                } else if ( this.options.shrink == 'scale' && this.height != this.indicatorHeight ) {
2103                    this.height = this.indicatorHeight;
2104                    this.indicatorStyle.height = this.height + 'px';
2105                }
2106            }
2107
2108            this.x = x;
2109            this.y = y;
2110
2111            if ( this.scroller.options.useTransform ) {
2112                this.indicatorStyle[utils.style.transform] = 'translate(' + x + 'px,' + y + 'px)' + this.scroller.translateZ;
2113            } else {
2114                this.indicatorStyle.left = x + 'px';
2115                this.indicatorStyle.top = y + 'px';
2116            }
2117        },
2118
2119        _pos: function (x, y) {
2120            if ( x < 0 ) {
2121                x = 0;
2122            } else if ( x > this.maxPosX ) {
2123                x = this.maxPosX;
2124            }
2125
2126            if ( y < 0 ) {
2127                y = 0;
2128            } else if ( y > this.maxPosY ) {
2129                y = this.maxPosY;
2130            }
2131
2132            x = this.options.listenX ? Math.round(x / this.sizeRatioX) : this.scroller.x;
2133            y = this.options.listenY ? Math.round(y / this.sizeRatioY) : this.scroller.y;
2134
2135            this.scroller.scrollTo(x, y);
2136        },
2137
2138        fade: function (val, hold) {
2139            if ( hold && !this.visible ) {
2140                return;
2141            }
2142
2143            clearTimeout(this.fadeTimeout);
2144            this.fadeTimeout = null;
2145
2146            var time = val ? 250 : 500,
2147                delay = val ? 0 : 300;
2148
2149            val = val ? '1' : '0';
2150
2151            this.wrapperStyle[utils.style.transitionDuration] = time + 'ms';
2152
2153            this.fadeTimeout = setTimeout((function (val) {
2154                this.wrapperStyle.opacity = val;
2155                this.visible = +val;
2156            }).bind(this, val), delay);
2157        }
2158    };
2159
2160    IScroll.utils = utils;
2161
2162    if ( typeof module != 'undefined' && module.exports ) {
2163        module.exports = IScroll;
2164    } else if ( typeof define == 'function' && define.amd ) {
2165        define( function () { return IScroll; } );
2166    } else {
2167        window.IScroll = IScroll;
2168    }
2169
2170})(window, document, Math);

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.