PageSourceSearch

https://mapesen.com/web/template/themes/default/skins/plugin/Owl-Carousel/js/owl.carousel.js

js mapesen.com collected 2026-10-09 03:54:05 UTC 77,669 bytes, 3,154 lines download raw bytes

1/**
2 * @name Owl Carousel - code name Phenix
3 * @author Bartosz Wojciechowski
4 * @release 2014
5 * Licensed under MIT
6 * 
7 * @version 2.0.0-beta.1.8
8 * @versionNotes Not compatibile with Owl Carousel <2.0.0
9 */
10
11/*
12
13To do:
14
15* Lazy Load Icon
16* prevent animationend bubling
17* itemsScaleUp 
18* Test Zepto
19
20Callback events list:
21
22onInitBefore
23onInitAfter
24onResponsiveBefore
25onResponsiveAfter
26onTransitionStart
27onTransitionEnd
28onTouchStart
29onTouchEnd
30onChangeState
31onLazyLoaded
32onVideoPlay
33onVideoStop
34
35Custom events list:
36
37next.owl
38prev.owl
39goTo.owl
40jumpTo.owl
41addItem.owl
42removeItem.owl
43refresh.owl
44play.owl
45stop.owl
46stopVideo.owl
47
48*/
49
50
51;(function ( $, window, document, undefined ) {
52
53	var defaults = {
54		items:				3,
55		loop:				false,
56		center:				false,
57
58		mouseDrag:			true,
59		touchDrag:			true,
60		pullDrag: 			true,
61		freeDrag:			false,
62
63		margin:				0,
64		stagePadding:		0,
65
66		merge:				false,
67		mergeFit:			true,
68		autoWidth:			false,
69		autoHeight:			false,
70
71		startPosition:		0,
72		URLhashListener:	false,
73
74		nav: 				false,
75		navRewind:			true,
76		navText: 			['prev','next'],
77		slideBy:			1,
78		dots: 				true,
79		dotsEach:			false,
80		dotData:			false,
81
82		lazyLoad:			false,
83		lazyContent:		false,
84
85		autoplay:			false,
86		autoplayTimeout:	5000,
87		autoplayHoverPause:	false,
88
89		smartSpeed:			250,
90		fluidSpeed:			false,
91		autoplaySpeed:		false,
92		navSpeed:			false,
93		dotsSpeed:			false,
94		dragEndSpeed:		false,
95		
96		responsive: 		{},
97		responsiveRefreshRate : 200,
98		responsiveBaseElement: window,
99		responsiveClass:	false,
100
101		video:				false,
102		videoHeight:		false,
103		videoWidth:			false,
104
105		animateOut:			false,
106		animateIn:			false,
107
108		fallbackEasing:		'swing',
109
110		callbacks:			false,
111		info: 				false,
112
113		nestedItemSelector:	false,
114		itemElement:		'div',
115		stageElement:		'div',
116
117		//Classes and Names
118		themeClass: 		'owl-theme',
119		baseClass:			'owl-carousel',
120		itemClass:			'owl-item',
121		centerClass:		'center',
122		activeClass: 		'active',
123		navContainerClass:	'owl-nav',
124		navClass:			['owl-prev','owl-next'],
125		controlsClass:		'owl-controls',
126		dotClass: 			'owl-dot',
127		dotsClass:			'owl-dots',
128		autoHeightClass:	'owl-height'
129
130	};
131
132	// Reference to DOM elements
133	// Those with $ sign are jQuery objects
134
135	var dom = {
136		el:			null,	// main element 
137		$el:		null,	// jQuery main element 
138		stage:		null,	// stage
139		$stage:		null,	// jQuery stage
140		oStage:		null,	// outer stage
141		$oStage:	null,	// $ outer stage
142		$items:		null,	// all items, clones and originals included 
143		$oItems:	null,	// original items
144		$cItems:	null,	// cloned items only
145		$cc:		null,
146		$navPrev:	null,
147		$navNext:	null,
148		$page:		null,
149		$nav:		null,
150		$content:	null
151	};
152
153	/**
154	 * Variables
155	 * @since 2.0.0
156	 */
157
158	// Only for development process
159
160	// Widths
161
162	var width = {
163		el:			0,
164		stage:		0,
165		item:		0,
166		prevWindow:	0,
167		cloneLast:  0
168	};
169
170	// Numbers
171
172	var num = {
173		items:				0,
174		oItems: 			0,
175		cItems:				0,
176		active:				0,
177		merged:				[],
178		nav:				[],
179		allPages:			0
180	};
181
182	// Positions
183
184	var pos = {
185		start:		0,
186		max:		0,
187		maxValue:	0,
188		prev:		0,
189		current:	0,
190		currentAbs:	0,
191		currentPage:0,
192		stage:		0,
193		items:		[],
194		lsCurrent:	0
195	};
196
197	// Drag/Touches
198
199	var drag = {
200		start:		0,
201		startX:		0,
202		startY:		0,
203		current:	0,
204		currentX:	0,
205		currentY:	0,
206		offsetX:	0,
207		offsetY:	0,
208		distance:	null,
209		startTime:	0,
210		endTime:	0,
211		updatedX:	0,
212		targetEl:	null
213	};
214
215	// Speeds
216
217	var speed = {
218		onDragEnd: 	300,
219		nav:		300,
220		css2speed:	0
221
222	};
223
224	// States
225
226	var state = {
227		isTouch:		false,
228		isScrolling:	false,
229		isSwiping:		false,
230		direction:		false,
231		inMotion:		false,
232		autoplay:		false,
233		lazyContent:	false
234	};
235
236	// Event functions references
237
238	var e = {
239		_onDragStart:	null,
240		_onDragMove:	null,
241		_onDragEnd:		null,
242		_transitionEnd: null,
243		_resizer:		null,
244		_responsiveCall:null,
245		_goToLoop:		null,
246		_checkVisibile: null,
247		_autoplay:		null,
248		_pause:			null,
249		_play:			null,
250		_stop:			null
251	};
252
253	function Owl( element, options ) {
254
255		// add basic Owl information to dom element
256
257		element.owlCarousel = {
258			'name':		'Owl Carousel',
259			'author':	'Bartosz Wojciechowski',
260			'version':	'2.0.0-beta.1.8',
261			'released':	'03.05.2014'
262		};
263
264		// Attach variables to object
265		// Only for development process
266
267		this.options = 		$.extend( {}, defaults, options);
268		this._options =		$.extend( {}, defaults, options);
269		this.dom =			$.extend( {}, dom);
270		this.width =		$.extend( {}, width);
271		this.num =			$.extend( {}, num);
272		this.pos =			$.extend( {}, pos);
273		this.drag =			$.extend( {}, drag);
274		this.speed =		$.extend( {}, speed);
275		this.state =		$.extend( {}, state);
276		this.e =			$.extend( {}, e);
277
278		this.dom.el =		element;
279		this.dom.$el =		$(element);
280		this.init();
281	}
282
283	/**
284	 * init
285	 * @since 2.0.0
286	 */
287
288	Owl.prototype.init = function(){
289
290		this.fireCallback('onInitBefore');
291
292		//Add base class
293		if(!this.dom.$el.hasClass(this.options.baseClass)){
294			this.dom.$el.addClass(this.options.baseClass);
295		}
296
297		//Add theme class
298		if(!this.dom.$el.hasClass(this.options.themeClass)){
299			this.dom.$el.addClass(this.options.themeClass);
300		}
301
302		//Add theme class
303		if(this.options.rtl){
304			this.dom.$el.addClass('owl-rtl');
305		}
306
307		// Check support
308		this.browserSupport();
309
310		// Sort responsive items in array
311		this.sortOptions();
312
313		// Update options.items on given size
314		this.setResponsiveOptions();
315
316		if(this.options.autoWidth && this.state.imagesLoaded !== true){
317			var imgs = this.dom.$el.find('img');
318			if(imgs.length){
319				this.preloadAutoWidthImages(imgs);
320				return false;
321			}
322		}
323
324		// Get and store window width
325		// iOS safari likes to trigger unnecessary resize event
326		this.width.prevWindow = this.windowWidth();
327
328		// create stage object
329		this.createStage();
330
331		// Append local content 
332		this.fetchContent();
333
334		// attach generic events 
335		this.eventsCall();
336
337		// attach custom control events
338		this.addCustomEvents();
339
340		// attach generic events 
341		this.internalEvents();
342
343		this.dom.$el.addClass('owl-loading');
344		this.refresh(true);
345		this.dom.$el.removeClass('owl-loading').addClass('owl-loaded');
346		this.fireCallback('onInitAfter');
347	};
348
349	/**
350	 * sortOptions
351	 * @desc Sort responsive sizes 
352	 * @since 2.0.0
353	 */
354
355	Owl.prototype.sortOptions = function(){
356
357		var resOpt = this.options.responsive;
358		this.responsiveSorted = {};
359		var keys = [],
360		i, j, k;
361		for (i in resOpt){
362			keys.push(i);
363		}
364
365		keys = keys.sort(function (a, b) {return a - b;});
366
367		for (j = 0; j < keys.length; j++){
368			k = keys[j];
369			this.responsiveSorted[k] = resOpt[k];
370		}
371
372	};
373
374	/**
375	 * setResponsiveOptions
376	 * @since 2.0.0
377	 */
378
379	Owl.prototype.setResponsiveOptions = function(){
380		if(this.options.responsive === false){return false;}
381
382		var width = this.windowWidth();
383		var resOpt = this.options.responsive;
384		var i,j,k, minWidth;
385
386		// overwrite non resposnive options
387		for(k in this._options){
388			if(k !== 'responsive'){
389				this.options[k] = this._options[k];
390			}
391		}
392
393		// find responsive width
394		for (i in this.responsiveSorted){
395			if(i<= width){
396				minWidth = i;
397				// set responsive options
398				for(j in this.responsiveSorted[minWidth]){
399					this.options[j] = this.responsiveSorted[minWidth][j];
400				}
401				
402			}
403		}
404		this.num.breakpoint = minWidth;
405
406		// Responsive Class
407		if(this.options.responsiveClass){
408			this.dom.$el.attr('class',
409				function(i, c){
410				return c.replace(/\b owl-responsive-\S+/g, '');
411			}).addClass('owl-responsive-'+minWidth);
412		}
413
414
415	};
416
417	/**
418	 * optionsLogic
419	 * @desc Update option logic if necessery
420	 * @since 2.0.0
421	 */
422
423	Owl.prototype.optionsLogic = function(){
424		// Toggle Center class
425		this.dom.$el.toggleClass('owl-center',this.options.center);
426
427		// Scroll per - 'page' option will scroll per visible items number
428		// You can set this to any other number below visible items.
429		if(this.options.slideBy && this.options.slideBy === 'page'){
430			this.options.slideBy = this.options.items;
431		} else if(this.options.slideBy > this.options.items){
432			this.options.slideBy = this.options.items;
433		}
434
435		// if items number is less than in body
436		if(this.options.loop && this.num.oItems < this.options.items){
437			this.options.loop = false;
438		}
439
440		if(this.num.oItems <= this.options.items){
441			this.options.navRewind = false;
442		}
443
444		if(this.options.autoWidth){
445			this.options.stagePadding = false;
446			this.options.dotsEach = 1;
447			this.options.merge = false;
448		}
449		if(this.state.lazyContent){
450			this.options.loop = false;
451			this.options.merge = false;
452			this.options.dots = false;
453			this.options.freeDrag = false;
454			this.options.lazyContent = true;
455		}
456
457		if((this.options.animateIn || this.options.animateOut) && this.options.items === 1 && this.support3d){
458			this.state.animate = true;
459		} else {this.state.animate = false;}
460
461	};
462
463	/**
464	 * createStage
465	 * @desc Create stage and Outer-stage elements
466	 * @since 2.0.0
467	 */
468
469	Owl.prototype.createStage = function(){
470		var oStage = document.createElement('div');
471		var stage = document.createElement(this.options.stageElement);
472
473		oStage.className = 'owl-stage-outer';
474		stage.className = 'owl-stage';
475
476		oStage.appendChild(stage);
477		this.dom.el.appendChild(oStage);
478
479		this.dom.oStage = oStage;
480		this.dom.$oStage = $(oStage);
481		this.dom.stage = stage;
482		this.dom.$stage = $(stage);
483
484		oStage = null;
485		stage = null;
486	};
487
488	/**
489	 * createItem
490	 * @desc Create item container
491	 * @since 2.0.0
492	 */
493
494	Owl.prototype.createItem = function(){
495		var item = document.createElement(this.options.itemElement);
496		item.className = this.options.itemClass;
497		return item;
498	};
499
500	/**
501	 * fetchContent
502	 * @since 2.0.0
503	 */
504
505	Owl.prototype.fetchContent = function(extContent){
506		if(extContent){
507			this.dom.$content = (extContent instanceof jQuery) ? extContent : $(extContent);
508		}
509		else if(this.options.nestedItemSelector){
510			this.dom.$content= this.dom.$el.find('.'+this.options.nestedItemSelector).not('.owl-stage-outer');
511		} 
512		else {
513			this.dom.$content= this.dom.$el.children().not('.owl-stage-outer');
514		}
515		// content length
516		this.num.oItems = this.dom.$content.length;
517
518		// init Structure
519		if(this.num.oItems !== 0){
520			this.initStructure();
521		}
522	};
523
524
525	/**
526	 * initStructure
527	 * @param [refresh] - if refresh and not lazyContent then dont create normal structure
528	 * @since 2.0.0
529	 */
530
531	Owl.prototype.initStructure = function(){
532
533		// lazyContent needs at least 3*items 
534
535		if(this.options.lazyContent && this.num.oItems >= this.options.items*3){
536			this.state.lazyContent = true;
537		} else {
538			this.state.lazyContent = false;
539		}
540
541		if(this.state.lazyContent){
542
543			// start position
544			this.pos.currentAbs = this.options.items;
545
546			//remove lazy content from DOM
547			this.dom.$content.remove();
548
549		} else {
550			// create normal structure
551			this.createNormalStructure();
552		}
553	};
554
555	/**
556	 * createNormalStructure
557	 * @desc Create normal structure for small/mid weight content
558	 * @since 2.0.0
559	 */
560
561	Owl.prototype.createNormalStructure = function(){
562		for(var i = 0; i < this.num.oItems; i++){
563			// fill 'owl-item' with content 
564			var item = this.fillItem(this.dom.$content,i);
565			// append into stage 
566			this.dom.$stage.append(item);
567		}
568		this.dom.$content = null;
569	};
570
571	/**
572	 * createCustomStructure
573	 * @since 2.0.0
574	 */
575
576	Owl.prototype.createCustomStructure = function(howManyItems){
577		for(var i = 0; i < howManyItems; i++){
578			var emptyItem = this.createItem();
579			var item = $(emptyItem);
580
581			this.setData(item,false);
582			this.dom.$stage.append(item);
583		}
584	};
585
586	/**
587	 * createLazyContentStructure
588	 * @desc Create lazyContent structure for large content and better mobile experience
589	 * @since 2.0.0
590	 */
591
592	Owl.prototype.createLazyContentStructure = function(refresh){
593		if(!this.state.lazyContent){return false;}
594
595		// prevent recreate - to do
596		if(refresh && this.dom.$stage.children().length === this.options.items*3){
597			return false;
598		}
599		// remove items from stage
600		this.dom.$stage.empty();
601
602		// create custom structure
603		this.createCustomStructure(3*this.options.items);
604	};
605
606	/**
607	 * fillItem
608	 * @desc Fill empty item container with provided content
609	 * @since 2.0.0
610	 * @param [content] - string/$dom - passed owl-item
611	 * @param [i] - index in jquery object
612	 * return $ new object
613	 */
614
615	Owl.prototype.fillItem = function(content,i){
616		var emptyItem = this.createItem();
617		var c = content[i] || content;
618		// set item data 
619		var traversed = this.traversContent(c);
620		this.setData(emptyItem,false,traversed);
621		return $(emptyItem).append(c);
622	};
623
624	/**
625	 * traversContent
626	 * @since 2.0.0
627	 * @param [c] - content
628	 * return object
629	 */
630
631	Owl.prototype.traversContent = function(c){
632		var $c = $(c), dotValue, hashValue;
633		if(this.options.dotData){
634			dotValue = $c.find('[data-dot]').andSelf().data('dot');
635		}
636		// update URL hash
637		if(this.options.URLhashListener){
638			hashValue = $c.find('[data-hash]').andSelf().data('hash');
639		}
640		return {
641			dot : dotValue || false,
642			hash : hashValue  || false
643		};
644	};
645
646
647	/**
648	 * setData
649	 * @desc Set item jQuery Data 
650	 * @since 2.0.0
651	 * @param [item] - dom - passed owl-item
652	 * @param [cloneObj] - $dom - passed clone item
653	 */
654
655
656	Owl.prototype.setData = function(item,cloneObj,traversed){
657		var dot,hash;
658		if(traversed){
659			dot = traversed.dot;
660			hash = traversed.hash;
661		}
662		var itemData = {
663			index:		false,
664			indexAbs:	false,
665			posLeft:	false,
666			clone:		false,
667			active:		false,
668			loaded:		false,
669			lazyLoad:	false,
670			current:	false,
671			width:		false,
672			center:		false,
673			page:		false,
674			hasVideo:	false,
675			playVideo:	false,
676			dot:		dot,
677			hash:		hash
678		};
679
680		// copy itemData to cloned item 
681
682		if(cloneObj){
683			itemData = $.extend({}, itemData, cloneObj.data('owl-item'));
684		}
685
686		$(item).data('owl-item', itemData);
687	};
688
689	/**
690	 * updateLocalContent
691	 * @since 2.0.0
692	 */
693
694	Owl.prototype.updateLocalContent = function(){
695		this.dom.$oItems = this.dom.$stage.find('.'+this.options.itemClass).filter(function(){
696			return $(this).data('owl-item').clone === false;
697		});
698
699		this.num.oItems = this.dom.$oItems.length;
700		//update index on original items
701
702		for(var k = 0; k<this.num.oItems; k++){
703			var item = this.dom.$oItems.eq(k);
704			item.data('owl-item').index = k;
705		}
706	};
707
708	/**
709	 * checkVideoLinks
710	 * @desc Check if for any videos links
711	 * @since 2.0.0
712	 */
713
714	Owl.prototype.checkVideoLinks = function(){
715		if(!this.options.video){return false;}
716		var videoEl,item;
717
718		for(var i = 0; i<this.num.items; i++){
719
720			item = this.dom.$items.eq(i);
721			if(item.data('owl-item').hasVideo){
722				continue;
723			}
724
725			videoEl = item.find('.owl-video');
726			if(videoEl.length){
727				this.state.hasVideos = true;
728				this.dom.$items.eq(i).data('owl-item').hasVideo = true;
729				videoEl.css('display','none');
730				this.getVideoInfo(videoEl,item);
731			}
732		}
733	};
734
735	/**
736	 * getVideoInfo
737	 * @desc Get Video ID and Type (YouTube/Vimeo only)
738	 * @since 2.0.0
739	 */
740
741	Owl.prototype.getVideoInfo = function(videoEl,item){
742
743		var info, type, id,
744			vimeoId = videoEl.data('vimeo-id'),
745			youTubeId = videoEl.data('youtube-id'),
746			width = videoEl.data('width') || this.options.videoWidth,
747			height = videoEl.data('height') || this.options.videoHeight,
748			url = videoEl.attr('href');
749
750		if(vimeoId){
751			type = 'vimeo';
752			id = vimeoId;
753		} else if(youTubeId){
754			type = 'youtube';
755			id = youTubeId;
756		} else if(url){
757			id = url.match(/(http:|https:|)\/\/(player.|www.)?(vimeo\.com|youtu(be\.com|\.be|be\.googleapis\.com))\/(video\/|embed\/|watch\?v=|v\/)?([A-Za-z0-9._%-]*)(\&\S+)?/);
758			
759			if (id[3].indexOf('youtu') > -1) {
760				type = 'youtube';
761			} else if (id[3].indexOf('vimeo') > -1) {
762				type = 'vimeo';
763			}
764			id = id[6];
765		} else {
766			throw new Error('Missing video link.');
767		}
768
769		item.data('owl-item').videoType = type;
770		item.data('owl-item').videoId = id;
771		item.data('owl-item').videoWidth = width;
772		item.data('owl-item').videoHeight = height;
773
774		info = {
775			type: type,
776			id: id
777		};
778		
779		// Check dimensions
780		var dimensions = width && height ? 'style="width:'+width+'px;height:'+height+'px;"' : '';
781
782		// wrap video content into owl-video-wrapper div
783		videoEl.wrap('<div class="owl-video-wrapper"'+dimensions+'></div>');
784
785		this.createVideoTn(videoEl,info);
786	};
787
788	/**
789	 * createVideoTn
790	 * @desc Create Video Thumbnail
791	 * @since 2.0.0
792	 */
793
794	Owl.prototype.createVideoTn = function(videoEl,info){
795
796		var tnLink,icon,height;
797		var customTn = videoEl.find('img');
798		var srcType = 'src';
799		var lazyClass = '';
800		var that = this;
801
802		if(this.options.lazyLoad){
803			srcType = 'data-src';
804			lazyClass = 'owl-lazy';
805		}
806
807		// Custom thumbnail
808
809		if(customTn.length){
810			addThumbnail(customTn.attr(srcType));
811			customTn.remove();
812			return false;
813		}
814		
815		function addThumbnail(tnPath){
816			icon = '<div class="owl-video-play-icon"></div>';
817
818			if(that.options.lazyLoad){
819				tnLink = '<div class="owl-video-tn '+ lazyClass +'" '+ srcType +'="'+ tnPath +'"></div>';
820			} else{
821				tnLink = '<div class="owl-video-tn" style="opacity:1;background-image:url(' + tnPath + ')"></div>';
822			}
823			videoEl.after(tnLink);
824			videoEl.after(icon);
825		}
826
827		if(info.type === 'youtube'){
828			var path = "http://img.youtube.com/vi/"+ info.id +"/hqdefault.jpg";
829			addThumbnail(path);
830		} else
831		if(info.type === 'vimeo'){
832			$.ajax({
833				type:'GET',
834				url: 'http://vimeo.com/api/v2/video/' + info.id + '.json',
835				jsonp: 'callback',
836				dataType: 'jsonp',
837				success: function(data){
838					var path = data[0].thumbnail_large;
839					addThumbnail(path);
840					if(that.options.loop){
841						that.updateItemState();
842					}
843				}
844			});
845		}
846	};
847
848	/**
849	 * stopVideo
850	 * @since 2.0.0
851	 */
852
853	Owl.prototype.stopVideo = function(){
854		this.fireCallback('onVideoStop');
855		var item = this.dom.$items.eq(this.state.videoPlayIndex);
856		item.find('.owl-video-frame').remove();
857		item.removeClass('owl-video-playing');
858		this.state.videoPlay = false;
859	};
860
861	/**
862	 * playVideo
863	 * @since 2.0.0
864	 */
865
866	Owl.prototype.playVideo = function(ev){
867		this.fireCallback('onVideoPlay');
868
869		if(this.state.videoPlay){
870			this.stopVideo();
871		}
872		var videoLink,videoWrap,
873			target = $(ev.target || ev.srcElement),
874			item = target.closest('.'+this.options.itemClass);
875
876		var videoType = item.data('owl-item').videoType,
877			id = item.data('owl-item').videoId,
878			width = item.data('owl-item').videoWidth || Math.floor(item.data('owl-item').width - this.options.margin),
879			height = item.data('owl-item').videoHeight || this.dom.$stage.height();
880
881		if(videoType === 'youtube'){
882			videoLink = "<iframe width=\""+ width +"\" height=\""+ height +"\" src=\"http://www.youtube.com/embed/" + id + "?autoplay=1&v=" + id + "\" frameborder=\"0\" allowfullscreen></iframe>";
883		} else if(videoType === 'vimeo'){
884			videoLink = '<iframe src="http://player.vimeo.com/video/'+ id +'?autoplay=1" width="'+ width +'" height="'+ height +'" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>';
885		}
886		
887		item.addClass('owl-video-playing');
888		this.state.videoPlay = true;
889		this.state.videoPlayIndex = item.data('owl-item').indexAbs;
890
891		videoWrap = $('<div style="height:'+ height +'px; width:'+ width +'px" class="owl-video-frame">' + videoLink + '</div>');
892		target.after(videoWrap);
893	};
894
895	/**
896	 * loopClone
897	 * @desc Make a clones for infinity loop
898	 * @since 2.0.0
899	 */
900
901	Owl.prototype.loopClone = function(){
902		if(!this.options.loop || this.state.lazyContent || this.num.oItems < this.options.items){return false;}
903
904		var firstClone,	lastClone, i,
905			num	=		this.options.items, 
906			lastNum =	this.num.oItems-1;
907
908		// if neighbour margin then add one more duplicat
909		if(this.options.stagePadding && this.options.items === 1){
910			num+=1;
911		}
912		this.num.cItems = num * 2;
913
914		for(i = 0; i < num; i++){
915			// Clone item 
916			var first =		this.dom.$oItems.eq(i).clone(true,true);
917			var last =		this.dom.$oItems.eq(lastNum-i).clone(true,true);
918			firstClone = 	$(first[0]).addClass('cloned');
919			lastClone = 	$(last[0]).addClass('cloned');
920
921			// set clone data 
922			// Somehow data has reference to same data id in cash 
923
924			this.setData(firstClone[0],first);
925			this.setData(lastClone[0],last);
926
927			firstClone.data('owl-item').clone = true;
928			lastClone.data('owl-item').clone = true;
929
930			this.dom.$stage.append(firstClone);
931			this.dom.$stage.prepend(lastClone);
932
933			firstClone = lastClone = null;
934		}
935
936		this.dom.$cItems = this.dom.$stage.find('.'+this.options.itemClass).filter(function(){
937			return $(this).data('owl-item').clone === true;
938		});
939	};
940
941	/**
942	 * reClone
943	 * @desc Update Cloned elements
944	 * @since 2.0.0
945	 */
946
947	Owl.prototype.reClone = function(){
948		// remove cloned items 
949		if(this.dom.$cItems !== null){ // && (this.num.oItems !== 0 && this.num.oItems <= this.options.items)){
950			this.dom.$cItems.remove();
951			this.dom.$cItems = null;
952			this.num.cItems = 0;
953		}
954
955		if(!this.options.loop){
956			return;
957		}
958		// generete new elements 
959		this.loopClone();
960	};
961
962	/**
963	 * calculate
964	 * @desc Update item index data
965	 * @since 2.0.0
966	 */
967
968	Owl.prototype.calculate = function(){
969
970		var i,j,k,dist,posLeft=0,fullWidth=0;
971
972		// element width minus neighbour 
973		this.width.el = this.dom.$el.width() - (this.options.stagePadding*2);
974
975		//to check
976		this.width.view = this.dom.$el.width();
977
978		// calculate width minus addition margins 
979		var elMinusMargin = this.width.el - (this.options.margin * (this.options.items === 1 ? 0 : this.options.items -1));
980
981		// calculate element width and item width 
982		this.width.el =  	this.width.el + this.options.margin;
983		this.width.item = 	((elMinusMargin / this.options.items) + this.options.margin).toFixed(3);
984
985		this.dom.$items = 	this.dom.$stage.find('.owl-item');
986		this.num.items = 	this.dom.$items.length;
987
988		//change to autoWidths
989		if(this.options.autoWidth){
990			this.dom.$items.css('width','');
991		}
992
993		// Set grid array 
994		this.pos.items = 	[];
995		this.num.merged = 	[];
996		this.num.nav = 		[];
997
998		// item distances
999		if(this.options.rtl){
1000			dist = this.options.center ? -((this.width.el)/2) : 0;
1001		} else {
1002			dist = this.options.center ? (this.width.el)/2 : 0;
1003		}
1004		
1005		this.width.mergeStage = 0;
1006
1007		// Calculate items positions
1008		for(i = 0; i<this.num.items; i++){
1009
1010			// check merged items
1011
1012			if(this.options.merge){
1013				var mergeNumber = this.dom.$items.eq(i).find('[data-merge]').attr('data-merge') || 1;
1014				if(this.options.mergeFit && mergeNumber > this.options.items){
1015					mergeNumber = this.options.items;
1016				}
1017				this.num.merged.push(parseInt(mergeNumber));
1018				this.width.mergeStage += this.width.item * this.num.merged[i];
1019			} else {
1020				this.num.merged.push(1);
1021			}
1022
1023			// Array based on merged items used by dots and navigation
1024			if(this.options.loop){
1025				if(i>
1025=this.num.cItems/2 && i<this.num.cItems/2+this.num.oItems){
1026					this.num.nav.push(this.num.merged[i]);
1027				}
1028			} else {
1029				this.num.nav.push(this.num.merged[i]);
1030			}
1031
1032			var iWidth = this.width.item * this.num.merged[i];
1033
1034			// autoWidth item size
1035			if(this.options.autoWidth){
1036				iWidth = this.dom.$items.eq(i).width() + this.options.margin;
1037				if(this.options.rtl){
1038					this.dom.$items[i].style.marginLeft = this.options.margin + 'px';
1039				} else {
1040					this.dom.$items[i].style.marginRight = this.options.margin + 'px';
1041				}
1042				
1043			}
1044			// push item position into array
1045			this.pos.items.push(dist);
1046
1047			// update item data
1048			this.dom.$items.eq(i).data('owl-item').posLeft = posLeft;
1049			this.dom.$items.eq(i).data('owl-item').width = iWidth;
1050
1051			// dist starts from middle of stage if center
1052			// posLeft always starts from 0
1053			if(this.options.rtl){
1054				dist += iWidth;
1055				posLeft += iWidth;
1056			} else{
1057				dist -= iWidth;
1058				posLeft -= iWidth;
1059			}
1060
1061			fullWidth -= Math.abs(iWidth);
1062
1063			// update position if center
1064			if(this.options.center){
1065				this.pos.items[i] = !this.options.rtl ? this.pos.items[i] - (iWidth/2) : this.pos.items[i] + (iWidth/2);
1066			}
1067		}
1068
1069		if(this.options.autoWidth){
1070			this.width.stage = this.options.center ? Math.abs(fullWidth) : Math.abs(dist);
1071		} else {
1072			this.width.stage = Math.abs(fullWidth);
1073		}
1074
1075		//update indexAbs on all items 
1076		var allItems = this.num.oItems + this.num.cItems;
1077
1078		for(j = 0; j< allItems; j++){
1079			this.dom.$items.eq(j).data('owl-item').indexAbs = j;
1080		}
1081
1082		// Set Min and Max
1083		this.setMinMax();
1084
1085		// Recalculate grid 
1086		this.setSizes();
1087	};
1088
1089	/**
1090	 * setMinMax
1091	 * @since 2.0.0
1092	 */
1093
1094	Owl.prototype.setMinMax = function(){
1095
1096		// set Min
1097		var minimum = this.dom.$oItems.eq(0).data('owl-item').indexAbs;
1098		this.pos.min = 0;
1099		this.pos.minValue = this.pos.items[minimum];
1100
1101		// set max position
1102		if(!this.options.loop){
1103			this.pos.max = this.num.oItems-1;
1104		}
1105
1106		if(this.options.loop){
1107			this.pos.max = this.num.oItems+this.options.items;
1108		}
1109
1110		if(!this.options.loop && !this.options.center){
1111			this.pos.max = this.num.oItems-this.options.items;
1112		}
1113
1114		if(this.options.loop && this.options.center){
1115			this.pos.max = this.num.oItems+this.options.items;
1116		}
1117
1118		//set max value
1119		this.pos.maxValue = this.pos.items[this.pos.max];
1120
1121		//Max for autoWidth content 
1122		if((!this.options.loop && !this.options.center && this.options.autoWidth) || (this.options.merge && !this.options.center) ){
1123			var revert = this.options.rtl ? 1 : -1;
1124			for (i = 0; i < this.pos.items.length; i++) {
1125				if( (this.pos.items[i] * revert) < this.width.stage-this.width.el ){
1126					this.pos.max = i+1;
1127				}
1128			}
1129			this.pos.maxValue = this.options.rtl ? this.width.stage-this.width.el : -(this.width.stage-this.width.el);
1130			this.pos.items[this.pos.max] = this.pos.maxValue;
1131		}
1132
1133		// Set loop boundries
1134		if(this.options.center){
1135			this.pos.loop = this.pos.items[0]-this.pos.items[this.num.oItems];
1136		} else {
1137			this.pos.loop = -this.pos.items[this.num.oItems];
1138		}
1139
1140		//if is less items
1141		if(this.num.oItems < this.options.items && !this.options.center){
1142			this.pos.max = 0;
1143			this.pos.maxValue = this.pos.items[0];
1144		}
1145	};
1146
1147	/**
1148	 * setSizes
1149	 * @desc Set sizes on elements (from collectData function)
1150	 * @since 2.0.0
1151	 */
1152
1153	Owl.prototype.setSizes = function(){
1154
1155		// show neighbours 
1156		if(this.options.stagePadding !== false){
1157			this.dom.oStage.style.paddingLeft = 	this.options.stagePadding + 'px';
1158			this.dom.oStage.style.paddingRight = 	this.options.stagePadding + 'px';
1159		}
1160
1161		// CRAZY FIX!!! Doublecheck this!
1162		//if(this.width.stagePrev > this.width.stage){
1163		if(this.options.rtl){
1164			window.setTimeout(function(){
1165				this.dom.stage.style.width = this.width.stage + 'px';
1166			}.bind(this),0);
1167		} else{
1168			this.dom.stage.style.width = this.width.stage + 'px';
1169		}
1170
1171		for(var i=0; i<this.num.items; i++){
1172
1173			// Set items width
1174			if(!this.options.autoWidth){
1175				this.dom.$items[i].style.width = this.width.item - (this.options.margin) + 'px';
1176			}
1177			// add margin
1178			if(this.options.rtl){
1179				this.dom.$items[i].style.marginLeft = this.options.margin + 'px';
1180			} else {
1181				this.dom.$items[i].style.marginRight = this.options.margin + 'px';
1182			}
1183			
1184			if(this.num.merged[i] !== 1 && !this.options.autoWidth){
1185				this.dom.$items[i].style.width = (this.width.item * this.num.merged[i]) - (this.options.margin) + 'px';
1186			}
1187		}
1188
1189		// save prev stage size 
1190		this.width.stagePrev = this.width.stage;
1191	};
1192
1193	/**
1194	 * responsive
1195	 * @desc Responsive function update all data by calling refresh() 
1196	 * @since 2.0.0
1197	 */
1198
1199	Owl.prototype.responsive = function(){
1200
1201		if(!this.num.oItems){return false;}
1202		// If El width hasnt change then stop responsive 
1203		var elChanged = this.isElWidthChanged();
1204		if(!elChanged){return false;}
1205
1206		// if Vimeo Fullscreen mode
1207		var fullscreenElement = document.fullscreenElement || document.mozFullScreenElement || document.webkitFullscreenElement;
1208		if(fullscreenElement){
1209			if($(fullscreenElement.parentNode).hasClass('owl-video-frame')){
1210				this.setSpeed(0);
1211				this.state.isFullScreen = true;
1212			}
1213		}
1214
1215		if(fullscreenElement && this.state.isFullScreen && this.state.videoPlay){
1216			return false;
1217		}
1218
1219		// Comming back from fullscreen
1220		if(this.state.isFullScreen){
1221			this.state.isFullScreen = false;
1222			return false;
1223		}
1224
1225		// check full screen mode and window orientation
1226		if (this.state.videoPlay) {
1227			if(this.state.orientation !== window.orientation){
1228				this.state.orientation = window.orientation;
1229				return false;
1230			}
1231		}
1232
1233		this.fireCallback('onResponsiveBefore');
1234		this.state.responsive = true;
1235		this.refresh();
1236		this.state.responsive = false;
1237		this.fireCallback('onResponsiveAfter');
1238	};
1239
1240	/**
1241	 * refresh
1242	 * @desc Refresh method is basically collection of functions that are responsible for Owl responsive functionality
1243	 * @since 2.0.0
1244	 */
1245
1246	Owl.prototype.refresh = function(init){
1247
1248		if(this.state.videoPlay){
1249			this.stopVideo();
1250		}
1251
1252		// Update Options for given width
1253		this.setResponsiveOptions();
1254
1255		//set lazy structure
1256		this.createLazyContentStructure(true);
1257
1258		// update info about local content
1259		this.updateLocalContent();
1260
1261		// udpate options
1262		this.optionsLogic();
1263
1264		// if no items then stop 
1265		if(this.num.oItems === 0){
1266			if(this.dom.$page !== null){
1267				this.dom.$page.hide();
1268			}
1269			return false;
1270		}
1271
1272		// Hide and Show methods helps here to set a proper widths.
1273		// This prevents Scrollbar to be calculated in stage width
1274		this.dom.$stage.addClass('owl-refresh');
1275		
1276		// Remove clones and generate new ones
1277		this.reClone();
1278
1279		// calculate 
1280		this.calculate();
1281
1282		//aaaand show.
1283		this.dom.$stage.removeClass('owl-refresh');
1284
1285		// to do
1286		// lazyContent last position on refresh
1287		if(this.state.lazyContent){
1288			this.pos.currentAbs = this.options.items;
1289		}
1290
1291		this.initPosition(init);
1292
1293		// jump to last position 
1294		if(!this.state.lazyContent && !init){
1295			this.jumpTo(this.pos.current,false); // fix that 
1296		}
1297
1298		//Check for videos ( YouTube and Vimeo currently supported)
1299		this.checkVideoLinks();
1300
1301		this.updateItemState();
1302
1303		// Update controls
1304		this.rebuildDots();
1305
1306		this.updateControls();
1307
1308		// update drag events
1309		//this.updateEvents();
1310
1311		// update autoplay
1312		this.autoplay();
1313
1314		this.autoHeight();
1315
1316		this.state.orientation = window.orientation;
1317
1318		this.watchVisibility();
1319	};
1320
1321	/**
1322	 * updateItemState
1323	 * @desc Update information about current state of items (visibile, hidden, active, etc.)
1324	 * @since 2.0.0
1325	 */
1326
1327	Owl.prototype.updateItemState = function(update){
1328
1329		if(!this.state.lazyContent){
1330			this.updateActiveItems();
1331		} else {
1332			this.updateLazyContent(update);
1333		}
1334
1335		if(this.options.center){
1336			this.dom.$items.eq(this.pos.currentAbs)
1337			.addClass(this.options.centerClass)
1338			.data('owl-item').center = true;
1339		}
1340
1341		if(this.options.lazyLoad){
1342			this.lazyLoad();
1343		}
1344	};
1345
1346	/**
1347	 * updateActiveItems
1348	 * @since 2.0.0
1349	 */
1350
1351
1352	Owl.prototype.updateActiveItems = function(){
1353		var i,j,item,ipos,iwidth,wpos,stage,outsideView,foundCurrent;
1354		// clear states
1355		for(i = 0; i<this.num.items; i++){
1356			this.dom.$items.eq(i).data('owl-item').active = false;
1357			this.dom.$items.eq(i).data('owl-item').current = false;
1358			this.dom.$items.eq(i).removeClass(this.options.activeClass).removeClass(this.options.centerClass);
1359		}
1360
1361		this.num.active = 0;
1362		stageX = this.pos.stage;
1363		view = this.options.rtl ? this.width.view : -this.width.view;
1364
1365		for(j = 0; j<this.num.items; j++){
1366
1367				item = this.dom.$items.eq(j);
1368				ipos = item.data('owl-item').posLeft;
1369				iwidth = item.data('owl-item').width;
1370				outsideView = this.options.rtl ? ipos + iwidth : ipos - iwidth;
1371
1372			if( (this.op(ipos,'<=',stageX) && (this.op(ipos,'>',stageX + view))) || 
1373				(this.op(outsideView,'<',stageX) && this.op(outsideView,'>',stageX + view)) 
1374				){
1375
1376				this.num.active++;
1377
1378				if(this.options.freeDrag && !foundCurrent){
1379					foundCurrent = true;
1380					this.pos.current = item.data('owl-item').index;
1381					this.pos.currentAbs = item.data('owl-item').indexAbs;
1382				}
1383
1384				item.data('owl-item').active = true;
1385				item.data('owl-item').current = true;
1386				item.addClass(this.options.activeClass);
1387
1388				if(!this.options.lazyLoad){
1389					item.data('owl-item').loaded = true;
1390				}
1391				if(this.options.loop && (this.options.lazyLoad || this.options.center)){
1392					this.updateClonedItemsState(item.data('owl-item').index);
1393				}
1394			}
1395		}
1396	};
1397
1398	/**
1399	 * updateClonedItemsState
1400	 * @desc Set current state on sibilings items for lazyLoad and center
1401	 * @since 2.0.0
1402	 */
1403
1404	Owl.prototype.updateClonedItemsState = function(activeIndex){
1405
1406		//find cloned center
1407		var center, $el,i;
1408		if(this.options.center){
1409			center = this.dom.$items.eq(this.pos.currentAbs).data('owl-item').index;
1410		}
1411
1412		for(i = 0; i<this.num.items; i++){
1413			$el = this.dom.$items.eq(i);
1414			if( $el.data('owl-item').index === activeIndex ){
1415				$el.data('owl-item').current = true;
1416				if($el.data('owl-item').index === center ){
1417					$el.addClass(this.options.centerClass);
1418				}
1419			}
1420		}
1421	};
1422
1423	/**
1424	 * updateLazyPosition
1425	 * @desc Set current state on sibilings items for lazyLoad and center
1426	 * @since 2.0.0
1427	 */
1428
1429	Owl.prototype.updateLazyPosition = function(){
1430		var jumpTo = this.pos.goToLazyContent || 0;
1431
1432		this.pos.lcMovedBy = Math.abs(this.options.items - this.pos.currentAbs);
1433
1434		if(this.options.items < this.pos.currentAbs ){
1435			this.pos.lcCurrent += this.pos.currentAbs - this.options.items;
1436			this.state.lcDirection = 'right';
1437		} else if(this.options.items > this.pos.currentAbs ){
1438			this.pos.lcCurrent -= this.options.items - this.pos.currentAbs;
1439			this.state.lcDirection = 'left';
1440		}
1441
1442		this.pos.lcCurrent = jumpTo !== 0 ? jumpTo : this.pos.lcCurrent;
1443
1444		if(this.pos.lcCurrent >= this.dom.$content.length){
1445			this.pos.lcCurrent = this.pos.lcCurrent-this.dom.$content.length;
1446		} else if(this.pos.lcCurrent < -this.dom.$content.length+1){
1447			this.pos.lcCurrent = this.pos.lcCurrent+this.dom.$content.length;
1448		}
1449
1450		if(this.options.startPosition>0){
1451			this.pos.lcCurrent = this.options.startPosition;
1452			this._options.startPosition = this.options.startPosition = 0;
1453		}
1454
1455		this.pos.lcCurrentAbs = this.pos.lcCurrent < 0 ? this.pos.lcCurrent+this.dom.$content.length : this.pos.lcCurrent;
1456
1457	};
1458
1459	/**
1460	 * updateLazyContent
1461	 * @param [update] - boolean - update call by content manipulations
1462	 * @since 2.0.0
1463	 */
1464
1465	Owl.prototype.updateLazyContent = function(update){
1466
1467		if(this.pos.lcCurrent === undefined){
1468			this.pos.lcCurrent = 0;
1469			this.pos.current = this.pos.currentAbs = this.options.items;
1470		}
1471
1472		if(!update){
1473			this.updateLazyPosition();
1474		}
1475		var i,j,item,contentPos,content,freshItem,freshData;
1476
1477		if(this.state.lcDirection !== false){
1478			for(i = 0; i<this.pos.lcMovedBy; i++){
1479
1480				if(this.state.lcDirection === 'right'){
1481					item = this.dom.$stage.find('.owl-item').eq(0); //.appendTo(this.dom.$stage);
1482					item.appendTo(this.dom.$stage);
1483				}
1484				if(this.state.lcDirection === 'left'){
1485					item = this.dom.$stage.find('.owl-item').eq(-1);
1486					item.prependTo(this.dom.$stage);
1487				}
1488				item.data('owl-item').active = false;
1489			}
1490		}
1491
1492		// recollect 
1493		this.dom.$items = this.dom.$stage.find('.owl-item');
1494
1495		for(j = 0; j<this.num.items; j++){
1496			// to do
1497			this.dom.$items.eq(j).removeClass(this.options.centerClass);
1498
1499			// get Content 
1500			contentPos = this.pos.lcCurrent + j - this.options.items;// + this.options.startPosition;
1501
1502			if(contentPos >= this.dom.$content.length){
1503				contentPos = contentPos - this.dom.$content.length;
1504			}
1505			if(contentPos < -this.dom.$content.length){
1506				contentPos = contentPos + this.dom.$content.length;
1507			}
1508
1509			content = this.dom.$content.eq(contentPos);
1510			freshItem = this.dom.$items.eq(j);
1511			freshData = freshItem.data('owl-item');
1512
1513			if(freshData.active === false || this.pos.goToLazyContent !== 0 || update === true){
1514
1515				freshItem.empty();
1516				freshItem.append(content.clone(true,true));
1517				freshData.active = true;
1518				freshData.current = true;
1519				if(!this.options.lazyLoad){
1520					freshData.loaded = true;
1521				} else {
1522					freshData.loaded = false;
1523				}
1524			}
1525		}
1526
1527		this.pos.goToLazyContent = 0;
1528		this.pos.current = this.pos.currentAbs = this.options.items;
1529		this.setSpeed(0);
1530		this.animStage(this.pos.items[this.options.items]);
1531	};
1532
1533	/**
1534	 * eventsCall
1535	 * @desc Save internal event references and add event based functions like transitionEnd,responsive etc.
1536	 * @since 2.0.0
1537	 */
1538
1539	Owl.prototype.eventsCall = function(){
1540		// Save events references 
1541		this.e._onDragStart =	function(e){this.onDragStart(e);		}.bind(this);
1542		this.e._onDragMove =	function(e){this.onDragMove(e);			}.bind(this);
1543		this.e._onDragEnd =		function(e){this.onDragEnd(e);			}.bind(this);
1544		this.e._transitionEnd =	function(e){this.transitionEnd(e);		}.bind(this);
1545		this.e._resizer =		function(){this.responsiveTimer();		}.bind(this);
1546		this.e._responsiveCall =function(){this.responsive();			}.bind(this);
1547		this.e._preventClick =	function(e){this.preventClick(e);		}.bind(this);
1548		this.e._goToHash =		function(){this.goToHash();				}.bind(this);
1549		this.e._goToPage =		function(e){this.goToPage(e);			}.bind(this);
1550		this.e._ap = 			function(){this.autoplay();				}.bind(this);
1551		this.e._play = 			function(){this.play();					}.bind(this);
1552		this.e._pause = 		function(){this.pause();				}.bind(this);
1553		this.e._playVideo = 	function(e){this.playVideo(e);			}.bind(this);
1554
1555		this.e._navNext = function(e){
1556			if($(e.target).hasClass('disabled')){return false;}
1557			e.preventDefault();
1558			this.next();				
1559		}.bind(this);
1560
1561		this.e._navPrev = function(e){
1562			if($(e.target).hasClass('disabled')){return false;}
1563			e.preventDefault();
1564			this.prev();
1565		}.bind(this);
1566
1567	};
1568
1569	/**
1570	 * responsiveTimer
1571	 * @desc Check Window resize event with 200ms delay / this.options.responsiveRefreshRate
1572	 * @since 2.0.0
1573	 */
1574
1575	Owl.prototype.responsiveTimer = function(){
1576		if(this.windowWidth() === this.width.prevWindow){
1577			return false;
1578		}
1579		window.clearInterval(this.e._autoplay);
1580		window.clearTimeout(this.resizeTimer);
1581		this.resizeTimer = window.setTimeout(this.e._responsiveCall, this.options.responsiveRefreshRate);
1582		this.width.prevWindow = this.windowWidth();
1583	};
1584
1585	/**
1586	 * internalEvents
1587	 * @desc Checks for touch/mouse drag options and add necessery event handlers.
1588	 * @since 2.0.0
1589	 */
1590
1591	Owl.prototype.internalEvents = function(){
1592		var isTouch = isTouchSupport();
1593		var isTouchIE = isTouchSupportIE();
1594
1595		if(isTouch && !isTouchIE){
1596			this.dragType = ['touchstart','touchmove','touchend','touchcancel'];
1597		} else if(isTouch && isTouchIE){
1598			this.dragType = ['MSPointerDown','MSPointerMove','MSPointerUp','MSPointerCancel'];
1599		} else {
1600			this.dragType = ['mousedown','mousemove','mouseup'];
1601		}
1602
1603		if( (isTouch || isTouchIE) && this.options.touchDrag){
1604			//touch cancel event 
1605			this.on(document, this.dragType[3], this.e._onDragEnd);
1606
1607		} else {
1608			// firefox startdrag fix - addeventlistener doesnt work here :/
1609			this.dom.$stage.on('dragstart', function() {return false;});
1610
1611			if(this.options.mouseDrag){
1612				//disable text select
1613				this.dom.stage.onselectstart = function(){return false;};
1614			} else {
1615				// enable text select
1616				this.dom.$el.addClass('owl-text-select-on');
1617			}
1618		}
1619
1620		// Video Play Button event delegation
1621		this.dom.$stage.on(this.dragType[2], '.owl-video-play-icon', this.e._playVideo);
1622
1623		if(this.options.URLhashListener){
1624			this.on(window, 'hashchange', this.e._goToHash, false);
1625		}
1626
1627		if(this.options.autoplayHoverPause){
1628			var that = this;
1629			this.dom.$stage.on('mouseover', this.e._pause );
1630			this.dom.$stage.on('mouseleave', this.e._ap );
1631		}
1632
1633		// Catch transitionEnd event
1634		if(this.transitionEndVendor){
1635			this.on(this.dom.stage, this.transitionEndVendor, this.e._transitionEnd, false);
1636		}
1637		
1638		// Responsive
1639		if(this.options.responsive !== false){
1640			this.on(window, 'resize', this.e._resizer, false);
1641		}
1642
1643		this.updateEvents();
1644	};
1645
1646	/**
1647	 * updateEvents
1648	 * @since 2.0.0
1649	 */
1650
1651	Owl.prototype.updateEvents = function(){
1652
1653		if(this.options.touchDrag && (this.dragType[0] === 'touchstart' || this.dragType[0] === 'MSPointerDown')){
1654			this.on(this.dom.stage, this.dragType[0], this.e._onDragStart,false);
1655		} else if(this.options.mouseDrag && this.dragType[0] === 'mousedown'){
1656			this.on(this.dom.stage, this.dragType[0], this.e._onDragStart,false);
1657
1658		} else {
1659			this.off(this.dom.stage, this.dragType[0], this.e._onDragStart);
1660		}
1661	};
1662
1663	/**
1664	 * onDragStart
1665	 * @desc touchstart/mousedown event
1666	 * @since 2.0.0
1667	 */
1668
1669	Owl.prototype.onDragStart = function(event){
1670		var ev = event.originalEvent || event || window.event;
1671		// prevent right click
1672		if (ev.which === 3) { 
1673			return false;
1674		}
1675
1676		if(this.dragType[0] === 'mousedown'){
1677			this.dom.$stage.addClass('owl-grab');
1678		}
1679
1680		this.fireCallback('onTouchStart');
1681		this.drag.startTime = new Date().getTime();
1682		this.setSpeed(0);
1683		this.state.isTouch = true;
1684		this.state.isScrolling = false;
1685		this.state.isSwiping = false;
1686		this.drag.distance = 0;
1687
1688		// if is 'touchstart'
1689		var isTouchEvent = ev.type === 'touchstart';
1690		var pageX = isTouchEvent ? event.targetTouches[0].pageX : (ev.pageX || ev.clientX);
1691		var pageY = isTouchEvent ? event.targetTouches[0].pageY : (ev.pageY || ev.clientY);
1692
1693		//get stage position left
1694		this.drag.offsetX = this.dom.$stage.position().left - this.options.stagePadding;
1695		this.drag.offsetY = this.dom.$stage.position().top;
1696
1697		if(this.options.rtl){
1698			this.drag.offsetX = this.dom.$stage.position().left + this.width.stage - this.width.el + this.options.margin;
1699		}
1700
1701		//catch position // ie to fix
1702		if(this.state.inMotion && this.support3d){
1703			var animatedPos = this.getTransformProperty();
1704			this.drag.offsetX = animatedPos;
1705			this.animStage(animatedPos);
1706		} else if(this.state.inMotion && !this.support3d ){
1707			this.state.inMotion = false;
1708			return false;
1709		}
1710
1711		this.drag.startX = pageX - this.drag.offsetX;
1712		this.drag.startY = pageY - this.drag.offsetY;
1713
1714		this.drag.start = pageX - this.drag.startX;
1715		this.drag.targetEl = ev.target || ev.srcElement;
1716		this.drag.updatedX = this.drag.start;
1717
1718		// to do/check
1719		//prevent links and images dragging;
1720		//this.drag.targetEl.draggable = false;
1721
1722		this.on(document, this.dragType[1], this.e._onDragMove, false);
1723		this.on(document, this.dragType[2], this.e._onDragEnd, false);
1724	};
1725
1726	/**
1727	 * onDragMove
1728	 * @desc touchmove/mousemove event
1729	 * @since 2.0.0
1730	 */
1731
1732	Owl.prototype.onDragMove = function(event){
1733		if (!this.state.isTouch){
1734			return;
1735		}
1736
1737		if (this.state.isScrolling){
1738			return;
1739		}
1740
1741		var neighbourItemWidth=0;
1742		var ev = event.originalEvent || event || window.event;
1743
1744		// if is 'touchstart'
1745		var isTouchEvent = ev.type == 'touchmove';
1746		var pageX = isTouchEvent ? ev.targetTouches[0].pageX : (ev.pageX || ev.clientX);
1747		var pageY = isTouchEvent ? ev.targetTouches[0].pageY : (ev.pageY || ev.clientY);
1748
1749		// Drag Direction 
1750		this.drag.currentX = pageX - this.drag.startX;
1751		this.drag.currentY = pageY - this.drag.startY;
1752		this.drag.distance = this.drag.currentX - this.drag.offsetX;
1753
1754		// Check move direction 
1755		if (this.drag.distance < 0) {
1756			this.state.direction = this.options.rtl ? 'right' : 'left';
1757		} else if(this.drag.distance > 0){
1758			this.state.direction = this.options.rtl ? 'left' : 'right';
1759		}
1760		// Loop
1761		if(this.options.loop){
1762			if(this.op(this.drag.currentX, '>', this.pos.minValue) && this.state.direction === 'right' ){
1763				this.drag.currentX -= this.pos.loop;
1764			}else if(this.op(this.drag.currentX, '<', this.pos.maxValue) && this.state.direction === 'left' ){
1765				this.drag.currentX += this.pos.loop;
1766			}
1767		} else {
1768			// pull
1769			var minValue = this.options.rtl ? this.pos.maxValue : this.pos.minValue;
1770			var maxValue = this.options.rtl ? this.pos.minValue : this.pos.maxValue;
1771			var pull = this.options.pullDrag ? this.drag.distance / 5 : 0;
1772			this.drag.currentX = Math.max(Math.min(this.drag.currentX, minValue + pull), maxValue + pull);
1773		}
1774
1775
1776
1777		// Lock browser if swiping horizontal
1778
1779		if ((this.drag.distance > 8 || this.drag.distance < -8)) {
1780			if (ev.preventDefault !== undefined) {
1781				ev.preventDefault();
1782			} else {
1783				ev.returnValue = false;
1784			}
1785			this.state.isSwiping = true;
1786		}
1787
1788		this.drag.updatedX = this.drag.currentX;
1789
1790		// Lock Owl if scrolling 
1791		if ((this.drag.currentY > 16 || this.drag.currentY < -16) && this.state.isSwiping === false) {
1792			 this.state.isScrolling = true;
1793			 this.drag.updatedX = this.drag.start;
1794		}
1795
1796		this.animStage(this.drag.updatedX);
1797	};
1798
1799	/**
1800	 * onDragEnd 
1801	 * @desc touchend/mouseup event
1802	 * @since 2.0.0
1803	 */
1804
1805	Owl.prototype.onDragEnd = function(event){
1806		if (!this.state.isTouch){
1807			return;
1808		}
1809		if(this.dragType[0] === 'mousedown'){
1810			this.dom.$stage.removeClass('owl-grab');
1811		}
1812
1813		this.fireCallback('onTouchEnd');
1814
1815		//prevent links and images dragging;
1816		//this.drag.targetEl.draggable = true;
1817
1818		//remove drag event listeners
1819
1820		this.state.isTouch = false;
1821		this.state.isScrolling = false;
1822		this.state.isSwiping = false;
1823
1824		//to check
1825		if(this.drag.distance === 0 && this.state.inMotion !== true){
1826			this.state.inMotion = false;
1827			return false;
1828		}
1829
1830		// prevent clicks while scrolling
1831
1832		this.drag.endTime = new Date().getTime();
1833		var compareTimes = this.drag.endTime - this.drag.startTime;
1834		var distanceAbs = Math.abs(this.drag.distance);
1835
1836		//to test
1837		if(distanceAbs > 3 || compareTimes > 300){
1838			this.removeClick(this.drag.targetEl);
1839		}
1840
1841		var closest = this.closest(this.drag.updatedX);
1842
1843		this.setSpeed(this.options.dragEndSpeed, false, true);
1844		this.animStage(this.pos.items[closest]);
1845		
1846		//if pullDrag is off then fire transitionEnd event manually when stick to border
1847		if(!this.options.pullDrag && this.drag.updatedX === this.pos.items[closest]){
1848			this.transitionEnd();
1849		}
1850
1851		this.drag.distance = 0;
1852
1853		this.off(document, this.dragType[1], this.e._onDragMove);
1854		this.off(document, this.dragType[2], this.e._onDragEnd);
1855	};
1856
1857	/**
1858	 * removeClick
1859	 * @desc Attach preventClick function to disable link while swipping
1860	 * @since 2.0.0
1861	 * @param [target] - clicked dom element
1862	 */
1863
1864	Owl.prototype.removeClick = function(target){
1865		this.drag.targetEl = target;
1866		this.on(target,'click', this.e._preventClick, false);
1867	};
1868
1869	/**
1870	 * preventClick
1871	 * @desc Add preventDefault for any link and then remove removeClick event hanlder
1872	 * @since 2.0.0
1873	 */
1874
1875	Owl.prototype.preventClick = function(ev){
1876		if(ev.preventDefault) {
1877			ev.preventDefault();
1878		}else {
1879			ev.returnValue = false;
1880		}
1881		if(ev.stopPropagation){
1882			ev.stopPropagation();
1883		}
1884		this.off(this.drag.targetEl,'click',this.e._preventClick,false);
1885	};
1886
1887	/**
1888	 * getTransformProperty
1889	 * @desc catch stage position while animate (only css3)
1890	 * @since 2.0.0
1891	 */
1892
1893	Owl.prototype.getTransformProperty = function(){
1894		var transform = window.getComputedStyle(this.dom.stage, null).getPropertyValue(this.vendorName + 'transform');
1895		//var transform = this.dom.$stage.css(this.vendorName + 'transform')
1896		transform = transform.replace(/matrix(3d)?\(|\)/g, '').split(',');
1897		var matrix3d = transform.length === 16;
1898
1899		return matrix3d !== true ? transform[4] : transform[12];
1900	};
1901
1902	/**
1903	 * closest
1904	 * @desc Get closest item after touchend/mouseup
1905	 * @since 2.0.0
1906	 * @param [x] - curent position in pixels
1907	 * return position in pixels
1908	 */
1909
1910	Owl.prototype.closest = function(x){
1911		var newX = 0,
1912			pull = 30;
1913
1914		if(!this.options.freeDrag){
1915			// Check closest item
1916			for(var i = 0; i< this.num.items; i++){
1917				if(x > this.pos.items[i]-pull && x < this.pos.items[i]+pull){
1918					newX = i;
1919				}else if(this.op(x,'<',this.pos.items[i]) && this.op(x,'>',this.pos.items[i+1 || this.pos.items[i] - this.width.el]) ){
1920					newX = this.state.direction === 'left' ? i+1 : i;
1921				}
1922			}
1923		}
1924		//non loop boundries
1925		if(!this.options.loop){
1926			if(this.op(x,'>',this.pos.minValue)){
1927				newX = x = this.pos.min;
1928			} else if(this.op(x,'<',this.pos.maxValue)){
1929				newX = x = this.pos.max;
1930			}
1931		}
1932
1933		if(!this.options.freeDrag){
1934			// set positions
1935			this.pos.currentAbs = newX;
1936			this.pos.current = this.dom.$items.eq(newX).data('owl-item').index;
1937		} else {
1938			this.updateItemState();
1939			return x;
1940		}
1941
1942		return newX;
1943	};
1944
1945	/**
1946	 * animStage
1947	 * @desc animate stage position (both css3/css2) and perform onChange functions/events
1948	 * @since 2.0.0
1949	 * @param [x] - curent position in pixels
1950	 */
1951
1952	Owl.prototype.animStage = function(pos){
1953
1954		// if speed is 0 the set inMotion to false
1955		if(this.speed.current !== 0 && this.pos.currentAbs !== this.pos.min){
1956			this.fireCallback('onTransitionStart');
1957			this.state.inMotion = true;
1958		}
1959
1960		var posX = this.pos.stage = pos,
1961			style = this.dom.stage.style;
1962
1963		if(this.support3d){
1964			translate = 'translate3d(' + posX + 'px'+',0px, 0px)';
1965			style[this.transformVendor] = translate;
1966		} else if(this.state.isTouch){
1967			style.left = posX+'px';
1968		} else {
1969			this.dom.$stage.animate({left: posX},this.speed.css2speed, this.options.fallbackEasing, function(){
1970				if(this.state.inMotion){
1971					this.transitionEnd();
1972				}
1973			}.bind(this));
1974		}
1975
1976		this.onChange();
1977	};
1978
1979	/**
1980	 * updatePosition
1981	 * @desc Update current positions
1982	 * @since 2.0.0
1983	 * @param [pos] - number - new position
1984	 */
1985
1986	Owl.prototype.updatePosition = function(pos){
1987
1988		// if no items then stop 
1989		if(this.num.oItems === 0){return false;}
1990		// to do
1991		//if(pos > this.num.items){pos = 0;}
1992		if(pos === undefined){return false;}
1993
1994		//pos - new current position
1995		var nextPos = pos;
1996		this.pos.prev = this.pos.currentAbs;
1997
1998		if(this.state.revert){
1999			this.pos.current = this.dom.$items.eq(nextPos).data('owl-item').index;
2000			this.pos.currentAbs = nextPos;
2001			return;
2002		}
2003
2004		if(!this.options.loop){
2005			if(this.options.navRewind){
2006				nextPos = nextPos > this.pos.max ? this.pos.min : (nextPos < 0 ? this.pos.max : nextPos);
2007			} else {
2008				nextPos = nextPos > this.pos.max ? this.pos.max : (nextPos <= 0 ? 0 : nextPos);
2009			}
2010		} else {
2011			nextPos = nextPos >= this.num.oItems ? this.num.oItems-1 : nextPos;
2012		}
2013
2014		this.pos.current = this.dom.$oItems.eq(nextPos).data('owl-item').index;
2015		this.pos.currentAbs = this.dom.$oItems.eq(nextPos).data('owl-item').indexAbs;
2016
2017	};
2018
2019	/**
2020	 * setSpeed
2021	 * @since 2.0.0
2022	 * @param [speed] - number
2023	 * @param [pos] - number - next position - use this param to calculate smartSpeed
2024	 * @param [drag] - boolean - if drag is true then smart speed is disabled
2025	 * return speed
2026	 */
2027
2028	Owl.prototype.setSpeed = function(speed,pos,drag) {
2029		var s = speed,
2030			nextPos = pos;
2031
2032		if((s === false && s !== 0 && drag !== true) || s === undefined){
2033
2034			//Double check this
2035			// var nextPx = this.pos.items[nextPos];
2036			// var currPx = this.pos.stage 
2037			// var diff = Math.abs(nextPx-currPx);
2038			// var s = diff/1
2039			// if(s>1000){
2040			// 	s = 1000;
2041			// }
2042			
2043			var diff = Math.abs(nextPos - this.pos.prev);
2044			diff = diff === 0 ? 1 : diff;
2045			if(diff>6){diff = 6;}
2046			s = diff * this.options.smartSpeed;
2047		}
2048
2049		if(s === false && drag === true){
2050			s = this.options.smartSpeed;
2051		}
2052
2053		if(s === 0){s=0;}
2054
2055		if(this.support3d){
2056			var style = this.dom.stage.style;
2057			style.webkitTransitionDuration = style.MsTransitionDuration = style.msTransitionDuration = style.MozTransitionDuration = style.OTransitionDuration = style.transitionDuration = (s / 1000) + 's';
2058		} else{
2059			this.speed.css2speed = s;
2060		}
2061		this.speed.current = s;
2062		return s;
2063	};
2064
2065	/**
2066	 * jumpTo
2067	 * @since 2.0.0
2068	 * @param [pos] - number - next position - use this param to calculate smartSpeed
2069	 * @param [update] - boolean - if drag is true then smart speed is disabled
2070	 */
2071
2072	Owl.prototype.jumpTo = function(pos,update){
2073		if(this.state.lazyContent){
2074			this.pos.goToLazyContent = pos;
2075		}
2076		this.updatePosition(pos);
2077		this.setSpeed(0);
2078		this.animStage(this.pos.items[this.pos.currentAbs]);
2079		if(update !== true){
2080			this.updateItemState();
2081		}
2082	};
2083
2084	/**
2085	 * goTo
2086	 * @since 2.0.0
2087	 * @param [pos] - number
2088	 * @param [speed] - speed in ms
2089	 * @param [speed] - speed in ms
2090	 */
2091
2092	Owl.prototype.goTo = function(pos,speed){
2093		if(this.state.lazyContent && this.state.inMotion){
2094			return false;
2095		}
2096
2097		this.updatePosition(pos);
2098
2099		if(this.state.animate){speed = 0;}
2100		this.setSpeed(speed,this.pos.currentAbs);
2101
2102		if(this.state.animate){this.animate();}
2103		this.animStage(this.pos.items[this.pos.currentAbs]);
2104	
2105	};
2106
2107	/**
2108	 * next
2109	 * @since 2.0.0
2110	 */
2111
2112	Owl.prototype.next = function(optionalSpeed){
2113		var s = optionalSpeed || this.options.navSpeed;
2114		if(this.options.loop && !this.state.lazyContent){
2115			this.goToLoop(this.options.slideBy, s);
2116		}else{
2117			this.goTo(this.pos.current + this.options.slideBy, s);
2118		}
2119	};
2120
2121	/**
2122	 * prev
2123	 * @since 2.0.0
2124	 */
2125
2126	Owl.prototype.prev = function(optionalSpeed){
2127		var s = optionalSpeed || this.options.navSpeed;
2128		if(this.options.loop && !this.state.lazyContent){
2129			this.goToLoop(-this.options.slideBy, s);
2130		}else{
2131			this.goTo(this.pos.current-this.options.slideBy, s);
2132		}
2133	};
2134
2135	/**
2136	 * goToLoop
2137	 * @desc Go to given position if loop is enabled - used only internal
2138	 * @since 2.0.0
2139	 * @param [distance] - number -how far to go
2140	 * @param [speed] - number - speed in ms
2141	 */
2142
2143	Owl.prototype.goToLoop = function(distance,speed){
2144
2145		var revert = this.pos.currentAbs,
2146			prevPosition = this.pos.currentAbs,
2147			newPosition = this.pos.currentAbs + distance,
2148			direction = prevPosition - newPosition < 0 ? true : false;
2149
2150		this.state.revert = true;
2151
2152		if(newPosition < 1 && direction === false){
2153
2154			this.state.bypass = true;
2155			revert = this.num.items - (this.options.items-prevPosition) - this.options.items;
2156			this.jumpTo(revert,true);
2157
2158		} else if(newPosition >= this.num.items - this.options.items && direction === true ){
2159
2160			this.state.bypass = true;
2161			revert = prevPosition - this.num.oItems;
2162			this.jumpTo(revert,true);
2163
2164		}
2165		window.clearTimeout(this.e._goToLoop);
2166		this.e._goToLoop = window.setTimeout(function(){
2167			this.state.bypass = false;
2168			this.goTo(revert + distance, speed);
2169			this.state.revert = false;
2170
2171		}.bind(this), 30);
2172	};
2173
2174	/**
2175	 * initPosition
2176	 * @since 2.0.0
2177	 */
2178
2179	Owl.prototype.initPosition = function(init){
2180
2181		if( !this.dom.$oItems || !init || this.state.lazyContent ){return false;}
2182		var pos = this.options.startPosition;
2183
2184		if(this.options.startPosition === 'URLHash'){
2185			pos = this.options.startPosition = this.hashPosition();
2186		} else if(typeof this.options.startPosition !== Number && !this.options.center){
2187			this.options.startPosition = 0;
2188		}
2189		this.dom.oStage.scrollLeft = 0;
2190		this.jumpTo(pos,true);
2191	};
2192
2193	/**
2194	 * goToHash
2195	 * @since 2.0.0
2196	 */
2197
2198	Owl.prototype.goToHash = function(){
2199		var pos = this.hashPosition();
2200		if(pos === false){
2201			pos = 0;
2202		}
2203		this.dom.oStage.scrollLeft = 0;
2204		this.goTo(pos,this.options.navSpeed);
2205	};
2206
2207	/**
2208	 * hashPosition
2209	 * @desc Find hash in URL then look into items to find contained ID
2210	 * @since 2.0.0
2211	 * return hashPos - number of item
2212	 */
2213
2214	Owl.prototype.hashPosition = function(){
2215		var hash = window.location.hash.substring(1),
2216			hashPos;
2217		if(hash === ""){return false;}
2218
2219		for(var i=0;i<this.num.oItems; i++){
2220			if(hash === this.dom.$oItems.eq(i).data('owl-item').hash){
2221				hashPos = i;
2222			}
2223		}
2224		return hashPos;
2225	};
2226
2227	/**
2228	 * Autoplay
2229	 * @since 2.0.0
2230	 */
2231
2232	Owl.prototype.autoplay = function(){
2233		if(this.options.autoplay && !this.state.videoPlay){
2234			window.clearInterval(this.e._autoplay);
2235			this.e._autoplay = window.setInterval(this.e._play, this.options.autoplayTimeout);
2236		} else {
2237			window.clearInterval(this.e._autoplay);
2238			this.state.autoplay=false;
2239		}
2240	};
2241
2242	/**
2243	 * play
2244	 * @param [timeout] - Integrer
2245	 * @param [speed] - Integrer
2246	 * @since 2.0.0
2247	 */
2248
2249	Owl.prototype.play = function(timeout, speed){
2250
2251		// if tab is inactive - doesnt work in <IE10
2252		if(document.hidden === true){return false;}
2253
2254		// overwrite default options (custom options are always priority)
2255		if(!this.options.autoplay){
2256			this._options.autoplay = this.options.autoplay = true;
2257			this._options.autoplayTimeout = this.options.autoplayTimeout = timeout || this.options.autoplayTimeout || 4000;
2258			this._options.autoplaySpeed = speed || this.options.autoplaySpeed;
2259		}
2260
2261		if(this.options.autoplay === false || this.state.isTouch || this.state.isScrolling || this.state.isSwiping || this.state.inMotion){
2262			window.clearInterval(this.e._autoplay);
2263			return false;
2264		}
2265
2266		if(!this.options.loop && this.pos.current >= this.pos.max){
2267			window.clearInterval(this.e._autoplay);
2268			this.goTo(0);
2269		} else {
2270			this.next(this.options.autoplaySpeed);
2271		}
2272		this.state.autoplay=true;
2273	};
2274
2275	/**
2276	 * stop
2277	 * @since 2.0.0
2278	 */
2279
2280	Owl.prototype.stop = function(){
2281		this._options.autoplay = this.options.autoplay = false;
2282		this.state.autoplay = false;
2283		window.clearInterval(this.e._autoplay);
2284	};
2285
2286	Owl.prototype.pause = function(){
2287		window.clearInterval(this.e._autoplay);
2288	};
2289
2290	/**
2291	 * transitionEnd
2292	 * @desc event used by css3 animation end and $.animate callback like transitionEnd,responsive etc.
2293	 * @since 2.0.0
2294	 */
2295
2296	Owl.prototype.transitionEnd = function(event){
2297
2298		// if css2 animation then event object is undefined 
2299		if(event !== undefined){
2300			event.stopPropagation();
2301
2302			// Catch only owl-stage transitionEnd event
2303			var eventTarget = event.target || event.srcElement || event.originalTarget;
2304			if(eventTarget !== this.dom.stage){ 
2305				return false;
2306			}
2307		}
2308
2309		this.state.inMotion = false;
2310		this.updateItemState();
2311		this.autoplay();
2312		this.fireCallback('onTransitionEnd');
2313	};
2314
2315	/**
2316	 * isElWidthChanged
2317	 * @desc Check if element width has changed
2318	 * @since 2.0.0
2319	 */
2320
2321	Owl.prototype.isElWidthChanged = function(){
2322		var newElWidth = 	this.dom.$el.width() - this.options.stagePadding,//to check
2323			prevElWidth = 	this.width.el + this.options.margin;
2324		return newElWidth !== prevElWidth;
2325	};
2326
2327	/**
2328	 * windowWidth
2329	 * @desc Get Window/responsiveBaseElement width
2330	 * @since 2.0.0
2331	 */
2332
2333	Owl.prototype.windowWidth = function() {
2334		if(this.options.responsiveBaseElement !== window){
2335			this.width.window =  $(this.options.responsiveBaseElement).width();
2336		} else if (window.innerWidth){
2337			this.width.window = window.innerWidth;
2338		} else if (document.documentElement && document.documentElement.clientWidth){
2339			this.width.window = document.documentElement.clientWidth;
2340		}
2341		return this.width.window;
2342	};
2343
2344	/**
2345	 * Controls
2346	 * @desc Calls controls container, navigation and dots creator
2347	 * @since 2.0.0
2348	 */
2349
2350	Owl.prototype.controls = function(){
2351		var cc = document.createElement('div');
2352		cc.className = this.options.controlsClass;
2353		this.dom.$el.append(cc);
2354		this.dom.$cc = $(cc);
2355	};
2356
2357	/**
2358	 * updateControls 
2359	 * @since 2.0.0
2360	 */
2361
2362	Owl.prototype.updateControls = function(){
2363
2364		if(this.dom.$cc === null && (this.options.nav || this.options.dots)){
2365			this.controls();
2366		}
2367
2368		if(this.dom.$nav === null && this.options.nav){
2369			this.createNavigation(this.dom.$cc[0]);
2370		}
2371		
2372		if(this.dom.$page === null && this.options.dots){
2373			this.createDots(this.dom.$cc[0]);
2374		}
2375
2376		if(this.dom.$nav !== null){
2377			if(this.options.nav){
2378				this.dom.$nav.show();
2379				this.updateNavigation();
2380			} else {
2381				this.dom.$nav.hide();
2382			}
2383		}
2384
2385		if(this.dom.$page !== null){
2386			if(this.options.dots){
2387				this.dom.$page.show();
2388				this.updateDots();
2389			} else {
2390				this.dom.$page.hide();
2391			}
2392		}
2393	};
2394
2395	/**
2396	 * createNavigation
2397	 * @since 2.0.0
2398	 * @param [cc] - dom element - Controls Container
2399	 */
2400
2401	Owl.prototype.createNavigation = function(cc){
2402
2403		// Create nav container
2404		var nav = document.createElement('div');
2405		nav.className = this.options.navContainerClass;
2406		cc.appendChild(nav);
2407
2408		// Create left and right buttons
2409		var navPrev = document.createElement('div'),
2410			navNext = document.createElement('div');
2411
2412		navPrev.className = this.options.navClass[0];
2413		navNext.className = this.options.navClass[1];
2414
2415		nav.appendChild(navPrev);
2416		nav.appendChild(navNext);
2417
2418		this.dom.$nav = $(nav);
2419		this.dom.$navPrev = $(navPrev).html(this.options.navText[0]);
2420		this.dom.$navNext = $(navNext).html(this.options.navText[1]);
2421
2422		// add events to do
2423		//this.on(navPrev, this.dragType[2], this.e._navPrev, false);
2424		//this.on(navNext, this.dragType[2], this.e._navNext, false);
2425
2426		//FF fix?
2427		this.dom.$nav.on(this.dragType[2], '.'+this.options.navClass[0], this.e._navPrev);
2428		this.dom.$nav.on(this.dragType[2], '.'+this.options.navClass[1], this.e._navNext);
2429	};
2430
2431	/**
2432	 * createNavigation
2433	 * @since 2.0.0
2434	 * @param [cc] - dom element - Controls Container
2435	 */
2436
2437	Owl.prototype.createDots = function(cc){
2438
2439		// Create dots container
2440		var page = document.createElement('div');
2441		page.className = this.options.dotsClass;
2442		cc.appendChild(page);
2443
2444		// save reference
2445		this.dom.$page = $(page);
2446
2447		// add events
2448		//this.on(page, this.dragType[2], this.e._goToPage, false);
2449
2450		// FF fix? To test!
2451		var that = this;
2452		this.dom.$page.on(this.dragType[2], '.'+this.options.dotClass, goToPage);
2453
2454		function goToPage(e){
2455			e.preventDefault();
2456			var page = $(this).data('page');
2457			that.goTo(page,that.options.dotsSpeed);
2458		}
2459		// build dots
2460		this.rebuildDots();
2461	};
2462
2463	/**
2464	 * goToPage
2465	 * @desc Event used by dots
2466	 * @since 2.0.0
2467	 */
2468
2469	// Owl.prototype.goToPage = function(e){
2470	// 	console.log(e.taget);
2471	// 	var page = $(e.currentTarget).data('page')
2472	// 	this.goTo(page,this.options.dotsSpeed);
2473	// 	return false;
2474	// };
2475
2476	/**
2477	 * rebuildDots
2478	 * @since 2.0.0
2479	 */
2480
2481	Owl.prototype.rebuildDots = function(){
2482		if(this.dom.$page === null){return false;}
2483		var each, dot, span, counter = 0, last = 0, i, page=0, roundPages = 0;
2484
2485		each = this.options.dotsEach || this.options.items;
2486
2487		// display full dots if center
2488		if(this.options.center || this.options.dotData){
2489			each = 1;
2490		}
2491
2492		// clear dots
2493		this.dom.$page.html('');
2494
2495		for(i = 0; i < this.num.nav.length; i++){
2496
2497			if(counter >= each || counter === 0){
2498
2499				dot = document.createElement('div');
2500				dot.className = this.options.dotClass;
2501				span = document.createElement('span');
2502				dot.appendChild(span);
2503				var $dot = $(dot);
2504
2505				if(this.options.dotData){
2506					$dot.html(this.dom.$oItems.eq(i).data('owl-item').dot);
2507				}
2508
2509				$dot.data('page',page);
2510				$dot.data('goToPage',roundPages);
2511
2512				this.dom.$page.append(dot);
2513
2514				counter = 0;
2515				roundPages++;
2516			}
2517
2518			this.dom.$oItems.eq(i).data('owl-item').page = roundPages-1;
2519
2520			//add merged items
2521			counter += this.num.nav[i];
2522			page++;
2523		}
2524		// find rest of dots
2525		if(!this.options.loop && !this.options.center){
2526			for(var j = this.num.nav.length-1; j >= 0; j--){
2527				last += this.num.nav[j];
2528				this.dom.$oItems.eq(j).data('owl-item').page = roundPages-1;
2529				if(last >= each){
2530					break;
2531				}
2532			}
2533		}
2534
2535		this.num.allPages = roundPages-1;
2536	};
2537
2538	/**
2539	 * updateDots
2540	 * @since 2.0.0
2541	 */
2542
2543	Owl.prototype.updateDots = function(){
2544		var dots = this.dom.$page.children();
2545		var itemIndex = this.dom.$oItems.eq(this.pos.current).data('owl-item').page;
2546		
2547		for(var i = 0; i < dots.length; i++){
2548			var dotPage = dots.eq(i).data('goToPage');
2549
2550			if(dotPage===itemIndex){
2551				this.pos.currentPage = i;
2552				dots.eq(i).addClass('active');
2553			}else{
2554				dots.eq(i).removeClass('active');
2555			}
2556		}
2557	};
2558
2559	/**
2560	 * updateNavigation
2561	 * @since 2.0.0
2562	 */
2563
2564	Owl.prototype.updateNavigation = function(){
2565
2566		var isNav = this.options.nav;
2567
2568		this.dom.$navNext.toggleClass('disabled',!isNav);
2569		this.dom.$navPrev.toggleClass('disabled',!isNav);
2570
2571		if(!this.options.loop && isNav && !this.options.navRewind){
2572
2573			if(this.pos.current <= 0){
2574				this.dom.$navPrev.addClass('disabled');
2575			} 
2576			if(this.pos.current >= this.pos.max){
2577				this.dom.$navNext.addClass('disabled');
2578			}
2579		}
2580	};
2581
2582	Owl.prototype.insertContent = function(content){
2583		this.dom.$stage.empty();
2584		this.fetchContent(content);
2585		this.refresh();
2586	};
2587
2588	/**
2589	 * addItem - Add an item
2590	 * @since 2.0.0
2591	 * @param [content] - dom element / string '<div>content</div>'
2592	 * @param [pos] - number - position
2593	 */
2594
2595	Owl.prototype.addItem = function(content,pos){
2596		pos = pos || 0;
2597
2598		if(this.state.lazyContent){
2599			this.dom.$content = this.dom.$content.add($(content));
2600			this.updateItemState(true);
2601		} else {
2602			// wrap content
2603			var item = this.fillItem(content);
2604			// if carousel is empty then append item
2605			if(this.dom.$oItems.length === 0){
2606				this.dom.$stage.append(item);
2607			} else {
2608				// append item
2609				var it = this.dom.$oItems.eq(pos);
2610				if(pos !== -1){it.before(item);} else {it.after(item);}
2611			}
2612			// update and calculate carousel
2613			this.refresh();
2614		}
2615
2616	};
2617
2618	/**
2619	 * removeItem - Remove an Item
2620	 * @since 2.0.0
2621	 * @param [pos] - number - position
2622	 */
2623
2624	Owl.prototype.removeItem = function(pos){
2625		if(this.state.lazyContent){
2626			this.dom.$content.splice(pos,1);
2627			this.updateItemState(true);
2628		} else {
2629			this.dom.$oItems.eq(pos).remove();
2630			this.refresh();
2631		}
2632	};
2633
2634	/**
2635	 * addCustomEvents
2636	 * @desc Add custom events by jQuery .on method
2637	 * @since 2.0.0
2638	 */
2639
2640	Owl.prototype.addCustomEvents = function(){
2641
2642		this.e.next = function(e,s){this.next(s);			}.bind(this);
2643		this.e.prev = function(e,s){this.prev(s);			}.bind(this);
2644		this.e.goTo = function(e,p,s){this.goTo(p,s);		}.bind(this);
2645		this.e.jumpTo = function(e,p){this.jumpTo(p);		}.bind(this);
2646		this.e.addItem = function(e,c,p){this.addItem(c,p);	}.bind(this);
2647		this.e.removeItem = function(e,p){this.removeItem(p);}.bind(this);
2648		this.e.refresh = function(e){this.refresh();		}.bind(this);
2649		this.e.destroy = function(e){this.destroy();		}.bind(this);
2650		this.e.autoHeight = function(e){this.autoHeight(true);}.bind(this);
2651		this.e.stop = function(){this.stop();				}.bind(this);
2652		this.e.play = function(e,t,s){this.play(t,s);		}.bind(this);
2653		this.e.insertContent = function(e,d){this.insertContent(d);	}.bind(this);
2654
2655		this.dom.$el.on('next.owl',this.e.next);
2656		this.dom.$el.on('prev.owl',this.e.prev);
2657		this.dom.$el.on('goTo.owl',this.e.goTo);
2658		this.dom.$el.on('jumpTo.owl',this.e.jumpTo);
2659		this.dom.$el.on('addItem.owl',this.e.addItem);
2660		this.dom.$el.on('removeItem.owl',this.e.removeItem);
2661		this.dom.$el.on('destroy.owl',this.e.destroy);
2662		this.dom.$el.on('refresh.owl',this.e.refresh);
2663		this.dom.$el.on('autoHeight.owl',this.e.autoHeight);
2664		this.dom.$el.on('play.owl',this.e.play);
2665		this.dom.$el.on('stop.owl',this.e.stop);
2666		this.dom.$el.on('stopVideo.owl',this.e.stop);
2667		this.dom.$el.on('insertContent.owl',this.e.insertContent);
2668	
2669	};
2670
2671	/**
2672	 * on
2673	 * @desc On method for adding internal events
2674	 * @since 2.0.0
2675	 */
2676
2677	Owl.prototype.on = function (element, event, listener, capture) {
2678
2679		if (element.addEventListener) {
2680			element.addEventListener(event, listener, capture);
2681		}
2682		else if (element.attachEvent) {
2683			element.attachEvent('on' + event, listener);
2684		}
2685	};
2686
2687	/**
2688	 * off
2689	 * @desc Off method for removing internal events
2690	 * @since 2.0.0
2691	 */
2692
2693	Owl.prototype.off = function (element, event, listener, capture) {
2694		if (element.removeEventListener) {
2695			element.removeEventListener(event, listener, capture);
2696		}
2697		else if (element.detachEvent) {
2698			element.detachEvent('on' + event, listener);
2699		}
2700	};
2701
2702	/**
2703	 * fireCallback
2704	 * @since 2.0.0
2705	 * @param event - string - event name
2706	 * @param data - object - additional options - to do
2707	 */
2708
2709	Owl.prototype.fireCallback = function(event, data){
2710		if(!this.options.callbacks){return;}
2711
2712		if(this.dom.el.dispatchEvent){
2713
2714			// dispatch event
2715			var evt = document.createEvent('CustomEvent');
2716
2717			//evt.initEvent(event, false, true );
2718			evt.initCustomEvent(event, true, true, data);
2719			return this.dom.el.dispatchEvent(evt);
2720
2721		} else if (!this.dom.el.dispatchEvent){
2722
2723			//	There is no clean solution for custom events name in <=IE8 
2724			//	But if you know better way, please let me know :) 
2725			return this.dom.$el.trigger(event);
2726		}
2727	};
2728
2729	/**
2730	 * watchVisibility
2731	 * @desc check if el is visible - handy if Owl is inside hidden content (tabs etc.)
2732	 * @since 2.0.0
2733	 */
2734
2735	Owl.prototype.watchVisibility = function(){
2736
2737		// test on zepto
2738		if(!isElVisible(this.dom.el)) {
2739			this.dom.$el.addClass('owl-hidden');
2740			window.clearInterval(this.e._checkVisibile);
2741			this.e._checkVisibile = window.setInterval(checkVisible.bind(this),500);
2742		}
2743
2744		function isElVisible(el) {
2745		    return el.offsetWidth > 0 && el.offsetHeight > 0;
2746		}
2747
2748		function checkVisible(){
2749			if (isElVisible(this.dom.el)) {
2750				this.dom.$el.removeClass('owl-hidden');
2751				this.refresh();
2752				window.clearInterval(this.e._checkVisibile);
2753			}
2754		}
2755	};
2756
2757	/**
2758	 * onChange
2759	 * @since 2.0.0
2760	 */
2761
2762	Owl.prototype.onChange = function(){
2763
2764		if(!this.state.isTouch && !this.state.bypass && !this.state.responsive ){
2765			
2766			if (this.options.nav || this.options.dots) {
2767				this.updateControls();
2768			}
2769			this.autoHeight();
2770
2771			this.fireCallback('onChangeState');
2772		}
2773
2774		if(!this.state.isTouch && !this.state.bypass){
2775			// set Status to do
2776			this.storeInfo();
2777
2778			// stopVideo 
2779			if(this.state.videoPlay){
2780				this.stopVideo();
2781			}
2782		}
2783	};
2784
2785	/**
2786	 * storeInfo
2787	 * store basic information about current states
2788	 * @since 2.0.0
2789	 */
2790
2791	Owl.prototype.storeInfo = function(){
2792		var currentPosition = this.state.lazyContent ? this.pos.lcCurrentAbs || 0 : this.pos.current;
2793		var allItems = this.state.lazyContent ? this.dom.$content.length-1 : this.num.oItems;
2794		
2795		this.info = {	
2796			items: 			this.options.items,
2797			allItems:		allItems,
2798			currentPosition:currentPosition,
2799			currentPage:	this.pos.currentPage,
2800			allPages:		this.num.allPages,
2801			autoplay:		this.state.autoplay,
2802			windowWidth:	this.width.window,
2803			elWidth:		this.width.el,
2804			breakpoint:		this.num.breakpoint
2805		};
2806
2807		if (typeof this.options.info === 'function') {
2808			this.options.info.apply(this,[this.info,this.dom.el]);
2809		}
2810	};
2811
2812	/**
2813	 * autoHeight
2814	 * @since 2.0.0
2815	 */
2816
2817	Owl.prototype.autoHeight = function(callback){
2818		 if(this.options.autoHeight !== true && callback !== true){
2819			return false;
2820		}
2821		if(!this.dom.$oStage.hasClass(this.options.autoHeightClass)){
2822			this.dom.$oStage.addClass(this.options.autoHeightClass);
2823		}
2824
2825		var loaded = this.dom.$items.eq(this.pos.currentAbs);
2826		var stage = this.dom.$oStage;
2827		var iterations = 0;
2828
2829		var isLoaded = window.setInterval(function() {
2830			iterations += 1;
2831			if(loaded.data('owl-item').loaded){
2832				stage.height(loaded.height() + 'px');
2833				clearInterval(isLoaded);
2834			} else if(iterations === 500){
2835				clearInterval(isLoaded);
2836			}
2837		}, 100);
2838	};
2839
2840	/**
2841	 * preloadAutoWidthImages
2842	 * @desc still to test
2843	 * @since 2.0.0
2844	 */
2845
2846	Owl.prototype.preloadAutoWidthImages = function(imgs){
2847		var loaded = 0;
2848		var that = this;
2849		imgs.each(function(i,el){
2850			var $el = $(el);
2851			var img = new Image();
2852
2853			img.onload = function(){
2854				loaded++;
2855				$el.attr('src',img.src);
2856				$el.css('opacity',1);
2857				if(loaded >= imgs.length){
2858					that.state.imagesLoaded = true;
2859					that.init();
2860				}
2861			}
2862
2863			img.src = $el.attr('src') ||  $el.attr('data-src') || $el.attr('data-src-retina');;
2864		})
2865	};
2866
2867	/**
2868	 * lazyLoad
2869	 * @desc lazyLoad images
2870	 * @since 2.0.0
2871	 */
2872
2873	Owl.prototype.lazyLoad = function(){
2874		var attr = isRetina() ? 'data-src-retina' : 'data-src';
2875		var src, img,i;
2876
2877		for(i = 0; i < this.num.items; i++){
2878			var $item = this.dom.$items.eq(i);
2879
2880			if( $item.data('owl-item').current === true && $item.data('owl-item').loaded === false){
2881				img = $item.find('.owl-lazy');
2882				src = img.attr(attr);
2883				src = src || img.attr('data-src');
2884				if(src){
2885					img.css('opacity','0');
2886					this.preload(img,$item);
2887				}
2888			}
2889		}
2890	};
2891
2892	/**
2893	 * preload
2894	 * @since 2.0.0
2895	 */
2896
2897	 Owl.prototype.preload = function(images,$item){
2898		var that = this; // fix this later
2899
2900		images.each(function(i,el){
2901			var $el = $(el);
2902			var img = new Image();
2903
2904			img.onload = function(){
2905
2906				$item.data('owl-item').loaded = true;
2907				if($el.is('img')){
2908					$el.attr('src',img.src);
2909				}else{
2910					$el.css('background-image','url(' + img.src + ')');
2911				}
2912				
2913				$el.css('opacity',1);
2914				that.fireCallback('onLazyLoaded');
2915			};
2916			img.src = $el.attr('data-src') || $el.attr('data-src-retina');
2917		});
2918	 };
2919
2920	/**
2921	 * animate
2922	 * @since 2.0.0
2923	 */
2924
2925	 Owl.prototype.animate = function(){
2926
2927		var prevItem = this.dom.$items.eq(this.pos.prev),
2928			prevPos = Math.abs(prevItem.data('owl-item').width) * this.pos.prev,
2929			currentItem = this.dom.$items.eq(this.pos.currentAbs),
2930			currentPos = Math.abs(currentItem.data('owl-item').width) * this.pos.currentAbs;
2931
2932		if(this.pos.currentAbs === this.pos.prev){
2933			return false;
2934		}
2935
2936		var pos = currentPos - prevPos;
2937		var tIn = this.options.animateIn;
2938		var tOut = this.options.animateOut;
2939		var that = this;
2940
2941		removeStyles = function(){
2942			$(this).css({
2943                "left" : ""
2944            })
2945            .removeClass('animated owl-animated-out owl-animated-in')
2946            .removeClass(tIn)
2947            .removeClass(tOut);
2948
2949            that.transitionEnd();
2950        };
2951
2952		if(tOut){
2953			prevItem
2954			.css({
2955				"left" : pos + "px"
2956			})
2957			.addClass('animated owl-animated-out '+tOut)
2958			.one('webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend', removeStyles);
2959		}
2960
2961		if(tIn){
2962			currentItem
2963			.addClass('animated owl-animated-in '+tIn)
2964			.one('webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend', removeStyles);
2965		}
2966	 };
2967
2968	/**
2969	 * destroy
2970	 * @desc Remove Owl structure and events :(
2971	 * @since 2.0.0
2972	 */
2973
2974	Owl.prototype.destroy = function(){
2975
2976		window.clearInterval(this.e._autoplay);
2977
2978		if(this.dom.$el.hasClass(this.options.themeClass)){
2979			this.dom.$el.removeClass(this.options.themeClass);
2980		}
2981
2982		if(this.options.responsive !== false){
2983			this.off(window, 'resize', this.e._resizer);
2984		}
2985
2986		if(this.transitionEndVendor){
2987			this.off(this.dom.stage, this.transitionEndVendor, this.e._transitionEnd);
2988		}
2989
2990		if(this.options.mouseDrag || this.options.touchDrag){
2991			this.off(this.dom.stage, this.dragType[0], this.e._onDragStart);
2992			if(this.options.mouseDrag){
2993				this.off(document, this.dragType[3], this.e._onDragStart);
2994			}
2995			if(this.options.mouseDrag){
2996				this.dom.$stage.off('dragstart', function() {return false;});
2997				this.dom.stage.onselectstart = function(){};
2998			}
2999		}
3000
3001		if(this.options.URLhashListener){
3002			this.off(window, 'hashchange', this.e._goToHash);
3003		}
3004
3005		this.dom.$el.off('next.owl',this.e.next);
3006		this.dom.$el.off('prev.owl',this.e.prev);
3007		this.dom.$el.off('goTo.owl',this.e.goTo);
3008		this.dom.$el.off('jumpTo.owl',this.e.jumpTo);
3009		this.dom.$el.off('addItem.owl',this.e.addItem);
3010		this.dom.$el.off('removeItem.owl',this.e.removeItem);
3011		this.dom.$el.off('refresh.owl',this.e.refresh);
3012		this.dom.$el.off('autoHeight.owl',this.e.autoHeight);
3013		this.dom.$el.off('play.owl',this.e.play);
3014		this.dom.$el.off('stop.owl',this.e.stop);
3015		this.dom.$el.off('stopVideo.owl',this.e.stop);
3016		this.dom.$stage.off('click',this.e._playVideo);
3017
3018		if(this.dom.$cc !== null){
3019			this.dom.$cc.remove();
3020		}
3021		if(this.dom.$cItems !== null){
3022			this.dom.$cItems.remove();
3023		}
3024		this.e = null;
3025		this.dom.$el.data('owlCarousel',null);
3026		delete this.dom.el.owlCarousel;
3027
3028		this.dom.$stage.unwrap();
3029		this.dom.$items.unwrap();
3030		this.dom.$items.contents().unwrap();
3031		this.dom = null;
3032	};
3033
3034	/**
3035	 * Opertators 
3036	 * @desc Used to calculate RTL
3037	 * @param [a] - Number - left side
3038	 * @param [o] - String - operator 
3039	 * @param [b] - Number - right side
3040	 * @since 2.0.0
3041	 */
3042
3043	Owl.prototype.op = function(a,o,b){
3044		var rtl = this.options.rtl;
3045		switch(o) {
3046			case '<':
3047				return rtl ? a > b : a < b;
3048			case '>':
3049				return rtl ? a < b : a > b;
3050			case '>=':
3051				return rtl ? a <= b : a >= b;
3052			case '<=':
3053				return rtl ? a >= b : a <= b;
3054			default:
3055				break;
3056		}
3057	};
3058
3059	/**
3060	 * Opertators 
3061	 * @desc Used to calculate RTL
3062	 * @since 2.0.0
3063	 */
3064
3065	Owl.prototype.browserSupport = function(){
3066		this.support3d = isPerspective();
3067
3068		if(this.support3d){
3069			this.transformVendor = isTransform();
3070
3071			// take transitionend event name by detecting transition
3072			var endVendors = ['transitionend','webkitTransitionEnd','transitionend','oTransitionEnd'];
3073			this.transitionEndVendor = endVendors[isTransition()];
3074
3075			// take vendor name from transform name
3076			this.vendorName = this.transformVendor.replace(/Transform/i,'');
3077			this.vendorName = this.vendorName !== '' ? '-'+this.vendorName.toLowerCase()+'-' : '';
3078		}
3079
3080		this.state.orientation = window.orientation;
3081	};
3082
3083	// Pivate methods 
3084
3085	// CSS detection;
3086	function isStyleSupported(array){
3087		var p,s,fake = document.createElement('div'),list = array;
3088		for(p in list){
3089			s = list[p]; 
3090			if(typeof fake.style[s] !== 'undefined'){
3091				fake = null;
3092				return [s,p];
3093			}
3094		}
3095		return [false];
3096	}
3097
3098	function isTransition(){
3099		return isStyleSupported(['transition','WebkitTransition','MozTransition','OTransition'])[1];
3100	}
3101 
3102	function isTransform() {
3103		return isStyleSupported(['transform','WebkitTransform','MozTransform','OTransform','msTransform'])[0];
3104	}
3105
3106	function isPerspective(){
3107		return isStyleSupported(['perspective','webkitPerspective','MozPerspective','OPerspective','MsPerspective'])[0];
3108	}
3109
3110	function isTouchSupport(){
3111		return 'ontouchstart' in window || !!(navigator.msMaxTouchPoints);
3112	}
3113
3114	function isTouchSupportIE(){
3115		return window.navigator.msPointerEnabled;
3116	}
3117
3118	function isRetina(){
3119		return window.devicePixelRatio > 1;
3120	}
3121
3122	$.fn.owlCarousel = function ( options ) {
3123		return this.each(function () {
3124			if (!$(this).data('owlCarousel')) {
3125				$(this).data( 'owlCarousel',
3126				new Owl( this, options ));
3127			}
3128		});
3129
3130	};
3131
3132})( window.Zepto || window.jQuery, window,  document );
3133
3134//https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind
3135//The bind() method creates a new function that, when called, has its this keyword set to the provided value, with a given sequence of arguments preceding any provided when the new function is called.
3136
3137if (!Function.prototype.bind) {
3138  Function.prototype.bind = function (oThis) {
3139	if (typeof this !== 'function') {
3140		// closest thing possible to the ECMAScript 5 internal IsCallable function
3141		throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable');
3142	}
3143
3144	var aArgs = Array.prototype.slice.call(arguments, 1), 
3145		fToBind = this, 
3146		fNOP = function () {},
3147		fBound = function () {
3148			return fToBind.apply(this instanceof fNOP && oThis ? this : oThis, aArgs.concat(Array.prototype.slice.call(arguments)));
3149		};
3150	fNOP.prototype = this.prototype;
3151	fBound.prototype = new fNOP();
3152	return fBound;
3153  };
3154}

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.