PageSourceSearch

https://jayantijaljeera.com/cn/js/jquery.fullPage.min.js

js jayantijaljeera.com collected 2026-10-07 20:59:09 UTC 106,562 bytes, 2,856 lines download raw bytes

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

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.