PageSourceSearch

https://www.rtasia.net/template/index/pc/js/jquery.fullpage.js

js rtasia.net collected 2026-10-06 13:43:18 UTC 120,600 bytes, 3,128 lines download raw bytes

1
2/*!
3 * fullPage 2.9.4
4 * https://github.com/alvarotrigo/fullPage.js
5 * @license MIT licensed
6 *
7 * Copyright (C) 2015 alvarotrigo.com - A project by Alvaro Trigo
8 */
9(function(global, factory) {
10    'use strict';
11    if (typeof define === 'function' && define.amd) {
12        define(['jquery'], function($) {
13          return factory($, global, global.document, global.Math);
14        });
15    } else if (typeof exports === "object" && exports) {
16        module.exports = factory(require('jquery'), global, global.document, global.Math);
17    } else {
18        factory(jQuery, global, global.document, global.Math);
19    }
20})(typeof window !== 'undefined' ? window : this, function($, window, document, Math, undefined) {
21    'use strict';
22
23    // keeping central set of classnames and selectors
24    var WRAPPER =               'fullpage-wrapper';
25    var WRAPPER_SEL =           '.' + WRAPPER;
26
27    // slimscroll
28    var SCROLLABLE =            'fp-scrollable';
29    var SCROLLABLE_SEL =        '.' + SCROLLABLE;
30
31    // util
32    var RESPONSIVE =            'fp-responsive';
33    var NO_TRANSITION =         'fp-notransition';
34    var DESTROYED =             'fp-destroyed';
35    var ENABLED =               'fp-enabled';
36    var VIEWING_PREFIX =        'fp-viewing';
37    var ACTIVE =                'active';
38    var ACTIVE_SEL =            '.' + ACTIVE;
39    var COMPLETELY =            'fp-completely';
40    var COMPLETELY_SEL =        '.' + COMPLETELY;
41
42    // section
43    var SECTION_DEFAULT_SEL =   '.section';
44    var SECTION =               'fp-section';
45    var SECTION_SEL =           '.' + SECTION;
46    var SECTION_ACTIVE_SEL =    SECTION_SEL + ACTIVE_SEL;
47    var SECTION_FIRST_SEL =     SECTION_SEL + ':first';
48    var SECTION_LAST_SEL =      SECTION_SEL + ':last';
49    var TABLE_CELL =            'fp-tableCell';
50    var TABLE_CELL_SEL =        '.' + TABLE_CELL;
51    var AUTO_HEIGHT =           'fp-auto-height';
52    var AUTO_HEIGHT_SEL =       '.fp-auto-height';
53    var NORMAL_SCROLL =         'fp-normal-scroll';
54    var NORMAL_SCROLL_SEL =     '.fp-normal-scroll';
55
56    // section nav
57    var SECTION_NAV =           'fp-nav';
58    var SECTION_NAV_SEL =       '#' + SECTION_NAV;
59    var SECTION_NAV_TOOLTIP =   'fp-tooltip';
60    var SECTION_NAV_TOOLTIP_SEL='.'+SECTION_NAV_TOOLTIP;
61    var SHOW_ACTIVE_TOOLTIP =   'fp-show-active';
62
63    // slide
64    var SLIDE_DEFAULT_SEL =     '.slide';
65    var SLIDE =                 'fp-slide';
66    var SLIDE_SEL =             '.' + SLIDE;
67    var SLIDE_ACTIVE_SEL =      SLIDE_SEL + ACTIVE_SEL;
68    var SLIDES_WRAPPER =        'fp-slides';
69    var SLIDES_WRAPPER_SEL =    '.' + SLIDES_WRAPPER;
70    var SLIDES_CONTAINER =      'fp-slidesContainer';
71    var SLIDES_CONTAINER_SEL =  '.' + SLIDES_CONTAINER;
72    var TABLE =                 'fp-table';
73
74    // slide nav
75    var SLIDES_NAV =            'fp-slidesNav';
76    var SLIDES_NAV_SEL =        '.' + SLIDES_NAV;
77    var SLIDES_NAV_LINK_SEL =   SLIDES_NAV_SEL + ' a';
78    var SLIDES_ARROW =          'fp-controlArrow';
79    var SLIDES_ARROW_SEL =      '.' + SLIDES_ARROW;
80    var SLIDES_PREV =           'fp-prev';
81    var SLIDES_PREV_SEL =       '.' + SLIDES_PREV;
82    var SLIDES_ARROW_PREV =     SLIDES_ARROW + ' ' + SLIDES_PREV;
83    var SLIDES_ARROW_PREV_SEL = SLIDES_ARROW_SEL + SLIDES_PREV_SEL;
84    var SLIDES_NEXT =           'fp-next';
85    var SLIDES_NEXT_SEL =       '.' + SLIDES_NEXT;
86    var SLIDES_ARROW_NEXT =     SLIDES_ARROW + ' ' + SLIDES_NEXT;
87    var SLIDES_ARROW_NEXT_SEL = SLIDES_ARROW_SEL + SLIDES_NEXT_SEL;
88
89    var $window = $(window);
90    var $document = $(document);
91
92    // Default options for iScroll.js used when using scrollOverflow
93    var iscrollOptions = {
94        scrollbars: true,
95        mouseWheel: true,
96        hideScrollbars: false,
97        fadeScrollbars: false,
98        disableMouse: true,
99        interactiveScrollbars: true
100    };
101
102    $.fn.fullpage = function(options) {
103        //only once my friend!
104        if($('html').hasClass(ENABLED)){ displayWarnings(); return; }
105
106        // common jQuery objects
107        var $htmlBody = $('html, body');
108        var $body = $('body');
109
110        var FP = $.fn.fullpage;
111
112        // Creating some defaults, extending them with any options that were provided
113        options = $.extend({
114            //navigation
115            menu: false,
116            anchors:[],
117            lockAnchors: false,
118            navigation: false,
119            navigationPosition: 'right',
120            navigationTooltips: [],
121            showActiveTooltip: false,
122            slidesNavigation: false,
123            slidesNavPosition: 'bottom',
124            scrollBar: false,
125            hybrid: false,
126
127            //scrolling
128            css3: true,
129            scrollingSpeed: 700,
130            autoScrolling: true,
131            fitToSection: true,
132            fitToSectionDelay: 1000,
133            easing: 'easeInOutCubic',
134            easingcss3: 'ease',
135            loopBottom: false,
136            loopTop: false,
137            loopHorizontal: true,
138            continuousVertical: false,
139            continuousHorizontal: false,
140            scrollHorizontally: false,
141            interlockedSlides: false,
142            dragAndMove: false,
143            offsetSections: false,
144            resetSliders: false,
145            fadingEffect: false,
146            normalScrollElements: null,
147            scrollOverflow: false,
148            scrollOverflowReset: false,
149            scrollOverflowHandler: iscrollHandler,
150            scrollOverflowOptions: null,
151            touchSensitivity: 5,
152            normalScrollElementTouchThreshold: 5,
153            bigSectionsDestination: null,
154
155            //Accessibility
156            keyboardScrolling: true,
157            animateAnchor: true,
158            recordHistory: true,
159
160            //design
161            controlArrows: true,
162            controlArrowColor: '#fff',
163            verticalCentered: true,
164            sectionsColor : [],
165            paddingTop: 0,
166            paddingBottom: 0,
167            fixedElements: null,
168            responsive: 0, //backwards compabitility with responsiveWiddth
169            responsiveWidth: 0,
170            responsiveHeight: 0,
171            responsiveSlides: false,
172            parallax: false,
173            parallaxOptions: {
174                type: 'reveal',
175                percentage: 62,
176                property: 'translate'
177            },
178
179            //Custom selectors
180            sectionSelector: SECTION_DEFAULT_SEL,
181            slideSelector: SLIDE_DEFAULT_SEL,
182
183            //events
184            afterLoad: null,
185            onLeave: null,
186            afterRender: null,
187            afterResize: null,
188            afterReBuild: null,
189            afterSlideLoad: null,
190            onSlideLeave: null,
191            afterResponsive: null,
192
193            lazyLoading: true
194        }, options);
195
196        //flag to avoid very fast sliding for landscape sliders
197        var slideMoving = false;
198
199        var isTouchDevice = navigator.userAgent.match(/(iPhone|iPod|iPad|Android|playbook|silk|BlackBerry|BB10|Windows Phone|Tizen|Bada|webOS|IEMobile|Opera Mini)/);
200        var isTouch = (('ontouchstart' in window) || (navigator.msMaxTouchPoints > 0) || (navigator.maxTouchPoints));
201        var container = $(this);
202        var windowsHeight = $window.height();
203        var isResizing = false;
204        var isWindowFocused = true;
205        var lastScrolledDestiny;
206        var lastScrolledSlide;
207        var canScroll = true;
208        var scrollings = [];
209        var controlPressed;
210        var startingSection;
211        var isScrollAllowed = {};
212        isScrollAllowed.m = {  'up':true, 'down':true, 'left':true, 'right':true };
213        isScrollAllowed.k = $.extend(true,{}, isScrollAllowed.m);
214        var MSPointer = getMSPointer();
215        var events = {
216            touchmove: 'ontouchmove' in window ? 'touchmove' :  MSPointer.move,
217            touchstart: 'ontouchstart' in window ? 'touchstart' :  MSPointer.down
218        };
219
220        //timeouts
221        var resizeId;
222        var afterSectionLoadsId;
223        var afterSlideLoadsId;
224        var scrollId;
225        var scrollId2;
226        var keydownId;
227        var originals = $.extend(true, {}, options); //deep copy
228
229        displayWarnings();
230
231        //fixing bug in iScroll with links: https://github.com/cubiq/iscroll/issues/783
232        iscrollOptions.click = isTouch; // see #2035
233
234        //extending iScroll options with the user custom ones
235        iscrollOptions = $.extend(iscrollOptions, options.scrollOverflowOptions);
236
237        //easeInOutCubic animation included in the plugin
238        $.extend($.easing,{ easeInOutCubic: function (x, t, b, c, d) {if ((t/=d/2) < 1) return c/2*t*t*t + b;return c/2*((t-=2)*t*t + 2) + b;}});
239
240        /**
241        * Sets the autoScroll option.
242        * It changes the scroll bar visibility and the history of the site as a result.
243        */
244        function setAutoScrolling(value, type){
245            //removing the transformation
246            if(!value){
247                silentScroll(0);
248            }
249
250            setVariableState('autoScrolling', value, type);
251
252            var element = $(SECTION_ACTIVE_SEL);
253
254            if(options.autoScrolling && !options.scrollBar){
255                $htmlBody.css({
256                    'overflow' : 'hidden',
257                    'height' : '100%'
258                });
259
260                setRecordHistory(originals.recordHistory, 'internal');
261
262                //for IE touch devices
263                container.css({
264                    '-ms-touch-action': 'none',
265                    'touch-action': 'none'
266                });
267
268                if(element.length){
269                    //moving the container up
270                    silentScroll(element.position().top);
271                }
272
273            }else{
274                $htmlBody.css({
275                    'overflow' : 'visible',
276                    'height' : 'initial'
277                });
278
279                setRecordHistory(false, 'internal');
280
281                //for IE touch devices
282                container.css({
283                    '-ms-touch-action': '',
284                    'touch-action': ''
285                });
286
287                //scrolling the page to the section with no animation
288                if (element.length) {
289                    $htmlBody.scrollTop(element.position().top);
290                }
291            }
292        }
293
294        /**
295        * Defines wheter to record the history for each hash change in the URL.
296        */
297        function setRecordHistory(value, type){
298            setVariableState('recordHistory', value, type);
299        }
300
301        /**
302        * Defines the scrolling speed
303        */
304        function setScrollingSpeed(value, type){
305            setVariableState('scrollingSpeed', value, type);
306        }
307
308        /**
309        * Sets fitToSection
310        */
311        function setFitToSection(value, type){
312            setVariableState('fitToSection', value, type);
313        }
314
315        /**
316        * Sets lockAnchors
317        */
318        function setLockAnchors(value){
319            options.lockAnchors = value;
320        }
321
322        /**
323        * Adds or remove the possiblity of scrolling through sections by using the mouse wheel or the trackpad.
324        */
325        function setMouseWheelScrolling(value){
326            if(value){
327                addMouseWheelHandler();
328                addMiddleWheelHandler();
329            }else{
330                removeMouseWheelHandler();
331                removeMiddleWheelHandler();
332            }
333        }
334
335        /**
336        * Adds or remove the possibility of scrolling through sections by using the mouse wheel/trackpad or touch gestures.
337        * Optionally a second parameter can be used to specify the direction for which the action will be applied.
338        *
339        * @param directions string containing the direction or directions separated by comma.
340        */
341        function setAllowScrolling(value, directions){
342            if(typeof directions !== 'undefined'){
343                directions = directions.replace(/ /g,'').split(',');
344
345                $.each(directions, function (index, direction){
346                    setIsScrollAllowed(value, direction, 'm');
347                });
348            }
349            else if(value){
350                setMouseWheelScrolling(true);
351                addTouchHandler();
352            }else{
353                setMouseWheelScrolling(false);
354                removeTouchHandler();
355            }
356        }
357
358        /**
359        * Adds or remove the possibility of scrolling through sections by using the keyboard arrow keys
360        */
361        function setKeyboardScrolling(value, directions){
362            if(typeof directions !== 'undefined'){
363                directions = directions.replace(/ /g,'').split(',');
364
365                $.each(directions, function (index, direction){
366                    setIsScrollAllowed(value, direction, 'k');
367                });
368            }else{
369                options.keyboardScrolling = value;
370            }
371        }
372
373        /**
374        * Moves the page up one section.
375        */
376        function moveSectionUp(){
377            var prev = $(SECTION_ACTIVE_SEL).prev(SECTION_SEL);
378
379            //looping to the bottom if there's no more sections above
380            if (!prev.length && (options.loopTop || options.continuousVertical)) {
381                prev = $(SECTION_SEL).last();
382            }
383
384            if (prev.length) {
385                scrollPage(prev, null, true);
386            }
387        }
388
389        /**
390        * Moves the page down one section.
391        */
392        function moveSectionDown(){
393            var next = $(SECTION_ACTIVE_SEL).next(SECTION_SEL);
394
395            //looping to the top if there's no more sections below
396            if(!next.length &&
397                (options.loopBottom || options.continuousVertical)){
398                next = $(SECTION_SEL).first();
399            }
400
401            if(next.length){
402                scrollPage(next, null, false);
403            }
404        }
405
406        /**
407        * Moves the page to the given section and slide with no animation.
408        * Anchors or index positions can be used as params.
409        */
410        function silentMoveTo(sectionAnchor, slideAnchor){
411            setScrollingSpeed (0, 'internal');
412            moveTo(sectionAnchor, slideAnchor);
413            setScrollingSpeed (originals.scrollingSpeed, 'internal');
414        }
415
416        /**
417        * Moves the page to the given section and slide.
418        * Anchors or index positions can be used as params.
419        */
420        function moveTo(sectionAnchor, slideAnchor){
421            var destiny = getSectionByAnchor(sectionAnchor);
422
423            if (typeof slideAnchor !== 'undefined'){
424                scrollPageAndSlide(sectionAnchor, slideAnchor);
425            }else if(destiny.length > 0){
426                scrollPage(destiny);
427            }
428        }
429
430        /**
431        * Slides right the slider of the active section.
432        * Optional `section` param.
433        */
434        function moveSlideRight(section){
435            moveSlide('right', section);
436        }
437
438        /**
439        * Slides left the slider of the active section.
440        * Optional `section` param.
441        */
442        function moveSlideLeft(section){
443            moveSlide('left', section);
444        }
445
446        /**
447         * When resizing is finished, we adjust the slides sizes and positions
448         */
449        function reBuild(resizing){
450            if(container.hasClass(DESTROYED)){ return; }  //nothing to do if the plugin was destroyed
451
452            isResizing = true;
453
454            windowsHeight = $window.height();  //updating global var
455
456            $(SECTION_SEL).each(function(){
457                var slidesWrap = $(this).find(SLIDES_WRAPPER_SEL);
458                var slides = $(this).find(SLIDE_SEL);
459
460                //adjusting the height of the table-cell for IE and Firefox
461                if(options.verticalCentered){
462                    $(this).find(TABLE_CELL_SEL).css('height', getTableHeight($(this)) + 'px');
463                }
464
465                $(this).css('height', windowsHeight + 'px');
466
467                //resizing the scrolling divs
468                if(options.scrollOverflow){
469                    if(slides.length){
470                        slides.each(function(){
471                            createScrollBar($(this));
472                        });
473                    }else{
474                        createScrollBar($(this));
475                    }
476                }
477
478                //adjusting the position fo the FULL WIDTH slides...
479                if (slides.length > 1) {
480                    landscapeScroll(slidesWrap, slidesWrap.find(SLIDE_ACTIVE_SEL));
481                }
482            });
483
484            var activeSection = $(SECTION_ACTIVE_SEL);
485            var sectionIndex = activeSection.index(SECTION_SEL);
486
487            //isn't it the first section?
488            if(sectionIndex){
489                //adjusting the position for the current section
490                silentMoveTo(sectionIndex + 1);
491            }
492
493            isResizing = false;
494            $.isFunction( options.afterResize ) && resizing && options.afterResize.call(container);
495            $.isFunction( options.afterReBuild ) && !resizing && options.afterReBuild.call(container);
496        }
497
498        /**
499        * Turns fullPage.js to normal scrolling mode when the viewport `width` or `height`
500        * are smaller than the set limit values.
501        */
502        function setResponsive(active){
503            var isResponsive = $body.hasClass(RESPONSIVE);
504
505            if(active){
506                if(!isResponsive){
507                    setAutoScrolling(false, 'internal');
508                    setFitToSection(false, 'internal');
509                    $(SECTION_NAV_SEL).hide();
510                    $body.addClass(RESPONSIVE);
511                    $.isFunction( options.afterResponsive ) && options.afterResponsive.call( container, active);
512                }
513            }
514            else if(isResponsive){
515                setAutoScrolling(originals.autoScrolling, 'internal');
516                setFitToSection(originals.autoScrolling, 'internal');
517                $(SECTION_NAV_SEL).show();
518                $body.removeClass(RESPONSIVE);
519                $.isFunction( options.afterResponsive ) && options.afterResponsive.call( container, active);
520            }
521        }
522
523        if($(this).length){
524            //public functions
525            FP.setAutoScrolling = setAutoScrolling;
526            FP.setRecordHistory = setRecordHistory;
527            FP.setScrollingSpeed = setScrollingSpeed;
528            FP.setFitToSection = setFitToSection;
529            FP.setLockAnchors = setLockAnchors;
530            FP.setMouseWheelScrolling = setMouseWheelScrolling;
531            FP.setAllowScrolling = setAllowScrolling;
532            FP.setKeyboardScrolling = setKeyboardScrolling;
533            FP.moveSectionUp = moveSectionUp;
534            FP.moveSectionDown = moveSectionDown;
535            FP.silentMoveTo = silentMoveTo;
536            FP.moveTo = moveTo;
537            FP.moveSlideRight = moveSlideRight;
538            FP.moveSlideLeft = moveSlideLeft;
539            FP.fitToSection = fitToSection;
540            FP.reBuild = reBuild;
541            FP.setResponsive = setResponsive;
542            FP.destroy = destroy;
543
544            init();
545
546            bindEvents();
547        }
548
549        function init(){
550            //if css3 is not supported, it will use jQuery animations
551            if(options.css3){
552                options.css3 = support3d();
553            }
554
555            options.scrollBar = options.scrollBar || options.hybrid;
556
557            setOptionsFromDOM();
558            prepareDom();
559            setAllowScrolling(true);
560            setAutoScrolling(options.autoScrolling, 'internal');
561            responsive();
562
563            //setting the class for the body element
564            setBodyClass();
565
566            if(document.readyState === 'complete'){
567                scrollToAnchor();
568            }
569            $window.on('load', scrollToAnchor);
570        }
571
572        function bindEvents(){
573            $window
574                //when scrolling...
575                .on('scroll', scrollHandler)
576
577                //detecting any change on the URL to scroll to the given anchor link
578                //(a way to detect back history button as we play with the hashes on the URL)
579                .on('hashchange', hashChangeHandler)
580
581                //when opening a new tab (ctrl + t), `control` won't be pressed when coming back.
582                .blur(blurHandler)
583
584                //when resizing the site, we adjust the heights of the sections, slimScroll...
585                .resize(resizeHandler);
586
587            $document
588                //Sliding with arrow keys, both, vertical and horizontal
589                .keydown(keydownHandler)
590
591                //to prevent scrolling while zooming
592                .keyup(keyUpHandler)
593
594                //Scrolls to the section when clicking the navigation bullet
595                .on('click touchstart', SECTION_NAV_SEL + ' a', sectionBulletHandler)
596
597                //Scrolls the slider to the given slide destination for the given section
598                .on('click touchstart', SLIDES_NAV_LINK_SEL, slideBulletHandler)
599
600                .on('click', SECTION_NAV_TOOLTIP_SEL, tooltipTextHandler);
601
602            //Scrolling horizontally when clicking on the slider controls.
603            $(SECTION_SEL).on('click touchstart', SLIDES_ARROW_SEL, slideArrowHandler);
604
605            /**
606            * Applying normalScroll elements.
607            * Ignoring the scrolls over the specified selectors.
608            */
609            if(options.normalScrollElements){
610                $document.on('mouseenter', options.normalScrollElements, function () {
611                    setMouseWheelScrolling(false);
612                });
613
614                $document.on('mouseleave', options.normalScrollElements, function(){
615                    setMouseWheelScrolling(true);
616                });
617            }
618        }
619
620        /**
621        * Setting options from DOM elements if they are not provided.
622        */
623        function setOptionsFromDOM(){
624            var sections = container.find(options.sectionSelector);
625
626            //no anchors option? Checking for them in the DOM attributes
627            if(!options.anchors.length){
628                options.anchors = sections.filter('[data-anchor]').map(function(){
629                    return $(this).data('anchor').toString();
630                }).get();
631            }
632
633            //no tooltips option? Checking for them in the DOM attributes
634            if(!options.navigationTooltips.length){
635                options.navigationTooltips = sections.filter('[data-tooltip]').map(function(){
636                    return $(this).data('tooltip').toString();
637                }).get();
638            }
639        }
640
641        /**
642        * Works over the DOM structure to set it up for the current fullpage options.
643        */
644        function prepareDom(){
645            container.css({
646                'height': '100%',
647                'position': 'relative'
648            });
649
650            //adding a class to recognize the container internally in the code
651            container.addClass(WRAPPER);
652            $('html').addClass(ENABLED);
653
654            //due to https://github.com/alvarotrigo/fullPage.js/issues/1502
655            windowsHeight = $window.height();
656
657            container.removeClass(DESTROYED); //in case it was destroyed before initializing it again
658
659            addInternalSelectors();
660
661             //styling the sections / slides / menu
662            $(SECTION_SEL).each(function(index){
663                var section = $(this);
664                var slides = section.find(SLIDE_SEL);
665                var numSlides = slides.length;
666
667                styleSection(section, index);
668                styleMenu(section, index);
669
670                // if there's any slide
671                if (numSlides > 0) {
672                    styleSlides(section, slides, numSlides);
673                }else{
674                    if(options.verticalCentered){
675                        addTableClass(section);
676                    }
677                }
678            });
679
680            //fixed elements need to be moved out of the plugin container due to problems with CSS3.
681            if(options.fixedElements && options.css3){
682                $(options.fixedElements).appendTo($body);
683            }
684
685            //vertical centered of the navigation + active bullet
686            if(options.navigation){
687                addVerticalNavigation();
688            }
689
690            enableYoutubeAPI();
691
692            if(options.scrollOverflow){
693                if(document.readyState === 'complete'){
694                    createScrollBarHandler();
695                }
696                //after DOM and images are loaded
697                $window.on('load', createScrollBarHandler);
698            }else{
699                afterRenderActions();
700            }
701        }
702
703        /**
704        * Styles the horizontal slides for a section.
705        */
706        function styleSlides(section, slides, numSlides){
707            var sliderWidth = numSlides * 100;
708            var slideWidth = 100 / numSlides;
709
710            slides.wrapAll('<div class="' + SLIDES_CONTAINER + '" />');
711            slides.parent().wrap('<div class="' + SLIDES_WRAPPER + '" />');
712
713            section.find(SLIDES_CONTAINER_SEL).css('width', sliderWidth + '%');
714
715            if(numSlides > 1){
716                if(options.controlArrows){
717                    createSlideArrows(section);
718                }
719
720                if(options.slidesNavigation){
721                    addSlidesNavigation(section, numSlides);
722                }
723            }
724
725            slides.each(function(index) {
726                $(this).css('width', slideWidth + '%');
727
728                if(options.verticalCentered){
729                    addTableClass($(this));
730                }
731            });
732
733            var startingSlide = section.find(SLIDE_ACTIVE_SEL);
734
735            //if the slide won't be an starting point, the default will be the first one
736            //the active section isn't the first one? Is not the first slide of the first section? Then we load that section/sl
736ide by default.
737            if( startingSlide.length &&  ($(SECTION_ACTIVE_SEL).index(SECTION_SEL) !== 0 || ($(SECTION_ACTIVE_SEL).index(SECTION_SEL) === 0 && startingSlide.index() !== 0))){
738                silentLandscapeScroll(startingSlide, 'internal');
739            }else{
740                slides.eq(0).addClass(ACTIVE);
741            }
742        }
743
744        /**
745        * Styling vertical sections
746        */
747        function styleSection(section, index){
748            //if no active section is defined, the 1st one will be the default one
749            if(!index && $(SECTION_ACTIVE_SEL).length === 0) {
750                section.addClass(ACTIVE);
751            }
752            startingSection = $(SECTION_ACTIVE_SEL);
753
754            section.css('height', windowsHeight + 'px');
755
756            if(options.paddingTop){
757                section.css('padding-top', options.paddingTop);
758            }
759
760            if(options.paddingBottom){
761                section.css('padding-bottom', options.paddingBottom);
762            }
763
764            if (typeof options.sectionsColor[index] !==  'undefined') {
765                section.css('background-color', options.sectionsColor[index]);
766            }
767
768            if (typeof options.anchors[index] !== 'undefined') {
769                section.attr('data-anchor', options.anchors[index]);
770            }
771        }
772
773        /**
774        * Sets the data-anchor attributes to the menu elements and activates the current one.
775        */
776        function styleMenu(section, index){
777            if (typeof options.anchors[index] !== 'undefined') {
778                //activating the menu / nav element on load
779                if(section.hasClass(ACTIVE)){
780                    activateMenuAndNav(options.anchors[index], index);
781                }
782            }
783
784            //moving the menu outside the main container if it is inside (avoid problems with fixed positions when using CSS3 tranforms)
785            if(options.menu && options.css3 && $(options.menu).closest(WRAPPER_SEL).length){
786                $(options.menu).appendTo($body);
787            }
788        }
789
790        /**
791        * Adds internal classes to be able to provide customizable selectors
792        * keeping the link with the style sheet.
793        */
794        function addInternalSelectors(){
795            container.find(options.sectionSelector).addClass(SECTION);
796            container.find(options.slideSelector).addClass(SLIDE);
797        }
798
799        /**
800        * Creates the control arrows for the given section
801        */
802        function createSlideArrows(section){
803            section.find(SLIDES_WRAPPER_SEL).after('<div class="' + SLIDES_ARROW_PREV + '"></div><div class="' + SLIDES_ARROW_NEXT + '"></div>');
804
805            if(options.controlArrowColor!='#fff'){
806                section.find(SLIDES_ARROW_NEXT_SEL).css('border-color', 'transparent transparent transparent '+options.controlArrowColor);
807                section.find(SLIDES_ARROW_PREV_SEL).css('border-color', 'transparent '+ options.controlArrowColor + ' transparent transparent');
808            }
809
810            if(!options.loopHorizontal){
811                section.find(SLIDES_ARROW_PREV_SEL).hide();
812            }
813        }
814
815        /**
816        * Creates a vertical navigation bar.
817        */
818        function addVerticalNavigation(){
819            $body.append('<div id="' + SECTION_NAV + '"><ul></ul></div>');
820            var nav = $(SECTION_NAV_SEL);
821
822            nav.addClass(function() {
823                return options.showActiveTooltip ? SHOW_ACTIVE_TOOLTIP + ' ' + options.navigationPosition : options.navigationPosition;
824            });
825
826            for (var i = 0; i < $(SECTION_SEL).length; i++) {
827                var link = '';
828                if (options.anchors.length) {
829                    link = options.anchors[i];
830                }
831
832                var li = '<li><a href="#' + link + '"><span></span></a>';
833
834                // Only add tooltip if needed (defined by user)
835                var tooltip = options.navigationTooltips[i];
836
837                if (typeof tooltip !== 'undefined' && tooltip !== '') {
838                    li += '<div class="' + SECTION_NAV_TOOLTIP + ' ' + options.navigationPosition + '">' + tooltip + '</div>';
839                }
840
841                li += '</li>';
842
843                nav.find('ul').append(li);
844            }
845
846            //centering it vertically
847            $(SECTION_NAV_SEL).css('margin-top', '-' + ($(SECTION_NAV_SEL).height()/2) + 'px');
848
849            //activating the current active section
850            $(SECTION_NAV_SEL).find('li').eq($(SECTION_ACTIVE_SEL).index(SECTION_SEL)).find('a').addClass(ACTIVE);
851        }
852
853        /**
854        * Creates the slim scroll scrollbar for the sections and slides inside them.
855        */
856        function createScrollBarHandler(){
857            $(SECTION_SEL).each(function(){
858                var slides = $(this).find(SLIDE_SEL);
859
860                if(slides.length){
861                    slides.each(function(){
862                        createScrollBar($(this));
863                    });
864                }else{
865                    createScrollBar($(this));
866                }
867
868            });
869            afterRenderActions();
870        }
871
872        /*
873        * Enables the Youtube videos API so we can control their flow if necessary.
874        */
875        function enableYoutubeAPI(){
876            container.find('iframe[src*="youtube.com/embed/"]').each(function(){
877                addURLParam($(this), 'enablejsapi=1');
878            });
879        }
880
881        /**
882        * Adds a new parameter and its value to the `src` of a given element
883        */
884        function addURLParam(element, newParam){
885            var originalSrc = element.attr('src');
886            element.attr('src', originalSrc + getUrlParamSign(originalSrc) + newParam);
887        }
888
889        /*
890        * Returns the prefix sign to use for a new parameter in an existen URL.
891        *
892        * @return {String}  ? | &
893        */
894        function getUrlParamSign(url){
895            return ( !/\?/.test( url ) ) ? '?' : '&';
896        }
897
898        /**
899        * Actions and callbacks to fire afterRender
900        */
901        function afterRenderActions(){
902            var section = $(SECTION_ACTIVE_SEL);
903
904            section.addClass(COMPLETELY);
905
906            if(options.scrollOverflowHandler.afterRender){
907                options.scrollOverflowHandler.afterRender(section);
908            }
909            lazyLoad(section);
910            playMedia(section);
911            options.scrollOverflowHandler.afterLoad();
912
913            if(isDestinyTheStartingSection()){
914                $.isFunction( options.afterLoad ) && options.afterLoad.call(section, section.data('anchor'), (section.index(SECTION_SEL) + 1));
915            }
916
917            $.isFunction( options.afterRender ) && options.afterRender.call(container);
918        }
919
920        /**
921        * Determines if the URL anchor destiny is the starting section (the one using 'active' class before initialization)
922        */
923        function isDestinyTheStartingSection(){
924            var anchors =  window.location.hash.replace('#', '').split('/');
925            var destinationSection = getSectionByAnchor(decodeURIComponent(anchors[0]));
926
927            return !destinationSection.length || destinationSection.length && destinationSection.index() === startingSection.index();
928        }
929
930
931        var isScrolling = false;
932        var lastScroll = 0;
933
934        //when scrolling...
935        function scrollHandler(){
936            var currentSection;
937
938            if(!options.autoScrolling || options.scrollBar){
939                var currentScroll = $window.scrollTop();
940                var scrollDirection = getScrollDirection(currentScroll);
941                var visibleSectionIndex = 0;
942                var screen_mid = currentScroll + ($window.height() / 2.0);
943                var isAtBottom = $body.height() - $window.height() === currentScroll;
944                var sections =  document.querySelectorAll(SECTION_SEL);
945
946                //when using `auto-height` for a small last section it won't be centered in the viewport
947                if(isAtBottom){
948                    visibleSectionIndex = sections.length - 1;
949                }
950                //is at top? when using `auto-height` for a small first section it won't be centered in the viewport
951                else if(!currentScroll){
952                    visibleSectionIndex = 0;
953                }
954
955                //taking the section which is showing more content in the viewport
956                else{
957                    for (var i = 0; i < sections.length; ++i) {
958                        var section = sections[i];
959
960                        // Pick the the last section which passes the middle line of the screen.
961                        if (section.offsetTop <= screen_mid)
962                        {
963                            visibleSectionIndex = i;
964                        }
965                    }
966                }
967
968                if(isCompletelyInViewPort(scrollDirection)){
969                    if(!$(SECTION_ACTIVE_SEL).hasClass(COMPLETELY)){
970                        $(SECTION_ACTIVE_SEL).addClass(COMPLETELY).siblings().removeClass(COMPLETELY);
971                    }
972                }
973
974                //geting the last one, the current one on the screen
975                currentSection = $(sections).eq(visibleSectionIndex);
976
977                //setting the visible section as active when manually scrolling
978                //executing only once the first time we reach the section
979                if(!currentSection.hasClass(ACTIVE)){
980                    isScrolling = true;
981                    var leavingSection = $(SECTION_ACTIVE_SEL);
982                    var leavingSectionIndex = leavingSection.index(SECTION_SEL) + 1;
983                    var yMovement = getYmovement(currentSection);
984                    var anchorLink  = currentSection.data('anchor');
985                    var sectionIndex = currentSection.index(SECTION_SEL) + 1;
986                    var activeSlide = currentSection.find(SLIDE_ACTIVE_SEL);
987                    var slideIndex;
988                    var slideAnchorLink;
989
990                    if(activeSlide.length){
991                        slideAnchorLink = activeSlide.data('anchor');
992                        slideIndex = activeSlide.index();
993                    }
994
995                    if(canScroll){
996                        currentSection.addClass(ACTIVE).siblings().removeClass(ACTIVE);
997
998                        $.isFunction( options.onLeave ) && options.onLeave.call( leavingSection, leavingSectionIndex, sectionIndex, yMovement);
999                        $.isFunction( options.afterLoad ) && options.afterLoad.call( currentSection, anchorLink, sectionIndex);
1000
1001                        stopMedia(leavingSection);
1002                        lazyLoad(currentSection);
1003                        playMedia(currentSection);
1004
1005                        activateMenuAndNav(anchorLink, sectionIndex - 1);
1006
1007                        if(options.anchors.length){
1008                            //needed to enter in hashChange event when using the menu with anchor links
1009                            lastScrolledDestiny = anchorLink;
1010                        }
1011                        setState(slideIndex, slideAnchorLink, anchorLink, sectionIndex);
1012                    }
1013
1014                    //small timeout in order to avoid entering in hashChange event when scrolling is not finished yet
1015                    clearTimeout(scrollId);
1016                    scrollId = setTimeout(function(){
1017                        isScrolling = false;
1018                    }, 100);
1019                }
1020
1021                if(options.fitToSection){
1022                    //for the auto adjust of the viewport to fit a whole section
1023                    clearTimeout(scrollId2);
1024
1025                    scrollId2 = setTimeout(function(){
1026                        //checking it again in case it changed during the delay
1027                        if(options.fitToSection){
1028                            fitToSection();
1029                        }
1030                    }, options.fitToSectionDelay);
1031                }
1032            }
1033        }
1034
1035        /**
1036        * Fits the site to the nearest active section
1037        */
1038        function fitToSection(){
1039            //checking fitToSection again in case it was set to false before the timeout delay
1040            if(canScroll){
1041                //allows to scroll to an active section and
1042                //if the section is already active, we prevent firing callbacks
1043                isResizing = true;
1044
1045                scrollPage($(SECTION_ACTIVE_SEL));
1046                isResizing = false;
1047            }
1048        }
1049
1050        /**
1051        * Determines whether the active section has seen in its whole or not.
1052        */
1053        function isCompletelyInViewPort(movement){
1054            var top = $(SECTION_ACTIVE_SEL).position().top;
1055            var bottom = top + $window.height();
1056
1057            if(movement == 'up'){
1058                return bottom >= ($window.scrollTop() + $window.height());
1059            }
1060            return top <= $window.scrollTop();
1061        }
1062
1063        /**
1064        * Gets the directon of the the scrolling fired by the scroll event.
1065        */
1066        function getScrollDirection(currentScroll){
1067            var direction = currentScroll > lastScroll ? 'down' : 'up';
1068
1069            lastScroll = currentScroll;
1070
1071            //needed for auto-height sections to determine if we want to scroll to the top or bottom of the destination
1072            previousDestTop = currentScroll;
1073
1074            return direction;
1075        }
1076
1077        /**
1078        * Determines the way of scrolling up or down:
1079        * by 'automatically' scrolling a section or by using the default and n
1079ormal scrolling.
1080        */
1081        function scrolling(type, scrollable){
1082            if (!isScrollAllowed.m[type]){
1083                return;
1084            }
1085            var check = (type === 'down') ? 'bottom' : 'top';
1086            var scrollSection = (type === 'down') ? moveSectionDown : moveSectionUp;
1087
1088            if(scrollable.length > 0 ){
1089                //is the scrollbar at the start/end of the scroll?
1090                if(options.scrollOverflowHandler.isScrolled(check, scrollable)){
1091                    scrollSection();
1092                }else{
1093                    return true;
1094                }
1095            }else{
1096                // moved up/down
1097                scrollSection();
1098            }
1099        }
1100
1101        /*
1102        * Preventing bouncing in iOS #2285
1103        */
1104        function preventBouncing(event){
1105            var e = event.originalEvent;
1106            if(!checkParentForNormalScrollElement(event.target) && options.autoScrolling && isReallyTouch(e)){
1107                //preventing the easing on iOS devices
1108                event.preventDefault();
1109            }
1110        }
1111
1112        var touchStartY = 0;
1113        var touchStartX = 0;
1114        var touchEndY = 0;
1115        var touchEndX = 0;
1116
1117        /* Detecting touch events
1118
1119        * As we are changing the top property of the page on scrolling, we can not use the traditional way to detect it.
1120        * This way, the touchstart and the touch moves shows an small difference between them which is the
1121        * used one to determine the direction.
1122        */
1123        function touchMoveHandler(event){
1124            var e = event.originalEvent;
1125            var activeSection = $(e.target).closest(SECTION_SEL);
1126
1127            // additional: if one of the normalScrollElements isn't within options.normalScrollElementTouchThreshold hops up the DOM chain
1128            if (!checkParentForNormalScrollElement(event.target) && isReallyTouch(e) ) {
1129
1130                if(options.autoScrolling){
1131                    //preventing the easing on iOS devices
1132                    event.preventDefault();
1133                }
1134
1135                var scrollable = options.scrollOverflowHandler.scrollable(activeSection);
1136                var touchEvents = getEventsPage(e);
1137
1138                touchEndY = touchEvents.y;
1139                touchEndX = touchEvents.x;
1140
1141                //if movement in the X axys is greater than in the Y and the currect section has slides...
1142                if (activeSection.find(SLIDES_WRAPPER_SEL).length && Math.abs(touchStartX - touchEndX) > (Math.abs(touchStartY - touchEndY))) {
1143
1144                    //is the movement greater than the minimum resistance to scroll?
1145                    if (!slideMoving && Math.abs(touchStartX - touchEndX) > ($window.outerWidth() / 100 * options.touchSensitivity)) {
1146                        if (touchStartX > touchEndX) {
1147                            if(isScrollAllowed.m.right){
1148                                moveSlideRight(activeSection); //next
1149                            }
1150                        } else {
1151                            if(isScrollAllowed.m.left){
1152                                moveSlideLeft(activeSection); //prev
1153                            }
1154                        }
1155                    }
1156                }
1157
1158                //vertical scrolling (only when autoScrolling is enabled)
1159                else if(options.autoScrolling && canScroll){
1160
1161                    //is the movement greater than the minimum resistance to scroll?
1162                    if (Math.abs(touchStartY - touchEndY) > ($window.height() / 100 * options.touchSensitivity)) {
1163                        if (touchStartY > touchEndY) {
1164                            scrolling('down', scrollable);
1165                        } else if (touchEndY > touchStartY) {
1166                            scrolling('up', scrollable);
1167                        }
1168                    }
1169                }
1170            }
1171        }
1172
1173        /**
1174         * recursive function to loop up the parent nodes to check if one of them exists in options.normalScrollElements
1175         * Currently works well for iOS - Android might need some testing
1176         * @param  {Element} el  target element / jquery selector (in subsequent nodes)
1177         * @param  {int}     hop current hop compared to options.normalScrollElementTouchThreshold
1178         * @return {boolean} true if there is a match to options.normalScrollElements
1179         */
1180        function checkParentForNormalScrollElement (el, hop) {
1181            hop = hop || 0;
1182            var parent = $(el).parent();
1183
1184            if (hop < options.normalScrollElementTouchThreshold &&
1185                parent.is(options.normalScrollElements) ) {
1186                return true;
1187            } else if (hop == options.normalScrollElementTouchThreshold) {
1188                return false;
1189            } else {
1190                return checkParentForNormalScrollElement(parent, ++hop);
1191            }
1192        }
1193
1194        /**
1195        * As IE >= 10 fires both touch and mouse events when using a mouse in a touchscreen
1196        * this way we make sure that is really a touch event what IE is detecting.
1197        */
1198        function isReallyTouch(e){
1199            //if is not IE   ||  IE is detecting `touch` or `pen`
1200            return typeof e.pointerType === 'undefined' || e.pointerType != 'mouse';
1201        }
1202
1203        /**
1204        * Handler for the touch start event.
1205        */
1206        function touchStartHandler(event){
1207            var e = event.originalEvent;
1208
1209            //stopping the auto scroll to adjust to a section
1210            if(options.fitToSection){
1211                $htmlBody.stop();
1212            }
1213
1214            if(isReallyTouch(e)){
1215                var touchEvents = getEventsPage(e);
1216                touchStartY = touchEvents.y;
1217                touchStartX = touchEvents.x;
1218            }
1219        }
1220
1221        /**
1222        * Gets the average of the last `number` elements of the given array.
1223        */
1224        function getAverage(elements, number){
1225            var sum = 0;
1226
1227            //taking `number` elements from the end to make the average, if there are not enought, 1
1228            var lastElements = elements.slice(Math.max(elements.length - number, 1));
1229
1230            for(var i = 0; i < lastElements.length; i++){
1231                sum = sum + lastElements[i];
1232            }
1233
1234            return Math.ceil(sum/number);
1235        }
1236
1237        /**
1238         * Detecting mousewheel scrolling
1239         *
1240         * http://blogs.sitepointstatic.com/examples/tech/mouse-wheel/index.html
1241         * http://www.sitepoint.com/html5-javascript-mouse-wheel/
1242         */
1243        var prevTime = new Date().getTime();
1244
1245        function MouseWheelHandler(e) {
1246            var curTime = new Date().getTime();
1247            var isNormalScroll = $(COMPLETELY_SEL).hasClass(NORMAL_SCROLL);
1248
1249            //autoscrolling and not zooming?
1250            if(options.autoScrolling && !controlPressed && !isNormalScroll){
1251                // cross-browser wheel delta
1252                e = e || window.event;
1253                var value = e.wheelDelta || -e.deltaY || -e.detail;
1254                var delta = Math.max(-1, Math.min(1, value));
1255
1256                var horizontalDetection = typeof e.wheelDeltaX !== 'undefined' || typeof e.deltaX !== 'undefined';
1257                var isScrollingVertically = (Math.abs(e.wheelDeltaX) < Math.abs(e.wheelDelta)) || (Math.abs(e.deltaX ) < Math.abs(e.deltaY) || !horizontalDetection);
1258
1259                //Limiting the array to 150 (lets not waste memory!)
1260                if(scrollings.length > 149){
1261                    scrollings.shift();
1262                }
1263
1264                //keeping record of the previous scrollings
1265                scrollings.push(Math.abs(value));
1266
1267                //preventing to scroll the site on mouse wheel when scrollbar is present
1268                if(options.scrollBar){
1269                    e.preventDefault ? e.preventDefault() : e.returnValue = false;
1270                }
1271
1272                var activeSection = $(SECTION_ACTIVE_SEL);
1273                var scrollable = options.scrollOverflowHandler.scrollable(activeSection);
1274
1275                //time difference between the last scroll and the current one
1276                var timeDiff = curTime-prevTime;
1277                prevTime = curTime;
1278
1279                //haven't they scrolled in a while?
1280                //(enough to be consider a different scrolling action to scroll another section)
1281                if(timeDiff > 200){
1282                    //emptying the array, we dont care about old scrollings for our averages
1283                    scrollings = [];
1284                }
1285
1286                if(canScroll){
1287                    var averageEnd = getAverage(scrollings, 10);
1288                    var averageMiddle = getAverage(scrollings, 70);
1289                    var isAccelerating = averageEnd >= averageMiddle;
1290
1291                    //to avoid double swipes...
1292                    if(isAccelerating && isScrollingVertically){
1293                        //scrolling down?
1294                        if (delta < 0) {
1295                            scrolling('down', scrollable);
1296
1297                        //scrolling up?
1298                        }else {
1299                            scrolling('up', scrollable);
1300                        }
1301                    }
1302                }
1303
1304                return false;
1305            }
1306
1307            if(options.fitToSection){
1308                //stopping the auto scroll to adjust to a section
1309                $htmlBody.stop();
1310            }
1311        }
1312
1313        /**
1314        * Slides a slider to the given direction.
1315        * Optional `section` param.
1316        */
1317        function moveSlide(direction, section){
1318            var activeSection = typeof section === 'undefined' ? $(SECTION_ACTIVE_SEL) : section;
1319            var slides = activeSection.find(SLIDES_WRAPPER_SEL);
1320            var numSlides = slides.find(SLIDE_SEL).length;
1321
1322            // more than one slide needed and nothing should be sliding
1323            if (!slides.length || slideMoving || numSlides < 2) {
1324                return;
1325            }
1326
1327            var currentSlide = slides.find(SLIDE_ACTIVE_SEL);
1328            var destiny = null;
1329
1330            if(direction === 'left'){
1331                destiny = currentSlide.prev(SLIDE_SEL);
1332            }else{
1333                destiny = currentSlide.next(SLIDE_SEL);
1334            }
1335
1336            //isn't there a next slide in the secuence?
1337            if(!destiny.length){
1338                //respect loopHorizontal settin
1339                if (!options.loopHorizontal) return;
1340
1341                if(direction === 'left'){
1342                    destiny = currentSlide.siblings(':last');
1343                }else{
1344                    destiny = currentSlide.siblings(':first');
1345                }
1346            }
1347
1348            slideMoving = true;
1349
1350            landscapeScroll(slides, destiny, direction);
1351        }
1352
1353        /**
1354        * Maintains the active slides in the viewport
1355        * (Because the `scroll` animation might get lost with some actions, such as when using continuousVertical)
1356        */
1357        function keepSlidesPosition(){
1358            $(SLIDE_ACTIVE_SEL).each(function(){
1359                silentLandscapeScroll($(this), 'internal');
1360            });
1361        }
1362
1363        var previousDestTop = 0;
1364        /**
1365        * Returns the destination Y position based on the scrolling direction and
1366        * the height of the section.
1367        */
1368        function getDestinationPosition(element){
1369            var elemPosition = element.position();
1370
1371            //top of the desination will be at the top of the viewport
1372            var position = elemPosition.top;
1373            var isScrollingDown =  elemPosition.top > previousDestTop;
1374            var sectionBottom = position - windowsHeight + element.outerHeight();
1375            var bigSectionsDestination = options.bigSectionsDestination;
1376
1377            //is the destination element bigger than the viewport?
1378            if(element.outerHeight() > windowsHeight){
1379                //scrolling up?
1380                if(!isScrollingDown && !bigSectionsDestination || bigSectionsDestination === 'bottom' ){
1381                    position = sectionBottom;
1382                }
1383            }
1384
1385            //sections equal or smaller than the viewport height && scrolling down? ||  is resizing and its in the last section
1386            else if(isScrollingDown || (isResizing && element.is(':last-child')) ){
1387                //The bottom of the destination will be at the bottom of the viewport
1388                position = sectionBottom;
1389            }
1390
1391            /*
1392            Keeping record of the last scrolled position to determine the scrolling direction.
1393            No conventional methods can be used as the scroll bar might not be present
1394            AND the section might not be active if it is auto-height and didnt reach the middle
1395            of the viewport.
1396            */
1397            previousDestTop = position;
1398            return position;
1399        }
1400
1401        /**
1402        * Scrolls the site to the given element and scrolls to the slide if a callback is given.
1403        */
1404        function scrollPage(element, callback, isMovementUp){
1405            if(typeof element === 'undefined'){ return; } //there's no element to scroll, leaving the function
1406
1407            var dtop = getDestinationPosition(element);
1408            var slideAnchorLink;
1409            var slideIndex;
1410
1411            //local variables
1412            var v = {
1413                element: element,
1414                callback: callback,
1415                isMovementUp: isMovementUp,
1416                dtop: dtop,
1417                yMovement: getYmovement(element),
1418                anchorLink: element.data('anchor'),
1419                sectionIndex: element.index(SECTION_SEL),
1420                activeSlide: element.find(SLIDE_ACTIVE_SEL),
1421                activeSection: $(SECTION_ACTIVE_SEL),
1422                leavingSection: $(SECTION_ACTIVE_SEL).index(SECTION_SEL) + 1,
1423
1424                //caching the value of isResizing at the momment the function is called
1425                //because it will be checked later inside a setTimeout and the value might change
1426                localIsResizing: isResizing
1427            };
1428
1429            //quiting when destination scroll is the same as the current one
1430            if((v.activeSection.is(element) && !isResizing) || (options.scrollBar && $window.scrollTop() === v.dtop && !element.hasClass(AUTO_HEIGHT) )){ return; }
1431
1432            if(v.activeSlide.length){
1433                slideAnchorLink = v.activeSlide.data('anchor');
1434                slideIndex = v.activeSlide.index();
1435            }
1436
1437            // If continuousVertical && we need to wrap around
1438            if (options.autoScrolling && options.continuousVertical && typeof (v.isMovementUp) !== "undefined" &&
1439                ((!v.isMovementUp && v.yMovement == 'up') || // Intending to scroll down but about to go up or
1440                (v.isMovementUp && v.yMovement == 'down'))) { // intending to scroll up but about to go down
1441
1442                v = createInfiniteSections(v);
1443            }
1444
1445            //callback (onLeave) if the site is not just resizing and readjusting the slides
1446            if($.isFunction(options.onLeave) && !v.localIsResizing){
1447                if(options.onLeave.call(v.activeSection, v.leavingSection, (v.sectionIndex + 1), v.yMovement) === false){
1448                    return;
1449                }
1450            }
1451
1452            //pausing media of the leaving section (if we are not just resizing, as destinatino will be the same one)
1453            if(!v.localIsResizing){
1454                stopMedia(v.activeSection);
1455            }
1456
1457            options.scrollOverflowHandler.beforeLeave();
1458            element.addClass(ACTIVE).siblings().removeClass(ACTIVE);
1459            lazyLoad(element);
1460            options.scrollOverflowHandler.onLeave();
1461
1462
1463            //preventing from activating the MouseWheelHandler event
1464            //more than once if the page is scrolling
1465            canScroll = false;
1466
1467            setState(slideIndex, slideAnchorLink, v.anchorLink, v.sectionIndex);
1468
1469            performMovement(v);
1470
1471            //flag to avoid callingn `scrollPage()` twice in case of using anchor links
1472            lastScrolledDestiny = v.anchorLink;
1473
1474            //avoid firing it twice (as it does also on scroll)
1475            activateMenuAndNav(v.anchorLink, v.sectionIndex);
1476        }
1477
1478        /**
1479        * Performs the vertical movement (by CSS3 or by jQuery)
1480        */
1481        function performMovement(v){
1482            // using CSS3 translate functionality
1483            if (options.css3 && options.autoScrolling && !options.scrollBar) {
1484
1485                // The first section can have a negative value in iOS 10. Not quite sure why: -0.0142822265625
1486                // that's why we round it to 0.
1487                var translate3d = 'translate3d(0px, -' + Math.round(v.dtop) + 'px, 0px)';
1488                transformContainer(translate3d, true);
1489
1490                //even when the scrollingSpeed is 0 there's a little delay, which might cause the
1491                //scrollingSpeed to change in case of using silentMoveTo();
1492                if(options.scrollingSpeed){
1493                    clearTimeout(afterSectionLoadsId);
1494                    afterSectionLoadsId = setTimeout(function () {
1495                        afterSectionLoads(v);
1496                    }, options.scrollingSpeed);
1497                }else{
1498                    afterSectionLoads(v);
1499                }
1500            }
1501
1502            // using jQuery animate
1503            else{
1504                var scrollSettings = getScrollSettings(v);
1505
1506                $(scrollSettings.element).animate(
1507                    scrollSettings.options,
1508                options.scrollingSpeed, options.easing).promise().done(function () { //only one single callback in case of animating  `html, body`
1509                    if(options.scrollBar){
1510
1511                        /* Hack!
1512                        The timeout prevents setting the most dominant section in the viewport as "active" when the user
1513                        scrolled to a smaller section by using the mousewheel (auto scrolling) rather than draging the scroll bar.
1514
1515                        When using scrollBar:true It seems like the scroll events still getting propagated even after the scrolling animation has finished.
1516                        */
1517                        setTimeout(function(){
1518                            afterSectionLoads(v);
1519                        },30);
1520                    }else{
1521                        afterSectionLoads(v);
1522                    }
1523                });
1524            }
1525        }
1526
1527        /**
1528        * Gets the scrolling settings depending on the plugin autoScrolling option
1529        */
1530        function getScrollSettings(v){
1531            var scroll = {};
1532
1533            if(options.autoScrolling && !options.scrollBar){
1534                scroll.options = { 'top': -v.dtop};
1535                scroll.element = WRAPPER_SEL;
1536            }else{
1537                scroll.options = { 'scrollTop': v.dtop};
1538                scroll.element = 'html, body';
1539            }
1540
1541            return scroll;
1542        }
1543
1544        /**
1545        * Adds sections before or after the current one to create the infinite effect.
1546        */
1547        function createInfiniteSections(v){
1548            // Scrolling down
1549            if (!v.isMovementUp) {
1550                // Move all previous sections to after the active section
1551                $(SECTION_ACTIVE_SEL).after(v.activeSection.prevAll(SECTION_SEL).get().reverse());
1552            }
1553            else { // Scrolling up
1554                // Move all next sections to before the active section
1555                $(SECTION_ACTIVE_SEL).before(v.activeSection.nextAll(SECTION_SEL));
1556            }
1557
1558            // Maintain the displayed position (now that we changed the element order)
1559            silentScroll($(SECTION_ACTIVE_SEL).position().top);
1560
1561            // Maintain the active slides visible in the viewport
1562            keepSlidesPosition();
1563
1564            // save for later the elements that still need to be reordered
1565            v.wrapAroundElements = v.activeSection;
1566
1567            // Recalculate animation variables
1568            v.dtop = v.element.position().top;
1569            v.yMovement = getYmovement(v.element);
1570
1571            return v;
1572        }
1573
1574        /**
1575        * Fix section order after continuousVertical changes have been animated
1576        */
1577        function continuousVerticalFixSectionOrder (v) {
1578            // If continuousVertical is in effect (and autoScrolling would also be in effect then),
1579            // finish moving the elements around so the direct navigation will function more simply
1580            if (!v.wrapAroundElements || !v.wrapAroundElements.length) {
1581                return;
1582            }
1583
1584            if (v.isMovementUp) {
1585                $(SECTION_FIRST_SEL).before(v.wrapAroundElements);
1586            }
1587            else {
1588                $(SECTION_LAST_SEL).after(v.wrapAroundElements);
1589            }
1590
1591            silentScroll($(SECTION_ACTIVE_SEL).position().top);
1592
1593            // Maintain the active slides visible in the viewport
1594            keepSlidesPosition();
1595        }
1596
1597
1598        /**
1599        * Actions to do once the section is loaded.
1600        */
1601        function afterSectionLoads (v){
1602            continuousVerticalFixSectionOrder(v);
1603
1604            //callback (afterLoad) if the site is not just resizing and readjusting the slides
1605            $.isFunction(options.afterLoad) && !v.localIsResizing && options.afterLoad.call(v.element, v.anchorLink, (v.sectionIndex + 1));
1606            options.scrollOverflowHandler.afterLoad();
1607
1608            if(!v.localIsResizing){
1609                playMedia(v.element);
1610            }
1611
1612            v.element.addClass(COMPLETELY).siblings().removeClass(COMPLETELY);
1613
1614            canScroll = true;
1615
1616            $.isFunction(v.callback) && v.callback.call(this);
1617        }
1618
1619        /**
1620        * Sets the value for the given attribute from the `data-` attribute with the same suffix
1621        * ie: data-srcset ==> srcset  |  data-src ==> src
1622        */
1623        function setSrc(element, attribute){
1624            element
1625                .attr(attribute, element.data(attribute))
1626                .removeAttr('data-' + attribute);
1627        }
1628
1629        /**
1630        * Lazy loads image, video and audio elements.
1631        */
1632        function lazyLoad(destiny){
1633            if (!options.lazyLoading){
1634                return;
1635            }
1636
1637            var panel = getSlideOrSection(destiny);
1638            var element;
1639
1640            panel.find('img[data-src], img[data-srcset], source[data-src], audio[data-src], iframe[data-src]').each(function(){
1641                element = $(this);
1642
1643                $.each(['src', 'srcset'], function(index, type){
1644                    var attribute = element.attr('data-' + type);
1645                    if(typeof attribute !== 'undefined' && attribute){
1646                        setSrc(element, type);
1647                    }
1648                });
1649
1650                if(element.is('source')){
1651                    element.closest('video').get(0).load();
1652                }
1653            });
1654        }
1655
1656        /**
1657        * Plays video and audio elements.
1658        */
1659        function playMedia(destiny){
1660            var panel = getSlideOrSection(destiny);
1661
1662            //playing HTML5 media elements
1663            panel.find('video, audio').each(function(){
1664                var element = $(this).get(0);
1665
1666                if( element.hasAttribute('data-autoplay') && typeof element.play === 'function' ) {
1667                    element.play();
1668                }
1669            });
1670
1671            //youtube videos
1672            panel.find('iframe[src*="youtube.com/embed/"]').each(function(){
1673                var element = $(this).get(0);
1674
1675                if ( element.hasAttribute('data-autoplay') ){
1676                    playYoutube(element);
1677                }
1678
1679                //in case the URL was not loaded yet. On page load we need time for the new URL (with the API string) to load.
1680                element.onload = function() {
1681                    if ( element.hasAttribute('data-autoplay') ){
1682                        playYoutube(element);
1683                    }
1684                };
1685            });
1686        }
1687
1688        /**
1689        * Plays a youtube video
1690        */
1691        function playYoutube(element){
1692            element.contentWindow.postMessage('{"event":"command","func":"playVideo","args":""}', '*');
1693        }
1694
1695        /**
1696        * Stops video and audio elements.
1697        */
1698        function stopMedia(destiny){
1699            var panel = getSlideOrSection(destiny);
1700
1701            //stopping HTML5 media elements
1702            panel.find('video, audio').each(function(){
1703                var element = $(this).get(0);
1704
1705                if( !element.hasAttribute('data-keepplaying') && typeof element.pause === 'function' ) {
1706                    element.pause();
1707                }
1708            });
1709
1710            //youtube videos
1711            panel.find('iframe[src*="youtube.com/embed/"]').each(function(){
1712                var element = $(this).get(0);
1713
1714                if( /youtube\.com\/embed\//.test($(this).attr('src')) && !element.hasAttribute('data-keepplaying')){
1715                    $(this).get(0).contentWindow.postMessage('{"event":"command","func":"pauseVideo","args":""}','*');
1716                }
1717            });
1718        }
1719
1720        /**
1721        * Gets the active slide (or section) for the given section
1722        */
1723        function getSlideOrSection(destiny){
1724            var slide = destiny.find(SLIDE_ACTIVE_SEL);
1725            if( slide.length ) {
1726                destiny = $(slide);
1727            }
1728
1729            return destiny;
1730        }
1731
1732        /**
1733        * Scrolls to the anchor in the URL when loading the site
1734        */
1735        function scrollToAnchor(){
1736            //getting the anchor link in the URL and deleting the `#`
1737            var value =  window.location.hash.replace('#', '').split('/');
1738            var sectionAnchor = decodeURIComponent(value[0]);
1739            var slideAnchor = decodeURIComponent(value[1]);
1740
1741            if(sectionAnchor){  //if theres any #
1742                if(options.animateAnchor){
1743                    scrollPageAndSlide(sectionAnchor, slideAnchor);
1744                }else{
1745                    silentMoveTo(sectionAnchor, slideAnchor);
1746                }
1747            }
1748        }
1749
1750        /**
1751        * Detecting any change on the URL to scroll to the given anchor link
1752        * (a way to detect back history button as we play with the hashes on the URL)
1753        */
1754        function hashChangeHandler(){
1755            if(!isScrolling && !options.lockAnchors){
1756                var value =  window.location.hash.replace('#', '').split('/');
1757                var sectionAnchor = decodeURIComponent(value[0]);
1758                var slideAnchor = decodeURIComponent(value[1]);
1759
1760                    //when moving to a slide in the first section for the first time (first time to add an anchor to the URL)
1761                    var isFirstSlideMove =  (typeof lastScrolledDestiny === 'undefined');
1762                    var isFirstScrollMove = (typeof lastScrolledDestiny === 'undefined' && typeof slideAnchor === 'undefined' && !slideMoving);
1763
1764
1765                if(sectionAnchor.length){
1766                    /*in order to call scrollpage() only once for each destination at a time
1767                    It is called twice for each scroll otherwise, as in case of using anchorlinks `hashChange`
1768                    event is fired on every scroll too.*/
1769                    if ((sectionAnchor && sectionAnchor !== lastScrolledDestiny) && !isFirstSlideMove || isFirstScrollMove || (!slideMoving && lastScrolledSlide != slideAnchor ))  {
1770                        scrollPageAndSlide(sectionAnchor, slideAnchor);
1771                    }
1772                }
1773            }
1774        }
1775
1776        //Sliding with arrow keys, both, vertical and horizontal
1777        function keydownHandler(e) {
1778
1779            clearTimeout(keydownId);
1780
1781            var activeElement = $(':focus');
1782
1783            if(!activeElement.is('textarea') && !activeElement.is('input') && !activeElement.is('select') &&
1784                activeElement.attr('contentEditable') !== "true" && activeElement.attr('contentEditable') !== '' &&
1785                options.keyboardScrolling && options.autoScrolling){
1786                var keyCode = e.which;
1787
1788                //preventing the scroll with arrow keys & spacebar & Page Up & Down keys
1789                var keyControls = [40, 38, 32, 33, 34];
1790                if($.inArray(keyCode, keyControls) > -1){
1791                    e.preventDefault();
1792                }
1793
1794                controlPressed = e.ctrlKey;
1795
1796                keydownId = setTimeout(function(){
1797                    onkeydown(e);
1798                },150);
1799            }
1800        }
1801
1802        function tooltipTextHandler(){
1803            $(this).prev().trigger('click');
1804        }
1805
1806        //to prevent scrolling while zooming
1807        function keyUpHandler(e){
1808            if(isWindowFocused){ //the keyup gets fired on new tab ctrl + t in Firefox
1809                controlPressed = e.ctrlKey;
1810            }
1811        }
1812
1813        //binding the mousemove when the mouse's middle button is released
1814        function mouseDownHandler(e){
1815            //middle button
1816            if (e.which == 2){
1817                oldPageY = e.pageY;
1818                container.on('mousemove', mouseMoveHandler);
1819            }
1820        }
1821
1822        //unbinding the mousemove when the mouse's middle button is released
1823        function mouseUpHandler(e){
1824            //middle button
1825            if (e.which == 2){
1826                container.off('mousemove');
1827            }
1828        }
1829
1830        //Scrolling horizontally when clicking on the slider controls.
1831        function slideArrowHandler(){
1832            var section = $(this).closest(SECTION_SEL);
1833
1834            if ($(this).hasClass(SLIDES_PREV)) {
1835                if(isScrollAllowed.m.left){
1836                    moveSlideLeft(section);
1837                }
1838            } else {
1839                if(isScrollAllowed.m.right){
1840                    moveSlideRight(section);
1841                }
1842            }
1843        }
1844
1845        //when opening a new tab (ctrl + t), `control` won't be pressed when coming back.
1846        function blurHandler(){
1847            isWindowFocused = false;
1848            controlPressed = false;
1849        }
1850
1851        //Scrolls to the section when clicking the navigation bullet
1852        function sectionBulletHandler(e){
1853            e.preventDefault();
1854            var index = $(this).parent().index();
1855            scrollPage($(SECTION_SEL).eq(index));
1856        }
1857
1858        //Scrolls the slider to the given slide destination for the given section
1859        function slideBulletHandler(e){
1860            e.preventDefault();
1861            var slides = $(this).closest(SECTION_SEL).find(SLIDES_WRAPPER_SEL);
1862            var destiny = slides.find(SLIDE_SEL).eq($(this).closest('li').index());
1863
1864            landscapeScroll(slides, destiny);
1865        }
1866
1867        /**
1868        * Keydown event
1869        */
1870        function onkeydown(e){
1871            var shiftPressed = e.shiftKey;
1872
1873            //do nothing if we can not scroll or we are not using horizotnal key arrows.
1874            if(!canScroll && [37,39].indexOf(e.which) < 0){
1875                return;
1876            }
1877
1878            switch (e.which) {
1879                //up
1880                case 38:
1881                case 33:
1882                    if(isScrollAllowed.k.up){
1883                        moveSectionUp();
1884                    }
1885                    break;
1886
1887                //down
1888                case 32: //spacebar
1889                    if(shiftPressed && isScrollAllowed.k.up){
1890                        moveSectionUp();
1891                        break;
1892                    }
1893                /* falls through */
1894                case 40:
1895                case 34:
1896                    if(isScrollAllowed.k.down){
1897                        moveSectionDown();
1898                    }
1899                    break;
1900
1901                //Home
1902                case 36:
1903                    if(isScrollAllowed.k.up){
1904                        moveTo(1);
1905                    }
1906                    break;
1907
1908                //End
1909                case 35:
1910                     if(isScrollAllowed.k.down){
1911                        moveTo( $(SECTION_SEL).length );
1912                    }
1913                    break;
1914
1915                //left
1916                case 37:
1917                    if(isScrollAllowed.k.left){
1918                        moveSlideLeft();
1919                    }
1920                    break;
1921
1922                //right
1923                case 39:
1924                    if(isScrollAllowed.k.right){
1925                        moveSlideRight();
1926                    }
1927                    break;
1928
1929                default:
1930                    return; // exit this handler for other keys
1931            }
1932        }
1933
1934        /**
1935        * Detecting the direction of the mouse movement.
1936        * Used only for the middle button of the mouse.
1937        */
1938        var oldPageY = 0;
1939        function mouseMoveHandler(e){
1940            if(canScroll){
1941                // moving up
1942                if (e.pageY < oldPageY && isScrollAllowed.m.up){
1943                    moveSectionUp();
1944                }
1945
1946                // moving down
1947                else if(e.pageY > oldPageY && isScrollAllowed.m.down){
1948                    moveSectionDown();
1949                }
1950            }
1951            oldPageY = e.pageY;
1952        }
1953
1954        /**
1955        * Scrolls horizontal sliders.
1956        */
1957        function landscapeScroll(slides, destiny, direction){
1958            var section = slides.closest(SECTION_SEL);
1959            var v = {
1960                slides: slides,
1961                destiny: destiny,
1962                direction: direction,
1963                destinyPos: destiny.position(),
1964                slideIndex: destiny.index(),
1965                section: section,
1966                sectionIndex: section.index(SECTION_SEL),
1967                anchorLink: section.data('anchor'),
1968                slidesNav: section.find(SLIDES_NAV_SEL),
1969                slideAnchor:  getAnchor(destiny),
1970                prevSlide: section.find(SLIDE_ACTIVE_SEL),
1971                prevSlideIndex: section.find(SLIDE_ACTIVE_SEL).index(),
1972
1973                //caching the value of isResizing at the momment the function is called
1974                //because it will be checked later inside a setTimeout and the value might change
1975                localIsResizing: isResizing
1976            };
1977            v.xMovement = getXmovement(v.prevSlideIndex, v.slideIndex);
1978
1979            //important!! Only do it when not resizing
1980            if(!v.localIsResizing){
1981                //preventing from scrolling to the next/prev section when using scrollHorizontally
1982                canScroll = false;
1983            }
1984
1985            if(options.onSlideLeave){
1986
1987                //if the site is not just resizing and readjusting the slides
1988                if(!v.localIsResizing && v.xMovement!=='none'){
1989                    if($.isFunction( options.onSlideLeave )){
1990                        if(options.onSlideLeave.call( v.prevSlide, v.anchorLink, (v.sectionIndex + 1), v.prevSlideIndex, v.xMovement, v.slideIndex ) === false){
1991                            slideMoving = false;
1992                            return;
1993                        }
1994                    }
1995                }
1996            }
1997
1998            destiny.addClass(ACTIVE).siblings().removeClass(ACTIVE);
1999
2000            if(!v.localIsResizing){
2001                stopMedia(v.prevSlide);
2002                lazyLoad(destiny);
2003            }
2004
2005            if(!options.loopHorizontal && options.controlArrows){
2006                //hidding it for the fist slide, showing for the rest
2007                section.find(SLIDES_ARROW_PREV_SEL).toggle(v.slideIndex!==0);
2008
2009                //hidding it for the last slide, showing for the rest
2010                section.find(SLIDES_ARROW_NEXT_SEL).toggle(!destiny.is(':last-child'));
2011            }
2012
2013            //only changing the URL if the slides are in the current section (not for resize re-adjusting)
2014            if(section.hasClass(ACTIVE) && !v.localIsResizing){
2015                setState(v.slideIndex, v.slideAnchor, v.anchorLink, v.sectionIndex);
2016            }
2017
2018            performHorizontalMove(slides, v, true);
2019        }
2020
2021
2022        function afterSlideLoads(v){
2023            activeSlidesNavigation(v.slidesNav, v.slideIndex);
2024
2025            //if the site is not just resizing and readjusting the slides
2026            if(!v.localIsResizing){
2027                $.isFunction( options.afterSlideLoad ) && options.afterSlideLoad.call( v.destiny, v.anchorLink, (v.sectionIndex + 1), v.slideAnchor, v.slideIndex);
2028
2029                //needs to be inside the condition to prevent problems with continuousVertical and scrollHorizontally
2030                //and to prevent double scroll right after a windows resize
2031                canScroll = true;
2032
2033                playMedia(v.destiny);
2034            }
2035
2036            //letting them slide again
2037            slideMoving = false;
2038        }
2039
2040        /**
2041        * Performs the horizontal movement. (CSS3 or jQuery)
2042        *
2043        * @param fireCallback {Bool} - determines whether or not to fire the callback
2044        */
2045        function performHorizontalMove(slides, v, fireCallback){
2046            var destinyPos = v.destinyPos;
2047
2048            if(options.css3){
2049                var translate3d = 'translate3d(-' + Math.round(destinyPos.left) + 'px, 0px, 0px)';
2050
2051                addAnimation(slides.find(SLIDES_CONTAINER_SEL)).css(getTransforms(translate3d));
2052
2053                afterSlideLoadsId = setTimeout(function(){
2054                    fireCallback && afterSlideLoads(v);
2055                }, options.scrollingSpeed, options.easing);
2056            }else{
2057                slides.animate({
2058                    scrollLeft : Math.round(destinyPos.left)
2059                }, options.scrollingSpeed, options.easing, function() {
2060
2061                    fireCallback && afterSlideLoads(v);
2062                });
2063            }
2064        }
2065
2066        /**
2067        * Sets the state for the horizontal bullet navigations.
2068        */
2069        function activeSlidesNavigation(slidesNav, slideIndex){
2070            slidesNav.find(ACTIVE_SEL).removeClass(ACTIVE);
2071            slidesNav.find('li').eq(slideIndex).find('a').addClass(ACTIVE);
2072        }
2073
2074        var previousHeight = windowsHeight;
2075
2076        //when resizing the site, we adjust the heights of the sections, slimScroll...
2077        function resizeHandler(){
2078            //checking if it needs to get responsive
2079            responsive();
2080
2081            // rebuild immediately on touch devices
2082            if (isTouchDevice) {
2083                var activeElement = $(document.activeElement);
2084
2085                //if the keyboard is NOT visible
2086                if (!activeElement.is('textarea') && !activeElement.is('input') && !activeElement.is('select')) {
2087                    var currentHeight = $window.height();
2088
2089                    //making sure the change in the viewport size is enough to force a rebuild. (20 % of the window to avoid problems when hidding scroll bars)
2090                    if( Math.abs(currentHeight - previousHeight) > (20 * Math.max(previousHeight, currentHeight) / 100) ){
2091                        reBuild(true);
2092                        previousHeight = currentHeight;
2093                    }
2094                }
2095            }else{
2096                //in order to call the functions only when the resize is finished
2097                //http://stackoverflow.com/questions/4298612/jquery-how-to-call-resize-event-only-once-its-finished-resizing
2098                clearTimeout(resizeId);
2099
2100                resizeId = setTimeout(function(){
2101                    reBuild(true);
2102                }, 350);
2103            }
2104        }
2105
2106        /**
2107        * Checks if the site needs to get responsive and disables autoScrolling if so.
2108        * A class `fp-responsive` is added to the plugin's container in case the user wants to use it for his own responsive CSS.
2109        */
2110        function responsive(){
2111            var widthLimit = options.responsive || options.responsiveWidth; //backwards compatiblity
2112            var heightLimit = options.responsiveHeight;
2113
2114            //only calculating what we need. Remember its called on the resize event.
2115            var isBreakingPointWidth = widthLimit && $window.outerWidth() < widthLimit;
2116            var isBreakingPointHeight = heightLimit && $window.height() < heightLimit;
2117
2118            if(widthLimit && heightLimit){
2119                setResponsive(isBreakingPointWidth || isBreakingPointHeight);
2120            }
2121            else if(widthLimit){
2122                setResponsive(isBreakingPointWidth);
2123            }
2124            else if(heightLimit){
2125                setResponsive(isBreakingPointHeight);
2126            }
2127        }
2128
2129        /**
2130        * Adds transition animations for the given element
2131        */
2132        function addAnimation(element){
2133            var transition = 'all ' + options.scrollingSpeed + 'ms ' + options.easingcss3;
2134
2135            element.removeClass(NO_TRANSITION);
2136            return element.css({
2137                '-webkit-transition': transition,
2138                'transition': transition
2139            });
2140        }
2141
2142        /**
2143        * Remove transition animations for the given element
2144        */
2145        function removeAnimation(element){
2146            return element.addClass(NO_TRANSITION);
2147        }
2148
2149        /**
2150        * Activating the vertical navigation bullets according to the given slide name.
2151        */
2152        function activateNavDots(name, sectionIndex){
2153            if(options.navigation){
2154                $(SECTION_NAV_SEL).find(ACTIVE_SEL).removeClass(ACTIVE);
2155                if(name){
2156                    $(SECTION_NAV_SEL).find('a[href="#' + name + '"]').addClass(ACTIVE);
2157                }else{
2158                    $(SECTION_NAV_SEL).find('li').eq(sectionIndex).find('a').addClass(ACTIVE);
2159                }
2160            }
2161        }
2162
2163        /**
2164        * Activating the website main menu elements according to the given slide name.
2165        */
2166        function activateMenuElement(name){
2167            if(options.menu){
2168                $(options.menu).find(ACTIVE_SEL).removeClass(ACTIVE);
2169                $(options.menu).find('[data-menuanchor="'+name+'"]').addClass(ACTIVE);
2170            }
2171        }
2172
2173        /**
2174        * Sets to active the current menu and vertical nav items.
2175        */
2176        function activateMenuAndNav(anchor, index){
2177            activateMenuElement(anchor);
2178            activateNavDots(anchor, index);
2179        }
2180
2181        /**
2182        * Retuns `up` or `down` depending on the scrolling movement to reach its destination
2183        * from the current section.
2184        */
2185        function getYmovement(destiny){
2186            var fromIndex = $(SECTION_ACTIVE_SEL).index(SECTION_SEL);
2187            var toIndex = destiny.index(SECTION_SEL);
2188            if( fromIndex == toIndex){
2189                return 'none';
2190            }
2191            if(fromIndex > toIndex){
2192                return 'up';
2193            }
2194            return 'down';
2195        }
2196
2197        /**
2198        * Retuns `right` or `left` depending on the scrolling movement to reach its destination
2199        * from the current slide.
2200        */
2201        function getXmovement(fromIndex, toIndex){
2202            if( fromIndex == toIndex){
2203                return 'none';
2204            }
2205            if(fromIndex > toIndex){
2206                return 'left';
2207            }
2208            return 'right';
2209        }
2210
2211        /**
2212        * Checks if the element needs scrollbar and if the user wants to apply it.
2213        * If so it creates it.
2214        *
2215        * @param {Object} element   jQuery object of the section or slide
2216        */
2217        function createScrollBar(element){
2218            //User doesn't want scrollbar here? Sayonara baby!
2219            if(element.hasClass('fp-noscroll')) return;
2220
2221            //needed to make `scrollHeight` work under Opera 12
2222            element.css('overflow', 'hidden');
2223
2224            var scrollOverflowHandler = options.scrollOverflowHandler;
2225            var wrap = scrollOverflowHandler.wrapContent();
2226            //in case element is a slide
2227            var section = element.closest(SECTION_SEL);
2228            var scrollable = scrollOverflowHandler.scrollable(element);
2229            var contentHeight;
2230
2231            //if there was scroll, the contentHeight will be the one in the scrollable section
2232            if(scrollable.length){
2233                contentHeight = scrollOverflowHandler.scrollHeight(element);
2234            }else{
2235                contentHeight = element.get(0).scrollHeight;
2236                if(options.verticalCentered){
2237                    contentHeight = element.find(TABLE_CELL_SEL).get(0).scrollHeight;
2238                }
2239            }
2240
2241            var scrollHeight = windowsHeight - parseInt(section.css('padding-bottom')) - parseInt(section.css('padding-top'));
2242
2243            //needs scroll?
2244            if ( contentHeight > scrollHeight) {
2245                //did we already have an scrollbar ? Updating it
2246                if(scrollable.length){
2247                    scrollOverflowHandler.update(element, scrollHeight);
2248                }
2249                //creating the scrolling
2250                else{
2251                    if(options.verticalCentered){
2252                        element.find(TABLE_CELL_SEL).wrapInner(wrap);
2253                    }else{
2254                        element.wrapInner(wrap);
2255                    }
2256                    scrollOverflowHandler.create(element, scrollHeight);
2257                }
2258            }
2259            //removing the scrolling when it is not necessary anymore
2260            else{
2261                scrollOverflowHandler.remove(element);
2262            }
2263
2264            //undo
2265            element.css('overflow', '');
2266        }
2267
2268        function addTableClass(element){
2269            //In case we are styling for the 2nd time as in with reponsiveSlides
2270            if(!element.hasClass(TABLE)){
2271                element.addClass(TABLE).wrapInner('<div class="' + TABLE_CELL + '" style="height:' + getTableHeight(element) + 'px;" />');
2272            }
2273        }
2274
2275        function getTableHeight(element){
2276            var sectionHeight = windowsHeight;
2277
2278            if(options.paddingTop || options.paddingBottom){
2279                var section = element;
2280                if(!section.hasClass(SECTION)){
2281                    section = element.closest(SECTION_SEL);
2282                }
2283
2284                var paddings = parseInt(section.css('padding-top')) + parseInt(section.css('padding-bottom'));
2285                sectionHeight = (windowsHeight - paddings);
2286            }
2287
2288            return sectionHeight;
2289        }
2290
2291        /**
2292        * Adds a css3 transform property to the container class with or without animation depending on the animated param.
2293        */
2294        function transformContainer(translate3d, animated){
2295            if(animated){
2296                addAnimation(container);
2297            }else{
2298                removeAnimation(container);
2299            }
2300
2301            container.css(getTransforms(translate3d));
2302
2303            //syncronously removing the class after the animation has been applied.
2304            setTimeout(function(){
2305                container.removeClass(NO_TRANSITION);
2306            },10);
2307        }
2308
2309        /**
2310        * Gets a section by its anchor / index
2311        */
2312        function getSectionByAnchor(sectionAnchor){
2313            if(!sectionAnchor) return [];
2314
2315            var section = container.find(SECTION_SEL + '[data-anchor="'+sectionAnchor+'"]');
2316            if(!section.length){
2317                section = $(SECTION_SEL).eq( sectionAnchor -1);
2318            }
2319
2320            return section;
2321        }
2322
2323        /**
2324        * Gets a slide inside a given section by its anchor / index
2325        */
2326        function getSlideByAnchor(slideAnchor, section){
2327            var slides = section.find(SLIDES_WRAPPER_SEL);
2328            var slide =  slides.find(SLIDE_SEL + '[data-anchor="'+slideAnchor+'"]');
2329
2330            if(!slide.length){
2331                slide = slides.find(SLIDE_SEL).eq(slideAnchor);
2332            }
2333
2334            return slide;
2335        }
2336
2337        /**
2338        * Scrolls to the given section and slide anchors
2339        */
2340        function scrollPageAndSlide(destiny, slide){
2341            var section = getSectionByAnchor(destiny);
2342
2343            //do nothing if there's no section with the given anchor name
2344            if(!section.length) return;
2345
2346            //default slide
2347            if (typeof slide === 'undefined') {
2348                slide = 0;
2349            }
2350
2351            //we need to scroll to the section and then to the slide
2352            if (destiny !== lastScrolledDestiny && !section.hasClass(ACTIVE)){
2353                scrollPage(section, function(){
2354                    scrollSlider(section, slide);
2355                });
2356            }
2357            //if we were already in the section
2358            else{
2359                scrollSlider(section, slide);
2360            }
2361        }
2362
2363        /**
2364        * Scrolls the slider to the given slide destination for the given section
2365        */
2366        function scrollSlider(section, slideAnchor){
2367            if(typeof slideAnchor !== 'undefined'){
2368                var slides = section.find(SLIDES_WRAPPER_SEL);
2369                var destiny =  getSlideByAnchor(slideAnchor, section);
2370
2371                if(destiny.length){
2372                    landscapeScroll(slides, destiny);
2373                }
2374            }
2375        }
2376
2377        /**
2378        * Creates a landscape navigation bar with dots for horizontal sliders.
2379        */
2380        function addSlidesNavigation(section, numSlides){
2381            section.append('<div class="' + SLIDES_NAV + '"><ul></ul></div>');
2382            var nav = section.find(SLIDES_NAV_SEL);
2383
2384            //top or bottom
2385            nav.addClass(options.slidesNavPosition);
2386
2387            for(var i=0; i< numSlides; i++){
2388                nav.find('ul').append('<li><a href="#"><span></span></a></li>');
2389            }
2390
2391            //centering it
2392            nav.css('margin-left', '-' + (nav.width()/2) + 'px');
2393
2394            nav.find('li').first().find('a').addClass(ACTIVE);
2395        }
2396
2397
2398        /**
2399        * Sets the state of the website depending on the active section/slide.
2400        * It changes the URL hash when needed and updates the body class.
2401        */
2402        function setState(slideIndex, slideAnchor, anchorLink, sectionIndex){
2403            var sectionHash = '';
2404
2405            if(options.anchors.length && !options.lockAnchors){
2406
2407                //isn't it the first slide?
2408                if(slideIndex){
2409                    if(typeof anchorLink !== 'undefined'){
2410                        sectionHash = anchorLink;
2411                    }
2412
2413                    //slide without anchor link? We take the index instead.
2414                    if(typeof slideAnchor === 'undefined'){
2415                        slideAnchor = slideIndex;
2416                    }
2417
2418                    lastScrolledSlide = slideAnchor;
2419                    setUrlHash(sectionHash + '/' + slideAnchor);
2420
2421                //first slide won't have slide anchor, just the section one
2422                }else if(typeof slideIndex !== 'undefined'){
2423                    lastScrolledSlide = slideAnchor;
2424                    setUrlHash(anchorLink);
2425                }
2426
2427                //section without slides
2428                else{
2429                    setUrlHash(anchorLink);
2430                }
2431            }
2432
2433            setBodyClass();
2434        }
2435
2436        /**
2437        * Sets the URL hash.
2438        */
2439        function setUrlHash(url){
2440            if(options.recordHistory){
2441                location.hash = url;
2442            }else{
2443                //Mobile Chrome doesn't work the normal way, so... lets use HTML5 for phones :)
2444                if(isTouchDevice || isTouch){
2445                    window.history.replaceState(undefined, undefined, '#' + url);
2446                }else{
2447                    var baseUrl = window.location.href.split('#')[0];
2448                    window.location.replace( baseUrl + '#' + url );
2449                }
2450            }
2451        }
2452
2453        /**
2454        * Gets the anchor for the given slide / section. Its index will be used if there's none.
2455        */
2456        function getAnchor(element){
2457            var anchor = element.data('anchor');
2458            var index = element.index();
2459
2460            //Slide without anchor link? We take the index instead.
2461            if(typeof anchor === 'undefined'){
2462                anchor = index;
2463            }
2464
2465            return anchor;
2466        }
2467
2468        /**
2469        * Sets a class for the body of the page depending on the active section / slide
2470        */
2471        function setBodyClass(){
2472            var section = $(SECTION_ACTIVE_SEL);
2473            var slide = section.find(SLIDE_ACTIVE_SEL);
2474
2475            var sectionAnchor = getAnchor(section);
2476            var slideAnchor = getAnchor(slide);
2477
2478            var text = String(sectionAnchor);
2479
2480            if(slide.length){
2481                text = text + '-' + slideAnchor;
2482            }
2483
2484            //changing slash for dash to make it a valid CSS style
2485            text = text.replace('/', '-').replace('#','');
2486
2487            //removing previous anchor classes
2488            var classRe = new RegExp('\\b\\s?' + VIEWING_PREFIX + '-[^\\s]+\\b', "g");
2489            $body[0].className = $body[0].className.replace(classRe, '');
2490
2491            //adding the current anchor
2492            $body.addClass(VIEWING_PREFIX + '-' + text);
2493        }
2494
2495        /**
2496        * Checks for translate3d support
2497        * @return boolean
2498        * http://stackoverflow.com/questions/5661671/detecting-transform-translate3d-support
2499        */
2500        function support3d() {
2501            var el = document.createElement('p'),
2502                has3d,
2503                transforms = {
2504                    'webkitTransform':'-webkit-transform',
2505                    'OTransform':'-o-transform',
2506                    'msTransform':'-ms-transform',
2507                    'MozTransform':'-moz-transform',
2508                    'transform':'transform'
2509                };
2510
2511            // Add it to the body to get the computed style.
2512            document.body.insertBefore(el, null);
2513
2514            for (var t in transforms) {
2515                if (el.style[t] !== undefined) {
2516                    el.style[t] = 'translate3d(1px,1px,1px)';
2517                    has3d = window.getComputedStyle(el).getPropertyValue(transforms[t]);
2518                }
2519            }
2520
2521            document.body.removeChild(el);
2522
2523            return (has3d !== undefined && has3d.length > 0 && has3d !== 'none');
2524        }
2525
2526        /**
2527        * Removes the auto scrolling action fired by the mouse wheel and trackpad.
2528        * After this function is called, the mousewheel and trackpad movements won't scroll through sections.
2529        */
2530        function removeMouseWheelHandler(){
2531            if (document.addEventListener) {
2532                document.removeEventListener('mousewheel', MouseWheelHandler, false); //IE9, Chrome, Safari, Oper
2533                document.removeEventListener('wheel', MouseWheelHandler, false); //Firefox
2534                document.removeEventListener('MozMousePixelScroll', MouseWheelHandler, false); //old Firefox
2535            } else {
2536                document.detachEvent('onmousewheel', MouseWheelHandler); //IE 6/7/8
2537            }
2538        }
2539
2540        /**
2541        * Adds the auto scrolling action for the mouse wheel and trackpad.
2542        * After this function is called, the mousewheel and trackpad movements will scroll through sections
2543        * https://developer.mozilla.org/en-US/docs/Web/Events/wheel
2544        */
2545        function addMouseWheelHandler(){
2546            var prefix = '';
2547            var _addEventListener;
2548
2549            if (window.addEventListener){
2550                _addEventListener = "addEventListener";
2551            }else{
2552                _addEventListener = "attachEvent";
2553                prefix = 'on';
2554            }
2555
2556             // detect available wheel event
2557            var support = 'onwheel' in document.createElement('div') ? 'wheel' : // Modern browsers support "wheel"
2558                      document.onmousewheel !== undefined ? 'mousewheel' : // Webkit and IE support at least "mousewheel"
2559                      'DOMMouseScroll'; // let's assume that remaining browsers are older Firefox
2560
2561
2562            if(support == 'DOMMouseScroll'){
2563                document[ _addEventListener ](prefix + 'MozMousePixelScroll', MouseWheelHandler, false);
2564            }
2565
2566            //handle MozMousePixelScroll in older Firefox
2567            else{
2568                document[ _addEventListener ](prefix + support, MouseWheelHandler, false);
2569            }
2570        }
2571
2572        /**
2573        * Binding the mousemove when the mouse's middle button is pressed
2574        */
2575        function addMiddleWheelHandler(){
2576            container
2577                .on('mousedown', mouseDownHandler)
2578                .on('mouseup', mouseUpHandler);
2579        }
2580
2581        /**
2582        * Unbinding the mousemove when the mouse's middle button is released
2583        */
2584        function removeMiddleWheelHandler(){
2585            container
2586                .off('mousedown', mouseDownHandler)
2587                .off('mouseup', mouseUpHandler);
2588        }
2589
2590        /**
2591        * Adds the possibility to auto scroll through sections on touch devices.
2592        */
2593        function addTouchHandler(){
2594            if(isTouchDevice || isTouch){
2595                if(options.autoScrolling){
2596                    $body.off(events.touchmove).on(events.touchmove, preventBouncing);
2597                }
2598
2599                $(WRAPPER_SEL)
2600                    .off(events.touchstart).on(events.touchstart, touchStartHandler)
2601                    .off(events.touchmove).on(events.touchmove, touchMoveHandler);
2602            }
2603        }
2604
2605        /**
2606        * Removes the auto scrolling for touch devices.
2607        */
2608        function removeTouchHandler(){
2609            if(isTouchDevice || isTouch){
2610                $(WRAPPER_SEL)
2611                    .off(events.touchstart)
2612                    .off(events.touchmove);
2613            }
2614        }
2615
2616        /*
2617        * Returns and object with Microsoft pointers (for IE<11 and for IE >= 11)
2618        * http://msdn.microsoft.com/en-us/library/ie/dn304886(v=vs.85).aspx
2619        */
2620        function getMSPointer(){
2621            var pointer;
2622
2623            //IE >= 11 & rest of browsers
2624            if(window.PointerEvent){
2625                pointer = { down: 'pointerdown', move: 'pointermove'};
2626            }
2627
2628            //IE < 11
2629            else{
2630                pointer = { down: 'MSPointerDown', move: 'MSPointerMove'};
2631            }
2632
2633            return pointer;
2634        }
2635
2636        /**
2637        * Gets the pageX and pageY properties depending on the browser.
2638        * https://github.com/alvarotrigo/fullPage.js/issues/194#issuecomment-34069854
2639        */
2640        function getEventsPage(e){
2641            var events = [];
2642
2643            events.y = (typeof e.pageY !== 'undefined' && (e.pageY || e.pageX) ? e.pageY : e.touches[0].pageY);
2644            events.x = (typeof e.pageX !== 'undefined' && (e.pageY || e.pageX) ? e.pageX : e.touches[0].pageX);
2645
2646            //in touch devices with scrollBar:true, e.pageY is detected, but we have to deal with touch events. #1008
2647            if(isTouch && isReallyTouch(e) && options.scrollBar){
2648                events.y = e.touches[0].pageY;
2649                events.x = e.touches[0].pageX;
2650            }
2651
2652            return events;
2653        }
2654
2655        /**
2656        * Slides silently (with no animation) the active slider to the given slide.
2657        * @param noCallback {bool} true or defined -> no callbacks
2658        */
2659        function silentLandscapeScroll(activeSlide, noCallbacks){
2660            setScrollingSpeed (0, 'internal');
2661
2662            if(typeof noCallbacks !== 'undefined'){
2663                //preventing firing callbacks afterSlideLoad etc.
2664                isResizing = true;
2665            }
2666
2667            landscapeScroll(activeSlide.closest(SLIDES_WRAPPER_SEL), activeSlide);
2668
2669            if(typeof noCallbacks !== 'undefined'){
2670                isResizing = false;
2671            }
2672
2673            setScrollingSpeed(originals.scrollingSpeed, 'internal');
2674        }
2675
2676        /**
2677        * Scrolls silently (with no animation) the page to the given Y position.
2678        */
2679        function silentScroll(top){
2680            // The first section can have a negative value in iOS 10. Not quite sure why: -0.0142822265625
2681            // that's why we round it to 0.
2682            var roundedTop = Math.round(top);
2683
2684            if (options.css3 && options.autoScrolling && !options.scrollBar){
2685                var translate3d = 'translate3d(0px, -' + roundedTop + 'px, 0px)';
2686                transformContainer(translate3d, false);
2687            }
2688            else if(options.autoScrolling && !options.scrollBar){
2689                container.css('top', -roundedTop);
2690            }
2691            else{
2692                $htmlBody.scrollTop(roundedTop);
2693            }
2694        }
2695
2696        /**
2697        * Returns the cross-browser transform string.
2698        */
2699        function getTransforms(translate3d){
2700            return {
2701                '-webkit-transform': translate3d,
2702                '-moz-transform': translate3d,
2703                '-ms-transform':translate3d,
2704                'transform': translate3d
2705            };
2706        }
2707
2708        /**
2709        * Allowing or disallowing the mouse/swipe scroll in a given direction. (not for keyboard)
2710        * @type  m (mouse) or k (keyboard)
2711        */
2712        function setIsScrollAllowed(value, direction, type){
2713            switch (direction){
2714                case 'up': isScrollAllowed[type].up = value; break;
2715                case 'down': isScrollAllowed[type].down = value; break;
2716                case 'left': isScrollAllowed[type].left = value; break;
2717                case 'right': isScrollAllowed[type].right = value; break;
2718                case 'all':
2719                    if(type == 'm'){
2720                        setAllowScrolling(value);
2721                    }else{
2722                        setKeyboardScrolling(value);
2723                    }
2724            }
2725        }
2726
2727        /*
2728        * Destroys fullpage.js plugin events and optinally its html markup and styles
2729        */
2730        function destroy(all){
2731            setAutoScrolling(false, 'internal');
2732            setAllowScrolling(false);
2733            setKeyboardScrolling(false);
2734            container.addClass(DESTROYED);
2735
2736            clearTimeout(afterSlideLoadsId);
2737            clearTimeout(afterSectionLoadsId);
2738            clearTimeout(resizeId);
2739            clearTimeout(scrollId);
2740            clearTimeout(scrollId2);
2741
2742            $window
2743                .off('scroll', scrollHandler)
2744                .off('hashchange', hashChangeHandler)
2745                .off('resize', resizeHandler);
2746
2747            $document
2748                .off('click touchstart', SECTION_NAV_SEL + ' a')
2749                .off('mouseenter', SECTION_NAV_SEL + ' li')
2750                .off('mouseleave', SECTION_NAV_SEL + ' li')
2751                .off('click touchstart', SLIDES_NAV_LINK_SEL)
2752                .off('mouseover', options.normalScrollElements)
2753                .off('mouseout', options.normalScrollElements);
2754
2755            $(SECTION_SEL)
2756                .off('click touchstart', SLIDES_ARROW_SEL);
2757
2758            clearTimeout(afterSlideLoadsId);
2759            clearTimeout(afterSectionLoadsId);
2760
2761            //lets make a mess!
2762            if(all){
2763                destroyStructure();
2764            }
2765        }
2766
2767        /*
2768        * Removes inline styles added by fullpage.js
2769        */
2770        function destroyStructure(){
2771            //reseting the `top` or `translate` properties to 0
2772            silentScroll(0);
2773
2774            //loading all the lazy load content
2775            container.find('img[data-src], source[data-src], audio[data-src], iframe[data-src]').each(function(){
2776                setSrc($(this), 'src');
2777            });
2778
2779            container.find('img[data-srcset]').each(function(){
2780                setSrc($(this), 'srcset');
2781            });
2782
2783            $(SECTION_NAV_SEL + ', ' + SLIDES_NAV_SEL +  ', ' + SLIDES_ARROW_SEL).remove();
2784
2785            //removing inline styles
2786            $(SECTION_SEL).css( {
2787                'height': '',
2788                'background-color' : '',
2789                'padding': ''
2790            });
2791
2792            $(SLIDE_SEL).css( {
2793                'width': ''
2794            });
2795
2796            container.css({
2797                'height': '',
2798                'position': '',
2799                '-ms-touch-action': '',
2800                'touch-action': ''
2801            });
2802
2803            $htmlBody.css({
2804                'overflow': '',
2805                'height': ''
2806            });
2807
2808            // remove .fp-enabled class
2809            $('html').removeClass(ENABLED);
2810
2811            // remove .fp-responsive class
2812            $body.removeClass(RESPONSIVE);
2813
2814            // remove all of the .fp-viewing- classes
2815            $.each($body.get(0).className.split(/\s+/), function (index, className) {
2816                if (className.indexOf(VIEWING_PREFIX) === 0) {
2817                    $body.removeClass(className);
2818                }
2819            });
2820
2821            //removing added classes
2822            $(SECTION_SEL + ', ' + SLIDE_SEL).each(function(){
2823                options.scrollOverflowHandler.remove($(this));
2824                $(this).removeClass(TABLE + ' ' + ACTIVE);
2825            });
2826
2827            removeAnimation(container);
2828
2829            //Unwrapping content
2830            container.find(TABLE_CELL_SEL + ', ' + SLIDES_CONTAINER_SEL + ', ' + SLIDES_WRAPPER_SEL).each(function(){
2831                //unwrap not being use in case there's no child element inside and its just text
2832                $(this).replaceWith(this.childNodes);
2833            });
2834
2835            //removing the applied transition from the fullpage wrapper
2836            container.css({
2837                '-webkit-transition': 'none',
2838                'transition': 'none'
2839            });
2840
2841            //scrolling the page to the top with no animation
2842            $htmlBody.scrollTop(0);
2843
2844            //removing selectors
2845            var usedSelectors = [SECTION, SLIDE, SLIDES_CONTAINER];
2846            $.each(usedSelectors, function(index, value){
2847                $('.' + value).removeClass(value);
2848            });
2849        }
2850
2851        /*
2852        * Sets the state for a variable with multiple states (original, and temporal)
2853        * Some variables such as `autoScrolling` or `recordHistory` might change automatically its state when using `responsive` or `autoScrolling:false`.
2854        * This function is used to keep track of both states, the original and the temporal one.
2855        * If type is not 'internal', then we assume the user is globally changing the variable.
2856        */
2857        function setVariableState(variable, value, type){
2858            options[variable] = value;
2859            if(type !== 'internal'){
2860                originals[variable] = value;
2861            }
2862        }
2863
2864        /**
2865        * Displays warnings
2866        */
2867        function displayWarnings(){
2868            var extensions = ['fadingEffect', 'continuousHorizontal', 'scrollHorizontally', 'interlockedSlides', 'resetSliders', 'responsiveSlides', 'offsetSections', 'dragAndMove', 'scrollOverflowReset', 'parallax'];
2869            if($('html').hasClass(ENABLED)){
2870                showError('error', 'Fullpage.js can only be initialized once and you are doing it multiple times!');
2871                return;
2872            }
2873
2874            // Disable mutually exclusive settings
2875            if (options.continuousVertical &&
2876                (options.loopTop || options.loopBottom)) {
2877                options.continuousVertical = false;
2878                showError('warn', 'Option `loopTop/loopBottom` is mutually exclusive with `continuousVertical`; `continuousVertical` disabled');
2879            }
2880
2881            if(options.scrollBar && options.scrollOverflow){
2882                showError('warn', 'Option `scrollBar` is mutually exclusive with `scrollOverflow`. Sections with scrollOverflow might not work well in Firefox');
2883            }
2884
2885            if(options.continuousVertical && (options.scrollBar || !options.autoScrolling)){
2886                options.continuousVertical = false;
2887                showError('warn', 'Scroll bars (`scrollBar:true` or `autoScrolling:false`) are mutually exclusive with `continuousVertical`; `continuousVertical` disabled');
2888            }
2889
2890            //using extensions? Wrong file!
2891            $.each(extensions, function(index, extension){
2892                //is the option set to true?
2893                if(options[extension]){
2894                    showError('warn', 'fullpage.js extensions require jquery.fullpage.extensions.min.js file instead of the usual jquery.fullpage.js. Requested: '+ extension);
2895                }
2896            });
2897
2898            //anchors can not have the same value as any element ID or NAME
2899            $.each(options.anchors, function(index, name){
2900
2901                //case insensitive selectors (http://stackoverflow.com/a/19465187/1081396)
2902                var nameAttr = $document.find('[name]').filter(function() {
2903                    return $(this).attr('name') && $(this).attr('name').toLowerCase() == name.toLowerCase();
2904                });
2905
2906                var idAttr = $document.find('[id]').filter(function() {
2907                    return $(this).attr('id') && $(this).attr('id').toLowerCase() == name.toLowerCase();
2908                });
2909
2910                if(idAttr.length || nameAttr.length ){
2911                    showError('error', 'data-anchor tags can not have the same value as any `id` element on the site (or `name` element for IE).');
2912                    idAttr.length && showError('error', '"' + name + '" is is being used by another element `id` property');
2913                    nameAttr.length && showError('error', '"' + name + '" is is being used by another element `name` property');
2914                }
2915            });
2916        }
2917
2918        /**
2919        * Shows a message in the console of the given type.
2920        */
2921        function showError(type, text){
2922            console && console[type] && console[type]('fullPage: ' + text);
2923        }
2924
2925    }; //end of $.fn.fullpage
2926
2927    if(typeof IScroll !== 'undefined'){
2928        /*
2929        * Turns iScroll `mousewheel` option off dynamically
2930        * https://github.com/cubiq/iscroll/issues/1036
2931        */
2932        IScroll.prototype.wheelOn = function () {
2933            this.wrapper.addEventListener('wheel', this);
2934            this.wrapper.addEventListener('mousewheel', this);
2935            this.wrapper.addEventListener('DOMMouseScroll', this);
2936        };
2937
2938        /*
2939        * Turns iScroll `mousewheel` option on dynamically
2940        * https://github.com/cubiq/iscroll/issues/1036
2941        */
2942        IScroll.prototype.wheelOff = function () {
2943            this.wrapper.removeEventListener('wheel', this);
2944            this.wrapper.removeEventListener('mousewheel', this);
2945            this.wrapper.removeEventListener('DOMMouseScroll', this);
2946        };
2947    }
2948
2949    /**
2950     * An object to handle overflow scrolling.
2951     * This uses jquery.slimScroll to accomplish overflow scrolling.
2952     * It is possible to pass in an alternate scrollOverflowHandler
2953     * to the fullpage.js option that implements the same functions
2954     * as this handler.
2955     *
2956     * @type {Object}
2957     */
2958    var iscrollHandler = {
2959        refreshId: null,
2960        iScrollInstances: [],
2961
2962        // Enables or disables the mouse wheel for the active section or all slides in it
2963        toggleWheel: function(value){
2964            var scrollable = $(SECTION_ACTIVE_SEL).find(SCROLLABLE_SEL);
2965            scrollable.each(function(){
2966                var iScrollInstance = $(this).data('iscrollInstance');
2967                if(typeof iScrollInstance !== 'undefined' && iScrollInstance){
2968                    if(value){
2969                        iScrollInstance.wheelOn();
2970                    }
2971                    else{
2972                        iScrollInstance.wheelOff();
2973                    }
2974                }
2975            });
2976        },
2977
2978        /**
2979        * Turns off iScroll for the destination section.
2980        * When scrolling very fast on some trackpads (and Apple laptops) the inertial scrolling would
2981        * scroll the destination section/slide before the sections animations ends.
2982        */
2983        onLeave: function(){
2984            iscrollHandler.toggleWheel(false);
2985        },
2986
2987        // Turns off iScroll for the leaving section
2988        beforeLeave: function(){
2989            iscrollHandler.onLeave()
2990        },
2991
2992        // Turns on iScroll on section load
2993        afterLoad: function(){
2994            iscrollHandler.toggleWheel(true);
2995        },
2996
2997        /**
2998         * Called when overflow scrolling is needed for a section.
2999         *
3000         * @param  {Object} element      jQuery object containing current section
3001         * @param  {Number} scrollHeight Current window height in pixels
3002         */
3003        create: function(element, scrollHeight) {
3004            var scrollable = element.find(SCROLLABLE_SEL);
3005
3006            scrollable.height(scrollHeight);
3007            scrollable.each(function() {
3008                var $this = $(this);
3009                var iScrollInstance = $this.data('iscrollInstance');
3010                if (iScrollInstance) {
3011                    $.each(iscrollHandler.iScrollInstances, function(){
3012                        $(this).destroy();
3013                    });
3014                }
3015
3016                iScrollInstance = new IScroll($this.get(0), iscrollOptions);
3017                iscrollHandler.iScrollInstances.push(iScrollInstance);
3018
3019                //off by default until the section gets active
3020                iScrollInstance.wheelOff();
3021
3022                $this.data('iscrollInstance', iScrollInstance);
3023            });
3024        },
3025
3026        /**
3027         * Return a boolean depending on whether the scrollable element is a
3028         * the end or at the start of the scrolling depending on the given type.
3029         *
3030         * @param  {String}  type       Either 'top' or 'bottom'
3031         * @param  {Object}  scrollable jQuery object for the scrollable element
3032         * @return {Boolean}
3033         */
3034        isScrolled: function(type, scrollable) {
3035            var scroller = scrollable.data('iscrollInstance');
3036
3037            //no scroller?
3038            if (!scroller) {
3039                return true;
3040            }
3041
3042            if (type === 'top') {
3043                return scroller.y >= 0 && !scrollable.scrollTop();
3044            } else if (type === 'bottom') {
3045                return (0 - scroller.y) + scrollable.scrollTop() + 1 + scrollable.innerHe
3045ight() >= scrollable[0].scrollHeight;
3046            }
3047        },
3048
3049        /**
3050         * Returns the scrollable element for the given section.
3051         * If there are landscape slides, will only return a scrollable element
3052         * if it is in the active slide.
3053         *
3054         * @param  {Object}  activeSection jQuery object containing current section
3055         * @return {Boolean}
3056         */
3057        scrollable: function(activeSection){
3058            // if there are landscape slides, we check if the scrolling bar is in the current one or not
3059            if (activeSection.find(SLIDES_WRAPPER_SEL).length) {
3060                return activeSection.find(SLIDE_ACTIVE_SEL).find(SCROLLABLE_SEL);
3061            }
3062            return activeSection.find(SCROLLABLE_SEL);
3063        },
3064
3065        /**
3066         * Returns the scroll height of the wrapped content.
3067         * If this is larger than the window height minus section padding,
3068         * overflow scrolling is needed.
3069         *
3070         * @param  {Object} element jQuery object containing current section
3071         * @return {Number}
3072         */
3073        scrollHeight: function(element) {
3074            return element.find(SCROLLABLE_SEL).children().first().get(0).scrollHeight;
3075        },
3076
3077        /**
3078         * Called when overflow scrolling is no longer needed for a section.
3079         *
3080         * @param  {Object} element      jQuery object containing current section
3081         */
3082        remove: function(element) {
3083            var scrollable = element.find(SCROLLABLE_SEL);
3084            if (scrollable.length) {
3085                var iScrollInstance = scrollable.data('iscrollInstance');
3086                iScrollInstance.destroy();
3087
3088                scrollable.data('iscrollInstance', null);
3089            }
3090            element.find(SCROLLABLE_SEL).children().first().children().first().unwrap().unwrap();
3091        },
3092
3093        /**
3094         * Called when overflow scrolling has already been setup but the
3095         * window height has potentially changed.
3096         *
3097         * @param  {Object} element      jQuery object containing current section
3098         * @param  {Number} scrollHeight Current window height in pixels
3099         */
3100        update: function(element, scrollHeight) {
3101            //using a timeout in order to execute the refresh function only once when `update` is called multiple times in a
3102            //short period of time.
3103            //it also comes on handy because iScroll requires the use of timeout when using `refresh`.
3104            clearTimeout(iscrollHandler.refreshId);
3105            iscrollHandler.refreshId = setTimeout(function(){
3106                $.each(iscrollHandler.iScrollInstances, function(){
3107                    $(this).get(0).refresh();
3108                });
3109            }, 150);
3110
3111            //updating the wrappers height
3112            element.find(SCROLLABLE_SEL).css('height', scrollHeight + 'px').parent().css('height', scrollHeight + 'px');
3113        },
3114
3115        /**
3116         * Called to get any additional elements needed to wrap the section
3117         * content in order to facilitate overflow scrolling.
3118         *
3119         * @return {String|Object} Can be a string containing HTML,
3120         *                         a DOM element, or jQuery object.
3121         */
3122        wrapContent: function() {
3123            return '<div class="' + SCROLLABLE + '"><div class="fp-scroller"></div></div>';
3124        }
3125    };
3126});
3127
3128

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.