PageSourceSearch

https://www.welcomebank.co.kr/web/ibn/js/pub/jquery.fullPage.js

js welcomebank.co.kr collected 2026-10-01 14:13:39 UTC 112,412 bytes, 2,923 lines download raw bytes

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

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.