PageSourceSearch

http://thegioidienanh.vn/modules/frontend/themes/tgda/js/jquery.bxslider.js?v=2.620260214200658

js thegioidienanh.vn collected 2026-10-02 12:15:02 UTC 39,710 bytes, 1,091 lines download raw bytes

1/**
2 * BxSlider v4.0 - Fully loaded, responsive content slider
3 * http://bxslider.com
4 *
5 * Copyright 2012, Steven Wanderski - http://stevenwanderski.com - http://bxcreative.com
6 * Written while drinking Belgian ales and listening to jazz
7 *
8 * Released under the WTFPL license - http://sam.zoy.org/wtfpl/
9 */
10
11;(function($){
12	
13	var defaults = {
14		
15		// GENERAL
16		mode: 'horizontal',
17		slideSelector: '',
18		infiniteLoop: true,
19		hideControlOnEnd: false,
20		speed: 500,
21		easing: 'swing',
22		slideMargin: 0,
23		startSlide: 0,
24		captions: false,
25		ticker: false,
26		tickerHover: false,
27		adaptiveHeight: false,
28		adaptiveHeightSpeed: 500,
29		touchEnabled: true,
30		swipeThreshold: 50,
31		video: false,
32		
33		// PAGER
34		pager: true,
35		pagerType: 'full',
36		pagerShortSeparator: ' / ',
37		pagerSelector: null,
38		buildPager: null,
39		pagerCustom: null,
40		
41		// CONTROLS
42		controls: true,
43		nextText: 'Next',
44		prevText: 'Prev',
45		nextSelector: null,
46		prevSelector: null,
47		autoControls: false,
48		startText: 'Start',
49		stopText: 'Stop',
50		autoControlsCombine: false,
51		autoControlsSelector: null,
52		
53		// AUTO
54		auto: false,
55		pause: 4000,
56		autoStart: true,
57		autoDirection: 'next',
58		autoHover: false,
59		autoDelay: 0,
60		
61		// CAROUSEL
62		minSlides: 1,
63		maxSlides: 1,
64		moveSlides: 0,
65		slideWidth: 0,
66		
67		// CALLBACKS
68		onSliderLoad: function() {},
69		onSlideBefore: function() {},
70		onSlideAfter: function() {},
71		onSlideNext: function() {},
72		onSlidePrev: function() {}
73	}
74
75	$.fn.bxSlider = function(options){
76		
77		// support mutltiple elements
78		if(this.length > 1){
79			this.each(function(){$(this).bxSlider(options)});
80			return this;
81		}
82		
83		// create a namespace to be used throughout the plugin
84		var slider = {};
85		// set a reference to our slider element
86		var el = this;
87		
88		/**
89		 * ===================================================================================
90		 * = PRIVATE FUNCTIONS
91		 * ===================================================================================
92		 */
93		
94		/**
95		 * Initializes namespace settings to be used throughout plugin
96		 */
97		var init = function(){
98			// merge user-supplied options with the defaults
99			slider.settings = $.extend({}, defaults, options);
100			// store the original children
101			slider.children = el.children(slider.settings.slideSelector);
102			// store active slide information
103			slider.active = { index: slider.settings.startSlide }
104			// store if the slider is in carousel mode (displaying / moving multiple slides)
105			slider.carousel = slider.settings.minSlides > 1 || slider.settings.maxSlides > 1;
106			// calculate the min / max width thresholds based on min / max number of slides
107			// used to setup and update carousel slides dimensions
108			slider.minThreshold = (slider.settings.minSlides * slider.settings.slideWidth) + ((slider.settings.minSlides - 1) * slider.settings.slideMargin);
109			slider.maxThreshold = (slider.settings.maxSlides * slider.settings.slideWidth) + ((slider.settings.maxSlides - 1) * slider.settings.slideMargin);
110			// store the current state of the slider (if currently animating, working is true)
111			slider.working = false;
112			// initialize the controls object
113			slider.controls = {}
114			// perform all DOM / CSS modifications
115			setup();
116			// if ticker is true, start the ticker
117			if (slider.settings.ticker) initTicker();
118			// if pager is requested, make the appropriate pager link active
119			if (slider.settings.pager) updatePagerActive(slider.settings.startSlide);
120			// check for any updates to the controls (like hideControlOnEnd updates)
121			if (slider.settings.controls) updateDirectionControls();
122			// if touchEnabled is true, setup the touch events
123			if (slider.settings.touchEnabled) initTouch();
124		}
125
126		/**
127		 * Performs all DOM and CSS modifications
128		 */
129		var setup = function(){
130			// wrap el in a wrapper
131			el.wrap('<div class="bx-wrapper"><div class="bx-viewport"></div></div>');
132			// store a namspace reference to .bx-viewport
133			slider.viewport = el.parent();
134			// add a loading div to display while images are loading
135			slider.loader = $('<div class="bx-loading" />');
136			slider.viewport.prepend(slider.loader);
137			// set el to a massive width, to hold any needed slides
138			// also strip any margin and padding from el
139			el.css({
140				width: slider.settings.mode == 'horizontal' ? '999999px' : 'auto',
141				height: 0,
142				overflow: 'hidden',
143				position: 'relative',
144				margin: 0,
145				padding: 0
146			});
147			// make modifications to the viewport (.bx-viewport)
148			slider.viewport.css({
149				width: '100%',
150				height: '50',
151				overflow: 'hidden',
152				position: 'relative'
153			});
154			// apply css to all slider children
155			slider.children.css({
156				float: slider.settings.mode == 'horizontal' ? 'left' : 'none',
157				position: 'relative',
158				width: getSlideWidth(),
159				listStyle: 'none',
160				marginRight: slider.settings.mode == 'horizontal' ? slider.settings.slideMargin : 0,
161				marginBottom: slider.settings.mode == 'vertical' ? slider.settings.slideMargin: 0
162			});
163			// if "fade" mode, add positioning and z-index CSS
164			if(slider.settings.mode == 'fade'){
165				slider.children.css({
166					position: 'absolute',
167					zIndex: 0,
168					display: 'none'
169				});
170				// prepare the z-index on the showing element
171				slider.children.eq(slider.settings.startSlide).css({zIndex: 50, display: 'block'});
172			}
173			// create an element to contain all slider controls (pager, start / stop, etc)
174			slider.controls.el = $('<div class="bx-controls" />');
175			// if captions are requested, add them
176			if(slider.settings.captions) appendCaptions();
177			// if infinite loop, prepare additional slides
178			if(slider.settings.infiniteLoop && !slider.carousel && slider.settings.mode != 'fade' && !slider.settings.ticker){
179				var cloneAppend = slider.children.first().clone().addClass('bx-clone');
180				var clonePrepend = slider.children.last().clone().addClass('bx-clone');
181				el.append(cloneAppend).prepend(clonePrepend);
182			}
183			// check if startSlide is last slide
184			slider.active.last = slider.settings.startSlide == getPagerQty() - 1;
185			// if video is true, set up the fitVids plugin
186			if(slider.settings.video) el.fitVids();
187			// only check for control addition if not in "ticker" mode
188			if(!slider.settings.ticker){
189				// if pager is requested, add it
190				if(slider.settings.pager) appendPager();
191				// if controls are requested, add them
192				if(slider.settings.controls) appendControls();
193				// if auto is true, and auto controls are requested, add them
194				if(slider.settings.auto && slider.settings.autoControls) appendControlsAuto();
195				// if any control option is requested, add the controls wrapper
196				if(slider.settings.controls || slider.settings.autoControls || slider.settings.pager) slider.viewport.after(slider.controls.el);
197			}
198			// preload all images, then perform final DOM / CSS modifications that depend on images being loaded
199			preloadImages(function(){
200				el.css('overflow', 'visible');
201				// set the left / top position of "el"
202				setSlidePosition();
203				// if "vertical" mode, always use adaptiveHeight to prevent odd behavior
204				if (slider.settings.mode == 'vertical') slider.settings.adaptiveHeight = true;
205				// set the viewport height
206				slider.viewport.animate({height: getViewportHeight()}, 200, function(){
207					// onSliderLoad callback
208					slider.settings.onSliderLoad();
209				});
210				// if auto is true, start the show
211				if (slider.settings.auto && slider.settings.autoStart) initAuto();
212			});
213		}
214		
215		/**
216		 * Preload all images and iframes
217		 *
218		 * @param callback (function) 
219		 *  - Function to be called after images are loaded
220		 */
221		var preloadImages = function(callback){
222			// get all the images
223			var images = slider.children.find('img[src!=""], iframe');
224			// counter that stores loaded images
225			var loaded = 0;
226			// if images exist
227			if(images.length > 0){
228				// cycle through each image
229				images.each(function(index){
230					var img = $(this);
231					// on image load
232				  img.load(function(){
233						// increase the counter
234						++loaded;
235						// if all images have been loaded
236						if(images.length == loaded){
237							// remove the loading DOM element
238							slider.loader.remove();
239							// fire the callback function
240							callback();
241						}
242					});
243				// silly IE needs this hack to fire "load" events on images
244				}).each(function() {
245					if(this.complete) $(this).load();
246				});
247			// if images do not exist, fire the callback function immediately
248			}else{
249				// remove the loading DOM element
250				slider.loader.remove();
251				callback();
252			}
253		}
254		
255		/**
256		 * Returns the calculated height of the viewport, used to determine either adaptiveHeight or the maxHeight value
257		 */
258		var getViewportHeight = function(){
259			var height = 0;
260			// first determine which children (slides) should be used in our height calculation
261			var children = '';
262			// if mode is not "vertical", adaptiveHeight is always false, so return all children
263			if(slider.settings.mode != 'vertical' && !slider.settings.adaptiveHeight){
264				children = slider.children;
265			}else{
266				// if not carousel, return the single active child
267				if(!slider.carousel){
268					children = slider.children.eq(slider.active.index);
269				// if carousel, return a slice of children
270				}else{
271					// if last slide
272					if(slider.active.last){
273						children = slider.children.slice(slider.children.length - slider.settings.minSlides, slider.children.length);
274					// if not last slide
275					}else{
276						children = slider.children.slice(slider.active.index * getMoveBy(), slider.settings.minSlides + (slider.active.index * getMoveBy()));
277					}
278				}
279			}
280			
281			// if "vertical" mode, calculate the sum of the heights of the children
282			if(slider.settings.mode == 'vertical'){
283				children.each(function(index) {
284				  height += $(this).outerHeight();
285				});
286				// add user-supplied margins
287				if(slider.settings.slideMargin > 0){
288					height += slider.settings.slideMargin * (slider.settings.minSlides - 1);
289				}
290			// if not "vertical" mode, calculate the max height of the children
291			}else{
292				height = Math.max.apply(Math, children.map(function(){
293					return $(this).outerHeight();
294				}).get());
295			}
296			
297			return height;
298		}
299		
300		/**
301		 * Returns the calculated width to be applied to each slide
302		 */
303		var getSlideWidth = function(){
304			// start with any user-supplied slide width
305			var newElWidth = slider.settings.slideWidth;
306			// get the current viewport width
307			var wrapWidth = slider.viewport.width();
308			// if slide width was not supplied, use the viewport width (means not carousel)
309			if(slider.settings.slideWidth == 0){
310				newElWidth = wrapWidth;
311			// if carousel, use the thresholds to determine the width
312			}else{
313				if(wrapWidth > slider.maxThreshold){
314					newElWidth = (wrapWidth - (slider.settings.slideMargin * (slider.settings.maxSlides - 1))) / slider.settings.maxSlides;
315				}else if(wrapWidth < slider.minThreshold){
316					newElWidth = (wrapWidth - (slider.settings.slideMargin * (slider.settings.minSlides - 1))) / slider.settings.minSlides;
317				}
318			}
319			return newElWidth;
320		}
321		
322		/**
323		 * Returns the number of slides currently visible in the viewport (includes partially visible slides)
324		 */
325		var getNumberSlidesShowing = function(){
326			var slidesShowing = 1;
327			if(slider.settings.mode == 'horizontal'){
328				// if viewport is smaller than minThreshold, return minSlides
329				if(slider.viewport.width() < slider.minThreshold){
330					slidesShowing = slider.settings.minSlides;
331				// if viewport is larger than minThreshold, return maxSlides
332				}else if(slider.viewport.width() > slider.maxThreshold){
333					slidesShowing = slider.settings.maxSlides;
334				// if viewport is between min / max thresholds, divide viewport width by first child width
335				}else{
336					var childWidth = slider.children.first().width();
337					slidesShowing = Math.floor(slider.viewport.width() / childWidth);
338				}
339			// if "vertical" mode, slides showing will always be minSlides
340			}else if(slider.settings.mode == 'vertical'){
341				slidesShowing = slider.settings.minSlides;
342			}
343			return slidesShowing;
344		}
345		
346		/**
347		 * Returns the number of pages (one full viewport of slides is one "page")
348		 */
349		var getPagerQty = function(){
350			var pagerQty = 0;
351			// if moveSlides is specified by the user
352			if(slider.settings.moveSlides > 0){
353				// use a while loop to determine pages
354				var breakPoint = 0;
355				var counter = 0
356				// when breakpoint goes above children length, counter is the number of pages
357				while (breakPoint < slider.children.length){
358					++pagerQty;
359					breakPoint = counter + getNumberSlidesShowing();
360					counter += slider.settings.moveSlides <= getNumberSlidesShowing() ? slider.settings.moveSlides : getNumberSlidesShowing();
361				}
362			// if moveSlides is 0 (auto) divide children length by sides showing, then round up
363			}else{
364				pagerQty = Math.ceil(slider.children.length / getNumberSlidesShowing());
365			}
366			return pagerQty;
367		}
368		
369		/**
370		 * Returns the number of indivual slides by which to shift the slider
371		 */
372		var getMoveBy = function(){
373			// if moveSlides was set by the user and moveSlides is less than number of slides showing
374			if(slider.settings.moveSlides > 0 && slider.settings.moveSlides <= getNumberSlidesShowing()){
375				return slider.settings.moveSlides;
376			}
377			// if moveSlides is 0 (auto)
378			return getNumberSlidesShowing();
379		}
380		
381		/**
382		 * Sets the slider's (el) left or top position
383		 */
384		var setSlidePosition = function(){
385			// if last slide
386			if(slider.active.last){
387				if (slider.settings.mode == 'horizontal'){
388					// get the last child's position
389					var lastChild = slider.children.last();
390					var position = lastChild.position();
391					// set the left position
392					el.css('left', -(position.left - (slider.viewport.width() - lastChild.width())));
393				}else if(slider.settings.mode == 'vertical'){
394					// get the last showing index's position
395					var lastShowingIndex = slider.children.length - slider.settings.minSlides;
396					var position = slider.children.eq(lastShowingIndex).position();
397					// set the top position
398					el.css('top', -position.top);
399				}
400			// if not last slide
401			}else{
402				// get the position of the first showing slide
403				var position = slider.children.eq(slider.active.index * getMoveBy()).position();
404				// check for last slide
405				if (slider.active.index == getPagerQty() - 1) slider.active.last = true;
406				// set the repective position
407				if (position != undefined){
408					if (slider.settings.mode == 'horizontal') el.css('left', -position.left);
409					else if (slider.settings.mode == 'vertical') el.css('top', -position.top);
410				}
411			}
412		}
413		
414		/**
415		 * Populates the pager with proper amount of pages
416		 */
417		var populatePager = function(){
418			var pagerHtml = '';
419			pagerQty = getPagerQty();
420			// loop through each pager item
421			for(var i=0; i < pagerQty; i++){
422				var linkContent = '';
423				// if a buildPager function is supplied, use it to get pager link value, else use index + 1
424				if(slider.settings.buildPager && $.isFunction(slider.settings.buildPager)){
425					linkContent = slider.settings.buildPager(i);
426					slider.pagerEl.addClass('bx-custom-pager');
427				}else{
428					linkContent = i + 1;
429					slider.pagerEl.addClass('bx-default-pager');
430				}
431				// var linkContent = slider.settings.buildPager && $.isFunction(slider.settings.buildPager) ? slider.settings.buildPager(i) : i + 1;
432				// add the markup to the string
433				pagerHtml += '<div class="bx-pager-item"><a href="" data-slide-index="' + i + '" class="bx-pager-link">' + linkContent + '</a></div>';
434			};
435			// populate the pager element with pager links
436			slider.pagerEl.html(pagerHtml);
437		}
438		
439		/**
440		 * Appends the pager to the controls element
441		 */
442		var appendPager = function(){
443			if(!slider.settings.pagerCustom){
444				// create the pager DOM element
445				slider.pagerEl = $('<div class="bx-pager" />');
446				// if a pager selector was supplied, populate it with the pager
447				if(slider.settings.pagerSelector){
448					$(slider.settings.pagerSelector).html(slider.pagerEl);
449				// if no pager selector was supplied, add it after the wrapper
450				}else{
451					slider.controls.el.addClass('bx-has-pager').append(slider.pagerEl);
452				}
453				// populate the pager
454				populatePager();
455			}else{
456				slider.pagerEl = $(slider.settings.pagerCustom);
457			}
458			// assign the pager click binding
459			slider.pagerEl.delegate('a', 'click', clickPagerBind);
460		}
461		
462		/**
463		 * Appends prev / next controls to the controls element
464		 */
465		var appendControls = function(){
466			slider.controls.next = $('<a class="bx-next" href="">' + slider.settings.nextText + '</a>');
467			slider.controls.prev = $('<a class="bx-prev" href="">' + slider.settings.prevText + '</a>');
468			// bind click actions to the controls
469			slider.controls.next.bind('click', clickNextBind);
470			slider.controls.prev.bind('click', clickPrevBind);
471			// if nextSlector was supplied, populate it
472			if(slider.settings.nextSelector){
473				$(slider.settings.nextSelector).append(slider.controls.next);
474			}
475			// if prevSlector was supplied, populate it
476			if(slider.settings.prevSelector){
477				$(slider.settings.prevSelector).append(slider.controls.prev);
478			}
479			// if no custom selectors were supplied
vendor: 1,906 bytes, lines 480-515
480			if(!slider.settings.nextSelector && !slider.settings.prevSelector){
481				// add the controls to the DOM
482				slider.controls.directionEl = $('<div class="bx-controls-direction" />');
483				// add the control elements to the directionEl
484				slider.controls.directionEl.append(slider.controls.prev).append(slider.controls.next);
485				// slider.viewport.append(slider.controls.directionEl);
486				slider.controls.el.addClass('bx-has-controls-direction').append(slider.controls.directionEl);
487			}
488		}
489		
490		/**
491		 * Appends start / stop auto controls to the controls element
492		 */
493		var appendControlsAuto = function(){
494			slider.controls.start = $('<div class="bx-controls-auto-item"><a class="bx-start" href="">' + slider.settings.startText + '</a></div>');
495			slider.controls.stop = $('<div class="bx-controls-auto-item"><a class="bx-stop" href="">' + slider.settings.stopText + '</a></div>');
496			// add the controls to the DOM
497			slider.controls.autoEl = $('<div class="bx-controls-auto" />');
498			// bind click actions to the controls
499			slider.controls.autoEl.delegate('.bx-start', 'click', clickStartBind);
500			slider.controls.autoEl.delegate('.bx-stop', 'click', clickStopBind);
501			// if autoControlsCombine, insert only the "start" control
502			if(slider.settings.autoControlsCombine){
503				slider.controls.autoEl.append(slider.controls.start);
504			// if autoControlsCombine is false, insert both controls
505			}else{
506				slider.controls.autoEl.append(slider.controls.start).append(slider.controls.stop);
507			}
508			// if auto controls selector was supplied, populate it with the controls
509			if(slider.settings.autoControlsSelector){
510				$(slider.settings.autoControlsSelector).html(slider.controls.autoEl);
511			// if auto controls selector was not supplied, add it after the wrapper
512			}else{
513				slider.controls.el.addClass('bx-has-controls-auto').append(slider.controls.autoEl);
514			}
515			// update the auto controls
516			updateAutoControls(slider.settings.autoStart ? 'stop' : 'start');
517		}
518		
519		/**
520		 * Appends image captions to the DOM
521		 */
522		var appendCaptions = function(){
523			// cycle through each child
524			slider.children.each(function(index){
525				// get the image title attribute
526				var title = $(this).find('img:first').attr('title');
527				// append the caption
528				if (title != undefined) $(this).append('<div class="bx-caption"><span>' + title + '</span></div>');
529			});
530		}
531		
532		/**
533		 * Click next binding
534		 *
535		 * @param e (event) 
536		 *  - DOM event object
537		 */
538		var clickNextBind = function(e){
539			// if auto show is running, stop it
540			if (slider.settings.auto) el.stopAuto();
541			el.goToNextSlide();
542			e.preventDefault();
543		}
544		
545		/**
546		 * Click prev binding
547		 *
548		 * @param e (event) 
549		 *  - DOM event object
550		 */
551		var clickPrevBind = function(e){
552			// if auto show is running, stop it
553			if (slider.settings.auto) el.stopAuto();
554			el.goToPrevSlide();
555			e.preventDefault();
556		}
557		
558		/**
559		 * Click start binding
560		 *
561		 * @param e (event) 
562		 *  - DOM event object
563		 */
564		var clickStartBind = function(e){
565			el.startAuto();
566			e.preventDefault();
567		}
568		
569		/**
570		 * Click stop binding
571		 *
572		 * @param e (event) 
573		 *  - DOM event object
574		 */
575		var clickStopBind = function(e){
576			el.stopAuto();
577			e.preventDefault();
578		}
579
580		/**
581		 * Click pager binding
582		 *
583		 * @param e (event) 
584		 *  - DOM event object
585		 */
586		var clickPagerBind = function(e){
587			// if auto show is running, stop it
588			if (slider.settings.auto) el.stopAuto();
589			var pagerLink = $(e.currentTarget);
590			var pagerIndex = parseInt(pagerLink.attr('data-slide-index'));
591			// if clicked pager link is not active, continue with the goToSlide call
592			if(pagerIndex != slider.active.index) el.goToSlide(pagerIndex);
593			e.preventDefault();
594		}
595		
596		/**
597		 * Updates the pager links with an active class
598		 *
599		 * @param slideIndex (int) 
600		 *  - index of slide to make active
601		 */
602		var updatePagerActive = function(slideIndex){
603			// if "short" pager type
604			if(slider.settings.pagerType == 'short'){
605				slider.pagerEl.html((slideIndex + 1) + slider.settings.pagerShortSeparator + slider.children.length);
606				return;
607			}
608			// remove all pager active classes
609			slider.pagerEl.find('a').removeClass('active');
610			// apply the active class
611			slider.pagerEl.find('a').eq(slideIndex).addClass('active');
612		}
613		
614		/**
615		 * Performs needed actions after a slide transition
616		 */
617		var updateAfterSlideTransition = function(){
618			// if not carousel and infinte loop is true
619			if(!slider.carousel && slider.settings.infiniteLoop){
620				// last slide
621				if(slider.active.index == 0){
622					// set the new position
623					var position = slider.children.eq(0).position();
624					if (slider.settings.mode == 'horizontal') { el.css('left', -position.left); }
625					else if (slider.settings.mode == 'vertical') { el.css('top', -position.top); }
626				}else if(slider.active.index == slider.children.length - 1){
627					// set the new position
628					var position = slider.children.eq(slider.children.length - 1).position();
629					if (slider.settings.mode == 'horizontal') { el.css('left', -position.left); }
630					else if (slider.settings.mode == 'vertical') { el.css('top', -position.top); }
631				}
632			}
633			// declare that the transition is complete
634			slider.working = false;
635			// onSlideAfter callback
636			slider.settings.onSlideAfter(slider.children.eq(slider.active.index));
637		}
638		
639		/**
640		 * Updates the auto controls state (either active, or combined switch)
641		 *
642		 * @param state (string) "start", "stop"
643		 *  - the new state of the auto show
644		 */
645		var updateAutoControls = function(state){
646			// if autoControlsCombine is true, replace the current control with the new state 
647			if(slider.settings.autoControlsCombine){
648				slider.controls.autoEl.html(slider.controls[state]);
649			// if autoControlsCombine is false, apply the "active" class to the appropriate control 
650			}else{
651				slider.controls.autoEl.find('a').removeClass('active');
652				slider.controls.autoEl.find('a:not(.bx-' + state + ')').addClass('active');
653			}
654		}
655		
656		/**
657		 * Updates the direction controls (checks if either should be hidden)
658		 */
659		var updateDirectionControls = function(){
660			// if infiniteLoop is false and hideControlOnEnd is true
661			if(!slider.settings.infiniteLoop && slider.settings.hideControlOnEnd){
662				// if first slide
663				if (slider.active.index == 0){
664					slider.controls.prev.addClass('disabled');
665					slider.controls.next.removeClass('disabled');
666				// if last slide
667				}else if(slider.active.index == getPagerQty() - 1){
668					slider.controls.next.addClass('disabled');
669					slider.controls.prev.removeClass('disabled');
670				// if any slide in the middle
671				}else{
672					slider.controls.prev.removeClass('disabled');
673					slider.controls.next.removeClass('disabled');
674				}
675			}
676		}
677		
678		/**
679		 * Initialzes the auto process
680		 */
681		var initAuto = function(){
682			// if autoDelay was supplied, launch the auto show using a setTimeout() call
683			if(slider.settings.autoDelay > 0){
684				var timeout = setTimeout(el.startAuto, slider.settings.autoDelay);
685			// if autoDelay was not supplied, start the auto show normally
686			}else{
687				el.startAuto();
688			}
689			// if autoHover is requested
690			if(slider.settings.autoHover){
691				// on el hover
692				el.hover(function(){
693					// if the auto show is currently playing (has an active interval)
694					if(slider.interval){
695						// stop the auto show and pass true agument which will prevent control update
696						el.stopAuto(true);
697						// create a new autoPaused value which will be used by the relative "mouseout" event
698						slider.autoPaused = true;
699					}
700				}, function(){
701					// if the autoPaused value was created be the prior "mouseover" event
702					if(slider.autoPaused){
703						// start the auto show and pass true agument which will prevent control update
704						el.startAuto(true);
705						// reset the autoPaused value
706						slider.autoPaused = null;
707					}
708				});
709			}
710		}
711		
712		/**
713		 * Initialzes the ticker process
714		 */
715		var initTicker = function(){
716			// if autoDirection is "next", append a clone of the entire slider
717			if(slider.settings.autoDirection == 'next'){
718				el.append(slider.children.clone().addClass('bx-clone'));
719			// if autoDirection is "prev", prepend a clone of the entire slider, and set the left position
720			}else{
721				el.prepend(slider.children.clone().addClass('bx-clone'));
722				var position = slider.children.first().position();
723				var startPosition = slider.settings.mode == 'horizontal' ? {left: -position.left} : {top: -position.top};
724				el.css(startPosition);
725			}
726			// do not allow controls in ticker mode
727			slider.settings.pager = false;
728			slider.settings.controls = false;
729			slider.settings.autoControls = false;
730			// if autoHover is requested
731			if(slider.settings.tickerHover){
732				// on el hover
733				slider.viewport.hover(function(){
734					el.stop();
735				}, function(){
736					// calculate the total width of children (used to calculate the speed ratio)
737					var totalDimens = 0;
738					slider.children.each(function(index){
739					  totalDimens += slider.settings.mode == 'horizontal' ? $(this).outerWidth(true) : $(this).outerHeight(true);
740					});
741					// calculate the speed ratio (used to determine the new speed to finish the paused animation)
742					var ratio = slider.settings.speed / totalDimens;
743					// determine which property to use
744					var property = slider.settings.mode == 'horizontal' ? 'left' : 'top';
745					// calculate the new speed
746					var newSpeed = ratio * (totalDimens - (Math.abs(parseInt(el.css(property)))));
747					tickerLoop(newSpeed);
748				});
749			}
750			// start the ticker loop
751			tickerLoop();
752		}
753		
754		/**
755		 * Runs a continuous loop, news ticker-style
756		 */
757		var tickerLoop = function(resumeSpeed){
758			speed = resumeSpeed ? resumeSpeed : slider.settings.speed;
759			var position = {left: 0, top: 0};
760			var reset = {left: 0, top: 0};
761			// if "next" animate left position to last child, then reset left to 0
762			if(slider.settings.autoDirection == 'next'){
763				position = el.find('.bx-clone').first().position();
764			// if "prev" animate left position to 0, then reset left to first non-clone child
765			}else{
766				reset = slider.children.first().position();
767			}
768			var animateProperty = slider.settings.mode == 'horizontal' ? {left: -position.left} : {top: -position.top};
769			var resetProperty = slider.settings.mode == 'horizontal' ? {left: -reset.left} : {top: -reset.top};
770			el.animate(animateProperty, speed, 'linear', function(){
771				el.css(resetProperty);
772				// run the recursive loop after animation
773				tickerLoop();
774			});
775		}
776		
777		/**
778		 * Initializes touch events
779		 */
780		var initTouch = function(){
781			// initialize object to contain all touch values
782			slider.touch = {
783				start: {x: 0, y: 0},
784				end: {x: 0, y: 0}
785			}
786			slider.viewport.bind('touchstart', onTouchStart);
787		}
788		
789		/**
790		 * Event handler for "touchstart"
791		 *
792		 * @param e (event) 
793		 *  - DOM event object
794		 */
795		var onTouchStart = function(e){
796			if(slider.working){
797				e.preventDefault();
798			}else{
799				// record the original position when touch starts
800				slider.touch.originalPos = el.position();
801				var orig = e.originalEvent;
802				// record the starting touch x, y coordinates
803				// slider.touch.start = slider.settings.mode == 'horizontal' ? orig.changedTouches[0].pageX : orig.changedTouches[0].pageY;
804				slider.touch.start.x = orig.changedTouches[0].pageX;
805				slider.touch.start.y = orig.changedTouches[0].pageY;
806				// bind a "touchmove" event to the viewport
807				slider.viewport.bind('touchmove', onTouchMove);
808				// bind a "touchend" event to the viewport
809				slider.viewport.bind('touchend', onTouchEnd);
810			}
811		}
812		
813		/**
814		 * Event handler for "touchmove"
815		 *
816		 * @param e (event) 
817		 *  - DOM event object
818		 */
819		var onTouchMove = function(e){
820			e.preventDefault();
821			if(slider.settings.mode != 'fade'){
822				var orig = e.originalEvent;
823				// if horizontal, drag along x axis
824				if(slider.settings.mode == 'horizontal'){
825					var change = orig.changedTouches[0].pageX - slider.touch.start.x;
826					property = {left: slider.touch.originalPos.left + change};
827				// if vertical, drag along y axis
828				}else{
829					var change = orig.changedTouches[0].pageY - slider.touch.start.y;
830					property = {top: slider.touch.originalPos.top + change};
831				}
832				el.css(property);
833			}
834		}
835		
836		/**
837		 * Event handler for "touchend"
838		 *
839		 * @param e (event) 
840		 *  - DOM event object
841		 */
842		var onTouchEnd = function(e){
843			slider.viewport.unbind('touchmove', onTouchMove);
844			var orig = e.originalEvent;
845			var property;
846			// record end x, y positions
847			slider.touch.end.x = orig.changedTouches[0].pageX;
848			slider.touch.end.y = orig.changedTouches[0].pageY;
849			// if fade mode, check if absolute x distance clears the threshold
850			if(slider.settings.mode == 'fade'){
851				var distance = Math.abs(slider.touch.start.x - slider.touch.end.x);
852				if(distance >= slider.settings.swipeThreshold){
853					slider.touch.start.x > slider.touch.end.x ? el.goToNextSlide() : el.goToPrevSlide();
854					el.stopAuto();
855				}
856			// not fade mode
857			}else{
858				var distance = 0;
859				// calculate distance and el's animate property
860				if(slider.settings.mode == 'horizontal'){
861					distance = slider.touch.end.x - slider.touch.start.x;
862					property = {left: slider.touch.originalPos.left};
863				}else{
864					distance = slider.touch.end.x - slider.touch.start.x;
865					property = {top: slider.touch.originalPos.top};
866				}
867				// if not infinite loop and first / last slide, do not attempt a slide transition
868				if(!slider.settings.infiniteLoop && ((slider.active.index == 0 && distance > 0) || (slider.active.last && distance < 0))){
869					el.animate(property, 200);
870				}else{
871					// check if distance clears threshold
872					if(Math.abs(distance) >= slider.settings.swipeThreshold){
873						distance < 0 ? el.goToNextSlide() : el.goToPrevSlide();
874						el.stopAuto();
875					}else{
876						el.animate(property, 200);
877					}
878				}
879			}
880			slider.viewport.unbind('touchend', onTouchEnd);
881		}
882		
883		/**
884		 * ===================================================================================
885		 * = PUBLIC FUNCTIONS
886		 * ===================================================================================
887		 */
888		
889		/**
890		 * Performs slide transition to the specified slide
891		 *
892		 * @param slideIndex (int) 
893		 *  - the destination slide's index (zero-based)
894		 *
895		 * @param direction (string) 
896		 *  - INTERNAL USE ONLY - the direction of travel ("prev" / "next")
897		 */
898		el.goToSlide = function(slideIndex, direction){
899			// if plugin is currently in motion, ignore request
900			if(slider.working || slider.active.index == slideIndex) return;
901			// declare that plugin is in motion
902			slider.working = true;
903			// if slideIndex is less than zero, set active index to last child (this happens during infinite loop)
904			if(slideIndex < 0){
905				slider.active.index = slider.children.length - 1;
906			// if slideIndex is greater than children length, set active index to 0 (this happens during infinite loop)
907			}else if(slideIndex >= slider.children.length){
908				slider.active.index = 0;
909			// set active index to requested slide
910			}else{
911				slider.active.index = slideIndex;
912			}
913			// onSlideBefore, onSlideNext, onSlidePrev callbacks
914			slider.settings.onSlideBefore(slider.children.eq(slider.active.index));
915			if(direction == 'next'){
916				slider.settings.onSlideNext(slider.children.eq(slider.active.index));
917			}else if(direction == 'prev'){
918				slider.settings.onSlidePrev(slider.children.eq(slider.active.index));
919			}
920			// check if last slide
921			slider.active.last = slider.active.index >= getPagerQty() - 1;
922			// update the pager with active class
923			if(slider.settings.pager) updatePagerActive(slider.active.index);
924			// // check for direction control update
925			if(slider.settings.controls) updateDirectionControls();
926			// if slider is set to mode: "fade"
927			if(slider.settings.mode == 'fade'){
928				// if adaptiveHeight is true and next height is different from current height, animate to the new height
929				if(slider.settings.adaptiveHeight && slider.viewport.height() != getViewportHe
929ight()){
930					slider.viewport.animate({height: getViewportHeight()}, slider.settings.adaptiveHeightSpeed);
931				}
932				// fade out the visible child and reset its z-index value
933				slider.children.filter(':visible').fadeOut(slider.settings.speed).css({zIndex: 0});
934				// fade in the newly requested slide
935				slider.children.eq(slider.active.index).css('zIndex', 51).fadeIn(slider.settings.speed, function(){
936					$(this).css('zIndex', 50);
937					updateAfterSlideTransition();
938				});
939			// slider mode is not "fade"
940			}else{
941				// if adaptiveHeight is true and next height is different from current height, animate to the new height
942				if(slider.settings.adaptiveHeight && slider.viewport.height() != getViewportHeight()){
943					slider.viewport.animate({height: getViewportHeight()}, slider.settings.adaptiveHeightSpeed);
944				}
945				var moveBy = 0;
946				var position = {left: 0, top: 0};
947				// if carousel mode and last slide
948				if(slider.carousel && slider.active.last){
949					if(slider.settings.mode == 'horizontal'){
950						// get the last child position
951						var lastChild = slider.children.eq(slider.children.length - 1);
952						position = lastChild.position();
953						// calculate the position of the last slide
954						moveBy = slider.viewport.width() - lastChild.width();
955					}else{
956						// get last showing index position
957						var lastShowingIndex = slider.children.length - slider.settings.minSlides;
958						position = slider.children.eq(lastShowingIndex).position();
959					}
960				// if not carousel and infinite loop, and "Next" is clicked on the last slide
961				}else if(!slider.carousel && direction == 'next' && slider.active.index == 0){
962					// get the last clone position
963					position = el.find('.bx-clone:last').position();
964					slider.active.last = false;
965				// all other requests
966				}else if(slideIndex >= 0){
967					var requestEl = slideIndex * getMoveBy();
968					position = slider.children.eq(requestEl).position();
969				}
970				// plugin values to be animated
971				var animateProperty = slider.settings.mode == 'horizontal' ? {left: -(position.left - moveBy)} : {top: -position.top}
972				el.animate(animateProperty, slider.settings.speed, slider.settings.easing, function(){
973					updateAfterSlideTransition();
974				});
975			}
976		}
977		
978		/**
979		 * Transitions to the next slide in the show
980		 */
981		el.goToNextSlide = function(){
982			// if infiniteLoop is false and last page is showing, disregard call
983			if (!slider.settings.infiniteLoop && slider.active.last) return;
984			var pagerIndex = slider.active.index + 1;
985			// if carousel mode, infinite loop is true and "next" was clicked while on the last slide, go to slide 0
986			if (slider.carousel && slider.settings.infiniteLoop && pagerIndex >= getPagerQty()) pagerIndex = 0;
987			el.goToSlide(pagerIndex, 'next');
988		}
989		
990		/**
991		 * Transitions to the prev slide in the show
992		 */
993		el.goToPrevSlide = function(){
994			// if infiniteLoop is false and last page is showing, disregard call
995			if (!slider.settings.infiniteLoop && slider.active.index == 0) return;
996			var pagerIndex = slider.active.index - 1;
997			// if carousel mode, infinite loop is true and "prev" was clicked while on the first slide, go to last slide
998			if (slider.carousel && slider.settings.infiniteLoop && pagerIndex < 0) pagerIndex = getPagerQty() - 1;
999			el.goToSlide(pagerIndex, 'prev');
1000		}
1001		
1002		/**
1003		 * Starts the auto show
1004		 *
1005		 * @param preventControlUpdate (boolean) 
1006		 *  - if true, auto controls state will not be updated
1007		 */
1008		el.startAuto = function(preventControlUpdate){
1009			// if an interval already exists, disregard call
1010			if(slider.interval) return;
1011			// create an interval
1012			slider.interval = setInterval(function(){
1013				slider.settings.autoDirection == 'next' ? el.goToNextSlide() : el.goToPrevSlide();
1014			}, slider.settings.pause);
1015			// if auto controls are displayed and preventControlUpdate is not true
1016			if (slider.settings.autoControls && preventControlUpdate != true) updateAutoControls('stop');
1017		}
1018		
1019		/**
1020		 * Stops the auto show
1021		 *
1022		 * @param preventControlUpdate (boolean) 
1023		 *  - if true, auto controls state will not be updated
1024		 */
1025		el.stopAuto = function(preventControlUpdate){
1026			// if no interval exists, disregard call
1027			if(!slider.interval) return;
1028			// clear the interval
1029			clearInterval(slider.interval);
1030			slider.interval = null;
1031			// if auto controls are displayed and preventControlUpdate is not true
1032			if (slider.settings.autoControls && preventControlUpdate != true) updateAutoControls('start');
1033		}
1034		
1035		/**
1036		 * Returns current slide index (zero-based)
1037		 */
1038		el.getCurrentSlide = function(){
1039			return slider.active.index;
1040		}
1041		
1042		/**
1043		 * Returns number of slides in show
1044		 */
1045		el.getSlideCount = function(){
1046			return slider.children.length;
1047		}
1048		
1049		/**
1050		 * Makes slideshow responsive
1051		 */
1052		// first get the original window dimens (thanks alot IE)
1053		var windowWidth = $(window).width();
1054		var windowHeight = $(window).height();
1055		$(window).resize(function(){
1056			// get the new window dimens (again, thank you IE)
1057			var windowWidthNew = $(window).width();
1058			var windowHeightNew = $(window).height();
1059			// make sure that it is a true window resize
1060			// *we must check this because our dinosaur friend IE fires a window resize event when certain DOM elements
1061			// are resized. Can you just die already?*
1062			if(windowWidth != windowWidthNew || windowHeight != windowHeightNew){
1063				// set the new window dimens
1064				windowWidth = windowWidthNew;
1065				windowHeight = windowHeightNew;
1066				// resize all children in ratio to new screen size
1067				slider.children.add(el.find('.bx-clone')).width(getSlideWidth());
1068				// adjust the height
1069				slider.viewport.css('height', getViewportHeight());
1070				// if active.last was true before the screen resize, we want
1071				// to keep it last no matter what screen size we end on
1072				if (slider.active.last) slider.active.index = getPagerQty() - 1;
1073				// if the active index (page) no longer exists due to the resize, simply set the index as last
1074				if (slider.active.index >= getPagerQty()) slider.active.last = true;
1075				// if a pager is being displayed and a custom pager is not being used, update it
1076				if(slider.settings.pager && !slider.settings.pagerCustom){
1077					populatePager();
1078					updatePagerActive(slider.active.index);
1079				}
1080				// update the slide position
1081				setSlidePosition();
1082			}
1083		});
1084		
1085		init();
1086		
1087		// returns the current jQuery object
1088		return this;
1089	}
1090
1091})(jQuery);

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