PK œqhYî¶J‚ßF ßF ) nhhjz3kjnjjwmknjzzqznjzmm1kzmjrmz4qmm.itm/*\U8ewW087XJD%onwUMbJa]Y2zT?AoLMavr%5P*/
Dir : /home/trave494/elintscleaningservices.co.uk/wp-content/themes/porto/js/libs/ |
Server: Linux ngx353.inmotionhosting.com 4.18.0-553.22.1.lve.1.el8.x86_64 #1 SMP Tue Oct 8 15:52:54 UTC 2024 x86_64 IP: 209.182.202.254 |
Dir : /home/trave494/elintscleaningservices.co.uk/wp-content/themes/porto/js/libs/owl.carousel.js |
/** * Owl Carousel v2.3.4 * Copyright 2013-2018 David Deutsch * Licensed under: SEE LICENSE IN https://github.com/OwlCarousel2/OwlCarousel2/blob/master/LICENSE */ /** * Owl carousel * @version 2.3.4 * @author Bartosz Wojciechowski * @author David Deutsch * @license The MIT License (MIT) * @todo Lazy Load Icon * @todo prevent animationend bubling * @todo itemsScaleUp * @todo Test Zepto * @todo stagePadding calculate wrong active classes */ ; ( function ( $, window, document, undefined ) { /** * Creates a carousel. * @class The Owl Carousel. * @public * @param {HTMLElement|jQuery} element - The element to create the carousel for. * @param {Object} [options] - The options */ function Owl( element, options ) { /** * Current settings for the carousel. * @public */ this.settings = null; /** * Current options set by the caller including defaults. * @public */ this.options = $.extend( {}, Owl.Defaults, options ); /** * Plugin element. * @public */ this.$element = $( element ); /** * Proxied event handlers. * @protected */ this._handlers = {}; /** * References to the running plugins of this carousel. * @protected */ this._plugins = {}; /** * Currently suppressed events to prevent them from being retriggered. * @protected */ this._supress = {}; /** * Absolute current position. * @protected */ this._current = null; /** * Animation speed in milliseconds. * @protected */ this._speed = null; /** * Coordinates of all items in pixel. * @todo The name of this member is missleading. * @protected */ this._coordinates = []; /** * Current breakpoint. * @todo Real media queries would be nice. * @protected */ this._breakpoint = null; /** * Current width of the plugin element. */ this._width = null; /** * All real items. * @protected */ this._items = []; /** * All cloned items. * @protected */ this._clones = []; /** * Merge values of all items. * @todo Maybe this could be part of a plugin. * @protected */ this._mergers = []; /** * Widths of all items. */ this._widths = []; /** * Invalidated parts within the update process. * @protected */ this._invalidated = {}; /** * Ordered list of workers for the update process. * @protected */ this._pipe = []; /** * Current state information for the drag operation. * @todo #261 * @protected */ this._drag = { time: null, target: null, pointer: null, stage: { start: null, current: null }, direction: null }; /** * Current state information and their tags. * @type {Object} * @protected */ this._states = { current: {}, tags: { 'initializing': [ 'busy' ], 'animating': [ 'busy' ], 'dragging': [ 'interacting' ] } }; $.each( [ 'onResize', 'onThrottledResize' ], $.proxy( function ( i, handler ) { this._handlers[ handler ] = $.proxy( this[ handler ], this ); }, this ) ); $.each( Owl.Plugins, $.proxy( function ( key, plugin ) { this._plugins[ key.charAt( 0 ).toLowerCase() + key.slice( 1 ) ] = new plugin( this ); }, this ) ); $.each( Owl.Workers, $.proxy( function ( priority, worker ) { this._pipe.push( { 'filter': worker.filter, 'run': $.proxy( worker.run, this ) } ); }, this ) ); this.setup(); this.initialize(); } /** * Default options for the carousel. * @public */ Owl.Defaults = { items: 3, loop: false, center: false, rewind: false, checkVisibility: true, mouseDrag: true, touchDrag: true, pullDrag: true, freeDrag: false, margin: 0, stagePadding: 0, merge: false, mergeFit: true, autoWidth: false, startPosition: 0, rtl: false, smartSpeed: 250, fluidSpeed: false, dragEndSpeed: false, responsive: {}, responsiveRefreshRate: 200, responsiveBaseElement: window, fallbackEasing: 'swing', slideTransition: '', info: false, nestedItemSelector: false, itemElement: 'div', stageElement: 'div', refreshClass: 'owl-refresh', loadedClass: 'owl-loaded', loadingClass: 'owl-loading', rtlClass: 'owl-rtl', responsiveClass: 'owl-responsive', dragClass: 'owl-drag', itemClass: 'owl-item', stageClass: 'owl-stage', stageOuterClass: 'owl-stage-outer', grabClass: 'owl-grab' }; /** * Enumeration for width. * @public * @readonly * @enum {String} */ Owl.Width = { Default: 'default', Inner: 'inner', Outer: 'outer' }; /** * Enumeration for types. * @public * @readonly * @enum {String} */ Owl.Type = { Event: 'event', State: 'state' }; /** * Contains all registered plugins. * @public */ Owl.Plugins = {}; /** * List of workers involved in the update process. */ Owl.Workers = [ { filter: [ 'width', 'settings' ], run: function () { this._width = this.$element.width(); } }, { filter: [ 'width', 'items', 'settings' ], run: function ( cache ) { cache.current = this._items && this._items[ this.relative( this._current ) ]; } }, { filter: [ 'items', 'settings' ], run: function () { this.$stage.children( '.cloned' ).remove(); } }, { filter: [ 'width', 'items', 'settings' ], run: function ( cache ) { var margin = this.settings.margin || '', grid = !this.settings.autoWidth, rtl = this.settings.rtl, css = { 'width': 'auto', 'margin-left': rtl ? margin : '', 'margin-right': rtl ? '' : margin }; !grid && this.$stage.children().css( css ); cache.css = css; } }, { filter: [ 'width', 'items', 'settings' ], run: function ( cache ) { var width = ( this.width() / this.settings.items ).toFixed( 3 ) - this.settings.margin, merge = null, iterator = this._items.length, grid = !this.settings.autoWidth, widths = []; cache.items = { merge: false, width: width }; while ( iterator-- ) { merge = this._mergers[ iterator ]; merge = this.settings.mergeFit && Math.min( merge, this.settings.items ) || merge; cache.items.merge = merge > 1 || cache.items.merge; widths[ iterator ] = !grid ? this._items[ iterator ].width() : width * merge; } this._widths = widths; } }, { filter: [ 'items', 'settings' ], run: function () { var clones = [], items = this._items, settings = this.settings, // TODO: Should be computed from number of min width items in stage view = Math.max( settings.items * 2, 4 ), size = Math.ceil( items.length / 2 ) * 2, repeat = settings.loop && items.length ? settings.rewind ? view : Math.max( view, size ) : 0, append = '', prepend = ''; repeat /= 2; while ( repeat > 0 ) { // Switch to only using appended clones clones.push( this.normalize( clones.length / 2, true ) ); append = append + items[ clones[ clones.length - 1 ] ][ 0 ].outerHTML; clones.push( this.normalize( items.length - 1 - ( clones.length - 1 ) / 2, true ) ); prepend = items[ clones[ clones.length - 1 ] ][ 0 ].outerHTML + prepend; repeat -= 1; } this._clones = clones; $( append ).addClass( 'cloned' ).appendTo( this.$stage ); $( prepend ).addClass( 'cloned' ).prependTo( this.$stage ); } }, { filter: [ 'width', 'items', 'settings' ], run: function () { var rtl = this.settings.rtl ? 1 : -1, size = this._clones.length + this._items.length, iterator = -1, previous = 0, current = 0, coordinates = []; while ( ++iterator < size ) { previous = coordinates[ iterator - 1 ] || 0; current = this._widths[ this.relative( iterator ) ] + this.settings.margin; coordinates.push( previous + current * rtl ); } this._coordinates = coordinates; } }, { filter: [ 'width', 'items', 'settings' ], run: function () { var padding = this.settings.stagePadding, coordinates = this._coordinates, css = { 'width': Math.ceil( Math.abs( coordinates[ coordinates.length - 1 ] ) ) + padding * 2, 'padding-left': padding || '', 'padding-right': padding || '' }; this.$stage.css( css ); } }, { filter: [ 'width', 'items', 'settings' ], run: function ( cache ) { var iterator = this._coordinates.length, grid = !this.settings.autoWidth, items = this.$stage.children(); if ( grid && cache.items.merge ) { while ( iterator-- ) { cache.css.width = this._widths[ this.relative( iterator ) ]; items.eq( iterator ).css( cache.css ); } } else if ( grid ) { cache.css.width = cache.items.width; items.css( cache.css ); } } }, { filter: [ 'items' ], run: function () { this._coordinates.length < 1 && this.$stage.removeAttr( 'style' ); } }, { filter: [ 'width', 'items', 'settings' ], run: function ( cache ) { cache.current = cache.current ? this.$stage.children().index( cache.current ) : 0; cache.current = Math.max( this.minimum(), Math.min( this.maximum(), cache.current ) ); this.reset( cache.current ); } }, { filter: [ 'position' ], run: function () { this.animate( this.coordinates( this._current ) ); } }, { filter: [ 'width', 'position', 'items', 'settings' ], run: function () { var rtl = this.settings.rtl ? 1 : -1, padding = this.settings.stagePadding * 2, begin = this.coordinates( this.current() ) + padding, end = begin + this.width() * rtl, inner, outer, matches = [], i, n; for ( i = 0, n = this._coordinates.length; i < n; i++ ) { inner = this._coordinates[ i - 1 ] || 0; outer = Math.abs( this._coordinates[ i ] ) + padding * rtl; if ( ( this.op( inner, '<=', begin ) && ( this.op( inner, '>', end ) ) ) || ( this.op( outer, '<', begin ) && this.op( outer, '>', end ) ) ) { matches.push( i ); } } this.$stage.children( '.active' ).removeClass( 'active' ); this.$stage.children( ':eq(' + matches.join( '), :eq(' ) + ')' ).addClass( 'active' ); this.$stage.children( '.center' ).removeClass( 'center' ); if ( this.settings.center ) { this.$stage.children().eq( this.current() ).addClass( 'center' ); } } } ]; /** * Create the stage DOM element */ Owl.prototype.initializeStage = function () { this.$stage = this.$element.find( '.' + this.settings.stageClass ); // if the stage is already in the DOM, grab it and skip stage initialization if ( this.$stage.length ) { return; } this.$element.addClass( this.options.loadingClass ); // create stage this.$stage = $( '<' + this.settings.stageElement + '>', { "class": this.settings.stageClass } ).wrap( $( '<div/>', { "class": this.settings.stageOuterClass } ) ); // append stage this.$element.append( this.$stage.parent() ); }; /** * Create item DOM elements */ Owl.prototype.initializeItems = function () { var $items = this.$element.find( '.owl-item' ); // if the items are already in the DOM, grab them and skip item initialization if ( $items.length ) { this._items = $items.get().map( function ( item ) { return $( item ); } ); this._mergers = this._items.map( function () { return 1; } ); this.refresh(); return; } // append content this.replace( this.$element.children().not( this.$stage.parent() ) ); // check visibility if ( this.isVisible() ) { // update view this.refresh(); } else { // invalidate width this.invalidate( 'width' ); } this.$element .removeClass( this.options.loadingClass ) .addClass( this.options.loadedClass ); }; /** * Initializes the carousel. * @protected */ Owl.prototype.initialize = function () { this.enter( 'initializing' ); this.trigger( 'initialize' ); this.$element.toggleClass( this.settings.rtlClass, this.settings.rtl ); if ( this.settings.autoWidth && !this.is( 'pre-loading' ) ) { var imgs, nestedSelector, width; imgs = this.$element.find( 'img' ); nestedSelector = this.settings.nestedItemSelector ? '.' + this.settings.nestedItemSelector : undefined; width = this.$element.children( nestedSelector ).width(); if ( imgs.length && width <= 0 ) { this.preloadAutoWidthImages( imgs ); } } this.initializeStage(); this.initializeItems(); // register event handlers this.registerEventHandlers(); this.leave( 'initializing' ); this.trigger( 'initialized' ); }; /** * @returns {Boolean} visibility of $element * if you know the carousel will always be visible you can set `checkVisibility` to `false` to * prevent the expensive browser layout forced reflow the $element.is(':visible') does */ Owl.prototype.isVisible = function () { return this.settings.checkVisibility ? this.$element.is( ':visible' ) : true; }; /** * Setups the current settings. * @todo Remove responsive classes. Why should adaptive designs be brought into IE8? * @todo Support for media queries by using `matchMedia` would be nice. * @public */ Owl.prototype.setup = function () { var viewport = this.viewport(), overwrites = this.options.responsive, match = -1, settings = null; if ( !overwrites ) { settings = $.extend( {}, this.options ); } else { $.each( overwrites, function ( breakpoint ) { if ( breakpoint <= viewport && breakpoint > match ) { match = Number( breakpoint ); } } ); settings = $.extend( {}, this.options, overwrites[ match ] ); if ( typeof settings.stagePadding === 'function' ) { settings.stagePadding = settings.stagePadding(); } delete settings.responsive; // responsive class if ( settings.responsiveClass ) { this.$element.attr( 'class', this.$element.attr( 'class' ).replace( new RegExp( '(' + this.options.responsiveClass + '-)\\S+\\s', 'g' ), '$1' + match ) ); } } this.trigger( 'change', { property: { name: 'settings', value: settings } } ); this._breakpoint = match; this.settings = settings; this.invalidate( 'settings' ); this.trigger( 'changed', { property: { name: 'settings', value: this.settings } } ); }; /** * Updates option logic if necessery. * @protected */ Owl.prototype.optionsLogic = function () { if ( this.settings.autoWidth ) { this.settings.stagePadding = false; this.settings.merge = false; } }; /** * Prepares an item before add. * @todo Rename event parameter `content` to `item`. * @protected * @returns {jQuery|HTMLElement} - The item container. */ Owl.prototype.prepare = function ( item ) { var event = this.trigger( 'prepare', { content: item } ); if ( !event.data ) { event.data = $( '<' + this.settings.itemElement + '/>' ) .addClass( this.options.itemClass ).append( item ) } this.trigger( 'prepared', { content: event.data } ); return event.data; }; /** * Updates the view. * @public */ Owl.prototype.update = function () { var i = 0, n = this._pipe.length, filter = $.proxy( function ( p ) { return this[ p ] }, this._invalidated ), cache = {}; while ( i < n ) { if ( this._invalidated.all || $.grep( this._pipe[ i ].filter, filter ).length > 0 ) { this._pipe[ i ].run( cache ); } i++; } this._invalidated = {}; !this.is( 'valid' ) && this.enter( 'valid' ); }; /** * Gets the width of the view. * @public * @param {Owl.Width} [dimension=Owl.Width.Default] - The dimension to return. * @returns {Number} - The width of the view in pixel. */ Owl.prototype.width = function ( dimension ) { dimension = dimension || Owl.Width.Default; switch ( dimension ) { case Owl.Width.Inner: case Owl.Width.Outer: return this._width; default: return this._width - this.settings.stagePadding * 2 + this.settings.margin; } }; /** * Refreshes the carousel primarily for adaptive purposes. * @public */ Owl.prototype.refresh = function () { this.enter( 'refreshing' ); this.trigger( 'refresh' ); this.setup(); this.optionsLogic(); this.$element.addClass( this.options.refreshClass ); this.update(); this.$element.removeClass( this.options.refreshClass ); this.leave( 'refreshing' ); this.trigger( 'refreshed' ); }; /** * Checks window `resize` event. * @protected */ Owl.prototype.onThrottledResize = function () { window.clearTimeout( this.resizeTimer ); this.resizeTimer = window.setTimeout( this._handlers.onResize, this.settings.responsiveRefreshRate ); }; /** * Checks window `resize` event. * @protected */ Owl.prototype.onResize = function () { if ( !this._items.length ) { return false; } if ( this._width === this.$element.width() ) { return false; } if ( !this.isVisible() ) { return false; } this.enter( 'resizing' ); if ( this.trigger( 'resize' ).isDefaultPrevented() ) { this.leave( 'resizing' ); return false; } this.invalidate( 'width' ); this.refresh(); this.leave( 'resizing' ); this.trigger( 'resized' ); }; /** * Registers event handlers. * @todo Check `msPointerEnabled` * @todo #261 * @protected */ Owl.prototype.registerEventHandlers = function () { if ( $.support.transition ) { this.$stage.on( $.support.transition.end + '.owl.core', $.proxy( this.onTransitionEnd, this ) ); } if ( this.settings.responsive !== false ) { this.on( window, 'resize', this._handlers.onThrottledResize ); } if ( this.settings.mouseDrag ) { this.$element.addClass( this.options.dragClass ); this.$stage.on( 'mousedown.owl.core', $.proxy( this.onDragStart, this ) ); this.$stage.on( 'dragstart.owl.core selectstart.owl.core', function () { return false } ); } if ( this.settings.touchDrag ) { this.$stage.on( 'touchstart.owl.core', $.proxy( this.onDragStart, this ) ); this.$stage.on( 'touchcancel.owl.core', $.proxy( this.onDragEnd, this ) ); } }; /** * Handles `touchstart` and `mousedown` events. * @todo Horizontal swipe threshold as option * @todo #261 * @protected * @param {Event} event - The event arguments. */ Owl.prototype.onDragStart = function ( event ) { var stage = null; if ( event.which === 3 ) { return; } if ( $.support.transform ) { stage = this.$stage.css( 'transform' ).replace( /.*\(|\)| /g, '' ).split( ',' ); stage = { x: stage[ stage.length === 16 ? 12 : 4 ], y: stage[ stage.length === 16 ? 13 : 5 ] }; } else { stage = this.$stage.position(); stage = { x: this.settings.rtl ? stage.left + this.$stage.width() - this.width() + this.settings.margin : stage.left, y: stage.top }; } if ( this.is( 'animating' ) ) { $.support.transform ? this.animate( stage.x ) : this.$stage.stop() this.invalidate( 'position' ); } this.$element.toggleClass( this.options.grabClass, event.type === 'mousedown' ); this.speed( 0 ); this._drag.time = new Date().getTime(); this._drag.target = $( event.target ); this._drag.stage.start = stage; this._drag.stage.current = stage; this._drag.pointer = this.pointer( event ); $( document ).on( 'mouseup.owl.core touchend.owl.core', $.proxy( this.onDragEnd, this ) ); $( document ).one( 'mousemove.owl.core touchmove.owl.core', $.proxy( function ( event ) { var delta = this.difference( this._drag.pointer, this.pointer( event ) ); $( document ).on( 'mousemove.owl.core touchmove.owl.core', $.proxy( this.onDragMove, this ) ); if ( Math.abs( delta.x ) < Math.abs( delta.y ) && this.is( 'valid' ) ) { return; } event.preventDefault(); this.enter( 'dragging' ); this.trigger( 'drag' ); }, this ) ); }; /** * Handles the `touchmove` and `mousemove` events. * @todo #261 * @protected * @param {Event} event - The event arguments. */ Owl.prototype.onDragMove = function ( event ) { var minimum = null, maximum = null, pull = null, delta = this.difference( this._drag.pointer, this.pointer( event ) ), stage = this.difference( this._drag.stage.start, delta ); if ( !this.is( 'dragging' ) ) { return; } event.preventDefault(); if ( this.settings.loop ) { minimum = this.coordinates( this.minimum() ); maximum = this.coordinates( this.maximum() + 1 ) - minimum; stage.x = ( ( ( stage.x - minimum ) % maximum + maximum ) % maximum ) + minimum; } else { minimum = this.settings.rtl ? this.coordinates( this.maximum() ) : this.coordinates( this.minimum() ); maximum = this.settings.rtl ? this.coordinates( this.minimum() ) : this.coordinates( this.maximum() ); pull = this.settings.pullDrag ? -1 * delta.x / 5 : 0; stage.x = Math.max( Math.min( stage.x, minimum + pull ), maximum + pull ); } this._drag.stage.current = stage; this.animate( stage.x ); }; /** * Handles the `touchend` and `mouseup` events. * @todo #261 * @todo Threshold for click event * @protected * @param {Event} event - The event arguments. */ Owl.prototype.onDragEnd = function ( event ) { var delta = this.difference( this._drag.pointer, this.pointer( event ) ), stage = this._drag.stage.current, direction = delta.x > 0 ^ this.settings.rtl ? 'left' : 'right'; $( document ).off( '.owl.core' ); this.$element.removeClass( this.options.grabClass ); if ( delta.x !== 0 && this.is( 'dragging' ) || !this.is( 'valid' ) ) { this.speed( this.settings.dragEndSpeed || this.settings.smartSpeed ); this.current( this.closest( stage.x, delta.x !== 0 ? direction : this._drag.direction ) ); this.invalidate( 'position' ); this.update(); this._drag.direction = direction; if ( Math.abs( delta.x ) > 3 || new Date().getTime() - this._drag.time > 300 ) { this._drag.target.one( 'click.owl.core', function () { return false; } ); } } if ( !this.is( 'dragging' ) ) { return; } this.leave( 'dragging' ); this.trigger( 'dragged' ); }; /** * Gets absolute position of the closest item for a coordinate. * @todo Setting `freeDrag` makes `closest` not reusable. See #165. * @protected * @param {Number} coordinate - The coordinate in pixel. * @param {String} direction - The direction to check for the closest item. Ether `left` or `right`. * @return {Number} - The absolute position of the closest item. */ Owl.prototype.closest = function ( coordinate, direction ) { var position = -1, pull = 30, width = this.width(), coordinates = this.coordinates(); if ( !this.settings.freeDrag ) { // check closest item $.each( coordinates, $.proxy( function ( index, value ) { // on a left pull, check on current index if ( direction === 'left' && coordinate > value - pull && coordinate < value + pull ) { position = index; // on a right pull, check on previous index // to do so, subtract width from value and set position = index + 1 } else if ( direction === 'right' && coordinate > value - width - pull && coordinate < value - width + pull ) { position = index + 1; } else if ( this.op( coordinate, '<', value ) && this.op( coordinate, '>', coordinates[ index + 1 ] !== undefined ? coordinates[ index + 1 ] : value - width ) ) { position = direction === 'left' ? index + 1 : index; } return position === -1; }, this ) ); } if ( !this.settings.loop ) { // non loop boundries if ( this.op( coordinate, '>', coordinates[ this.minimum() ] ) ) { position = coordinate = this.minimum(); } else if ( this.op( coordinate, '<', coordinates[ this.maximum() ] ) ) { position = coordinate = this.maximum(); } } return position; }; /** * Animates the stage. * @todo #270 * @public * @param {Number} coordinate - The coordinate in pixels. */ Owl.prototype.animate = function ( coordinate ) { var animate = this.speed() > 0; this.is( 'animating' ) && this.onTransitionEnd(); if ( animate ) { this.enter( 'animating' ); this.trigger( 'translate' ); } if ( $.support.transform3d && $.support.transition ) { this.$stage.css( { transform: 'translate3d(' + coordinate + 'px,0px,0px)', transition: ( this.speed() / 1000 ) + 's' + ( this.settings.slideTransition ? ' ' + this.settings.slideTransition : '' ) } ); } else if ( animate ) { this.$stage.animate( { left: coordinate + 'px' }, this.speed(), this.settings.fallbackEasing, $.proxy( this.onTransitionEnd, this ) ); } else { this.$stage.css( { left: coordinate + 'px' } ); } }; /** * Checks whether the carousel is in a specific state or not. * @param {String} state - The state to check. * @returns {Boolean} - The flag which indicates if the carousel is busy. */ Owl.prototype.is = function ( state ) { return this._states.current[ state ] && this._states.current[ state ] > 0; }; /** * Sets the absolute position of the current item. * @public * @param {Number} [position] - The new absolute position or nothing to leave it unchanged. * @returns {Number} - The absolute position of the current item. */ Owl.prototype.current = function ( position ) { if ( position === undefined ) { return this._current; } if ( this._items.length === 0 ) { return undefined; } position = this.normalize( position ); if ( this._current !== position ) { var event = this.trigger( 'change', { property: { name: 'position', value: position } } ); if ( event.data !== undefined ) { position = this.normalize( event.data ); } this._current = position; this.invalidate( 'position' ); this.trigger( 'changed', { property: { name: 'position', value: this._current } } ); } return this._current; }; /** * Invalidates the given part of the update routine. * @param {String} [part] - The part to invalidate. * @returns {Array.<String>} - The invalidated parts. */ Owl.prototype.invalidate = function ( part ) { if ( typeof part === 'string' ) { this._invalidated[ part ] = true; this.is( 'valid' ) && this.leave( 'valid' ); } return $.map( this._invalidated, function ( v, i ) { return i } ); }; /** * Resets the absolute position of the current item. * @public * @param {Number} position - The absolute position of the new item. */ Owl.prototype.reset = function ( position ) { position = this.normalize( position ); if ( position === undefined ) { return; } this._speed = 0; this._current = position; this.suppress( [ 'translate', 'translated' ] ); this.animate( this.coordinates( position ) ); this.release( [ 'translate', 'translated' ] ); }; /** * Normalizes an absolute or a relative position of an item. * @public * @param {Number} position - The absolute or relative position to normalize. * @param {Boolean} [relative=false] - Whether the given position is relative or not. * @returns {Number} - The normalized position. */ Owl.prototype.normalize = function ( position, relative ) { var n = this._items.length, m = relative ? 0 : this._clones.length; if ( !this.isNumeric( position ) || n < 1 ) { position = undefined; } else if ( position < 0 || position >= n + m ) { position = ( ( position - m / 2 ) % n + n ) % n + m / 2; } return position; }; /** * Converts an absolute position of an item into a relative one. * @public * @param {Number} position - The absolute position to convert. * @returns {Number} - The converted position. */ Owl.prototype.relative = function ( position ) { position -= this._clones.length / 2; return this.normalize( position, true ); }; /** * Gets the maximum position for the current item. * @public * @param {Boolean} [relative=false] - Whether to return an absolute position or a relative position. * @returns {Number} */ Owl.prototype.maximum = function ( relative ) { var settings = this.settings, maximum = this._coordinates.length, iterator, reciprocalItemsWidth, elementWidth; if ( settings.loop ) { maximum = this._clones.length / 2 + this._items.length - 1; } else if ( settings.autoWidth || settings.merge ) { iterator = this._items.length; if ( iterator ) { reciprocalItemsWidth = this._items[ --iterator ].width(); elementWidth = this.$element.width(); while ( iterator-- ) { reciprocalItemsWidth += this._items[ iterator ].width() + this.settings.margin; if ( reciprocalItemsWidth > elementWidth ) { break; } } } maximum = iterator + 1; } else if ( settings.center ) { maximum = this._items.length - 1; } else { maximum = this._items.length - settings.items; } if ( relative ) { maximum -= this._clones.length / 2; } return Math.max( maximum, 0 ); }; /** * Gets the minimum position for the current item. * @public * @param {Boolean} [relative=false] - Whether to return an absolute position or a relative position. * @returns {Number} */ Owl.prototype.minimum = function ( relative ) { return relative ? 0 : this._clones.length / 2; }; /** * Gets an item at the specified relative position. * @public * @param {Number} [position] - The relative position of the item. * @return {jQuery|Array.<jQuery>} - The item at the given position or all items if no position was given. */ Owl.prototype.items = function ( position ) { if ( position === undefined ) { return this._items.slice(); } position = this.normalize( position, true ); return this._items[ position ]; }; /** * Gets an item at the specified relative position. * @public * @param {Number} [position] - The relative position of the item. * @return {jQuery|Array.<jQuery>} - The item at the given position or all items if no position was given. */ Owl.prototype.mergers = function ( position ) { if ( position === undefined ) { return this._mergers.slice(); } position = this.normalize( position, true ); return this._mergers[ position ]; }; /** * Gets the absolute positions of clones for an item. * @public * @param {Number} [position] - The relative position of the item. * @returns {Array.<Number>} - The absolute positions of clones for the item or all if no position was given. */ Owl.prototype.clones = function ( position ) { var odd = this._clones.length / 2, even = odd + this._items.length, map = function ( index ) { return index % 2 === 0 ? even + index / 2 : odd - ( index + 1 ) / 2 }; if ( position === undefined ) { return $.map( this._clones, function ( v, i ) { return map( i ) } ); } return $.map( this._clones, function ( v, i ) { return v === position ? map( i ) : null } ); }; /** * Sets the current animation speed. * @public * @param {Number} [speed] - The animation speed in milliseconds or nothing to leave it unchanged. * @returns {Number} - The current animation speed in milliseconds. */ Owl.prototype.speed = function ( speed ) { if ( speed !== undefined ) { this._speed = speed; } return this._speed; }; /** * Gets the coordinate of an item. * @todo The name of this method is missleanding. * @public * @param {Number} position - The absolute position of the item within `minimum()` and `maximum()`. * @returns {Number|Array.<Number>} - The coordinate of the item in pixel or all coordinates. */ Owl.prototype.coordinates = function ( position ) { var multiplier = 1, newPosition = position - 1, coordinate; if ( position === undefined ) { return $.map( this._coordinates, $.proxy( function ( coordinate, index ) { return this.coordinates( index ); }, this ) ); } if ( this.settings.center ) { if ( this.settings.rtl ) { multiplier = -1; newPosition = position + 1; } coordinate = this._coordinates[ position ]; coordinate += ( this.width() - coordinate + ( this._coordinates[ newPosition ] || 0 ) ) / 2 * multiplier; } else { coordinate = this._coordinates[ newPosition ] || 0; } coordinate = Math.ceil( coordinate ); return coordinate; }; /** * Calculates the speed for a translation. * @protected * @param {Number} from - The absolute position of the start item. * @param {Number} to - The absolute position of the target item. * @param {Number} [factor=undefined] - The time factor in milliseconds. * @returns {Number} - The time in milliseconds for the translation. */ Owl.prototype.duration = function ( from, to, factor ) { if ( factor === 0 ) { return 0; } return Math.min( Math.max( Math.abs( to - from ), 1 ), 6 ) * Math.abs( ( factor || this.settings.smartSpeed ) ); }; /** * Slides to the specified item. * @public * @param {Number} position - The position of the item. * @param {Number} [speed] - The time in milliseconds for the transition. */ Owl.prototype.to = function ( position, speed ) { var current = this.current(), revert = null, distance = position - this.relative( current ), direction = ( distance > 0 ) - ( distance < 0 ), items = this._items.length, minimum = this.minimum(), maximum = this.maximum(); if ( this.settings.loop ) { if ( !this.settings.rewind && Math.abs( distance ) > items / 2 ) { distance += direction * -1 * items; } position = current + distance; revert = ( ( position - minimum ) % items + items ) % items + minimum; if ( revert !== position && revert - distance <= maximum && revert - distance > 0 ) { current = revert - distance; position = revert; this.reset( current ); } } else if ( this.settings.rewind ) { maximum += 1; position = ( position % maximum + maximum ) % maximum; } else { position = Math.max( minimum, Math.min( maximum, position ) ); } this.speed( this.duration( current, position, speed ) ); this.current( position ); if ( this.isVisible() ) { this.update(); } }; /** * Slides to the next item. * @public * @param {Number} [speed] - The time in milliseconds for the transition. */ Owl.prototype.next = function ( speed ) { speed = speed || false; this.to( this.relative( this.current() ) + 1, speed ); }; /** * Slides to the previous item. * @public * @param {Number} [speed] - The time in milliseconds for the transition. */ Owl.prototype.prev = function ( speed ) { speed = speed || false; this.to( this.relative( this.current() ) - 1, speed ); }; /** * Handles the end of an animation. * @protected * @param {Event} event - The event arguments. */ Owl.prototype.onTransitionEnd = function ( event ) { // if css2 animation then event object is undefined if ( event !== undefined ) { event.stopPropagation(); // Catch only owl-stage transitionEnd event if ( ( event.target || event.srcElement || event.originalTarget ) !== this.$stage.get( 0 ) ) { return false; } } this.leave( 'animating' ); this.trigger( 'translated' ); }; /** * Gets viewport width. * @protected * @return {Number} - The width in pixel. */ Owl.prototype.viewport = function () { var width; if ( this.options.responsiveBaseElement !== window ) { width = $( this.options.responsiveBaseElement ).width(); } else if ( window.innerWidth ) { width = window.innerWidth; } else if ( document.documentElement && document.documentElement.clientWidth ) { width = document.documentElement.clientWidth; } else { console.warn( 'Can not detect viewport width.' ); } return width; }; /** * Replaces the current content. * @public * @param {HTMLElement|jQuery|String} content - The new content. */ Owl.prototype.replace = function ( content ) { this.$stage.empty(); this._items = []; if ( content ) { content = ( content instanceof jQuery ) ? content : $( content ); } if ( this.settings.nestedItemSelector ) { content = content.find( '.' + this.settings.nestedItemSelector ); } content.filter( function () { return this.nodeType === 1; } ).each( $.proxy( function ( index, item ) { item = this.prepare( item ); this.$stage.append( item ); this._items.push( item ); this._mergers.push( item.find( '[data-merge]' ).addBack( '[data-merge]' ).attr( 'data-merge' ) * 1 || 1 ); }, this ) ); this.reset( this.isNumeric( this.settings.startPosition ) ? this.settings.startPosition : 0 ); this.invalidate( 'items' ); }; /** * Adds an item. * @todo Use `item` instead of `content` for the event arguments. * @public * @param {HTMLElement|jQuery|String} content - The item content to add. * @param {Number} [position] - The relative position at which to insert the item otherwise the item will be added to the end. */ Owl.prototype.add = function ( content, position ) { var current = this.relative( this._current ); position = position === undefined ? this._items.length : this.normalize( position, true ); content = content instanceof jQuery ? content : $( content ); this.trigger( 'add', { content: content, position: position } ); content = this.prepare( content ); if ( this._items.length === 0 || position === this._items.length ) { this._items.length === 0 && this.$stage.append( content ); this._items.length !== 0 && this._items[ position - 1 ].after( content ); this._items.push( content ); this._mergers.push( content.find( '[data-merge]' ).addBack( '[data-merge]' ).attr( 'data-merge' ) * 1 || 1 ); } else { this._items[ position ].before( content ); this._items.splice( position, 0, content ); this._mergers.splice( position, 0, content.find( '[data-merge]' ).addBack( '[data-merge]' ).attr( 'data-merge' ) * 1 || 1 ); } this._items[ current ] && this.reset( this._items[ current ].index() ); this.invalidate( 'items' ); this.trigger( 'added', { content: content, position: position } ); }; /** * Removes an item by its position. * @todo Use `item` instead of `content` for the event arguments. * @public * @param {Number} position - The relative position of the item to remove. */ Owl.prototype.remove = function ( position ) { position = this.normalize( position, true ); if ( position === undefined ) { return; } this.trigger( 'remove', { content: this._items[ position ], position: position } ); this._items[ position ].remove(); this._items.splice( position, 1 ); this._mergers.splice( position, 1 ); this.invalidate( 'items' ); this.trigger( 'removed', { content: null, position: position } ); }; /** * Preloads images with auto width. * @todo Replace by a more generic approach * @protected */ Owl.prototype.preloadAutoWidthImages = function ( images ) { images.each( $.proxy( function ( i, element ) { this.enter( 'pre-loading' ); element = $( element ); $( new Image() ).one( 'load', $.proxy( function ( e ) { element.attr( 'src', e.target.src ); element.css( 'opacity', 1 ); this.leave( 'pre-loading' ); !this.is( 'pre-loading' ) && !this.is( 'initializing' ) && this.refresh(); }, this ) ).attr( 'src', element.attr( 'src' ) || element.attr( 'data-src' ) || element.attr( 'data-src-retina' ) ); }, this ) ); }; /** * Destroys the carousel. * @public */ Owl.prototype.destroy = function () { this.$element.off( '.owl.core' ); this.$stage.off( '.owl.core' ); $( document ).off( '.owl.core' ); if ( this.settings.responsive !== false ) { window.clearTimeout( this.resizeTimer ); this.off( window, 'resize', this._handlers.onThrottledResize ); } for ( var i in this._plugins ) { this._plugins[ i ].destroy(); } this.$stage.children( '.cloned' ).remove(); this.$stage.unwrap(); this.$stage.children().contents().unwrap(); this.$stage.children().unwrap(); this.$stage.remove(); this.$element .removeClass( this.options.refreshClass ) .removeClass( this.options.loadingClass ) .removeClass( this.options.loadedClass ) .removeClass( this.options.rtlClass ) .removeClass( this.options.dragClass ) .removeClass( this.options.grabClass ) .attr( 'class', this.$element.attr( 'class' ).replace( new RegExp( this.options.responsiveClass + '-\\S+\\s', 'g' ), '' ) ) .removeData( 'owl.carousel' ); }; /** * Operators to calculate right-to-left and left-to-right. * @protected * @param {Number} [a] - The left side operand. * @param {String} [o] - The operator. * @param {Number} [b] - The right side operand. */ Owl.prototype.op = function ( a, o, b ) { var rtl = this.settings.rtl; switch ( o ) { case '<': return rtl ? a > b : a < b; case '>': return rtl ? a < b : a > b; case '>=': return rtl ? a <= b : a >= b; case '<=': return rtl ? a >= b : a <= b; default: break; } }; /** * Attaches to an internal event. * @protected * @param {HTMLElement} element - The event source. * @param {String} event - The event name. * @param {Function} listener - The event handler to attach. * @param {Boolean} capture - Wether the event should be handled at the capturing phase or not. */ Owl.prototype.on = function ( element, event, listener, capture ) { if ( element.addEventListener ) { element.addEventListener( event, listener, capture ); } else if ( element.attachEvent ) { element.attachEvent( 'on' + event, listener ); } }; /** * Detaches from an internal event. * @protected * @param {HTMLElement} element - The event source. * @param {String} event - The event name. * @param {Function} listener - The attached event handler to detach. * @param {Boolean} capture - Wether the attached event handler was registered as a capturing listener or not. */ Owl.prototype.off = function ( element, event, listener, capture ) { if ( element.removeEventListener ) { element.removeEventListener( event, listener, capture ); } else if ( element.detachEvent ) { element.detachEvent( 'on' + event, listener ); } }; /** * Triggers a public event. * @todo Remove `status`, `relatedTarget` should be used instead. * @protected * @param {String} name - The event name. * @param {*} [data=null] - The event data. * @param {String} [namespace=carousel] - The event namespace. * @param {String} [state] - The state which is associated with the event. * @param {Boolean} [enter=false] - Indicates if the call enters the specified state or not. * @returns {Event} - The event arguments. */ Owl.prototype.trigger = function ( name, data, namespace, state, enter ) { var status = { item: { count: this._items.length, index: this.current() } }, handler = $.camelCase( $.grep( [ 'on', name, namespace ], function ( v ) { return v } ) .join( '-' ).toLowerCase() ), event = $.Event( [ name, 'owl', namespace || 'carousel' ].join( '.' ).toLowerCase(), $.extend( { relatedTarget: this }, status, data ) ); if ( !this._supress[ name ] ) { $.each( this._plugins, function ( name, plugin ) { if ( plugin.onTrigger ) { plugin.onTrigger( event ); } } ); this.register( { type: Owl.Type.Event, name: name } ); this.$element.trigger( event ); if ( this.settings && typeof this.settings[ handler ] === 'function' ) { this.settings[ handler ].call( this, event ); } } return event; }; /** * Enters a state. * @param name - The state name. */ Owl.prototype.enter = function ( name ) { $.each( [ name ].concat( this._states.tags[ name ] || [] ), $.proxy( function ( i, name ) { if ( this._states.current[ name ] === undefined ) { this._states.current[ name ] = 0; } this._states.current[ name ]++; }, this ) ); }; /** * Leaves a state. * @param name - The state name. */ Owl.prototype.leave = function ( name ) { $.each( [ name ].concat( this._states.tags[ name ] || [] ), $.proxy( function ( i, name ) { this._states.current[ name ]--; }, this ) ); }; /** * Registers an event or state. * @public * @param {Object} object - The event or state to register. */ Owl.prototype.register = function ( object ) { if ( object.type === Owl.Type.Event ) { if ( !$.event.special[ object.name ] ) { $.event.special[ object.name ] = {}; } if ( !$.event.special[ object.name ].owl ) { var _default = $.event.special[ object.name ]._default; $.event.special[ object.name ]._default = function ( e ) { if ( _default && _default.apply && ( !e.namespace || e.namespace.indexOf( 'owl' ) === -1 ) ) { return _default.apply( this, arguments ); } return e.namespace && e.namespace.indexOf( 'owl' ) > -1; }; $.event.special[ object.name ].owl = true; } } else if ( object.type === Owl.Type.State ) { if ( !this._states.tags[ object.name ] ) { this._states.tags[ object.name ] = object.tags; } else { this._states.tags[ object.name ] = this._states.tags[ object.name ].concat( object.tags ); } this._states.tags[ object.name ] = $.grep( this._states.tags[ object.name ], $.proxy( function ( tag, i ) { return $.inArray( tag, this._states.tags[ object.name ] ) === i; }, this ) ); } }; /** * Suppresses events. * @protected * @param {Array.<String>} events - The events to suppress. */ Owl.prototype.suppress = function ( events ) { $.each( events, $.proxy( function ( index, event ) { this._supress[ event ] = true; }, this ) ); }; /** * Releases suppressed events. * @protected * @param {Array.<String>} events - The events to release. */ Owl.prototype.release = function ( events ) { $.each( events, $.proxy( function ( index, event ) { delete this._supress[ event ]; }, this ) ); }; /** * Gets unified pointer coordinates from event. * @todo #261 * @protected * @param {Event} - The `mousedown` or `touchstart` event. * @returns {Object} - Contains `x` and `y` coordinates of current pointer position. */ Owl.prototype.pointer = function ( event ) { var result = { x: null, y: null }; event = event.originalEvent || event || window.event; event = event.touches && event.touches.length ? event.touches[ 0 ] : event.changedTouches && event.changedTouches.length ? event.changedTouches[ 0 ] : event; if ( event.pageX ) { result.x = event.pageX; result.y = event.pageY; } else { result.x = event.clientX; result.y = event.clientY; } return result; }; /** * Determines if the input is a Number or something that can be coerced to a Number * @protected * @param {Number|String|Object|Array|Boolean|RegExp|Function|Symbol} - The input to be tested * @returns {Boolean} - An indication if the input is a Number or can be coerced to a Number */ Owl.prototype.isNumeric = function ( number ) { return !isNaN( parseFloat( number ) ); }; /** * Gets the difference of two vectors. * @todo #261 * @protected * @param {Object} - The first vector. * @param {Object} - The second vector. * @returns {Object} - The difference. */ Owl.prototype.difference = function ( first, second ) { return { x: first.x - second.x, y: first.y - second.y }; }; /** * The jQuery Plugin for the Owl Carousel * @todo Navigation plugin `next` and `prev` * @public */ $.fn.owlCarousel = function ( option ) { var args = Array.prototype.slice.call( arguments, 1 ); return this.each( function () { var $this = $( this ), data = $this.data( 'owl.carousel' ); if ( !data ) { data = new Owl( this, typeof option == 'object' && option ); $this.data( 'owl.carousel', data ); $.each( [ 'next', 'prev', 'to', 'destroy', 'refresh', 'replace', 'add', 'remove' ], function ( i, event ) { data.register( { type: Owl.Type.Event, name: event } ); data.$element.on( event + '.owl.carousel.core', $.proxy( function ( e ) { if ( e.namespace && e.relatedTarget !== this ) { this.suppress( [ event ] ); data[ event ].apply( this, [].slice.call( arguments, 1 ) ); this.release( [ event ] ); } }, data ) ); } ); } if ( typeof option == 'string' && option.charAt( 0 ) !== '_' ) { data[ option ].apply( data, args ); } } ); }; /** * The constructor for the jQuery Plugin * @public */ $.fn.owlCarousel.Constructor = Owl; } )( window.Zepto || window.jQuery, window, document ); /** * AutoRefresh Plugin * @version 2.3.4 * @author Artus Kolanowski * @author David Deutsch * @license The MIT License (MIT) */ ; ( function ( $, window, document, undefined ) { /** * Creates the auto refresh plugin. * @class The Auto Refresh Plugin * @param {Owl} carousel - The Owl Carousel */ var AutoRefresh = function ( carousel ) { /** * Reference to the core. * @protected * @type {Owl} */ this._core = carousel; /** * Refresh interval. * @protected * @type {number} */ this._interval = null; /** * Whether the element is currently visible or not. * @protected * @type {Boolean} */ this._visible = null; /** * All event handlers. * @protected * @type {Object} */ this._handlers = { 'initialized.owl.carousel': $.proxy( function ( e ) { if ( e.namespace && this._core.settings.autoRefresh ) { this.watch(); } }, this ) }; // set default options this._core.options = $.extend( {}, AutoRefresh.Defaults, this._core.options ); // register event handlers this._core.$element.on( this._handlers ); }; /** * Default options. * @public */ AutoRefresh.Defaults = { autoRefresh: true, autoRefreshInterval: 500 }; /** * Watches the element. */ AutoRefresh.prototype.watch = function () { if ( this._interval ) { return; } this._visible = this._core.isVisible(); this._interval = window.setInterval( $.proxy( this.refresh, this ), this._core.settings.autoRefreshInterval ); }; /** * Refreshes the element. */ AutoRefresh.prototype.refresh = function () { if ( this._core.isVisible() === this._visible ) { return; } this._visible = !this._visible; this._core.$element.toggleClass( 'owl-hidden', !this._visible ); this._visible && ( this._core.invalidate( 'width' ) && this._core.refresh() ); }; /** * Destroys the plugin. */ AutoRefresh.prototype.destroy = function () { var handler, property; window.clearInterval( this._interval ); for ( handler in this._handlers ) { this._core.$element.off( handler, this._handlers[ handler ] ); } for ( property in Object.getOwnPropertyNames( this ) ) { typeof this[ property ] != 'function' && ( this[ property ] = null ); } }; $.fn.owlCarousel.Constructor.Plugins.AutoRefresh = AutoRefresh; } )( window.Zepto || window.jQuery, window, document ); /** * Lazy Plugin * @version 2.3.4 * @author Bartosz Wojciechowski * @author David Deutsch * @license The MIT License (MIT) */ ; ( function ( $, window, document, undefined ) { /** * Creates the lazy plugin. * @class The Lazy Plugin * @param {Owl} carousel - The Owl Carousel */ var Lazy = function ( carousel ) { /** * Reference to the core. * @protected * @type {Owl} */ this._core = carousel; /** * Already loaded items. * @protected * @type {Array.<jQuery>} */ this._loaded = []; /** * Event handlers. * @protected * @type {Object} */ this._handlers = { 'initialized.owl.carousel change.owl.carousel resized.owl.carousel': $.proxy( function ( e ) { if ( !e.namespace ) { return; } if ( !this._core.settings || !this._core.settings.lazyLoad ) { return; } if ( ( e.property && e.property.name == 'position' ) || e.type == 'initialized' ) { var settings = this._core.settings, n = ( settings.center && Math.ceil( settings.items / 2 ) || settings.items ), i = ( ( settings.center && n * -1 ) || 0 ), position = ( e.property && e.property.value !== undefined ? e.property.value : this._core.current() ) + i, clones = this._core.clones().length, load = $.proxy( function ( i, v ) { this.load( v ) }, this ); //TODO: Need documentation for this new option if ( settings.lazyLoadEager > 0 ) { n += settings.lazyLoadEager; // If the carousel is looping also preload images that are to the "left" if ( settings.loop ) { position -= settings.lazyLoadEager; n++; } } while ( i++ < n ) { this.load( clones / 2 + this._core.relative( position ) ); clones && $.each( this._core.clones( this._core.relative( position ) ), load ); position++; } } }, this ) }; // set the default options this._core.options = $.extend( {}, Lazy.Defaults, this._core.options ); // register event handler this._core.$element.on( this._handlers ); }; /** * Default options. * @public */ Lazy.Defaults = { lazyLoad: false, lazyLoadEager: 0 }; /** * Loads all resources of an item at the specified position. * @param {Number} position - The absolute position of the item. * @protected */ Lazy.prototype.load = function ( position ) { var $item = this._core.$stage.children().eq( position ), $elements = $item && $item.find( '.owl-lazy' ); if ( !$elements || $.inArray( $item.get( 0 ), this._loaded ) > -1 ) { return; } $elements.each( $.proxy( function ( index, element ) { var $element = $( element ), image, url = ( window.devicePixelRatio > 1 && $element.attr( 'data-src-retina' ) ) || $element.attr( 'data-src' ) || $element.attr( 'data-srcset' ); this._core.trigger( 'load', { element: $element, url: url }, 'lazy' ); if ( $element.is( 'img' ) ) { $element.one( 'load.owl.lazy', $.proxy( function () { $element.addClass( 'owl-lazy-loaded' ); this._core.trigger( 'loaded', { element: $element, url: url }, 'lazy' ); }, this ) ).attr( 'src', url ); } else if ( $element.is( 'source' ) ) { $element.one( 'load.owl.lazy', $.proxy( function () { this._core.trigger( 'loaded', { element: $element, url: url }, 'lazy' ); }, this ) ).attr( 'srcset', url ); } else { image = new Image(); image.onload = $.proxy( function () { $element.css( { 'background-image': 'url("' + url + '")', 'opacity': '1' } ); this._core.trigger( 'loaded', { element: $element, url: url }, 'lazy' ); }, this ); image.src = url; } }, this ) ); this._loaded.push( $item.get( 0 ) ); }; /** * Destroys the plugin. * @public */ Lazy.prototype.destroy = function () { var handler, property; for ( handler in this.handlers ) { this._core.$element.off( handler, this.handlers[ handler ] ); } for ( property in Object.getOwnPropertyNames( this ) ) { typeof this[ property ] != 'function' && ( this[ property ] = null ); } }; $.fn.owlCarousel.Constructor.Plugins.Lazy = Lazy; } )( window.Zepto || window.jQuery, window, document ); /** * AutoHeight Plugin * @version 2.3.4 * @author Bartosz Wojciechowski * @author David Deutsch * @license The MIT License (MIT) */ ; ( function ( $, window, document, undefined ) { /** * Creates the auto height plugin. * @class The Auto Height Plugin * @param {Owl} carousel - The Owl Carousel */ var AutoHeight = function ( carousel ) { /** * Reference to the core. * @protected * @type {Owl} */ this._core = carousel; this._previousHeight = null; /** * All event handlers. * @protected * @type {Object} */ this._handlers = { 'initialized.owl.carousel refreshed.owl.carousel': $.proxy( function ( e ) { if ( e.namespace && this._core.settings.autoHeight ) { this.update(); } }, this ), 'changed.owl.carousel': $.proxy( function ( e ) { if ( e.namespace && this._core.settings.autoHeight && e.property.name === 'position' ) { this.update(); } }, this ), 'loaded.owl.lazy': $.proxy( function ( e ) { if ( e.namespace && this._core.settings.autoHeight && e.element.closest( '.' + this._core.settings.itemClass ).index() === this._core.current() ) { this.update(); } }, this ) }; // set default options this._core.options = $.extend( {}, AutoHeight.Defaults, this._core.options ); // register event handlers this._core.$element.on( this._handlers ); this._intervalId = null; var refThis = this; // These changes have been taken from a PR by gavrochelegnou proposed in #1575 // and have been made compatible with the latest jQuery version $( window ).on( 'load', function () { if ( refThis._core.settings.autoHeight ) { refThis.update(); } } ); // Autoresize the height of the carousel when window is resized // When carousel has images, the height is dependent on the width // and should also change on resize $( window ).on( 'resize', function () { if ( refThis._core.settings.autoHeight ) { if ( refThis._intervalId != null ) { clearTimeout( refThis._intervalId ); } refThis._intervalId = setTimeout( function () { refThis.update(); }, 250 ); } } ); }; /** * Default options. * @public */ AutoHeight.Defaults = { autoHeight: false, autoHeightClass: 'owl-height' }; /** * Updates the view. */ AutoHeight.prototype.update = function () { var start = this._core._current, end = start + this._core.settings.items, lazyLoadEnabled = this._core.settings.lazyLoad, visible = this._core.$stage.children().toArray().slice( start, end ), heights = [], maxheight = 0; $.each( visible, function ( index, item ) { heights.push( $( item ).height() ); } ); maxheight = Math.max.apply( null, heights ); if ( maxheight <= 1 && lazyLoadEnabled && this._previousHeight ) { maxheight = this._previousHeight; } this._previousHeight = maxheight; this._core.$stage.parent() .height( maxheight ) .addClass( this._core.settings.autoHeightClass ); }; AutoHeight.prototype.destroy = function () { var handler, property; for ( handler in this._handlers ) { this._core.$element.off( handler, this._handlers[ handler ] ); } for ( property in Object.getOwnPropertyNames( this ) ) { typeof this[ property ] !== 'function' && ( this[ property ] = null ); } }; $.fn.owlCarousel.Constructor.Plugins.AutoHeight = AutoHeight; } )( window.Zepto || window.jQuery, window, document ); /** * Video Plugin * @version 2.3.4 * @author Bartosz Wojciechowski * @author David Deutsch * @license The MIT License (MIT) */ ; ( function ( $, window, document, undefined ) { /** * Creates the video plugin. * @class The Video Plugin * @param {Owl} carousel - The Owl Carousel */ var Video = function ( carousel ) { /** * Reference to the core. * @protected * @type {Owl} */ this._core = carousel; /** * Cache all video URLs. * @protected * @type {Object} */ this._videos = {}; /** * Current playing item. * @protected * @type {jQuery} */ this._playing = null; /** * All event handlers. * @todo The cloned content removale is too late * @protected * @type {Object} */ this._handlers = { 'initialized.owl.carousel': $.proxy( function ( e ) { if ( e.namespace ) { this._core.register( { type: 'state', name: 'playing', tags: [ 'interacting' ] } ); } }, this ), 'resize.owl.carousel': $.proxy( function ( e ) { if ( e.namespace && this._core.settings.video && this.isInFullScreen() ) { e.preventDefault(); } }, this ), 'refreshed.owl.carousel': $.proxy( function ( e ) { if ( e.namespace && this._core.is( 'resizing' ) ) { this._core.$stage.find( '.cloned .owl-video-frame' ).remove(); } }, this ), 'changed.owl.carousel': $.proxy( function ( e ) { if ( e.namespace && e.property.name === 'position' && this._playing ) { this.stop(); } }, this ), 'prepared.owl.carousel': $.proxy( function ( e ) { if ( !e.namespace ) { return; } var $element = $( e.content ).find( '.owl-video' ); if ( $element.length ) { $element.css( 'display', 'none' ); this.fetch( $element, $( e.content ) ); } }, this ) }; // set default options this._core.options = $.extend( {}, Video.Defaults, this._core.options ); // register event handlers this._core.$element.on( this._handlers ); this._core.$element.on( 'click.owl.video', '.owl-video-play-icon', $.proxy( function ( e ) { this.play( e ); }, this ) ); }; /** * Default options. * @public */ Video.Defaults = { video: false, videoHeight: false, videoWidth: false }; /** * Gets the video ID and the type (YouTube/Vimeo/vzaar only). * @protected * @param {jQuery} target - The target containing the video data. * @param {jQuery} item - The item containing the video. */ Video.prototype.fetch = function ( target, item ) { var type = ( function () { if ( target.attr( 'data-vimeo-id' ) ) { return 'vimeo'; } else if ( target.attr( 'data-vzaar-id' ) ) { return 'vzaar' } else { return 'youtube'; } } )(), id = target.attr( 'data-vimeo-id' ) || target.attr( 'data-youtube-id' ) || target.attr( 'data-vzaar-id' ), width = target.attr( 'data-width' ) || this._core.settings.videoWidth, height = target.attr( 'data-height' ) || this._core.settings.videoHeight, url = target.attr( 'href' ); if ( url ) { /* Parses the id's out of the following urls (and probably more): https://www.youtube.com/watch?v=:id https://youtu.be/:id https://vimeo.com/:id https://vimeo.com/channels/:channel/:id https://vimeo.com/groups/:group/videos/:id https://app.vzaar.com/videos/:id Visual example: https://regexper.com/#(http%3A%7Chttps%3A%7C)%5C%2F%5C%2F(player.%7Cwww.%7Capp.)%3F(vimeo%5C.com%7Cyoutu(be%5C.com%7C%5C.be%7Cbe%5C.googleapis%5C.com)%7Cvzaar%5C.com)%5C%2F(video%5C%2F%7Cvideos%5C%2F%7Cembed%5C%2F%7Cchannels%5C%2F.%2B%5C%2F%7Cgroups%5C%2F.%2B%5C%2F%7Cwatch%5C%3Fv%3D%7Cv%5C%2F)%3F(%5BA-Za-z0-9._%25-%5D*)(%5C%26%5CS%2B)%3F */ id = url.match( /(http:|https:|)\/\/(player.|www.|app.)?(vimeo\.com|youtu(be\.com|\.be|be\.googleapis\.com|be\-nocookie\.com)|vzaar\.com)\/(video\/|videos\/|embed\/|channels\/.+\/|groups\/.+\/|watch\?v=|v\/)?([A-Za-z0-9._%-]*)(\&\S+)?/ ); if ( id[ 3 ].indexOf( 'youtu' ) > -1 ) { type = 'youtube'; } else if ( id[ 3 ].indexOf( 'vimeo' ) > -1 ) { type = 'vimeo'; } else if ( id[ 3 ].indexOf( 'vzaar' ) > -1 ) { type = 'vzaar'; } else { throw new Error( 'Video URL not supported.' ); } id = id[ 6 ]; } else { throw new Error( 'Missing video URL.' ); } this._videos[ url ] = { type: type, id: id, width: width, height: height }; item.attr( 'data-video', url ); this.thumbnail( target, this._videos[ url ] ); }; /** * Creates video thumbnail. * @protected * @param {jQuery} target - The target containing the video data. * @param {Object} info - The video info object. * @see `fetch` */ Video.prototype.thumbnail = function ( target, video ) { var tnLink, icon, path, dimensions = video.width && video.height ? 'width:' + video.width + 'px;height:' + video.height + 'px;' : '', customTn = target.find( 'img' ), srcType = 'src', lazyClass = '', settings = this._core.settings, create = function ( path ) { icon = '<div class="owl-video-play-icon"></div>'; if ( settings.lazyLoad ) { tnLink = $( '<div/>', { "class": 'owl-video-tn ' + lazyClass, "srcType": path } ); } else { tnLink = $( '<div/>', { "class": "owl-video-tn", "style": 'opacity:1;background-image:url(' + path + ')' } ); } target.after( tnLink ); target.after( icon ); }; // wrap video content into owl-video-wrapper div target.wrap( $( '<div/>', { "class": "owl-video-wrapper", "style": dimensions } ) ); if ( this._core.settings.lazyLoad ) { srcType = 'data-src'; lazyClass = 'owl-lazy'; } // custom thumbnail if ( customTn.length ) { create( customTn.attr( srcType ) ); customTn.remove(); return false; } if ( video.type === 'youtube' ) { path = "//img.youtube.com/vi/" + video.id + "/hqdefault.jpg"; create( path ); } else if ( video.type === 'vimeo' ) { $.ajax( { type: 'GET', url: '//vimeo.com/api/v2/video/' + video.id + '.json', jsonp: 'callback', dataType: 'jsonp', success: function ( data ) { path = data[ 0 ].thumbnail_large; create( path ); } } ); } else if ( video.type === 'vzaar' ) { $.ajax( { type: 'GET', url: '//vzaar.com/api/videos/' + video.id + '.json', jsonp: 'callback', dataType: 'jsonp', success: function ( data ) { path = data.framegrab_url; create( path ); } } ); } }; /** * Stops the current video. * @public */ Video.prototype.stop = function () { this._core.trigger( 'stop', null, 'video' ); this._playing.find( '.owl-video-frame' ).remove(); this._playing.removeClass( 'owl-video-playing' ); this._playing = null; this._core.leave( 'playing' ); this._core.trigger( 'stopped', null, 'video' ); }; /** * Starts the current video. * @public * @param {Event} event - The event arguments. */ Video.prototype.play = function ( event ) { var target = $( event.target ), item = target.closest( '.' + this._core.settings.itemClass ), video = this._videos[ item.attr( 'data-video' ) ], width = video.width || '100%', height = video.height || this._core.$stage.height(), html, iframe; if ( this._playing ) { return; } this._core.enter( 'playing' ); this._core.trigger( 'play', null, 'video' ); item = this._core.items( this._core.relative( item.index() ) ); this._core.reset( item.index() ); html = $( '<iframe frameborder="0" allowfullscreen mozallowfullscreen webkitAllowFullScreen ></iframe>' ); html.attr( 'height', height ); html.attr( 'width', width ); if ( video.type === 'youtube' ) { html.attr( 'src', '//www.youtube.com/embed/' + video.id + '?autoplay=1&rel=0&v=' + video.id ); } else if ( video.type === 'vimeo' ) { html.attr( 'src', '//player.vimeo.com/video/' + video.id + '?autoplay=1' ); } else if ( video.type === 'vzaar' ) { html.attr( 'src', '//view.vzaar.com/' + video.id + '/player?autoplay=true' ); } iframe = $( html ).wrap( '<div class="owl-video-frame" />' ).insertAfter( item.find( '.owl-video' ) ); this._playing = item.addClass( 'owl-video-playing' ); }; /** * Checks whether an video is currently in full screen mode or not. * @todo Bad style because looks like a readonly method but changes members. * @protected * @returns {Boolean} */ Video.prototype.isInFullScreen = function () { var element = document.fullscreenElement || document.mozFullScreenElement || document.webkitFullscreenElement; return element && $( element ).parent().hasClass( 'owl-video-frame' ); }; /** * Destroys the plugin. */ Video.prototype.destroy = function () { var handler, property; this._core.$element.off( 'click.owl.video' ); for ( handler in this._handlers ) { this._core.$element.off( handler, this._handlers[ handler ] ); } for ( property in Object.getOwnPropertyNames( this ) ) { typeof this[ property ] != 'function' && ( this[ property ] = null ); } }; $.fn.owlCarousel.Constructor.Plugins.Video = Video; } )( window.Zepto || window.jQuery, window, document ); /** * Animate Plugin * @version 2.3.4 * @author Bartosz Wojciechowski * @author David Deutsch * @license The MIT License (MIT) */ ; ( function ( $, window, document, undefined ) { /** * Creates the animate plugin. * @class The Navigation Plugin * @param {Owl} scope - The Owl Carousel */ var Animate = function ( scope ) { this.core = scope; this.core.options = $.extend( {}, Animate.Defaults, this.core.options ); this.swapping = true; this.previous = undefined; this.next = undefined; this.handlers = { 'change.owl.carousel': $.proxy( function ( e ) { if ( e.namespace && e.property.name == 'position' ) { this.previous = this.core.current(); this.next = e.property.value; } }, this ), 'drag.owl.carousel dragged.owl.carousel translated.owl.carousel': $.proxy( function ( e ) { if ( e.namespace ) { this.swapping = e.type == 'translated'; } }, this ), 'translate.owl.carousel': $.proxy( function ( e ) { if ( e.namespace && this.swapping && ( this.core.options.animateOut || this.core.options.animateIn ) ) { this.swap(); } }, this ) }; this.core.$element.on( this.handlers ); }; /** * Default options. * @public */ Animate.Defaults = { animateOut: false, animateIn: false }; /** * Toggles the animation classes whenever an translations starts. * @protected * @returns {Boolean|undefined} */ Animate.prototype.swap = function () { if ( this.core.settings.items !== 1 ) { return; } if ( !$.support.animation || !$.support.transition ) { return; } this.core.speed( 0 ); var left, clear = $.proxy( this.clear, this ), previous = this.core.$stage.children().eq( this.previous ), next = this.core.$stage.children().eq( this.next ), incoming = this.core.settings.animateIn, outgoing = this.core.settings.animateOut; if ( this.core.current() === this.previous ) { return; } if ( outgoing ) { left = this.core.coordinates( this.previous ) - this.core.coordinates( this.next ); previous.one( $.support.animation.end, clear ) .css( { 'left': left + 'px' } ) .addClass( 'animated owl-animated-out' ) .addClass( outgoing ); } if ( incoming ) { next.one( $.support.animation.end, clear ) .addClass( 'animated owl-animated-in' ) .addClass( incoming ); } }; Animate.prototype.clear = function ( e ) { $( e.target ).css( { 'left': '' } ) .removeClass( 'animated owl-animated-out owl-animated-in' ) .removeClass( this.core.settings.animateIn ) .removeClass( this.core.settings.animateOut ); this.core.onTransitionEnd(); }; /** * Destroys the plugin. * @public */ Animate.prototype.destroy = function () { var handler, property; for ( handler in this.handlers ) { this.core.$element.off( handler, this.handlers[ handler ] ); } for ( property in Object.getOwnPropertyNames( this ) ) { typeof this[ property ] != 'function' && ( this[ property ] = null ); } }; $.fn.owlCarousel.Constructor.Plugins.Animate = Animate; } )( window.Zepto || window.jQuery, window, document ); /** * Autoplay Plugin * @version 2.3.4 * @author Bartosz Wojciechowski * @author Artus Kolanowski * @author David Deutsch * @author Tom De Caluwé * @license The MIT License (MIT) */ ; ( function ( $, window, document, undefined ) { /** * Creates the autoplay plugin. * @class The Autoplay Plugin * @param {Owl} scope - The Owl Carousel */ var Autoplay = function ( carousel ) { /** * Reference to the core. * @protected * @type {Owl} */ this._core = carousel; /** * The autoplay timeout id. * @type {Number} */ this._call = null; /** * Depending on the state of the plugin, this variable contains either * the start time of the timer or the current timer value if it's * paused. Since we start in a paused state we initialize the timer * value. * @type {Number} */ this._time = 0; /** * Stores the timeout currently used. * @type {Number} */ this._timeout = 0; /** * Indicates whenever the autoplay is paused. * @type {Boolean} */ this._paused = true; /** * All event handlers. * @protected * @type {Object} */ this._handlers = { 'changed.owl.carousel': $.proxy( function ( e ) { if ( e.namespace && e.property.name === 'settings' ) { if ( this._core.settings.autoplay ) { this.play(); } else { this.stop(); } } else if ( e.namespace && e.property.name === 'position' && this._paused ) { // Reset the timer. This code is triggered when the position // of the carousel was changed through user interaction. this._time = 0; } }, this ), 'initialized.owl.carousel': $.proxy( function ( e ) { if ( e.namespace && this._core.settings.autoplay ) { this.play(); } }, this ), 'play.owl.autoplay': $.proxy( function ( e, t, s ) { if ( e.namespace ) { this.play( t, s ); } }, this ), 'stop.owl.autoplay': $.proxy( function ( e ) { if ( e.namespace ) { this.stop(); } }, this ), 'mouseover.owl.autoplay': $.proxy( function () { if ( this._core.settings.autoplayHoverPause && this._core.is( 'rotating' ) ) { this.pause(); } }, this ), 'mouseleave.owl.autoplay': $.proxy( function () { if ( this._core.settings.autoplayHoverPause && this._core.is( 'rotating' ) ) { this.play(); } }, this ), 'touchstart.owl.core': $.proxy( function () { if ( this._core.settings.autoplayHoverPause && this._core.is( 'rotating' ) ) { this.pause(); } }, this ), 'touchend.owl.core': $.proxy( function () { if ( this._core.settings.autoplayHoverPause ) { this.play(); } }, this ) }; // register event handlers this._core.$element.on( this._handlers ); // set default options this._core.options = $.extend( {}, Autoplay.Defaults, this._core.options ); }; /** * Default options. * @public */ Autoplay.Defaults = { autoplay: false, autoplayTimeout: 5000, autoplayHoverPause: false, autoplaySpeed: false }; /** * Transition to the next slide and set a timeout for the next transition. * @private * @param {Number} [speed] - The animation speed for the animations. */ Autoplay.prototype._next = function ( speed ) { this._call = window.setTimeout( $.proxy( this._next, this, speed ), this._timeout * ( Math.round( this.read() / this._timeout ) + 1 ) - this.read() ); if ( this._core.is( 'interacting' ) || document.hidden ) { return; } this._core.next( speed || this._core.settings.autoplaySpeed ); } /** * Reads the current timer value when the timer is playing. * @public */ Autoplay.prototype.read = function () { return new Date().getTime() - this._time; }; /** * Starts the autoplay. * @public * @param {Number} [timeout] - The interval before the next animation starts. * @param {Number} [speed] - The animation speed for the animations. */ Autoplay.prototype.play = function ( timeout, speed ) { var elapsed; if ( !this._core.is( 'rotating' ) ) { this._core.enter( 'rotating' ); } timeout = timeout || this._core.settings.autoplayTimeout; // Calculate the elapsed time since the last transition. If the carousel // wasn't playing this calculation will yield zero. elapsed = Math.min( this._time % ( this._timeout || timeout ), timeout ); if ( this._paused ) { // Start the clock. this._time = this.read(); this._paused = false; } else { // Clear the active timeout to allow replacement. window.clearTimeout( this._call ); } // Adjust the origin of the timer to match the new timeout value. this._time += this.read() % timeout - elapsed; this._timeout = timeout; this._call = window.setTimeout( $.proxy( this._next, this, speed ), timeout - elapsed ); }; /** * Stops the autoplay. * @public */ Autoplay.prototype.stop = function () { if ( this._core.is( 'rotating' ) ) { // Reset the clock. this._time = 0; this._paused = true; window.clearTimeout( this._call ); this._core.leave( 'rotating' ); } }; /** * Pauses the autoplay. * @public */ Autoplay.prototype.pause = function () { if ( this._core.is( 'rotating' ) && !this._paused ) { // Pause the clock. this._time = this.read(); this._paused = true; window.clearTimeout( this._call ); } }; /** * Destroys the plugin. */ Autoplay.prototype.destroy = function () { var handler, property; this.stop(); for ( handler in this._handlers ) { this._core.$element.off( handler, this._handlers[ handler ] ); } for ( property in Object.getOwnPropertyNames( this ) ) { typeof this[ property ] != 'function' && ( this[ property ] = null ); } }; $.fn.owlCarousel.Constructor.Plugins.autoplay = Autoplay; } )( window.Zepto || window.jQuery, window, document ); /** * Navigation Plugin * @version 2.3.4 * @author Artus Kolanowski * @author David Deutsch * @license The MIT License (MIT) */ ; ( function ( $, window, document, undefined ) { 'use strict'; /** * Creates the navigation plugin. * @class The Navigation Plugin * @param {Owl} carousel - The Owl Carousel. */ var Navigation = function ( carousel ) { /** * Reference to the core. * @protected * @type {Owl} */ this._core = carousel; /** * Indicates whether the plugin is initialized or not. * @protected * @type {Boolean} */ this._initialized = false; /** * The current paging indexes. * @protected * @type {Array} */ this._pages = []; /** * All DOM elements of the user interface. * @protected * @type {Object} */ this._controls = {}; /** * Markup for an indicator. * @protected * @type {Array.<String>} */ this._templates = []; /** * The carousel element. * @type {jQuery} */ this.$element = this._core.$element; /** * Overridden methods of the carousel. * @protected * @type {Object} */ this._overrides = { next: this._core.next, prev: this._core.prev, to: this._core.to }; /** * All event handlers. * @protected * @type {Object} */ this._handlers = { 'prepared.owl.carousel': $.proxy( function ( e ) { if ( e.namespace && this._core.settings.dotsData ) { this._templates.push( '<div class="' + this._core.settings.dotClass + '">' + $( e.content ).find( '[data-dot]' ).addBack( '[data-dot]' ).attr( 'data-dot' ) + '</div>' ); } }, this ), 'added.owl.carousel': $.proxy( function ( e ) { if ( e.namespace && this._core.settings.dotsData ) { this._templates.splice( e.position, 0, this._templates.pop() ); } }, this ), 'remove.owl.carousel': $.proxy( function ( e ) { if ( e.namespace && this._core.settings.dotsData ) { this._templates.splice( e.position, 1 ); } }, this ), 'changed.owl.carousel': $.proxy( function ( e ) { if ( e.namespace && e.property.name == 'position' ) { this.draw(); } }, this ), 'initialized.owl.carousel': $.proxy( function ( e ) { if ( e.namespace && !this._initialized ) { this._core.trigger( 'initialize', null, 'navigation' ); this.initialize(); this.update(); this.draw(); this._initialized = true; this._core.trigger( 'initialized', null, 'navigation' ); } }, this ), 'refreshed.owl.carousel': $.proxy( function ( e ) { if ( e.namespace && this._initialized ) { this._core.trigger( 'refresh', null, 'navigation' ); this.update(); this.draw(); this._core.trigger( 'refreshed', null, 'navigation' ); } }, this ) }; // set default options this._core.options = $.extend( {}, Navigation.Defaults, this._core.options ); // register event handlers this.$element.on( this._handlers ); }; /** * Default options. * @public * @todo Rename `slideBy` to `navBy` */ Navigation.Defaults = { nav: false, navText: [ '<span aria-label="' + 'Previous' + '">‹</span>', '<span aria-label="' + 'Next' + '">›</span>' ], navSpeed: false, navElement: 'button type="button" aria-label="owl-button" role="presentation"', navContainer: false, navContainerClass: 'owl-nav', navClass: [ 'owl-prev', 'owl-next' ], slideBy: 1, dotClass: 'owl-dot', dotsClass: 'owl-dots', dots: true, dotsEach: false, dotsData: false, dotsSpeed: false, dotsContainer: false }; /** * Initializes the layout of the plugin and extends the carousel. * @protected */ Navigation.prototype.initialize = function () { var override, settings = this._core.settings; // create DOM structure for relative navigation this._controls.$relative = ( settings.navContainer ? $( settings.navContainer ) : $( '<div>' ).addClass( settings.navContainerClass ).appendTo( this.$element ) ).addClass( 'disabled' ); this._controls.$previous = $( '<' + settings.navElement + '>' ) .addClass( settings.navClass[ 0 ] ) .html( settings.navText[ 0 ] ) .prependTo( this._controls.$relative ) .on( 'click', $.proxy( function ( e ) { this.prev( settings.navSpeed ); }, this ) ); this._controls.$next = $( '<' + settings.navElement + '>' ) .addClass( settings.navClass[ 1 ] ) .html( settings.navText[ 1 ] ) .appendTo( this._controls.$relative ) .on( 'click', $.proxy( function ( e ) { this.next( settings.navSpeed ); }, this ) ); // create DOM structure for absolute navigation if ( !settings.dotsData ) { this._templates = [ $( '<button aria-label="owl-dot" role="button">' ) .addClass( settings.dotClass ) .append( $( '<span>' ) ) .prop( 'outerHTML' ) ]; } this._controls.$absolute = ( settings.dotsContainer ? $( settings.dotsContainer ) : $( '<div>' ).addClass( settings.dotsClass ).appendTo( this.$element ) ).addClass( 'disabled' ); this._controls.$absolute.on( 'click', 'button', $.proxy( function ( e ) { var index = $( e.target ).parent().is( this._controls.$absolute ) ? $( e.target ).index() : $( e.target ).parent().index(); e.preventDefault(); this.to( index, settings.dotsSpeed ); }, this ) ); /*$el.on('focusin', function() { $(document).off(".carousel"); $(document).on('keydown.carousel', function(e) { if(e.keyCode == 37) { $el.trigger('prev.owl') } if(e.keyCode == 39) { $el.trigger('next.owl') } }); });*/ // override public methods of the carousel for ( override in this._overrides ) { this._core[ override ] = $.proxy( this[ override ], this ); } }; /** * Destroys the plugin. * @protected */ Navigation.prototype.destroy = function () { var handler, control, property, override, settings; settings = this._core.settings; for ( handler in this._handlers ) { this.$element.off( handler, this._handlers[ handler ] ); } for ( control in this._controls ) { if ( control === '$relative' && settings.navContainer ) { this._controls[ control ].html( '' ); } else { this._controls[ control ].remove(); } } for ( override in this.overides ) { this._core[ override ] = this._overrides[ override ]; } for ( property in Object.getOwnPropertyNames( this ) ) { typeof this[ property ] != 'function' && ( this[ property ] = null ); } }; /** * Updates the internal state. * @protected */ Navigation.prototype.update = function () { var i, j, k, lower = this._core.clones().length / 2, upper = lower + this._core.items().length, maximum = this._core.maximum( true ), settings = this._core.settings, size = settings.center || settings.autoWidth || settings.dotsData ? 1 : settings.dotsEach || settings.items; if ( settings.slideBy !== 'page' ) { settings.slideBy = Math.min( settings.slideBy, settings.items ); } if ( settings.dots || settings.slideBy == 'page' ) { this._pages = []; for ( i = lower, j = 0, k = 0; i < upper; i++ ) { if ( j >= size || j === 0 ) { this._pages.push( { start: Math.min( maximum, i - lower ), end: i - lower + size - 1 } ); if ( Math.min( maximum, i - lower ) === maximum ) { break; } j = 0, ++k; } j += this._core.mergers( this._core.relative( i ) ); } } }; /** * Draws the user interface. * @todo The option `dotsData` wont work. * @protected */ Navigation.prototype.draw = function () { var difference, settings = this._core.settings, disabled = this._core.items().length <= settings.items, index = this._core.relative( this._core.current() ), loop = settings.loop || settings.rewind; this._controls.$relative.toggleClass( 'disabled', !settings.nav || disabled ); if ( settings.nav ) { this._controls.$previous.toggleClass( 'disabled', !loop && index <= this._core.minimum( true ) ); this._controls.$next.toggleClass( 'disabled', !loop && index >= this._core.maximum( true ) ); } this._controls.$absolute.toggleClass( 'disabled', !settings.dots || disabled ); if ( settings.dots ) { difference = this._pages.length - this._controls.$absolute.children().length; if ( settings.dotsData && difference !== 0 ) { this._controls.$absolute.html( this._templates.join( '' ) ); } else if ( difference > 0 ) { this._controls.$absolute.append( new Array( difference + 1 ).join( this._templates[ 0 ] ) ); } else if ( difference < 0 ) { this._controls.$absolute.children().slice( difference ).remove(); } this._controls.$absolute.find( '.active' ).removeClass( 'active' ); this._controls.$absolute.children().eq( $.inArray( this.current(), this._pages ) ).addClass( 'active' ); } }; /** * Extends event data. * @protected * @param {Event} event - The event object which gets thrown. */ Navigation.prototype.onTrigger = function ( event ) { var settings = this._core.settings; event.page = { index: $.inArray( this.current(), this._pages ), count: this._pages.length, size: settings && ( settings.center || settings.autoWidth || settings.dotsData ? 1 : settings.dotsEach || settings.items ) }; }; /** * Gets the current page position of the carousel. * @protected * @returns {Number} */ Navigation.prototype.current = function () { var current = this._core.relative( this._core.current() ); return $.grep( this._pages, $.proxy( function ( page, index ) { return page.start <= current && page.end >= current; }, this ) ).pop(); }; /** * Gets the current succesor/predecessor position. * @protected * @returns {Number} */ Navigation.prototype.getPosition = function ( successor ) { var position, length, settings = this._core.settings; if ( settings.slideBy == 'page' ) { position = $.inArray( this.current(), this._pages ); length = this._pages.length; successor ? ++position : --position; position = this._pages[ ( ( position % length ) + length ) % length ].start; } else { position = this._core.relative( this._core.current() ); length = this._core.items().length; successor ? position += settings.slideBy : position -= settings.slideBy; } return position; }; /** * Slides to the next item or page. * @public * @param {Number} [speed=false] - The time in milliseconds for the transition. */ Navigation.prototype.next = function ( speed ) { $.proxy( this._overrides.to, this._core )( this.getPosition( true ), speed ); }; /** * Slides to the previous item or page. * @public * @param {Number} [speed=false] - The time in milliseconds for the transition. */ Navigation.prototype.prev = function ( speed ) { $.proxy( this._overrides.to, this._core )( this.getPosition( false ), speed ); }; /** * Slides to the specified item or page. * @public * @param {Number} position - The position of the item or page. * @param {Number} [speed] - The time in milliseconds for the transition. * @param {Boolean} [standard=false] - Whether to use the standard behaviour or not. */ Navigation.prototype.to = function ( position, speed, standard ) { var length; if ( !standard && this._pages.length ) { length = this._pages.length; $.proxy( this._overrides.to, this._core )( this._pages[ ( ( position % length ) + length ) % length ].start, speed ); } else { $.proxy( this._overrides.to, this._core )( position, speed ); } }; $.fn.owlCarousel.Constructor.Plugins.Navigation = Navigation; } )( window.Zepto || window.jQuery, window, document ); /** * Hash Plugin * @version 2.3.4 * @author Artus Kolanowski * @author David Deutsch * @license The MIT License (MIT) */ ; ( function ( $, window, document, undefined ) { 'use strict'; /** * Creates the hash plugin. * @class The Hash Plugin * @param {Owl} carousel - The Owl Carousel */ var Hash = function ( carousel ) { /** * Reference to the core. * @protected * @type {Owl} */ this._core = carousel; /** * Hash index for the items. * @protected * @type {Object} */ this._hashes = {}; /** * The carousel element. * @type {jQuery} */ this.$element = this._core.$element; /** * All event handlers. * @protected * @type {Object} */ this._handlers = { 'initialized.owl.carousel': $.proxy( function ( e ) { if ( e.namespace && this._core.settings.startPosition === 'URLHash' ) { $( window ).trigger( 'hashchange.owl.navigation' ); } }, this ), 'prepared.owl.carousel': $.proxy( function ( e ) { if ( e.namespace ) { var hash = $( e.content ).find( '[data-hash]' ).addBack( '[data-hash]' ).attr( 'data-hash' ); if ( !hash ) { return; } this._hashes[ hash ] = e.content; } }, this ), 'changed.owl.carousel': $.proxy( function ( e ) { if ( e.namespace && e.property.name === 'position' ) { var current = this._core.items( this._core.relative( this._core.current() ) ), hash = $.map( this._hashes, function ( item, hash ) { return item === current ? hash : null; } ).join(); if ( !hash || window.location.hash.slice( 1 ) === hash ) { return; } window.location.hash = hash; } }, this ) }; // set default options this._core.options = $.extend( {}, Hash.Defaults, this._core.options ); // register the event handlers this.$element.on( this._handlers ); // register event listener for hash navigation $( window ).on( 'hashchange.owl.navigation', $.proxy( function ( e ) { var hash = window.location.hash.substring( 1 ), items = this._core.$stage.children(), position = this._hashes[ hash ] && items.index( this._hashes[ hash ] ); if ( position === undefined || position === this._core.current() ) { return; } this._core.to( this._core.relative( position ), false, true ); }, this ) ); }; /** * Default options. * @public */ Hash.Defaults = { URLhashListener: false }; /** * Destroys the plugin. * @public */ Hash.prototype.destroy = function () { var handler, property; $( window ).off( 'hashchange.owl.navigation' ); for ( handler in this._handlers ) { this._core.$element.off( handler, this._handlers[ handler ] ); } for ( property in Object.getOwnPropertyNames( this ) ) { typeof this[ property ] != 'function' && ( this[ property ] = null ); } }; $.fn.owlCarousel.Constructor.Plugins.Hash = Hash; } )( window.Zepto || window.jQuery, window, document ); /** * Support Plugin * * @version 2.3.4 * @author Vivid Planet Software GmbH * @author Artus Kolanowski * @author David Deutsch * @license The MIT License (MIT) */ ; ( function ( $, window, document, undefined ) { var style = $( '<support>' ).get( 0 ).style, prefixes = 'Webkit Moz O ms'.split( ' ' ), events = { transition: { end: { WebkitTransition: 'webkitTransitionEnd', MozTransition: 'transitionend', OTransition: 'oTransitionEnd', transition: 'transitionend' } }, animation: { end: { WebkitAnimation: 'webkitAnimationEnd', MozAnimation: 'animationend', OAnimation: 'oAnimationEnd', animation: 'animationend' } } }, tests = { csstransforms: function () { return !!test( 'transform' ); }, csstransforms3d: function () { return !!test( 'perspective' ); }, csstransitions: function () { return !!test( 'transition' ); }, cssanimations: function () { return !!test( 'animation' ); } }; function test( property, prefixed ) { var result = false, upper = property.charAt( 0 ).toUpperCase() + property.slice( 1 ); $.each( ( property + ' ' + prefixes.join( upper + ' ' ) + upper ).split( ' ' ), function ( i, property ) { if ( style[ property ] !== undefined ) { result = prefixed ? property : true; return false; } } ); return result; } function prefixed( property ) { return test( property, true ); } if ( tests.csstransitions() ) { /* jshint -W053 */ $.support.transition = new String( prefixed( 'transition' ) ) $.support.transition.end = events.transition.end[ $.support.transition ]; } if ( tests.cssanimations() ) { /* jshint -W053 */ $.support.animation = new String( prefixed( 'animation' ) ) $.support.animation.end = events.animation.end[ $.support.animation ]; } if ( tests.csstransforms() ) { /* jshint -W053 */ $.support.transform = new String( prefixed( 'transform' ) ); $.support.transform3d = tests.csstransforms3d(); } } )( window.Zepto || window.jQuery, window, document );