/*
* jQuery Superfish Menu Plugin - v1.7.10
* Copyright (c) 2018 Joel Birch
*
* Dual licensed under the MIT and GPL licenses:
* http://www.opensource.org/licenses/mit-license.php
* http://www.gnu.org/licenses/gpl.html
*/
;(function ($, w) {
"use strict";
var methods = (function () {
// private properties and methods go here
var c = {
bcClass: 'sf-breadcrumb',
menuClass: 'sf-js-enabled',
anchorClass: 'sf-with-ul',
menuArrowClass: 'sf-arrows'
},
ios = (function () {
var ios = /^(?![\w\W]*Windows Phone)[\w\W]*(iPhone|iPad|iPod)/i.test(navigator.userAgent);
if (ios) {
// tap anywhere on iOS to unfocus a submenu
$('html').css('cursor', 'pointer').on('click', $.noop);
}
return ios;
})(),
wp7 = (function () {
var style = document.documentElement.style;
return ('behavior' in style && 'fill' in style && /iemobile/i.test(navigator.userAgent));
})(),
unprefixedPointerEvents = (function () {
return (!!w.PointerEvent);
})(),
toggleMenuClasses = function ($menu, o, add) {
var classes = c.menuClass,
method;
if (o.cssArrows) {
classes += ' ' + c.menuArrowClass;
}
method = (add) ? 'addClass' : 'removeClass';
$menu[method](classes);
},
setPathToCurrent = function ($menu, o) {
return $menu.find('li.' + o.pathClass).slice(0, o.pathLevels)
.addClass(o.hoverClass + ' ' + c.bcClass)
.filter(function () {
return ($(this).children(o.popUpSelector).hide().show().length);
}).removeClass(o.pathClass);
},
toggleAnchorClass = function ($li, add) {
var method = (add) ? 'addClass' : 'removeClass';
$li.children('a')[method](c.anchorClass);
},
toggleTouchAction = function ($menu) {
var msTouchAction = $menu.css('ms-touch-action');
var touchAction = $menu.css('touch-action');
touchAction = touchAction || msTouchAction;
touchAction = (touchAction === 'pan-y') ? 'auto' : 'pan-y';
$menu.css({
'ms-touch-action': touchAction,
'touch-action': touchAction
});
},
getMenu = function ($el) {
return $el.closest('.' + c.menuClass);
},
getOptions = function ($el) {
return getMenu($el).data('sfOptions');
},
over = function () {
var $this = $(this),
o = getOptions($this);
clearTimeout(o.sfTimer);
$this.siblings().superfish('hide').end().superfish('show');
},
close = function (o) {
o.retainPath = ($.inArray(this[0], o.$path) > -1);
this.superfish('hide');
if (!this.parents('.' + o.hoverClass).length) {
o.onIdle.call(getMenu(this));
if (o.$path.length) {
$.proxy(over, o.$path)();
}
}
},
out = function () {
var $this = $(this),
o = getOptions($this);
if (ios) {
$.proxy(close, $this, o)();
}
else {
clearTimeout(o.sfTimer);
o.sfTimer = setTimeout($.proxy(close, $this, o), o.delay);
}
},
touchHandler = function (e) {
var $this = $(this),
o = getOptions($this),
$ul = $this.siblings(e.data.popUpSelector);
if (o.onHandleTouch.call($ul) === false) {
return this;
}
if ($ul.length > 0 && $ul.is(':hidden')) {
$this.one('click.superfish', false);
if (e.type === 'MSPointerDown' || e.type === 'pointerdown') {
$this.trigger('focus');
} else {
$.proxy(over, $this.parent('li'))();
}
}
},
applyHandlers = function ($menu, o) {
var targets = 'li:has(' + o.popUpSelector + ')';
if ($.fn.hoverIntent && !o.disableHI) {
$menu.hoverIntent(over, out, targets);
}
else {
$menu
.on('mouseenter.superfish', targets, over)
.on('mouseleave.superfish', targets, out);
}
var touchevent = 'MSPointerDown.superfish';
if (unprefixedPointerEvents) {
touchevent = 'pointerdown.superfish';
}
if (!ios) {
touchevent += ' touchend.superfish';
}
if (wp7) {
touchevent += ' mousedown.superfish';
}
$menu
.on('focusin.superfish', 'li', over)
.on('focusout.superfish', 'li', out)
.on(touchevent, 'a', o, touchHandler);
};
return {
// public methods
hide: function (instant) {
if (this.length) {
var $this = this,
o = getOptions($this);
if (!o) {
return this;
}
var not = (o.retainPath === true) ? o.$path : '',
$ul = $this.find('li.' + o.hoverClass).add(this).not(not).removeClass(o.hoverClass).children(o.popUpSelector),
speed = o.speedOut;
if (instant) {
$ul.show();
speed = 0;
}
o.retainPath = false;
if (o.onBeforeHide.call($ul) === false) {
return this;
}
$ul.stop(true, true).animate(o.animationOut, speed, function () {
var $this = $(this);
o.onHide.call($this);
});
}
return this;
},
show: function () {
var o = getOptions(this);
if (!o) {
return this;
}
var $this = this.addClass(o.hoverClass),
$ul = $this.children(o.popUpSelector);
if (o.onBeforeShow.call($ul) === false) {
return this;
}
$ul.stop(true, true).animate(o.animation, o.speed, function () {
o.onShow.call($ul);
});
return this;
},
destroy: function () {
return this.each(function () {
var $this = $(this),
o = $this.data('sfOptions'),
$hasPopUp;
if (!o) {
return false;
}
$hasPopUp = $this.find(o.popUpSelector).parent('li');
clearTimeout(o.sfTimer);
toggleMenuClasses($this, o);
toggleAnchorClass($hasPopUp);
toggleTouchAction($this);
// remove event handlers
$this.off('.superfish').off('.hoverIntent');
// clear animation's inline display style
$hasPopUp.children(o.popUpSelector).attr('style', function (i, style) {
if (typeof style !== 'undefined') {
return style.replace(/display[^;]+;?/g, '');
}
});
// reset 'current' path classes
o.$path.removeClass(o.hoverClass + ' ' + c.bcClass).addClass(o.pathClass);
$this.find('.' + o.hoverClass).removeClass(o.hoverClass);
o.onDestroy.call($this);
$this.removeData('sfOptions');
});
},
init: function (op) {
return this.each(function () {
var $this = $(this);
if ($this.data('sfOptions')) {
return false;
}
var o = $.extend({}, $.fn.superfish.defaults, op),
$hasPopUp = $this.find(o.popUpSelector).parent('li');
o.$path = setPathToCurrent($this, o);
$this.data('sfOptions', o);
toggleMenuClasses($this, o, true);
toggleAnchorClass($hasPopUp, true);
toggleTouchAction($this);
applyHandlers($this, o);
$hasPopUp.not('.' + c.bcClass).superfish('hide', true);
o.onInit.call(this);
});
}
};
})();
$.fn.superfish = function (method, args) {
if (methods[method]) {
return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
}
else if (typeof method === 'object' || ! method) {
return methods.init.apply(this, arguments);
}
else {
return $.error('Method ' + method + ' does not exist on jQuery.fn.superfish');
}
};
$.fn.superfish.defaults = {
popUpSelector: 'ul,.sf-mega', // within menu context
hoverClass: 'sfHover',
pathClass: 'overrideThisToUse',
pathLevels: 1,
delay: 800,
animation: {opacity: 'show'},
animationOut: {opacity: 'hide'},
speed: 'normal',
speedOut: 'fast',
cssArrows: true,
disableHI: false,
onInit: $.noop,
onBeforeShow: $.noop,
onShow: $.noop,
onBeforeHide: $.noop,
onHide: $.noop,
onIdle: $.noop,
onDestroy: $.noop,
onHandleTouch: $.noop
};
})(jQuery, window);
/*!
* Modernizr v2.8.3
* www.modernizr.com
*
* Copyright (c) Faruk Ates, Paul Irish, Alex Sexton
* Available under the BSD and MIT licenses: www.modernizr.com/license/
*/
/*
* Modernizr tests which native CSS3 and HTML5 features are available in
* the current UA and makes the results available to you in two ways:
* as properties on a global Modernizr object, and as classes on the
* element. This information allows you to progressively enhance
* your pages with a granular level of control over the experience.
*
* Modernizr has an optional (not included) conditional resource loader
* called Modernizr.load(), based on Yepnope.js (yepnopejs.com).
* To get a build that includes Modernizr.load(), as well as choosing
* which tests to include, go to www.modernizr.com/download/
*
* Authors Faruk Ates, Paul Irish, Alex Sexton
* Contributors Ryan Seddon, Ben Alman
*/
window.Modernizr = (function( window, document, undefined ) {
var version = '2.8.3',
Modernizr = {},
/*>>cssclasses*/
// option for enabling the HTML classes to be added
enableClasses = true,
/*>>cssclasses*/
docElement = document.documentElement,
/**
* Create our "modernizr" element that we do most feature tests on.
*/
mod = 'modernizr',
modElem = document.createElement(mod),
mStyle = modElem.style,
/**
* Create the input element for various Web Forms feature tests.
*/
inputElem /*>>inputelem*/ = document.createElement('input') /*>>inputelem*/ ,
/*>>smile*/
smile = ':)',
/*>>smile*/
toString = {}.toString,
// TODO :: make the prefixes more granular
/*>>prefixes*/
// List of property values to set for css tests. See ticket #21
prefixes = ' -webkit- -moz- -o- -ms- '.split(' '),
/*>>prefixes*/
/*>>domprefixes*/
// Following spec is to expose vendor-specific style properties as:
// elem.style.WebkitBorderRadius
// and the following would be incorrect:
// elem.style.webkitBorderRadius
// Webkit ghosts their properties in lowercase but Opera & Moz do not.
// Microsoft uses a lowercase `ms` instead of the correct `Ms` in IE8+
// erik.eae.net/archives/2008/03/10/21.48.10/
// More here: github.com/Modernizr/Modernizr/issues/issue/21
omPrefixes = 'Webkit Moz O ms',
cssomPrefixes = omPrefixes.split(' '),
domPrefixes = omPrefixes.toLowerCase().split(' '),
/*>>domprefixes*/
/*>>ns*/
ns = {'svg': 'http://www.w3.org/2000/svg'},
/*>>ns*/
tests = {},
inputs = {},
attrs = {},
classes = [],
slice = classes.slice,
featureName, // used in testing loop
/*>>teststyles*/
// Inject element with style element and some CSS rules
injectElementWithStyles = function( rule, callback, nodes, testnames ) {
var style, ret, node, docOverflow,
div = document.createElement('div'),
// After page load injecting a fake body doesn't work so check if body exists
body = document.body,
// IE6 and 7 won't return offsetWidth or offsetHeight unless it's in the body element, so we fake it.
fakeBody = body || document.createElement('body');
if ( parseInt(nodes, 10) ) {
// In order not to give false positives we create a node for each test
// This also allows the method to scale for unspecified uses
while ( nodes-- ) {
node = document.createElement('div');
node.id = testnames ? testnames[nodes] : mod + (nodes + 1);
div.appendChild(node);
}
}
// '].join('');
div.id = mod;
// IE6 will false positive on some tests due to the style element inside the test div somehow interfering offsetHeight, so insert it into body or fakebody.
// Opera will act all quirky when injecting elements in documentElement when page is served as xml, needs fakebody too. #270
(body ? div : fakeBody).innerHTML += style;
fakeBody.appendChild(div);
if ( !body ) {
//avoid crashing IE8, if background image is used
fakeBody.style.background = '';
//Safari 5.13/5.1.4 OSX stops loading if ::-webkit-scrollbar is used and scrollbars are visible
fakeBody.style.overflow = 'hidden';
docOverflow = docElement.style.overflow;
docElement.style.overflow = 'hidden';
docElement.appendChild(fakeBody);
}
ret = callback(div, rule);
// If this is done after page load we don't want to remove the body so check if body exists
if ( !body ) {
fakeBody.parentNode.removeChild(fakeBody);
docElement.style.overflow = docOverflow;
} else {
div.parentNode.removeChild(div);
}
return !!ret;
},
/*>>teststyles*/
/*>>mq*/
// adapted from matchMedia polyfill
// by Scott Jehl and Paul Irish
// gist.github.com/786768
testMediaQuery = function( mq ) {
var matchMedia = window.matchMedia || window.msMatchMedia;
if ( matchMedia ) {
return matchMedia(mq) && matchMedia(mq).matches || false;
}
var bool;
injectElementWithStyles('@media ' + mq + ' { #' + mod + ' { position: absolute; } }', function( node ) {
bool = (window.getComputedStyle ?
getComputedStyle(node, null) :
node.currentStyle)['position'] == 'absolute';
});
return bool;
},
/*>>mq*/
/*>>hasevent*/
//
// isEventSupported determines if a given element supports the given event
// kangax.github.com/iseventsupported/
//
// The following results are known incorrects:
// Modernizr.hasEvent("webkitTransitionEnd", elem) // false negative
// Modernizr.hasEvent("textInput") // in Webkit. github.com/Modernizr/Modernizr/issues/333
// ...
isEventSupported = (function() {
var TAGNAMES = {
'select': 'input', 'change': 'input',
'submit': 'form', 'reset': 'form',
'error': 'img', 'load': 'img', 'abort': 'img'
};
function isEventSupported( eventName, element ) {
element = element || document.createElement(TAGNAMES[eventName] || 'div');
eventName = 'on' + eventName;
// When using `setAttribute`, IE skips "unload", WebKit skips "unload" and "resize", whereas `in` "catches" those
var isSupported = eventName in element;
if ( !isSupported ) {
// If it has no `setAttribute` (i.e. doesn't implement Node interface), try generic element
if ( !element.setAttribute ) {
element = document.createElement('div');
}
if ( element.setAttribute && element.removeAttribute ) {
element.setAttribute(eventName, '');
isSupported = is(element[eventName], 'function');
// If property was created, "remove it" (by setting value to `undefined`)
if ( !is(element[eventName], 'undefined') ) {
element[eventName] = undefined;
}
element.removeAttribute(eventName);
}
}
element = null;
return isSupported;
}
return isEventSupported;
})(),
/*>>hasevent*/
// TODO :: Add flag for hasownprop ? didn't last time
// hasOwnProperty shim by kangax needed for Safari 2.0 support
_hasOwnProperty = ({}).hasOwnProperty, hasOwnProp;
if ( !is(_hasOwnProperty, 'undefined') && !is(_hasOwnProperty.call, 'undefined') ) {
hasOwnProp = function (object, property) {
return _hasOwnProperty.call(object, property);
};
}
else {
hasOwnProp = function (object, property) { /* yes, this can give false positives/negatives, but most of the time we don't care about those */
return ((property in object) && is(object.constructor.prototype[property], 'undefined'));
};
}
// Adapted from ES5-shim https://github.com/kriskowal/es5-shim/blob/master/es5-shim.js
// es5.github.com/#x15.3.4.5
if (!Function.prototype.bind) {
Function.prototype.bind = function bind(that) {
var target = this;
if (typeof target != "function") {
throw new TypeError();
}
var args = slice.call(arguments, 1),
bound = function () {
if (this instanceof bound) {
var F = function(){};
F.prototype = target.prototype;
var self = new F();
var result = target.apply(
self,
args.concat(slice.call(arguments))
);
if (Object(result) === result) {
return result;
}
return self;
} else {
return target.apply(
that,
args.concat(slice.call(arguments))
);
}
};
return bound;
};
}
/**
* setCss applies given styles to the Modernizr DOM node.
*/
function setCss( str ) {
mStyle.cssText = str;
}
/**
* setCssAll extrapolates all vendor-specific css strings.
*/
function setCssAll( str1, str2 ) {
return setCss(prefixes.join(str1 + ';') + ( str2 || '' ));
}
/**
* is returns a boolean for if typeof obj is exactly type.
*/
function is( obj, type ) {
return typeof obj === type;
}
/**
* contains returns a boolean for if substr is found within str.
*/
function contains( str, substr ) {
return !!~('' + str).indexOf(substr);
}
/*>>testprop*/
// testProps is a generic CSS / DOM property test.
// In testing support for a given CSS property, it's legit to test:
// `elem.style[styleName] !== undefined`
// If the property is supported it will return an empty string,
// if unsupported it will return undefined.
// We'll take advantage of this quick test and skip setting a style
// on our modernizr element, but instead just testing undefined vs
// empty string.
// Because the testing of the CSS property names (with "-", as
// opposed to the camelCase DOM properties) is non-portable and
// non-standard but works in WebKit and IE (but not Gecko or Opera),
// we explicitly reject properties with dashes so that authors
// developing in WebKit or IE first don't end up with
// browser-specific content by accident.
function testProps( props, prefixed ) {
for ( var i in props ) {
var prop = props[i];
if ( !contains(prop, "-") && mStyle[prop] !== undefined ) {
return prefixed == 'pfx' ? prop : true;
}
}
return false;
}
/*>>testprop*/
// TODO :: add testDOMProps
/**
* testDOMProps is a generic DOM property test; if a browser supports
* a certain property, it won't return undefined for it.
*/
function testDOMProps( props, obj, elem ) {
for ( var i in props ) {
var item = obj[props[i]];
if ( item !== undefined) {
// return the property name as a string
if (elem === false) return props[i];
// let's bind a function
if (is(item, 'function')){
// default to autobind unless override
return item.bind(elem || obj);
}
// return the unbound function or obj or value
return item;
}
}
return false;
}
/*>>testallprops*/
/**
* testPropsAll tests a list of DOM properties we want to check against.
* We specify literally ALL possible (known and/or likely) properties on
* the element including the non-vendor prefixed one, for forward-
* compatibility.
*/
function testPropsAll( prop, prefixed, elem ) {
var ucProp = prop.charAt(0).toUpperCase() + prop.slice(1),
props = (prop + ' ' + cssomPrefixes.join(ucProp + ' ') + ucProp).split(' ');
// did they call .prefixed('boxSizing') or are we just testing a prop?
if(is(prefixed, "string") || is(prefixed, "undefined")) {
return testProps(props, prefixed);
// otherwise, they called .prefixed('requestAnimationFrame', window[, elem])
} else {
props = (prop + ' ' + (domPrefixes).join(ucProp + ' ') + ucProp).split(' ');
return testDOMProps(props, prefixed, elem);
}
}
/*>>testallprops*/
/**
* Tests
* -----
*/
// The *new* flexbox
// dev.w3.org/csswg/css3-flexbox
tests['flexbox'] = function() {
return testPropsAll('flexWrap');
};
// The *old* flexbox
// www.w3.org/TR/2009/WD-css3-flexbox-20090723/
tests['flexboxlegacy'] = function() {
return testPropsAll('boxDirection');
};
// On the S60 and BB Storm, getContext exists, but always returns undefined
// so we actually have to call getContext() to verify
// github.com/Modernizr/Modernizr/issues/issue/97/
tests['canvas'] = function() {
var elem = document.createElement('canvas');
return !!(elem.getContext && elem.getContext('2d'));
};
tests['canvastext'] = function() {
return !!(Modernizr['canvas'] && is(document.createElement('canvas').getContext('2d').fillText, 'function'));
};
// webk.it/70117 is tracking a legit WebGL feature detect proposal
// We do a soft detect which may false positive in order to avoid
// an expensive context creation: bugzil.la/732441
tests['webgl'] = function() {
return !!window.WebGLRenderingContext;
};
/*
* The Modernizr.touch test only indicates if the browser supports
* touch events, which does not necessarily reflect a touchscreen
* device, as evidenced by tablets running Windows 7 or, alas,
* the Palm Pre / WebOS (touch) phones.
*
* Additionally, Chrome (desktop) used to lie about its support on this,
* but that has since been rectified: crbug.com/36415
*
* We also test for Firefox 4 Multitouch Support.
*
* For more info, see: modernizr.github.com/Modernizr/touch.html
*/
tests['touch'] = function() {
var bool;
if(('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch) {
bool = true;
} else {
injectElementWithStyles(['@media (',prefixes.join('touch-enabled),('),mod,')','{#modernizr{top:9px;position:absolute}}'].join(''), function( node ) {
bool = node.offsetTop === 9;
});
}
return bool;
};
// geolocation is often considered a trivial feature detect...
// Turns out, it's quite tricky to get right:
//
// Using !!navigator.geolocation does two things we don't want. It:
// 1. Leaks memory in IE9: github.com/Modernizr/Modernizr/issues/513
// 2. Disables page caching in WebKit: webk.it/43956
//
// Meanwhile, in Firefox < 8, an about:config setting could expose
// a false positive that would throw an exception: bugzil.la/688158
tests['geolocation'] = function() {
return 'geolocation' in navigator;
};
tests['postmessage'] = function() {
return !!window.postMessage;
};
// Chrome incognito mode used to throw an exception when using openDatabase
// It doesn't anymore.
tests['websqldatabase'] = function() {
return !!window.openDatabase;
};
// Vendors had inconsistent prefixing with the experimental Indexed DB:
// - Webkit's implementation is accessible through webkitIndexedDB
// - Firefox shipped moz_indexedDB before FF4b9, but since then has been mozIndexedDB
// For speed, we don't test the legacy (and beta-only) indexedDB
tests['indexedDB'] = function() {
return !!testPropsAll("indexedDB", window);
};
// documentMode logic from YUI to filter out IE8 Compat Mode
// which false positives.
tests['hashchange'] = function() {
return isEventSupported('hashchange', window) && (document.documentMode === undefined || document.documentMode > 7);
};
// Per 1.6:
// This used to be Modernizr.historymanagement but the longer
// name has been deprecated in favor of a shorter and property-matching one.
// The old API is still available in 1.6, but as of 2.0 will throw a warning,
// and in the first release thereafter disappear entirely.
tests['history'] = function() {
return !!(window.history && history.pushState);
};
tests['draganddrop'] = function() {
var div = document.createElement('div');
return ('draggable' in div) || ('ondragstart' in div && 'ondrop' in div);
};
// FF3.6 was EOL'ed on 4/24/12, but the ESR version of FF10
// will be supported until FF19 (2/12/13), at which time, ESR becomes FF17.
// FF10 still uses prefixes, so check for it until then.
// for more ESR info, see: mozilla.org/en-US/firefox/organizations/faq/
tests['websockets'] = function() {
return 'WebSocket' in window || 'MozWebSocket' in window;
};
// css-tricks.com/rgba-browser-support/
tests['rgba'] = function() {
// Set an rgba() color and check the returned value
setCss('background-color:rgba(150,255,150,.5)');
return contains(mStyle.backgroundColor, 'rgba');
};
tests['hsla'] = function() {
// Same as rgba(), in fact, browsers re-map hsla() to rgba() internally,
// except IE9 who retains it as hsla
setCss('background-color:hsla(120,40%,100%,.5)');
return contains(mStyle.backgroundColor, 'rgba') || contains(mStyle.backgroundColor, 'hsla');
};
tests['multiplebgs'] = function() {
// Setting multiple images AND a color on the background shorthand property
// and then querying the style.background property value for the number of
// occurrences of "url(" is a reliable method for detecting ACTUAL support for this!
setCss('background:url(https://),url(https://),red url(https://)');
// If the UA supports multiple backgrounds, there should be three occurrences
// of the string "url(" in the return value for elemStyle.background
return (/(url\s*\(.*?){3}/).test(mStyle.background);
};
// this will false positive in Opera Mini
// github.com/Modernizr/Modernizr/issues/396
tests['backgroundsize'] = function() {
return testPropsAll('backgroundSize');
};
tests['borderimage'] = function() {
return testPropsAll('borderImage');
};
// Super comprehensive table about all the unique implementations of
// border-radius: muddledramblings.com/table-of-css3-border-radius-compliance
tests['borderradius'] = function() {
return testPropsAll('borderRadius');
};
// WebOS unfortunately false positives on this test.
tests['boxshadow'] = function() {
return testPropsAll('boxShadow');
};
// FF3.0 will false positive on this test
tests['textshadow'] = function() {
return document.createElement('div').style.textShadow === '';
};
tests['opacity'] = function() {
// Browsers that actually have CSS Opacity implemented have done so
// according to spec, which means their return values are within the
// range of [0.0,1.0] - including the leading zero.
setCssAll('opacity:.55');
// The non-literal . in this regex is intentional:
// German Chrome returns this value as 0,55
// github.com/Modernizr/Modernizr/issues/#issue/59/comment/516632
return (/^0.55$/).test(mStyle.opacity);
};
// Note, Android < 4 will pass this test, but can only animate
// a single property at a time
// goo.gl/v3V4Gp
tests['cssanimations'] = function() {
return testPropsAll('animationName');
};
tests['csscolumns'] = function() {
return testPropsAll('columnCount');
};
tests['cssgradients'] = function() {
/**
* For CSS Gradients syntax, please see:
* webkit.org/blog/175/introducing-css-gradients/
* developer.mozilla.org/en/CSS/-moz-linear-gradient
* developer.mozilla.org/en/CSS/-moz-radial-gradient
* dev.w3.org/csswg/css3-images/#gradients-
*/
var str1 = 'background-image:',
str2 = 'gradient(linear,left top,right bottom,from(#9f9),to(white));',
str3 = 'linear-gradient(left top,#9f9, white);';
setCss(
// legacy webkit syntax (FIXME: remove when syntax not in use anymore)
(str1 + '-webkit- '.split(' ').join(str2 + str1) +
// standard syntax // trailing 'background-image:'
prefixes.join(str3 + str1)).slice(0, -str1.length)
);
return contains(mStyle.backgroundImage, 'gradient');
};
tests['cssreflections'] = function() {
return testPropsAll('boxReflect');
};
tests['csstransforms'] = function() {
return !!testPropsAll('transform');
};
tests['csstransforms3d'] = function() {
var ret = !!testPropsAll('perspective');
// Webkit's 3D transforms are passed off to the browser's own graphics renderer.
// It works fine in Safari on Leopard and Snow Leopard, but not in Chrome in
// some conditions. As a result, Webkit typically recognizes the syntax but
// will sometimes throw a false positive, thus we must do a more thorough check:
if ( ret && 'webkitPerspective' in docElement.style ) {
// Webkit allows this media query to succeed only if the feature is enabled.
// `@media (transform-3d),(-webkit-transform-3d){ ... }`
injectElementWithStyles('@media (transform-3d),(-webkit-transform-3d){#modernizr{left:9px;position:absolute;height:3px;}}', function( node, rule ) {
ret = node.offsetLeft === 9 && node.offsetHeight === 3;
});
}
return ret;
};
tests['csstransitions'] = function() {
return testPropsAll('transition');
};
/*>>fontface*/
// @font-face detection routine by Diego Perini
// javascript.nwbox.com/CSSSupport/
// false positives:
// WebOS github.com/Modernizr/Modernizr/issues/342
// WP7 github.com/Modernizr/Modernizr/issues/538
tests['fontface'] = function() {
var bool;
injectElementWithStyles('@font-face {font-family:"font";src:url("https://")}', function( node, rule ) {
var style = document.getElementById('smodernizr'),
sheet = style.sheet || style.styleSheet,
cssText = sheet ? (sheet.cssRules && sheet.cssRules[0] ? sheet.cssRules[0].cssText : sheet.cssText || '') : '';
bool = /src/i.test(cssText) && cssText.indexOf(rule.split(' ')[0]) === 0;
});
return bool;
};
/*>>fontface*/
// CSS generated content detection
tests['generatedcontent'] = function() {
var bool;
injectElementWithStyles(['#',mod,'{font:0/0 a}#',mod,':after{content:"',smile,'";visibility:hidden;font:3px/1 a}'].join(''), function( node ) {
bool = node.offsetHeight >= 3;
});
return bool;
};
// These tests evaluate support of the video/audio elements, as well as
// testing what types of content they support.
//
// We're using the Boolean constructor here, so that we can extend the value
// e.g. Modernizr.video // true
// Modernizr.video.ogg // 'probably'
//
// Codec values from : github.com/NielsLeenheer/html5test/blob/9106a8/index.html#L845
// thx to NielsLeenheer and zcorpan
// Note: in some older browsers, "no" was a return value instead of empty string.
// It was live in FF3.5.0 and 3.5.1, but fixed in 3.5.2
// It was also live in Safari 4.0.0 - 4.0.4, but fixed in 4.0.5
tests['video'] = function() {
var elem = document.createElement('video'),
bool = false;
// IE9 Running on Windows Server SKU can cause an exception to be thrown, bug #224
try {
if ( bool = !!elem.canPlayType ) {
bool = new Boolean(bool);
bool.ogg = elem.canPlayType('video/ogg; codecs="theora"') .replace(/^no$/,'');
// Without QuickTime, this value will be `undefined`. github.com/Modernizr/Modernizr/issues/546
bool.h264 = elem.canPlayType('video/mp4; codecs="avc1.42E01E"') .replace(/^no$/,'');
bool.webm = elem.canPlayType('video/webm; codecs="vp8, vorbis"').replace(/^no$/,'');
}
} catch(e) { }
return bool;
};
tests['audio'] = function() {
var elem = document.createElement('audio'),
bool = false;
try {
if ( bool = !!elem.canPlayType ) {
bool = new Boolean(bool);
bool.ogg = elem.canPlayType('audio/ogg; codecs="vorbis"').replace(/^no$/,'');
bool.mp3 = elem.canPlayType('audio/mpeg;') .replace(/^no$/,'');
// Mimetypes accepted:
// developer.mozilla.org/En/Media_formats_supported_by_the_audio_and_video_elements
// bit.ly/iphoneoscodecs
bool.wav = elem.canPlayType('audio/wav; codecs="1"') .replace(/^no$/,'');
bool.m4a = ( elem.canPlayType('audio/x-m4a;') ||
elem.canPlayType('audio/aac;')) .replace(/^no$/,'');
}
} catch(e) { }
return bool;
};
// In FF4, if disabled, window.localStorage should === null.
// Normally, we could not test that directly and need to do a
// `('localStorage' in window) && ` test first because otherwise Firefox will
// throw bugzil.la/365772 if cookies are disabled
// Also in iOS5 Private Browsing mode, attempting to use localStorage.setItem
// will throw the exception:
// QUOTA_EXCEEDED_ERRROR DOM Exception 22.
// Peculiarly, getItem and removeItem calls do not throw.
// Because we are forced to try/catch this, we'll go aggressive.
// Just FWIW: IE8 Compat mode supports these features completely:
// www.quirksmode.org/dom/html5.html
// But IE8 doesn't support either with local files
tests['localstorage'] = function() {
try {
localStorage.setItem(mod, mod);
localStorage.removeItem(mod);
return true;
} catch(e) {
return false;
}
};
tests['sessionstorage'] = function() {
try {
sessionStorage.setItem(mod, mod);
sessionStorage.removeItem(mod);
return true;
} catch(e) {
return false;
}
};
tests['webworkers'] = function() {
return !!window.Worker;
};
tests['applicationcache'] = function() {
return !!window.applicationCache;
};
// Thanks to Erik Dahlstrom
tests['svg'] = function() {
return !!document.createElementNS && !!document.createElementNS(ns.svg, 'svg').createSVGRect;
};
// specifically for SVG inline in HTML, not within XHTML
// test page: paulirish.com/demo/inline-svg
tests['inlinesvg'] = function() {
var div = document.createElement('div');
div.innerHTML = '';
return (div.firstChild && div.firstChild.namespaceURI) == ns.svg;
};
// SVG SMIL animation
tests['smil'] = function() {
return !!document.createElementNS && /SVGAnimate/.test(toString.call(document.createElementNS(ns.svg, 'animate')));
};
// This test is only for clip paths in SVG proper, not clip paths on HTML content
// demo: srufaculty.sru.edu/david.dailey/svg/newstuff/clipPath4.svg
// However read the comments to dig into applying SVG clippaths to HTML content here:
// github.com/Modernizr/Modernizr/issues/213#issuecomment-1149491
tests['svgclippaths'] = function() {
return !!document.createElementNS && /SVGClipPath/.test(toString.call(document.createElementNS(ns.svg, 'clipPath')));
};
/*>>webforms*/
// input features and input types go directly onto the ret object, bypassing the tests loop.
// Hold this guy to execute in a moment.
function webforms() {
/*>>input*/
// Run through HTML5's new input attributes to see if the UA understands any.
// We're using f which is the element created early on
// Mike Taylr has created a comprehensive resource for testing these attributes
// when applied to all input types:
// miketaylr.com/code/input-type-attr.html
// spec: www.whatwg.org/specs/web-apps/current-work/multipage/the-input-element.html#input-type-attr-summary
// Only input placeholder is tested while textarea's placeholder is not.
// Currently Safari 4 and Opera 11 have support only for the input placeholder
// Both tests are available in feature-detects/forms-placeholder.js
Modernizr['input'] = (function( props ) {
for ( var i = 0, len = props.length; i < len; i++ ) {
attrs[ props[i] ] = !!(props[i] in inputElem);
}
if (attrs.list){
// safari false positive's on datalist: webk.it/74252
// see also github.com/Modernizr/Modernizr/issues/146
attrs.list = !!(document.createElement('datalist') && window.HTMLDataListElement);
}
return attrs;
})('autocomplete autofocus list placeholder max min multiple pattern required step'.split(' '));
/*>>input*/
/*>>inputtypes*/
// Run through HTML5's new input types to see if the UA understands any.
// This is put behind the tests runloop because it doesn't return a
// true/false like all the other tests; instead, it returns an object
// containing each input type with its corresponding true/false value
// Big thanks to @miketaylr for the html5 forms expertise. miketaylr.com/
Modernizr['inputtypes'] = (function(props) {
for ( var i = 0, bool, inputElemType, defaultView, len = props.length; i < len; i++ ) {
inputElem.setAttribute('type', inputElemType = props[i]);
bool = inputElem.type !== 'text';
// We first check to see if the type we give it sticks..
// If the type does, we feed it a textual value, which shouldn't be valid.
// If the value doesn't stick, we know there's input sanitization which infers a custom UI
if ( bool ) {
inputElem.value = smile;
inputElem.style.cssText = 'position:absolute;visibility:hidden;';
if ( /^range$/.test(inputElemType) && inputElem.style.WebkitAppearance !== undefined ) {
docElement.appendChild(inputElem);
defaultView = document.defaultView;
// Safari 2-4 allows the smiley as a value, despite making a slider
bool = defaultView.getComputedStyle &&
defaultView.getComputedStyle(inputElem, null).WebkitAppearance !== 'textfield' &&
// Mobile android web browser has false positive, so must
// check the height to see if the widget is actually there.
(inputElem.offsetHeight !== 0);
docElement.removeChild(inputElem);
} else if ( /^(search|tel)$/.test(inputElemType) ){
// Spec doesn't define any special parsing or detectable UI
// behaviors so we pass these through as true
// Interestingly, opera fails the earlier test, so it doesn't
// even make it here.
} else if ( /^(url|email)$/.test(inputElemType) ) {
// Real url and email support comes with prebaked validation.
bool = inputElem.checkValidity && inputElem.checkValidity() === false;
} else {
// If the upgraded input compontent rejects the :) text, we got a winner
bool = inputElem.value != smile;
}
}
inputs[ props[i] ] = !!bool;
}
return inputs;
})('search tel url email datetime date month week time datetime-local number range color'.split(' '));
/*>>inputtypes*/
}
/*>>webforms*/
// End of test definitions
// -----------------------
// Run through all tests and detect their support in the current UA.
// todo: hypothetically we could be doing an array of tests and use a basic loop here.
for ( var feature in tests ) {
if ( hasOwnProp(tests, feature) ) {
// run the test, throw the return value into the Modernizr,
// then based on that boolean, define an appropriate className
// and push it into an array of classes we'll join later.
featureName = feature.toLowerCase();
Modernizr[featureName] = tests[feature]();
classes.push((Modernizr[featureName] ? '' : 'no-') + featureName);
}
}
/*>>webforms*/
// input tests need to run.
Modernizr.input || webforms();
/*>>webforms*/
/**
* addTest allows the user to define their own feature tests
* the result will be added onto the Modernizr object,
* as well as an appropriate className set on the html element
*
* @param feature - String naming the feature
* @param test - Function returning true if feature is supported, false if not
*/
Modernizr.addTest = function ( feature, test ) {
if ( typeof feature == 'object' ) {
for ( var key in feature ) {
if ( hasOwnProp( feature, key ) ) {
Modernizr.addTest( key, feature[ key ] );
}
}
} else {
feature = feature.toLowerCase();
if ( Modernizr[feature] !== undefined ) {
// we're going to quit if you're trying to overwrite an existing test
// if we were to allow it, we'd do this:
// var re = new RegExp("\\b(no-)?" + feature + "\\b");
// docElement.className = docElement.className.replace( re, '' );
// but, no rly, stuff 'em.
return Modernizr;
}
test = typeof test == 'function' ? test() : test;
if (typeof enableClasses !== "undefined" && enableClasses) {
docElement.className += ' ' + (test ? '' : 'no-') + feature;
}
Modernizr[feature] = test;
}
return Modernizr; // allow chaining.
};
// Reset modElem.cssText to nothing to reduce memory footprint.
setCss('');
modElem = inputElem = null;
/*>>shiv*/
/**
* @preserve HTML5 Shiv prev3.7.1 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed
*/
;(function(window, document) {
/*jshint evil:true */
/** version */
var version = '3.7.0';
/** Preset options */
var options = window.html5 || {};
/** Used to skip problem elements */
var reSkip = /^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i;
/** Not all elements can be cloned in IE **/
var saveClones = /^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i;
/** Detect whether the browser supports default html5 styles */
var supportsHtml5Styles;
/** Name of the expando, to work with multiple documents or to re-shiv one document */
var expando = '_html5shiv';
/** The id for the the documents expando */
var expanID = 0;
/** Cached data for each document */
var expandoData = {};
/** Detect whether the browser supports unknown elements */
var supportsUnknownElements;
(function() {
try {
var a = document.createElement('a');
a.innerHTML = '';
//if the hidden property is implemented we can assume, that the browser supports basic HTML5 Styles
supportsHtml5Styles = ('hidden' in a);
supportsUnknownElements = a.childNodes.length == 1 || (function() {
// assign a false positive if unable to shiv
(document.createElement)('a');
var frag = document.createDocumentFragment();
return (
typeof frag.cloneNode == 'undefined' ||
typeof frag.createDocumentFragment == 'undefined' ||
typeof frag.createElement == 'undefined'
);
}());
} catch(e) {
// assign a false positive if detection fails => unable to shiv
supportsHtml5Styles = true;
supportsUnknownElements = true;
}
}());
/*--------------------------------------------------------------------------*/
/**
* Creates a style sheet with the given CSS text and adds it to the document.
* @private
* @param {Document} ownerDocument The document.
* @param {String} cssText The CSS text.
* @returns {StyleSheet} The style element.
*/
function addStyleSheet(ownerDocument, cssText) {
var p = ownerDocument.createElement('p'),
parent = ownerDocument.getElementsByTagName('head')[0] || ownerDocument.documentElement;
p.innerHTML = 'x';
return parent.insertBefore(p.lastChild, parent.firstChild);
}
/**
* Returns the value of `html5.elements` as an array.
* @private
* @returns {Array} An array of shived element node names.
*/
function getElements() {
var elements = html5.elements;
return typeof elements == 'string' ? elements.split(' ') : elements;
}
/**
* Returns the data associated to the given document
* @private
* @param {Document} ownerDocument The document.
* @returns {Object} An object of data.
*/
function getExpandoData(ownerDocument) {
var data = expandoData[ownerDocument[expando]];
if (!data) {
data = {};
expanID++;
ownerDocument[expando] = expanID;
expandoData[expanID] = data;
}
return data;
}
/**
* returns a shived element for the given nodeName and document
* @memberOf html5
* @param {String} nodeName name of the element
* @param {Document} ownerDocument The context document.
* @returns {Object} The shived element.
*/
function createElement(nodeName, ownerDocument, data){
if (!ownerDocument) {
ownerDocument = document;
}
if(supportsUnknownElements){
return ownerDocument.createElement(nodeName);
}
if (!data) {
data = getExpandoData(ownerDocument);
}
var node;
if (data.cache[nodeName]) {
node = data.cache[nodeName].cloneNode();
} else if (saveClones.test(nodeName)) {
node = (data.cache[nodeName] = data.createElem(nodeName)).cloneNode();
} else {
node = data.createElem(nodeName);
}
// Avoid adding some elements to fragments in IE < 9 because
// * Attributes like `name` or `type` cannot be set/changed once an element
// is inserted into a document/fragment
// * Link elements with `src` attributes that are inaccessible, as with
// a 403 response, will cause the tab/window to crash
// * Script elements appended to fragments will execute when their `src`
// or `text` property is set
return node.canHaveChildren && !reSkip.test(nodeName) && !node.tagUrn ? data.frag.appendChild(node) : node;
}
/**
* returns a shived DocumentFragment for the given document
* @memberOf html5
* @param {Document} ownerDocument The context document.
* @returns {Object} The shived DocumentFragment.
*/
function createDocumentFragment(ownerDocument, data){
if (!ownerDocument) {
ownerDocument = document;
}
if(supportsUnknownElements){
return ownerDocument.createDocumentFragment();
}
data = data || getExpandoData(ownerDocument);
var clone = data.frag.cloneNode(),
i = 0,
elems = getElements(),
l = elems.length;
for(;i>shiv*/
// Assign private properties to the return object with prefix
Modernizr._version = version;
// expose these for the plugin API. Look in the source for how to join() them against your input
/*>>prefixes*/
Modernizr._prefixes = prefixes;
/*>>prefixes*/
/*>>domprefixes*/
Modernizr._domPrefixes = domPrefixes;
Modernizr._cssomPrefixes = cssomPrefixes;
/*>>domprefixes*/
/*>>mq*/
// Modernizr.mq tests a given media query, live against the current state of the window
// A few important notes:
// * If a browser does not support media queries at all (eg. oldIE) the mq() will always return false
// * A max-width or orientation query will be evaluated against the current state, which may change later.
// * You must specify values. Eg. If you are testing support for the min-width media query use:
// Modernizr.mq('(min-width:0)')
// usage:
// Modernizr.mq('only screen and (max-width:768)')
Modernizr.mq = testMediaQuery;
/*>>mq*/
/*>>hasevent*/
// Modernizr.hasEvent() detects support for a given event, with an optional element to test on
// Modernizr.hasEvent('gesturestart', elem)
Modernizr.hasEvent = isEventSupported;
/*>>hasevent*/
/*>>testprop*/
// Modernizr.testProp() investigates whether a given style property is recognized
// Note that the property names must be provided in the camelCase variant.
// Modernizr.testProp('pointerEvents')
Modernizr.testProp = function(prop){
return testProps([prop]);
};
/*>>testprop*/
/*>>testallprops*/
// Modernizr.testAllProps() investigates whether a given style property,
// or any of its vendor-prefixed variants, is recognized
// Note that the property names must be provided in the camelCase variant.
// Modernizr.testAllProps('boxSizing')
Modernizr.testAllProps = testPropsAll;
/*>>testallprops*/
/*>>teststyles*/
// Modernizr.testStyles() allows you to add custom styles to the document and test an element afterwards
// Modernizr.testStyles('#modernizr { position:absolute }', function(elem, rule){ ... })
Modernizr.testStyles = injectElementWithStyles;
/*>>teststyles*/
/*>>prefixed*/
// Modernizr.prefixed() returns the prefixed or nonprefixed property name variant of your input
// Modernizr.prefixed('boxSizing') // 'MozBoxSizing'
// Properties must be passed as dom-style camelcase, rather than `box-sizing` hypentated style.
// Return values will also be the camelCase variant, if you need to translate that to hypenated style use:
//
// str.replace(/([A-Z])/g, function(str,m1){ return '-' + m1.toLowerCase(); }).replace(/^ms-/,'-ms-');
// If you're trying to ascertain which transition end event to bind to, you might do something like...
//
// var transEndEventNames = {
// 'WebkitTransition' : 'webkitTransitionEnd',
// 'MozTransition' : 'transitionend',
// 'OTransition' : 'oTransitionEnd',
// 'msTransition' : 'MSTransitionEnd',
// 'transition' : 'transitionend'
// },
// transEndEventName = transEndEventNames[ Modernizr.prefixed('transition') ];
Modernizr.prefixed = function(prop, obj, elem){
if(!obj) {
return testPropsAll(prop, 'pfx');
} else {
// Testing DOM property e.g. Modernizr.prefixed('requestAnimationFrame', window) // 'mozRequestAnimationFrame'
return testPropsAll(prop, obj, elem);
}
};
/*>>prefixed*/
/*>>cssclasses*/
// Remove "no-js" class from element, if it exists:
docElement.className = docElement.className.replace(/(^|\s)no-js(\s|$)/, '$1$2') +
// Add the new classes to the element.
(enableClasses ? ' js ' + classes.join(' ') : '');
/*>>cssclasses*/
return Modernizr;
})(this, this.document);
/**
* @preserve HTML5 Shiv 3.7.3 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed
*/
;(function(window, document) {
/*jshint evil:true */
/** version */
var version = '3.7.3';
/** Preset options */
var options = window.html5 || {};
/** Used to skip problem elements */
var reSkip = /^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i;
/** Not all elements can be cloned in IE **/
var saveClones = /^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i;
/** Detect whether the browser supports default html5 styles */
var supportsHtml5Styles;
/** Name of the expando, to work with multiple documents or to re-shiv one document */
var expando = '_html5shiv';
/** The id for the the documents expando */
var expanID = 0;
/** Cached data for each document */
var expandoData = {};
/** Detect whether the browser supports unknown elements */
var supportsUnknownElements;
(function() {
try {
var a = document.createElement('a');
a.innerHTML = '';
//if the hidden property is implemented we can assume, that the browser supports basic HTML5 Styles
supportsHtml5Styles = ('hidden' in a);
supportsUnknownElements = a.childNodes.length == 1 || (function() {
// assign a false positive if unable to shiv
(document.createElement)('a');
var frag = document.createDocumentFragment();
return (
typeof frag.cloneNode == 'undefined' ||
typeof frag.createDocumentFragment == 'undefined' ||
typeof frag.createElement == 'undefined'
);
}());
} catch(e) {
// assign a false positive if detection fails => unable to shiv
supportsHtml5Styles = true;
supportsUnknownElements = true;
}
}());
/*--------------------------------------------------------------------------*/
/**
* Creates a style sheet with the given CSS text and adds it to the document.
* @private
* @param {Document} ownerDocument The document.
* @param {String} cssText The CSS text.
* @returns {StyleSheet} The style element.
*/
function addStyleSheet(ownerDocument, cssText) {
var p = ownerDocument.createElement('p'),
parent = ownerDocument.getElementsByTagName('head')[0] || ownerDocument.documentElement;
p.innerHTML = 'x';
return parent.insertBefore(p.lastChild, parent.firstChild);
}
/**
* Returns the value of `html5.elements` as an array.
* @private
* @returns {Array} An array of shived element node names.
*/
function getElements() {
var elements = html5.elements;
return typeof elements == 'string' ? elements.split(' ') : elements;
}
/**
* Extends the built-in list of html5 elements
* @memberOf html5
* @param {String|Array} newElements whitespace separated list or array of new element names to shiv
* @param {Document} ownerDocument The context document.
*/
function addElements(newElements, ownerDocument) {
var elements = html5.elements;
if(typeof elements != 'string'){
elements = elements.join(' ');
}
if(typeof newElements != 'string'){
newElements = newElements.join(' ');
}
html5.elements = elements +' '+ newElements;
shivDocument(ownerDocument);
}
/**
* Returns the data associated to the given document
* @private
* @param {Document} ownerDocument The document.
* @returns {Object} An object of data.
*/
function getExpandoData(ownerDocument) {
var data = expandoData[ownerDocument[expando]];
if (!data) {
data = {};
expanID++;
ownerDocument[expando] = expanID;
expandoData[expanID] = data;
}
return data;
}
/**
* returns a shived element for the given nodeName and document
* @memberOf html5
* @param {String} nodeName name of the element
* @param {Document|DocumentFragment} ownerDocument The context document.
* @returns {Object} The shived element.
*/
function createElement(nodeName, ownerDocument, data){
if (!ownerDocument) {
ownerDocument = document;
}
if(supportsUnknownElements){
return ownerDocument.createElement(nodeName);
}
if (!data) {
data = getExpandoData(ownerDocument);
}
var node;
if (data.cache[nodeName]) {
node = data.cache[nodeName].cloneNode();
} else if (saveClones.test(nodeName)) {
node = (data.cache[nodeName] = data.createElem(nodeName)).cloneNode();
} else {
node = data.createElem(nodeName);
}
// Avoid adding some elements to fragments in IE < 9 because
// * Attributes like `name` or `type` cannot be set/changed once an element
// is inserted into a document/fragment
// * Link elements with `src` attributes that are inaccessible, as with
// a 403 response, will cause the tab/window to crash
// * Script elements appended to fragments will execute when their `src`
// or `text` property is set
return node.canHaveChildren && !reSkip.test(nodeName) && !node.tagUrn ? data.frag.appendChild(node) : node;
}
/**
* returns a shived DocumentFragment for the given document
* @memberOf html5
* @param {Document} ownerDocument The context document.
* @returns {Object} The shived DocumentFragment.
*/
function createDocumentFragment(ownerDocument, data){
if (!ownerDocument) {
ownerDocument = document;
}
if(supportsUnknownElements){
return ownerDocument.createDocumentFragment();
}
data = data || getExpandoData(ownerDocument);
var clone = data.frag.cloneNode(),
i = 0,
elems = getElements(),
l = elems.length;
for(;i 1) {
this.each(function() {
$(this).bxSlider(options);
});
return this;
}
// create a namespace to be used throughout the plugin
var slider = {},
// set a reference to our slider element
el = this,
// get the original window dimens (thanks a lot IE)
windowWidth = $(window).width(),
windowHeight = $(window).height();
// Return if slider is already initialized
if ($(el).data('bxSlider')) { return; }
/**
* ===================================================================================
* = PRIVATE FUNCTIONS
* ===================================================================================
*/
/**
* Initializes namespace settings to be used throughout plugin
*/
var init = function() {
// Return if slider is already initialized
if ($(el).data('bxSlider')) { return; }
// merge user-supplied options with the defaults
slider.settings = $.extend({}, defaults, options);
// parse slideWidth setting
slider.settings.slideWidth = parseInt(slider.settings.slideWidth);
// store the original children
slider.children = el.children(slider.settings.slideSelector);
// check if actual number of slides is less than minSlides / maxSlides
if (slider.children.length < slider.settings.minSlides) { slider.settings.minSlides = slider.children.length; }
if (slider.children.length < slider.settings.maxSlides) { slider.settings.maxSlides = slider.children.length; }
// if random start, set the startSlide setting to random number
if (slider.settings.randomStart) { slider.settings.startSlide = Math.floor(Math.random() * slider.children.length); }
// store active slide information
slider.active = { index: slider.settings.startSlide };
// store if the slider is in carousel mode (displaying / moving multiple slides)
slider.carousel = slider.settings.minSlides > 1 || slider.settings.maxSlides > 1;
// if carousel, force preloadImages = 'all'
if (slider.carousel) { slider.settings.preloadImages = 'all'; }
// calculate the min / max width thresholds based on min / max number of slides
// used to setup and update carousel slides dimensions
slider.minThreshold = (slider.settings.minSlides * slider.settings.slideWidth) + ((slider.settings.minSlides - 1) * slider.settings.slideMargin);
slider.maxThreshold = (slider.settings.maxSlides * slider.settings.slideWidth) + ((slider.settings.maxSlides - 1) * slider.settings.slideMargin);
// store the current state of the slider (if currently animating, working is true)
slider.working = false;
// initialize the controls object
slider.controls = {};
// initialize an auto interval
slider.interval = null;
// determine which property to use for transitions
slider.animProp = slider.settings.mode === 'vertical' ? 'top' : 'left';
// determine if hardware acceleration can be used
slider.usingCSS = slider.settings.useCSS && slider.settings.mode !== 'fade' && (function() {
// create our test div element
var div = document.createElement('div'),
// css transition properties
props = ['WebkitPerspective', 'MozPerspective', 'OPerspective', 'msPerspective'];
// test for each property
for (var i = 0; i < props.length; i++) {
if (div.style[props[i]] !== undefined) {
slider.cssPrefix = props[i].replace('Perspective', '').toLowerCase();
slider.animProp = '-' + slider.cssPrefix + '-transform';
return true;
}
}
return false;
}());
// if vertical mode always make maxSlides and minSlides equal
if (slider.settings.mode === 'vertical') { slider.settings.maxSlides = slider.settings.minSlides; }
// save original style data
el.data('origStyle', el.attr('style'));
el.children(slider.settings.slideSelector).each(function() {
$(this).data('origStyle', $(this).attr('style'));
});
// perform all DOM / CSS modifications
setup();
};
/**
* Performs all DOM and CSS modifications
*/
var setup = function() {
var preloadSelector = slider.children.eq(slider.settings.startSlide); // set the default preload selector (visible)
// wrap el in a wrapper
el.wrap('
');
// store a namespace reference to .bx-viewport
slider.viewport = el.parent();
// add aria-live if the setting is enabled and ticker mode is disabled
if (slider.settings.ariaLive && !slider.settings.ticker) {
slider.viewport.attr('aria-live', 'polite');
}
// add a loading div to display while images are loading
slider.loader = $('');
slider.viewport.prepend(slider.loader);
// set el to a massive width, to hold any needed slides
// also strip any margin and padding from el
el.css({
width: slider.settings.mode === 'horizontal' ? (slider.children.length * 1000 + 215) + '%' : 'auto',
position: 'relative'
});
// if using CSS, add the easing property
if (slider.usingCSS && slider.settings.easing) {
el.css('-' + slider.cssPrefix + '-transition-timing-function', slider.settings.easing);
// if not using CSS and no easing value was supplied, use the default JS animation easing (swing)
} else if (!slider.settings.easing) {
slider.settings.easing = 'swing';
}
// make modifications to the viewport (.bx-viewport)
slider.viewport.css({
width: '100%',
overflow: 'hidden',
position: 'relative'
});
slider.viewport.parent().css({
maxWidth: getViewportMaxWidth()
});
// apply css to all slider children
slider.children.css({
// the float attribute is a reserved word in compressors like YUI compressor and need to be quoted #48
'float': slider.settings.mode === 'horizontal' ? 'left' : 'none',
listStyle: 'none',
position: 'relative'
});
// apply the calculated width after the float is applied to prevent scrollbar interference
slider.children.css('width', getSlideWidth());
// if slideMargin is supplied, add the css
if (slider.settings.mode === 'horizontal' && slider.settings.slideMargin > 0) { slider.children.css('marginRight', slider.settings.slideMargin); }
if (slider.settings.mode === 'vertical' && slider.settings.slideMargin > 0) { slider.children.css('marginBottom', slider.settings.slideMargin); }
// if "fade" mode, add positioning and z-index CSS
if (slider.settings.mode === 'fade') {
slider.children.css({
position: 'absolute',
zIndex: 0,
display: 'none'
});
// prepare the z-index on the showing element
slider.children.eq(slider.settings.startSlide).css({zIndex: slider.settings.slideZIndex, display: 'block'});
}
// create an element to contain all slider controls (pager, start / stop, etc)
slider.controls.el = $('');
// if captions are requested, add them
if (slider.settings.captions) { appendCaptions(); }
// check if startSlide is last slide
slider.active.last = slider.settings.startSlide === getPagerQty() - 1;
// if video is true, set up the fitVids plugin
if (slider.settings.video) { el.fitVids(); }
//preloadImages
if (slider.settings.preloadImages === 'none') {
preloadSelector = null;
}
else if (slider.settings.preloadImages === 'all' || slider.settings.ticker) {
preloadSelector = slider.children;
}
// only check for control addition if not in "ticker" mode
if (!slider.settings.ticker) {
// if controls are requested, add them
if (slider.settings.controls) { appendControls(); }
// if auto is true, and auto controls are requested, add them
if (slider.settings.auto && slider.settings.autoControls) { appendControlsAuto(); }
// if pager is requested, add it
if (slider.settings.pager) { appendPager(); }
// if any control option is requested, add the controls wrapper
if (slider.settings.controls || slider.settings.autoControls || slider.settings.pager) { slider.viewport.after(slider.controls.el); }
// if ticker mode, do not allow a pager
} else {
slider.settings.pager = false;
}
if (preloadSelector === null) {
start();
} else {
loadElements(preloadSelector, start);
}
};
var loadElements = function(selector, callback) {
var total = selector.find('img:not([src=""]), iframe').length,
count = 0;
if (total === 0) {
callback();
return;
}
selector.find('img:not([src=""]), iframe').each(function() {
$(this).one('load error', function() {
if (++count === total) { callback(); }
}).each(function() {
if (this.complete || this.src == '') { $(this).trigger('load'); }
});
});
};
/**
* Start the slider
*/
var start = function() {
// if infinite loop, prepare additional slides
if (slider.settings.infiniteLoop && slider.settings.mode !== 'fade' && !slider.settings.ticker) {
var slice = slider.settings.mode === 'vertical' ? slider.settings.minSlides : slider.settings.maxSlides,
sliceAppend = slider.children.slice(0, slice).clone(true).addClass('bx-clone'),
slicePrepend = slider.children.slice(-slice).clone(true).addClass('bx-clone');
if (slider.settings.ariaHidden) {
sliceAppend.attr('aria-hidden', true);
slicePrepend.attr('aria-hidden', true);
}
el.append(sliceAppend).prepend(slicePrepend);
}
// remove the loading DOM element
slider.loader.remove();
// set the left / top position of "el"
setSlidePosition();
// if "vertical" mode, always use adaptiveHeight to prevent odd behavior
if (slider.settings.mode === 'vertical') { slider.settings.adaptiveHeight = true; }
// set the viewport height
slider.viewport.height(getViewportHeight());
// make sure everything is positioned just right (same as a window resize)
el.redrawSlider();
// onSliderLoad callback
slider.settings.onSliderLoad.call(el, slider.active.index);
// slider has been fully initialized
slider.initialized = true;
// add the resize call to the window
if (slider.settings.responsive) { $(window).on('resize', resizeWindow); }
// if auto is true and has more than 1 page, start the show
if (slider.settings.auto && slider.settings.autoStart && (getPagerQty() > 1 || slider.settings.autoSlideForOnePage)) { initAuto(); }
// if ticker is true, start the ticker
if (slider.settings.ticker) { initTicker(); }
// if pager is requested, make the appropriate pager link active
if (slider.settings.pager) { updatePagerActive(slider.settings.startSlide); }
// check for any updates to the controls (like hideControlOnEnd updates)
if (slider.settings.controls) { updateDirectionControls(); }
// if touchEnabled is true, setup the touch events
if (slider.settings.touchEnabled && !slider.settings.ticker) { initTouch(); }
// if keyboardEnabled is true, setup the keyboard events
if (slider.settings.keyboardEnabled && !slider.settings.ticker) {
$(document).keydown(keyPress);
}
};
/**
* Returns the calculated height of the viewport, used to determine either adaptiveHeight or the maxHeight value
*/
var getViewportHeight = function() {
var height = 0;
// first determine which children (slides) should be used in our height calculation
var children = $();
// if mode is not "vertical" and adaptiveHeight is false, include all children
if (slider.settings.mode !== 'vertical' && !slider.settings.adaptiveHeight) {
children = slider.children;
} else {
// if not carousel, return the single active child
if (!slider.carousel) {
children = slider.children.eq(slider.active.index);
// if carousel, return a slice of children
} else {
// get the individual slide index
var currentIndex = slider.settings.moveSlides === 1 ? slider.active.index : slider.active.index * getMoveBy();
// add the current slide to the children
children = slider.children.eq(currentIndex);
// cycle through the remaining "showing" slides
for (i = 1; i <= slider.settings.maxSlides - 1; i++) {
// if looped back to the start
if (currentIndex + i >= slider.children.length) {
children = children.add(slider.children.eq(i - 1));
} else {
children = children.add(slider.children.eq(currentIndex + i));
}
}
}
}
// if "vertical" mode, calculate the sum of the heights of the children
if (slider.settings.mode === 'vertical') {
children.each(function(index) {
height += $(this).outerHeight();
});
// add user-supplied margins
if (slider.settings.slideMargin > 0) {
height += slider.settings.slideMargin * (slider.settings.minSlides - 1);
}
// if not "vertical" mode, calculate the max height of the children
} else {
height = Math.max.apply(Math, children.map(function() {
return $(this).outerHeight(false);
}).get());
}
if (slider.viewport.css('box-sizing') === 'border-box') {
height += parseFloat(slider.viewport.css('padding-top')) + parseFloat(slider.viewport.css('padding-bottom')) +
parseFloat(slider.viewport.css('border-top-width')) + parseFloat(slider.viewport.css('border-bottom-width'));
} else if (slider.viewport.css('box-sizing') === 'padding-box') {
height += parseFloat(slider.viewport.css('padding-top')) + parseFloat(slider.viewport.css('padding-bottom'));
}
return height;
};
/**
* Returns the calculated width to be used for the outer wrapper / viewport
*/
var getViewportMaxWidth = function() {
var width = '100%';
if (slider.settings.slideWidth > 0) {
if (slider.settings.mode === 'horizontal') {
width = (slider.settings.maxSlides * slider.settings.slideWidth) + ((slider.settings.maxSlides - 1) * slider.settings.slideMargin);
} else {
width = slider.settings.slideWidth;
}
}
return width;
};
/**
* Returns the calculated width to be applied to each slide
*/
var getSlideWidth = function() {
var newElWidth = slider.settings.slideWidth, // start with any user-supplied slide width
wrapWidth = slider.viewport.width(); // get the current viewport width
// if slide width was not supplied, or is larger than the viewport use the viewport width
if (slider.settings.slideWidth === 0 ||
(slider.settings.slideWidth > wrapWidth && !slider.carousel) ||
slider.settings.mode === 'vertical') {
newElWidth = wrapWidth;
// if carousel, use the thresholds to determine the width
} else if (slider.settings.maxSlides > 1 && slider.settings.mode === 'horizontal') {
if (wrapWidth > slider.maxThreshold) {
return newElWidth;
} else if (wrapWidth < slider.minThreshold) {
newElWidth = (wrapWidth - (slider.settings.slideMargin * (slider.settings.minSlides - 1))) / slider.settings.minSlides;
} else if (slider.settings.shrinkItems) {
newElWidth = Math.floor((wrapWidth + slider.settings.slideMargin) / (Math.ceil((wrapWidth + slider.settings.slideMargin) / (newElWidth + slider.settings.slideMargin))) - slider.settings.slideMargin);
}
}
return newElWidth;
};
/**
* Returns the number of slides currently visible in the viewport (includes partially visible slides)
*/
var getNumberSlidesShowing = function() {
var slidesShowing = 1,
childWidth = null;
if (slider.settings.mode === 'horizontal' && slider.settings.slideWidth > 0) {
// if viewport is smaller than minThreshold, return minSlides
if (slider.viewport.width() < slider.minThreshold) {
slidesShowing = slider.settings.minSlides;
// if viewport is larger than maxThreshold, return maxSlides
} else if (slider.viewport.width() > slider.maxThreshold) {
slidesShowing = slider.settings.maxSlides;
// if viewport is between min / max thresholds, divide viewport width by first child width
} else {
childWidth = slider.children.first().width() + slider.settings.slideMargin;
slidesShowing = Math.floor((slider.viewport.width() +
slider.settings.slideMargin) / childWidth) || 1;
}
// if "vertical" mode, slides showing will always be minSlides
} else if (slider.settings.mode === 'vertical') {
slidesShowing = slider.settings.minSlides;
}
return slidesShowing;
};
/**
* Returns the number of pages (one full viewport of slides is one "page")
*/
var getPagerQty = function() {
var pagerQty = 0,
breakPoint = 0,
counter = 0;
// if moveSlides is specified by the user
if (slider.settings.moveSlides > 0) {
if (slider.settings.infiniteLoop) {
pagerQty = Math.ceil(slider.children.length / getMoveBy());
} else {
// when breakpoint goes above children length, counter is the number of pages
while (breakPoint < slider.children.length) {
++pagerQty;
breakPoint = counter + getNumberSlidesShowing();
counter += slider.settings.moveSlides <= getNumberSlidesShowing() ? slider.settings.moveSlides : getNumberSlidesShowing();
}
return counter;
}
// if moveSlides is 0 (auto) divide children length by sides showing, then round up
} else {
pagerQty = Math.ceil(slider.children.length / getNumberSlidesShowing());
}
return pagerQty;
};
/**
* Returns the number of individual slides by which to shift the slider
*/
var getMoveBy = function() {
// if moveSlides was set by the user and moveSlides is less than number of slides showing
if (slider.settings.moveSlides > 0 && slider.settings.moveSlides <= getNumberSlidesShowing()) {
return slider.settings.moveSlides;
}
// if moveSlides is 0 (auto)
return getNumberSlidesShowing();
};
/**
* Sets the slider's (el) left or top position
*/
var setSlidePosition = function() {
var position, lastChild, lastShowingIndex;
// if last slide, not infinite loop, and number of children is larger than specified maxSlides
if (slider.children.length > slider.settings.maxSlides && slider.active.last && !slider.settings.infiniteLoop) {
if (slider.settings.mode === 'horizontal') {
// get the last child's position
lastChild = slider.children.last();
position = lastChild.position();
// set the left position
setPositionProperty(-(position.left - (slider.viewport.width() - lastChild.outerWidth())), 'reset', 0);
} else if (slider.settings.mode === 'vertical') {
// get the last showing index's position
lastShowingIndex = slider.children.length - slider.settings.minSlides;
position = slider.children.eq(lastShowingIndex).position();
// set the top position
setPositionProperty(-position.top, 'reset', 0);
}
// if not last slide
} else {
// get the position of the first showing slide
position = slider.children.eq(slider.active.index * getMoveBy()).position();
// check for last slide
if (slider.active.index === getPagerQty() - 1) { slider.active.last = true; }
// set the respective position
if (position !== undefined) {
if (slider.settings.mode === 'horizontal') { setPositionProperty(-position.left, 'reset', 0); }
else if (slider.settings.mode === 'vertical') { setPositionProperty(-position.top, 'reset', 0); }
}
}
};
/**
* Sets the el's animating property position (which in turn will sometimes animate el).
* If using CSS, sets the transform property. If not using CSS, sets the top / left property.
*
* @param value (int)
* - the animating property's value
*
* @param type (string) 'slide', 'reset', 'ticker'
* - the type of instance for which the function is being
*
* @param duration (int)
* - the amount of time (in ms) the transition should occupy
*
* @param params (array) optional
* - an optional parameter containing any variables that need to be passed in
*/
var setPositionProperty = function(value, type, duration, params) {
var animateObj, propValue;
// use CSS transform
if (slider.usingCSS) {
// determine the translate3d value
propValue = slider.settings.mode === 'vertical' ? 'translate3d(0, ' + value + 'px, 0)' : 'translate3d(' + value + 'px, 0, 0)';
// add the CSS transition-duration
el.css('-' + slider.cssPrefix + '-transition-duration', duration / 1000 + 's');
if (type === 'slide') {
// set the property value
el.css(slider.animProp, propValue);
if (duration !== 0) {
// add a callback method - executes when CSS transition completes
el.on('transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd', function(e) {
//make sure it's the correct one
if (!$(e.target).is(el)) { return; }
// remove the callback
el.off('transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd');
updateAfterSlideTransition();
});
} else { //duration = 0
updateAfterSlideTransition();
}
} else if (type === 'reset') {
el.css(slider.animProp, propValue);
} else if (type === 'ticker') {
// make the transition use 'linear'
el.css('-' + slider.cssPrefix + '-transition-timing-function', 'linear');
el.css(slider.animProp, propValue);
if (duration !== 0) {
el.on('transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd', function(e) {
//make sure it's the correct one
if (!$(e.target).is(el)) { return; }
// remove the callback
el.off('transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd');
// reset the position
setPositionProperty(params.resetValue, 'reset', 0);
// start the loop again
tickerLoop();
});
} else { //duration = 0
setPositionProperty(params.resetValue, 'reset', 0);
tickerLoop();
}
}
// use JS animate
} else {
animateObj = {};
animateObj[slider.animProp] = value;
if (type === 'slide') {
el.animate(animateObj, duration, slider.settings.easing, function() {
updateAfterSlideTransition();
});
} else if (type === 'reset') {
el.css(slider.animProp, value);
} else if (type === 'ticker') {
el.animate(animateObj, duration, 'linear', function() {
setPositionProperty(params.resetValue, 'reset', 0);
// run the recursive loop after animation
tickerLoop();
});
}
}
};
/**
* Populates the pager with proper amount of pages
*/
var populatePager = function() {
var pagerHtml = '',
linkContent = '',
pagerQty = getPagerQty();
// loop through each pager item
for (var i = 0; i < pagerQty; i++) {
linkContent = '';
// if a buildPager function is supplied, use it to get pager link value, else use index + 1
if (slider.settings.buildPager && $.isFunction(slider.settings.buildPager) || slider.settings.pagerCustom) {
linkContent = slider.settings.buildPager(i);
slider.pagerEl.addClass('bx-custom-pager');
} else {
linkContent = i + 1;
slider.pagerEl.addClass('bx-default-pager');
}
// var linkContent = slider.settings.buildPager && $.isFunction(slider.settings.buildPager) ? slider.settings.buildPager(i) : i + 1;
// add the markup to the string
pagerHtml += '
';
}
// populate the pager element with pager links
slider.pagerEl.html(pagerHtml);
};
/**
* Appends the pager to the controls element
*/
var appendPager = function() {
if (!slider.settings.pagerCustom) {
// create the pager DOM element
slider.pagerEl = $('');
// if a pager selector was supplied, populate it with the pager
if (slider.settings.pagerSelector) {
$(slider.settings.pagerSelector).html(slider.pagerEl);
// if no pager selector was supplied, add it after the wrapper
} else {
slider.controls.el.addClass('bx-has-pager').append(slider.pagerEl);
}
// populate the pager
populatePager();
} else {
slider.pagerEl = $(slider.settings.pagerCustom);
}
// assign the pager click binding
slider.pagerEl.on('click touchend', 'a', clickPagerBind);
};
/**
* Appends prev / next controls to the controls element
*/
var appendControls = function() {
slider.controls.next = $('' + slider.settings.nextText + '');
slider.controls.prev = $('' + slider.settings.prevText + '');
// add click actions to the controls
slider.controls.next.on('click touchend', clickNextBind);
slider.controls.prev.on('click touchend', clickPrevBind);
// if nextSelector was supplied, populate it
if (slider.settings.nextSelector) {
$(slider.settings.nextSelector).append(slider.controls.next);
}
// if prevSelector was supplied, populate it
if (slider.settings.prevSelector) {
$(slider.settings.prevSelector).append(slider.controls.prev);
}
// if no custom selectors were supplied
if (!slider.settings.nextSelector && !slider.settings.prevSelector) {
// add the controls to the DOM
slider.controls.directionEl = $('');
// add the control elements to the directionEl
slider.controls.directionEl.append(slider.controls.prev).append(slider.controls.next);
// slider.viewport.append(slider.controls.directionEl);
slider.controls.el.addClass('bx-has-controls-direction').append(slider.controls.directionEl);
}
};
/**
* Appends start / stop auto controls to the controls element
*/
var appendControlsAuto = function() {
slider.controls.start = $('
');
// add the controls to the DOM
slider.controls.autoEl = $('');
// on click actions to the controls
slider.controls.autoEl.on('click', '.bx-start', clickStartBind);
slider.controls.autoEl.on('click', '.bx-stop', clickStopBind);
// if autoControlsCombine, insert only the "start" control
if (slider.settings.autoControlsCombine) {
slider.controls.autoEl.append(slider.controls.start);
// if autoControlsCombine is false, insert both controls
} else {
slider.controls.autoEl.append(slider.controls.start).append(slider.controls.stop);
}
// if auto controls selector was supplied, populate it with the controls
if (slider.settings.autoControlsSelector) {
$(slider.settings.autoControlsSelector).html(slider.controls.autoEl);
// if auto controls selector was not supplied, add it after the wrapper
} else {
slider.controls.el.addClass('bx-has-controls-auto').append(slider.controls.autoEl);
}
// update the auto controls
updateAutoControls(slider.settings.autoStart ? 'stop' : 'start');
};
/**
* Appends image captions to the DOM
*/
var appendCaptions = function() {
// cycle through each child
slider.children.each(function(index) {
// get the image title attribute
var title = $(this).find('img:first').attr('title');
// append the caption
if (title !== undefined && ('' + title).length) {
$(this).append('
' + title + '
');
}
});
};
/**
* Click next binding
*
* @param e (event)
* - DOM event object
*/
var clickNextBind = function(e) {
e.preventDefault();
if (slider.controls.el.hasClass('disabled')) { return; }
// if auto show is running, stop it
if (slider.settings.auto && slider.settings.stopAutoOnClick) { el.stopAuto(); }
el.goToNextSlide();
};
/**
* Click prev binding
*
* @param e (event)
* - DOM event object
*/
var clickPrevBind = function(e) {
e.preventDefault();
if (slider.controls.el.hasClass('disabled')) { return; }
// if auto show is running, stop it
if (slider.settings.auto && slider.settings.stopAutoOnClick) { el.stopAuto(); }
el.goToPrevSlide();
};
/**
* Click start binding
*
* @param e (event)
* - DOM event object
*/
var clickStartBind = function(e) {
el.startAuto();
e.preventDefault();
};
/**
* Click stop binding
*
* @param e (event)
* - DOM event object
*/
var clickStopBind = function(e) {
el.stopAuto();
e.preventDefault();
};
/**
* Click pager binding
*
* @param e (event)
* - DOM event object
*/
var clickPagerBind = function(e) {
var pagerLink, pagerIndex;
e.preventDefault();
if (slider.controls.el.hasClass('disabled')) {
return;
}
// if auto show is running, stop it
if (slider.settings.auto && slider.settings.stopAutoOnClick) { el.stopAuto(); }
pagerLink = $(e.currentTarget);
if (pagerLink.attr('data-slide-index') !== undefined) {
pagerIndex = parseInt(pagerLink.attr('data-slide-index'));
// if clicked pager link is not active, continue with the goToSlide call
if (pagerIndex !== slider.active.index) { el.goToSlide(pagerIndex); }
}
};
/**
* Updates the pager links with an active class
*
* @param slideIndex (int)
* - index of slide to make active
*/
var updatePagerActive = function(slideIndex) {
// if "short" pager type
var len = slider.children.length; // nb of children
if (slider.settings.pagerType === 'short') {
if (slider.settings.maxSlides > 1) {
len = Math.ceil(slider.children.length / slider.settings.maxSlides);
}
slider.pagerEl.html((slideIndex + 1) + slider.settings.pagerShortSeparator + len);
return;
}
// remove all pager active classes
slider.pagerEl.find('a').removeClass('active');
// apply the active class for all pagers
slider.pagerEl.each(function(i, el) { $(el).find('a').eq(slideIndex).addClass('active'); });
};
/**
* Performs needed actions after a slide transition
*/
var updateAfterSlideTransition = function() {
// if infinite loop is true
if (slider.settings.infiniteLoop) {
var position = '';
// first slide
if (slider.active.index === 0) {
// set the new position
position = slider.children.eq(0).position();
// carousel, last slide
} else if (slider.active.index === getPagerQty() - 1 && slider.carousel) {
position = slider.children.eq((getPagerQty() - 1) * getMoveBy()).position();
// last slide
} else if (slider.active.index === slider.children.length - 1) {
position = slider.children.eq(slider.children.length - 1).position();
}
if (position) {
if (slider.settings.mode === 'horizontal') { setPositionProperty(-position.left, 'reset', 0); }
else if (slider.settings.mode === 'vertical') { setPositionProperty(-position.top, 'reset', 0); }
}
}
// declare that the transition is complete
slider.working = false;
// onSlideAfter callback
slider.settings.onSlideAfter.call(el, slider.children.eq(slider.active.index), slider.oldIndex, slider.active.index);
};
/**
* Updates the auto controls state (either active, or combined switch)
*
* @param state (string) "start", "stop"
* - the new state of the auto show
*/
var updateAutoControls = function(state) {
// if autoControlsCombine is true, replace the current control with the new state
if (slider.settings.autoControlsCombine) {
slider.controls.autoEl.html(slider.controls[state]);
// if autoControlsCombine is false, apply the "active" class to the appropriate control
} else {
slider.controls.autoEl.find('a').removeClass('active');
slider.controls.autoEl.find('a:not(.bx-' + state + ')').addClass('active');
}
};
/**
* Updates the direction controls (checks if either should be hidden)
*/
var updateDirectionControls = function() {
if (getPagerQty() === 1) {
slider.controls.prev.addClass('disabled');
slider.controls.next.addClass('disabled');
} else if (!slider.settings.infiniteLoop && slider.settings.hideControlOnEnd) {
// if first slide
if (slider.active.index === 0) {
slider.controls.prev.addClass('disabled');
slider.controls.next.removeClass('disabled');
// if last slide
} else if (slider.active.index === getPagerQty() - 1) {
slider.controls.next.addClass('disabled');
slider.controls.prev.removeClass('disabled');
// if any slide in the middle
} else {
slider.controls.prev.removeClass('disabled');
slider.controls.next.removeClass('disabled');
}
}
};
/* auto start and stop functions */
var windowFocusHandler = function() { el.startAuto(); };
var windowBlurHandler = function() { el.stopAuto(); };
/**
* Initializes the auto process
*/
var initAuto = function() {
// if autoDelay was supplied, launch the auto show using a setTimeout() call
if (slider.settings.autoDelay > 0) {
setTimeout(el.startAuto, slider.settings.autoDelay);
// if autoDelay was not supplied, start the auto show normally
} else {
el.startAuto();
//add focus and blur events to ensure its running if timeout gets paused
$(window).focus(windowFocusHandler).blur(windowBlurHandler);
}
// if autoHover is requested
if (slider.settings.autoHover) {
// on el hover
el.hover(function() {
// if the auto show is currently playing (has an active interval)
if (slider.interval) {
// stop the auto show and pass true argument which will prevent control update
el.stopAuto(true);
// create a new autoPaused value which will be used by the relative "mouseout" event
slider.autoPaused = true;
}
}, function() {
// if the autoPaused value was created be the prior "mouseover" event
if (slider.autoPaused) {
// start the auto show and pass true argument which will prevent control update
el.startAuto(true);
// reset the autoPaused value
slider.autoPaused = null;
}
});
}
};
/**
* Initializes the ticker process
*/
var initTicker = function() {
var startPosition = 0,
position, transform, value, idx, ratio, property, newSpeed, totalDimens;
// if autoDirection is "next", append a clone of the entire slider
if (slider.settings.autoDirection === 'next') {
el.append(slider.children.clone().addClass('bx-clone'));
// if autoDirection is "prev", prepend a clone of the entire slider, and set the left position
} else {
el.prepend(slider.children.clone().addClass('bx-clone'));
position = slider.children.first().position();
startPosition = slider.settings.mode === 'horizontal' ? -position.left : -position.top;
}
setPositionProperty(startPosition, 'reset', 0);
// do not allow controls in ticker mode
slider.settings.pager = false;
slider.settings.controls = false;
slider.settings.autoControls = false;
// if autoHover is requested
if (slider.settings.tickerHover) {
if (slider.usingCSS) {
idx = slider.settings.mode === 'horizontal' ? 4 : 5;
slider.viewport.hover(function() {
transform = el.css('-' + slider.cssPrefix + '-transform');
value = parseFloat(transform.split(',')[idx]);
setPositionProperty(value, 'reset', 0);
}, function() {
totalDimens = 0;
slider.children.each(function(index) {
totalDimens += slider.settings.mode === 'horizontal' ? $(this).outerWidth(true) : $(this).outerHeight(true);
});
// calculate the speed ratio (used to determine the new speed to finish the paused animation)
ratio = slider.settings.speed / totalDimens;
// determine which property to use
property = slider.settings.mode === 'horizontal' ? 'left' : 'top';
// calculate the new speed
newSpeed = ratio * (totalDimens - (Math.abs(parseInt(value))));
tickerLoop(newSpeed);
});
} else {
// on el hover
slider.viewport.hover(function() {
el.stop();
}, function() {
// calculate the total width of children (used to calculate the speed ratio)
totalDimens = 0;
slider.children.each(function(index) {
totalDimens += slider.settings.mode === 'horizontal' ? $(this).outerWidth(true) : $(this).outerHeight(true);
});
// calculate the speed ratio (used to determine the new speed to finish the paused animation)
ratio = slider.settings.speed / totalDimens;
// determine which property to use
property = slider.settings.mode === 'horizontal' ? 'left' : 'top';
// calculate the new speed
newSpeed = ratio * (totalDimens - (Math.abs(parseInt(el.css(property)))));
tickerLoop(newSpeed);
});
}
}
// start the ticker loop
tickerLoop();
};
/**
* Runs a continuous loop, news ticker-style
*/
var tickerLoop = function(resumeSpeed) {
var speed = resumeSpeed ? resumeSpeed : slider.settings.speed,
position = {left: 0, top: 0},
reset = {left: 0, top: 0},
animateProperty, resetValue, params;
// if "next" animate left position to last child, then reset left to 0
if (slider.settings.autoDirection === 'next') {
position = el.find('.bx-clone').first().position();
// if "prev" animate left position to 0, then reset left to first non-clone child
} else {
reset = slider.children.first().position();
}
animateProperty = slider.settings.mode === 'horizontal' ? -position.left : -position.top;
resetValue = slider.settings.mode === 'horizontal' ? -reset.left : -reset.top;
params = {resetValue: resetValue};
setPositionProperty(animateProperty, 'ticker', speed, params);
};
/**
* Check if el is on screen
*/
var isOnScreen = function(el) {
var win = $(window),
viewport = {
top: win.scrollTop(),
left: win.scrollLeft()
},
bounds = el.offset();
viewport.right = viewport.left + win.width();
viewport.bottom = viewport.top + win.height();
bounds.right = bounds.left + el.outerWidth();
bounds.bottom = bounds.top + el.outerHeight();
return (!(viewport.right < bounds.left || viewport.left > bounds.right || viewport.bottom < bounds.top || viewport.top > bounds.bottom));
};
/**
* Initializes keyboard events
*/
var keyPress = function(e) {
var activeElementTag = document.activeElement.tagName.toLowerCase(),
tagFilters = 'input|textarea',
p = new RegExp(activeElementTag,['i']),
result = p.exec(tagFilters);
if (result == null && isOnScreen(el)) {
if (e.keyCode === 39) {
clickNextBind(e);
return false;
} else if (e.keyCode === 37) {
clickPrevBind(e);
return false;
}
}
};
/**
* Initializes touch events
*/
var initTouch = function() {
// initialize object to contain all touch values
slider.touch = {
start: {x: 0, y: 0},
end: {x: 0, y: 0}
};
slider.viewport.on('touchstart MSPointerDown pointerdown', onTouchStart);
//for browsers that have implemented pointer events and fire a click after
//every pointerup regardless of whether pointerup is on same screen location as pointerdown or not
slider.viewport.on('click', '.bxslider a', function(e) {
if (slider.viewport.hasClass('click-disabled')) {
e.preventDefault();
slider.viewport.removeClass('click-disabled');
}
});
};
/**
* Event handler for "touchstart"
*
* @param e (event)
* - DOM event object
*/
var onTouchStart = function(e) {
// watch only for left mouse, touch contact and pen contact
// touchstart event object doesn`t have button property
if (e.type !== 'touchstart' && e.button !== 0) {
return;
}
e.preventDefault();
//disable slider controls while user is interacting with slides to avoid slider freeze that happens on touch devices when a slide swipe happens immediately after interacting with slider controls
slider.controls.el.addClass('disabled');
if (slider.working) {
slider.controls.el.removeClass('disabled');
} else {
// record the original position when touch starts
slider.touch.originalPos = el.position();
var orig = e.originalEvent,
touchPoints = (typeof orig.changedTouches !== 'undefined') ? orig.changedTouches : [orig];
var chromePointerEvents = typeof PointerEvent === 'function';
if (chromePointerEvents) {
if (orig.pointerId === undefined) {
return;
}
}
// record the starting touch x, y coordinates
slider.touch.start.x = touchPoints[0].pageX;
slider.touch.start.y = touchPoints[0].pageY;
if (slider.viewport.get(0).setPointerCapture) {
slider.pointerId = orig.pointerId;
slider.viewport.get(0).setPointerCapture(slider.pointerId);
}
// store original event data for click fixation
slider.originalClickTarget = orig.originalTarget || orig.target;
slider.originalClickButton = orig.button;
slider.originalClickButtons = orig.buttons;
slider.originalEventType = orig.type;
// at this moment we don`t know what it is click or swipe
slider.hasMove = false;
// on a "touchmove" event to the viewport
slider.viewport.on('touchmove MSPointerMove pointermove', onTouchMove);
// on a "touchend" event to the viewport
slider.viewport.on('touchend MSPointerUp pointerup', onTouchEnd);
slider.viewport.on('MSPointerCancel pointercancel', onPointerCancel);
}
};
/**
* Cancel Pointer for Windows Phone
*
* @param e (event)
* - DOM event object
*/
var onPointerCancel = function(e) {
e.preventDefault();
/* onPointerCancel handler is needed to deal with situations when a touchend
doesn't fire after a touchstart (this happens on windows phones only) */
setPositionProperty(slider.touch.originalPos.left, 'reset', 0);
//remove handlers
slider.controls.el.removeClass('disabled');
slider.viewport.off('MSPointerCancel pointercancel', onPointerCancel);
slider.viewport.off('touchmove MSPointerMove pointermove', onTouchMove);
slider.viewport.off('touchend MSPointerUp pointerup', onTouchEnd);
if (slider.viewport.get(0).releasePointerCapture) {
slider.viewport.get(0).releasePointerCapture(slider.pointerId);
}
};
/**
* Event handler for "touchmove"
*
* @param e (event)
* - DOM event object
*/
var onTouchMove = function(e) {
var orig = e.originalEvent,
touchPoints = (typeof orig.changedTouches !== 'undefined') ? orig.changedTouches : [orig],
// if scrolling on y axis, do not prevent default
xMovement = Math.abs(touchPoints[0].pageX - slider.touch.start.x),
yMovement = Math.abs(touchPoints[0].pageY - slider.touch.start.y),
value = 0,
change = 0;
// this is swipe
slider.hasMove = true;
// x axis swipe
if ((xMovement * 3) > yMovement && slider.settings.preventDefaultSwipeX) {
e.preventDefault();
// y axis swipe
} else if ((yMovement * 3) > xMovement && slider.settings.preventDefaultSwipeY) {
e.preventDefault();
}
if (e.type !== 'touchmove') {
e.preventDefault();
}
if (slider.settings.mode !== 'fade' && slider.settings.oneToOneTouch) {
// if horizontal, drag along x axis
if (slider.settings.mode === 'horizontal') {
change = touchPoints[0].pageX - slider.touch.start.x;
value = slider.touch.originalPos.left + change;
// if vertical, drag along y axis
} else {
change = touchPoints[0].pageY - slider.touch.start.y;
value = slider.touch.originalPos.top + change;
}
setPositionProperty(value, 'reset', 0);
}
};
/**
* Event handler for "touchend"
*
* @param e (event)
* - DOM event object
*/
var onTouchEnd = function(e) {
e.preventDefault();
slider.viewport.off('touchmove MSPointerMove pointermove', onTouchMove);
//enable slider controls as soon as user stops interacing with slides
slider.controls.el.removeClass('disabled');
var orig = e.originalEvent,
touchPoints = (typeof orig.changedTouches !== 'undefined') ? orig.changedTouches : [orig],
value = 0,
distance = 0;
// record end x, y positions
slider.touch.end.x = touchPoints[0].pageX;
slider.touch.end.y = touchPoints[0].pageY;
// if fade mode, check if absolute x distance clears the threshold
if (slider.settings.mode === 'fade') {
distance = Math.abs(slider.touch.start.x - slider.touch.end.x);
if (distance >= slider.settings.swipeThreshold) {
if (slider.touch.start.x > slider.touch.end.x) {
el.goToNextSlide();
} else {
el.goToPrevSlide();
}
el.stopAuto();
}
// not fade mode
} else {
// calculate distance and el's animate property
if (slider.settings.mode === 'horizontal') {
distance = slider.touch.end.x - slider.touch.start.x;
value = slider.touch.originalPos.left;
} else {
distance = slider.touch.end.y - slider.touch.start.y;
value = slider.touch.originalPos.top;
}
// if not infinite loop and first / last slide, do not attempt a slide transition
if (!slider.settings.infiniteLoop && ((slider.active.index === 0 && distance > 0) || (slider.active.last && distance < 0))) {
setPositionProperty(value, 'reset', 200);
} else {
// check if distance clears threshold
if (Math.abs(distance) >= slider.settings.swipeThreshold) {
if (distance < 0) {
el.goToNextSlide();
} else {
el.goToPrevSlide();
}
el.stopAuto();
} else {
// el.animate(property, 200);
setPositionProperty(value, 'reset', 200);
}
}
}
slider.viewport.off('touchend MSPointerUp pointerup', onTouchEnd);
if (slider.viewport.get(0).releasePointerCapture) {
slider.viewport.get(0).releasePointerCapture(slider.pointerId);
}
// if slider had swipe with left mouse, touch contact and pen contact
if (slider.hasMove === false && (slider.originalClickButton === 0 || slider.originalEventType === 'touchstart')) {
// trigger click event (fix for Firefox59 and PointerEvent standard compatibility)
$(slider.originalClickTarget).trigger({
type: 'click',
button: slider.originalClickButton,
buttons: slider.originalClickButtons
});
}
};
/**
* Window resize event callback
*/
var resizeWindow = function(e) {
// don't do anything if slider isn't initialized.
if (!slider.initialized) { return; }
// Delay if slider working.
if (slider.working) {
window.setTimeout(resizeWindow, 10);
} else {
// get the new window dimens (again, thank you IE)
var windowWidthNew = $(window).width(),
windowHeightNew = $(window).height();
// make sure that it is a true window resize
// *we must check this because our dinosaur friend IE fires a window resize event when certain DOM elements
// are resized. Can you just die already?*
if (windowWidth !== windowWidthNew || windowHeight !== windowHeightNew) {
// set the new window dimens
windowWidth = windowWidthNew;
windowHeight = windowHeightNew;
// update all dynamic elements
el.redrawSlider();
// Call user resize handler
slider.settings.onSliderResize.call(el, slider.active.index);
}
}
};
/**
* Adds an aria-hidden=true attribute to each element
*
* @param startVisibleIndex (int)
* - the first visible element's index
*/
var applyAriaHiddenAttributes = function(startVisibleIndex) {
var numberOfSlidesShowing = getNumberSlidesShowing();
// only apply attributes if the setting is enabled and not in ticker mode
if (slider.settings.ariaHidden && !slider.settings.ticker) {
// add aria-hidden=true to all elements
slider.children.attr('aria-hidden', 'true');
// get the visible elements and change to aria-hidden=false
slider.children.slice(startVisibleIndex, startVisibleIndex + numberOfSlidesShowing).attr('aria-hidden', 'false');
}
};
/**
* Returns index according to present page range
*
* @param slideOndex (int)
* - the desired slide index
*/
var setSlideIndex = function(slideIndex) {
if (slideIndex < 0) {
if (slider.settings.infiniteLoop) {
return getPagerQty() - 1;
}else {
//we don't go to undefined slides
return slider.active.index;
}
// if slideIndex is greater than children length, set active index to 0 (this happens during infinite loop)
} else if (slideIndex >= getPagerQty()) {
if (slider.settings.infiniteLoop) {
return 0;
} else {
//we don't move to undefined pages
return slider.active.index;
}
// set active index to requested slide
} else {
return slideIndex;
}
};
/**
* ===================================================================================
* = PUBLIC FUNCTIONS
* ===================================================================================
*/
/**
* Performs slide transition to the specified slide
*
* @param slideIndex (int)
* - the destination slide's index (zero-based)
*
* @param direction (string)
* - INTERNAL USE ONLY - the direction of travel ("prev" / "next")
*/
el.goToSlide = function(slideIndex, direction) {
// onSlideBefore, onSlideNext, onSlidePrev callbacks
// Allow transition canceling based on returned value
var performTransition = true,
moveBy = 0,
position = {left: 0, top: 0},
lastChild = null,
lastShowingIndex, eq, value, requestEl;
// store the old index
slider.oldIndex = slider.active.index;
//set new index
slider.active.index = setSlideIndex(slideIndex);
// if plugin is currently in motion, ignore request
if (slider.working || slider.active.index === slider.oldIndex) { return; }
// declare that plugin is in motion
slider.working = true;
performTransition = slider.settings.onSlideBefore.call(el, slider.children.eq(slider.active.index), slider.oldIndex, slider.active.index);
// If transitions canceled, reset and return
if (typeof (performTransition) !== 'undefined' && !performTransition) {
slider.active.index = slider.oldIndex; // restore old index
slider.working = false; // is not in motion
return;
}
if (direction === 'next') {
// Prevent canceling in future functions or lack there-of from negating previous commands to cancel
if (!slider.settings.onSlideNext.call(el, slider.children.eq(slider.active.index), slider.oldIndex, slider.active.index)) {
performTransition = false;
}
} else if (direction === 'prev') {
// Prevent canceling in future functions or lack there-of from negating previous commands to cancel
if (!slider.settings.onSlidePrev.call(el, slider.children.eq(slider.active.index), slider.oldIndex, slider.active.index)) {
performTransition = false;
}
}
// check if last slide
slider.active.last = slider.active.index >= getPagerQty() - 1;
// update the pager with active class
if (slider.settings.pager || slider.settings.pagerCustom) { updatePagerActive(slider.active.index); }
// // check for direction control update
if (slider.settings.controls) { updateDirectionControls(); }
// if slider is set to mode: "fade"
if (slider.settings.mode === 'fade') {
// if adaptiveHeight is true and next height is different from current height, animate to the new height
if (slider.settings.adaptiveHeight && slider.viewport.height() !== getViewportHeight()) {
slider.viewport.animate({height: getViewportHeight()}, slider.settings.adaptiveHeightSpeed);
}
// fade out the visible child and reset its z-index value
slider.children.filter(':visible').fadeOut(slider.settings.speed).css({zIndex: 0});
// fade in the newly requested slide
slider.children.eq(slider.active.index).css('zIndex', slider.settings.slideZIndex + 1).fadeIn(slider.settings.speed, function() {
$(this).css('zIndex', slider.settings.slideZIndex);
updateAfterSlideTransition();
});
// slider mode is not "fade"
} else {
// if adaptiveHeight is true and next height is different from current height, animate to the new height
if (slider.settings.adaptiveHeight && slider.viewport.height() !== getViewportHeight()) {
slider.viewport.animate({height: getViewportHeight()}, slider.settings.adaptiveHeightSpeed);
}
// if carousel and not infinite loop
if (!slider.settings.infiniteLoop && slider.carousel && slider.active.last) {
if (slider.settings.mode === 'horizontal') {
// get the last child position
lastChild = slider.children.eq(slider.children.length - 1);
position = lastChild.position();
// calculate the position of the last slide
moveBy = slider.viewport.width() - lastChild.outerWidth();
} else {
// get last showing index position
lastShowingIndex = slider.children.length - slider.settings.minSlides;
position = slider.children.eq(lastShowingIndex).position();
}
// horizontal carousel, going previous while on first slide (infiniteLoop mode)
} else if (slider.carousel && slider.active.last && direction === 'prev') {
// get the last child position
eq = slider.settings.moveSlides === 1 ? slider.settings.maxSlides - getMoveBy() : ((getPagerQty() - 1) * getMoveBy()) - (slider.children.length - slider.settings.maxSlides);
lastChild = el.children('.bx-clone').eq(eq);
position = lastChild.position();
// if infinite loop and "Next" is clicked on the last slide
} else if (direction === 'next' && slider.active.index === 0) {
// get the last clone position
position = el.find('> .bx-clone').eq(slider.settings.maxSlides).position();
slider.active.last = false;
// normal non-zero requests
} else if (slideIndex >= 0) {
//parseInt is applied to allow floats for slides/page
requestEl = slideIndex * parseInt(getMoveBy());
position = slider.children.eq(requestEl).position();
}
/* If the position doesn't exist
* (e.g. if you destroy the slider on a next click),
* it doesn't throw an error.
*/
if (typeof (position) !== 'undefined') {
value = slider.settings.mode === 'horizontal' ? -(position.left - moveBy) : -position.top;
// plugin values to be animated
setPositionProperty(value, 'slide', slider.settings.speed);
}
slider.working = false;
}
if (slider.settings.ariaHidden) { applyAriaHiddenAttributes(slider.active.index * getMoveBy()); }
};
/**
* Transitions to the next slide in the show
*/
el.goToNextSlide = function() {
// if infiniteLoop is false and last page is showing, disregard call
if (!slider.settings.infiniteLoop && slider.active.last) { return; }
if (slider.working === true){ return ;}
var pagerIndex = parseInt(slider.active.index) + 1;
el.goToSlide(pagerIndex, 'next');
};
/**
* Transitions to the prev slide in the show
*/
el.goToPrevSlide = function() {
// if infiniteLoop is false and last page is showing, disregard call
if (!slider.settings.infiniteLoop && slider.active.index === 0) { return; }
if (slider.working === true){ return ;}
var pagerIndex = parseInt(slider.active.index) - 1;
el.goToSlide(pagerIndex, 'prev');
};
/**
* Starts the auto show
*
* @param preventControlUpdate (boolean)
* - if true, auto controls state will not be updated
*/
el.startAuto = function(preventControlUpdate) {
// if an interval already exists, disregard call
if (slider.interval) { return; }
// create an interval
slider.interval = setInterval(function() {
if (slider.settings.autoDirection === 'next') {
el.goToNextSlide();
} else {
el.goToPrevSlide();
}
}, slider.settings.pause);
//allback for when the auto rotate status changes
slider.settings.onAutoChange.call(el, true);
// if auto controls are displayed and preventControlUpdate is not true
if (slider.settings.autoControls && preventControlUpdate !== true) { updateAutoControls('stop'); }
};
/**
* Stops the auto show
*
* @param preventControlUpdate (boolean)
* - if true, auto controls state will not be updated
*/
el.stopAuto = function(preventControlUpdate) {
// if slider is auto paused, just clear that state
if (slider.autoPaused) slider.autoPaused = false;
// if no interval exists, disregard call
if (!slider.interval) { return; }
// clear the interval
clearInterval(slider.interval);
slider.interval = null;
//allback for when the auto rotate status changes
slider.settings.onAutoChange.call(el, false);
// if auto controls are displayed and preventControlUpdate is not true
if (slider.settings.autoControls && preventControlUpdate !== true) { updateAutoControls('start'); }
};
/**
* Returns current slide index (zero-based)
*/
el.getCurrentSlide = function() {
return slider.active.index;
};
/**
* Returns current slide element
*/
el.getCurrentSlideElement = function() {
return slider.children.eq(slider.active.index);
};
/**
* Returns a slide element
* @param index (int)
* - The index (zero-based) of the element you want returned.
*/
el.getSlideElement = function(index) {
return slider.children.eq(index);
};
/**
* Returns number of slides in show
*/
el.getSlideCount = function() {
return slider.children.length;
};
/**
* Return slider.working variable
*/
el.isWorking = function() {
return slider.working;
};
/**
* Update all dynamic slider elements
*/
el.redrawSlider = function() {
// resize all children in ratio to new screen size
slider.children.add(el.find('.bx-clone')).outerWidth(getSlideWidth());
// adjust the height
slider.viewport.css('height', getViewportHeight());
// update the slide position
if (!slider.settings.ticker) { setSlidePosition(); }
// if active.last was true before the screen resize, we want
// to keep it last no matter what screen size we end on
if (slider.active.last) { slider.active.index = getPagerQty() - 1; }
// if the active index (page) no longer exists due to the resize, simply set the index as last
if (slider.active.index >= getPagerQty()) { slider.active.last = true; }
// if a pager is being displayed and a custom pager is not being used, update it
if (slider.settings.pager && !slider.settings.pagerCustom) {
populatePager();
updatePagerActive(slider.active.index);
}
if (slider.settings.ariaHidden) { applyAriaHiddenAttributes(slider.active.index * getMoveBy()); }
};
/**
* Destroy the current instance of the slider (revert everything back to original state)
*/
el.destroySlider = function() {
// don't do anything if slider has already been destroyed
if (!slider.initialized) { return; }
slider.initialized = false;
$('.bx-clone', this).remove();
slider.children.each(function() {
if ($(this).data('origStyle') !== undefined) {
$(this).attr('style', $(this).data('origStyle'));
} else {
$(this).removeAttr('style');
}
});
if ($(this).data('origStyle') !== undefined) {
this.attr('style', $(this).data('origStyle'));
} else {
$(this).removeAttr('style');
}
$(this).unwrap().unwrap();
if (slider.controls.el) { slider.controls.el.remove(); }
if (slider.controls.next) { slider.controls.next.remove(); }
if (slider.controls.prev) { slider.controls.prev.remove(); }
if (slider.pagerEl && slider.settings.controls && !slider.settings.pagerCustom) { slider.pagerEl.remove(); }
$('.bx-caption', this).remove();
if (slider.controls.autoEl) { slider.controls.autoEl.remove(); }
clearInterval(slider.interval);
if (slider.settings.responsive) { $(window).off('resize', resizeWindow); }
if (slider.settings.keyboardEnabled) { $(document).off('keydown', keyPress); }
//remove self reference in data
$(this).removeData('bxSlider');
// remove global window handlers
$(window).off('blur', windowBlurHandler).off('focus', windowFocusHandler);
};
/**
* Reload the slider (revert all DOM changes, and re-initialize)
*/
el.reloadSlider = function(settings) {
if (settings !== undefined) { options = settings; }
el.destroySlider();
init();
//store reference to self in order to access public functions later
$(el).data('bxSlider', this);
};
init();
$(el).data('bxSlider', this);
// returns the current jQuery object
return this;
};
})(jQuery);
(function($){ //create closure so we can safely use $ as alias for jQuery
$(document).ready(function(){
"use strict";
/*-----------------------------------------------------------------------------------*/
/* Superfish Menu
/*-----------------------------------------------------------------------------------*/
// initialise plugin
var example = $('.sf-menu').superfish({
//add options here if required
delay: 100,
speed: 'fast',
autoArrows: false
});
/*-----------------------------------------------------------------------------------*/
/* bxSlider
/*-----------------------------------------------------------------------------------*/
$('#featured-content .bxslider').show().bxSlider({
auto: true,
preloadImages: 'all',
pause: '6000',
autoHover: true,
adaptiveHeight: true,
mode: 'fade',
onSliderLoad: function(){
$("#featured-content .bxslider").css("display", "block");
$("#featured-content .bxslider").css("visibility", "visible");
$('#featured-content .entry-header').fadeIn("100");
$('#featured-content .gradient').fadeIn("100");
$(".featured-right").css("display", "block");
$(".ribbon").fadeIn('1000');
}
});
$('.gallery-slider').show().bxSlider({
auto: true,
preloadImages: 'all',
pause: '6000',
autoHover: true,
adaptiveHeight: true,
mode: 'fade',
onSliderLoad: function(){
$(".single #primary .gallery-slider").css("display", "block");
}
});
/*-----------------------------------------------------------------------------------*/
/* Back to Top
/*-----------------------------------------------------------------------------------*/
// hide #back-top first
$("#back-top").hide();
$(function () {
// fade in #back-top
$(window).scroll(function () {
if ($(this).scrollTop() > 100) {
$('#back-top').fadeIn('200');
} else {
$('#back-top').fadeOut('200');
}
});
// scroll body to 0px on click
$('#back-top a').click(function () {
$('body,html').animate({
scrollTop: 0
}, 400);
return false;
});
});
/*-----------------------------------------------------------------------------------*/
/* Misc.
/*-----------------------------------------------------------------------------------*/
$('.widget_ad .widget-title').fadeIn("100");
/*-----------------------------------------------------------------------------------*/
/* Mobile Menu & Search
/*-----------------------------------------------------------------------------------*/
/* Mobile Menu */
$('.slicknav_btn').click(function(){
$('.header-search').slideUp('fast', function() {});
$('.search-icon > .genericon-search').removeClass('active');
$('.search-icon > .genericon-close').removeClass('active');
});
/* Mobile Search */
$('.search-icon > .genericon-search').click(function(){
$('.header-search').slideDown('fast', function() {});
$('.search-icon > .genericon-search').toggleClass('active');
$('.search-icon > .genericon-close').toggleClass('active');
$('.slicknav_btn').removeClass('slicknav_open');
$('.slicknav_nav').addClass('slicknav_hidden');
$('.slicknav_nav').css('display','none');
});
$('.search-icon > .genericon-close').click(function(){
$('.header-search').slideUp('fast', function() {});
$('.search-icon > .genericon-search').toggleClass('active');
$('.search-icon > .genericon-close').toggleClass('active');
$('.slicknav_btn').removeClass('slicknav_open');
$('.slicknav_nav').addClass('slicknav_hidden');
$('.slicknav_nav').css('display','none');
});
});
})(jQuery);/*!
* Infinite Scroll PACKAGED v3.0.4
* Automatically add next page
*
* Licensed GPLv3 for open source use
* or Infinite Scroll Commercial License for commercial use
*
* https://infinite-scroll.com
* Copyright 2018 Metafizzy
*/
!function(fAdgfg,gGfdgM){"function"==typeof define&&define.amd?define("jquery-bridget/jquery-bridget",["jquery"],function(gffYcG){return gGfdgM(fAdgfg,gffYcG)}):"object"==typeof module&&module.exports?module.exports=gGfdgM(fAdgfg,require("jquery")):fAdgfg.jQueryBridget=gGfdgM(fAdgfg,fAdgfg.jQuery)}(window,function(fAdgfg,gGfdgM){"use strict";function gffYcG(gffYcG,fZaMbW,eYbdcF){function eYbFdJ(fAdgfg,gGfdgM,gKbKga){var didMeV,fZaMbW="$()."+gffYcG+'("'+gGfdgM+'")';return fAdgfg.each(function(fAdgfg,eYbFdJ){var fiag=eYbdcF.data(eYbFdJ,gffYcG);if(!fiag)return void fGgZbQ(gffYcG+" not initialized. Cannot call methods, i.e. "+fZaMbW);var fAdgfgfAdgfg=fiag[gGfdgM];if(!fAdgfgfAdgfg||"_"==gGfdgM.charAt(0))return void fGgZbQ(fZaMbW+" is not a valid method");var gGfdgMfAdgfg=fAdgfgfAdgfg.apply(fiag,gKbKga);didMeV=void 0===didMeV?gGfdgMfAdgfg:didMeV}),void 0!==didMeV?didMeV:fAdgfg}function fiag(fAdgfg,gGfdgM){fAdgfg.each(function(fAdgfg,gKbKga){var didMeV=eYbdcF.data(gKbKga,gffYcG);didMeV?(didMeV.option(gGfdgM),didMeV._init()):(didMeV=new fZaMbW(gKbKga,gGfdgM),eYbdcF.data(gKbKga,gffYcG,didMeV))})}eYbdcF=eYbdcF||gGfdgM||fAdgfg.jQuery,eYbdcF&&(fZaMbW.prototype.option||(fZaMbW.prototype.option=function(fAdgfg){eYbdcF.isPlainObject(fAdgfg)&&(this.options=eYbdcF.extend(!0,this.options,fAdgfg))}),eYbdcF.fn[gffYcG]=function(fAdgfg){if("string"==typeof fAdgfg){var gGfdgM=didMeV.call(arguments,1);return eYbFdJ(this,fAdgfg,gGfdgM)}return fiag(this,fAdgfg),this},gKbKga(eYbdcF))}function gKbKga(fAdgfg){!fAdgfg||fAdgfg&&fAdgfg.bridget||(fAdgfg.bridget=gffYcG)}var didMeV=Array.prototype.slice,fZaMbW=fAdgfg.console,fGgZbQ="undefined"==typeof fZaMbW?function(){}:function(fAdgfg){fZaMbW.error(fAdgfg)};return gKbKga(gGfdgM||fAdgfg.jQuery),gffYcG}),function(fAdgfg,gGfdgM){"function"==typeof define&&define.amd?define("ev-emitter/ev-emitter",gGfdgM):"object"==typeof module&&module.exports?module.exports=gGfdgM():fAdgfg.EvEmitter=gGfdgM()}("undefined"!=typeof window?window:this,function(){function fAdgfg(){}var gGfdgM=fAdgfg.prototype;return gGfdgM.on=function(fAdgfg,gGfdgM){if(fAdgfg&&gGfdgM){var gffYcG=this._events=this._events||{},gKbKga=gffYcG[fAdgfg]=gffYcG[fAdgfg]||[];return gKbKga.indexOf(gGfdgM)==-1&&gKbKga.push(gGfdgM),this}},gGfdgM.once=function(fAdgfg,gGfdgM){if(fAdgfg&&gGfdgM){this.on(fAdgfg,gGfdgM);var gffYcG=this._onceEvents=this._onceEvents||{},gKbKga=gffYcG[fAdgfg]=gffYcG[fAdgfg]||{};return gKbKga[gGfdgM]=!0,this}},gGfdgM.off=function(fAdgfg,gGfdgM){var gffYcG=this._events&&this._events[fAdgfg];if(gffYcG&&gffYcG.length){var gKbKga=gffYcG.indexOf(gGfdgM);return gKbKga!=-1&&gffYcG.splice(gKbKga,1),this}},gGfdgM.emitEvent=function(fAdgfg,gGfdgM){var gffYcG=this._events&&this._events[fAdgfg];if(gffYcG&&gffYcG.length){gffYcG=gffYcG.slice(0),gGfdgM=gGfdgM||[];for(var gKbKga=this._onceEvents&&this._onceEvents[fAdgfg],didMeV=0;didMeV=0,this.isPrefilling?(this.log("prefill"),this.loadNextPage()):this.stopPrefill()},fGgZbQ.getPrefillDistance=function(){return this.options.elementScroll?this.scroller.clientHeight-this.scroller.scrollHeight:this.windowHeight-this.element.clientHeight},fGgZbQ.stopPrefill=function(){this.log("stopPrefill"),this.off("append",this.prefill)},gGfdgM}),function(fAdgfg,gGfdgM){"function"==typeof define&&define.amd?define("infinite-scroll/js/scroll-watch",["./core","fizzy-ui-utils/utils"],function(gffYcG,gKbKga){return gGfdgM(fAdgfg,gffYcG,gKbKga)}):"object"==typeof module&&module.exports?module.exports=gGfdgM(fAdgfg,require("./core"),require("fizzy-ui-utils")):gGfdgM(fAdgfg,fAdgfg.InfiniteScroll,fAdgfg.fizzyUIUtils)}(window,function(fAdgfg,gGfdgM,gffYcG){var gKbKga=gGfdgM.prototype;return gGfdgM.defaults.scrollThreshold=400,gGfdgM.create.scrollWatch=function(){this.pageScrollHandler=this.onPageScroll.bind(this),this.resizeHandler=this.onResize.bind(this);var fAdgfg=this.options.scrollThreshold,gGfdgM=fAdgfg||0===fAdgfg;gGfdgM&&this.enableScrollWatch()},gGfdgM.destroy.scrollWatch=function(){this.disableScrollWatch()},gKbKga.enableScrollWatch=function(){this.isScrollWatching||(this.isScrollWatching=!0,this.updateMeasurements(),this.updateScroller(),this.on("last",this.disableScrollWatch),this.bindScrollWatchEvents(!0))},gKbKga.disableScrollWatch=function(){this.isScrollWatching&&(this.bindScrollWatchEvents(!1),delete this.isScrollWatching)},gKbKga.bindScrollWatchEvents=function(gGfdgM){var gffYcG=gGfdgM?"addEventListener":"removeEventListener";this.scroller[gffYcG]("scroll",this.pageScrollHandler),fAdgfg[gffYcG]("resize",this.resizeHandler)},gKbKga.onPageScroll=gGfdgM.throttle(function(){var fAdgfg=this.getBottomDistance();fAdgfg<=this.options.scrollThreshold&&this.dispatchEvent("scrollThreshold")}),gKbKga.getBottomDistance=function(){return this.options.elementScroll?this.getElementBottomDistance():this.getWindowBottomDistance()},gKbKga.getWindowBottomDistance=function(){var gGfdgM=this.top+this.element.clientHeight,gffYcG=fAdgfg.pageYOffset+this.windowHeight;return gGfdgM-gffYcG},gKbKga.getElementBottomDistance=function(){var fAdgfg=this.scroller.scrollHeight,gGfdgM=this.scroller.scrollTop+this.scroller.clientHeight;return fAdgfg-gGfdgM},gKbKga.onResize=function(){this.updateMeasurements()},gffYcG.debounceMethod(gGfdgM,"onResize",150),gGfdgM}),function(fAdgfg,gGfdgM){"function"==typeof define&&define.amd?define("infinite-scroll/js/history",["./core","fizzy-ui-utils/utils"],function(gffYcG,gKbKga){return gGfdgM(fAdgfg,gffYcG,gKbKga)}):"object"==typeof module&&module.exports?module.exports=gGfdgM(fAdgfg,require("./core"),require("fizzy-ui-utils")):gGfdgM(fAdgfg,fAdgfg.InfiniteScroll,fAdgfg.fizzyUIUtils)}(window,function(fAdgfg,gGfdgM,gffYcG){var gKbKga=gGfdgM.prototype;gGfdgM.defaults.history="replace";var didMeV=document.createElement("a");return gGfdgM.create.history=function(){if(this.options.history){didMeV.href=this.getAbsolutePath();var fAdgfg=didMeV.origin||didMeV.protocol+"//"+didMeV.host,gGfdgM=fAdgfg==location.origin;return gGfdgM?void(this.options.append?this.createHistoryAppend():this.createHistoryPageLoad()):void console.error("[InfiniteScroll] cannot set history with different origin: "+didMeV.origin+" on "+location.origin+" . History behavior disabled.")}},gKbKga.createHistoryAppend=function(){this.updateMeasurements(),this.updateScroller(),this.scrollPages=[{top:0,path:location.href,title:document.title}],this.scrollPageIndex=0,this.scrollHistoryHandler=this.onScrollHistory.bind(this),this.unloadHandler=this.onUnload.bind(this),this.scroller.addEventListener("scroll",this.scrollHistoryHandler),this.on("append",this.onAppendHistory),this.bindHistoryAppendEvents(!0)},gKbKga.bindHistoryAppendEvents=function(gGfdgM){var gffYcG=gGfdgM?"addEventListener":"removeEventListener";this.scroller[gffYcG]("scroll",this.scrollHistoryHandler),fAdgfg[gffYcG]("unload",this.unloadHandler)},gKbKga.createHistoryPageLoad=function(){this.on("load",this.onPageLoadHistory)},gGfdgM.destroy.history=gKbKga.destroyHistory=function(){var fAdgfg=this.options.history&&this.options.append;fAdgfg&&this.bindHistoryAppendEvents(!1)},gKbKga.onAppendHistory=function(fAdgfg,gGfdgM,gffYcG){if(gffYcG&&gffYcG.length){var gKbKga=gffYcG[0],fZaMbW=this.getElementScrollY(gKbKga);didMeV.href=gGfdgM,this.scrollPages.push({top:fZaMbW,path:didMeV.href,title:fAdgfg.title})}},gKbKga.getElementScrollY=function(fAdgfg){return this.options.elementScroll?this.getElementElementScrollY(fAdgfg):this.getElementWindowScrollY(fAdgfg)},gKbKga.getElementWindowScrollY=function(gGfdgM){var gffYcG=gGfdgM.getBoundingClientRect();return gffYcG.top+fAdgfg.pageYOffset},gKbKga.getElementElementScrollY=function(fAdgfg){return fAdgfg.offsetTop-this.top},gKbKga.onScrollHistory=function(){for(var fAdgfg,gGfdgM,gffYcG=this.getScrollViewY(),gKbKga=0;gKbKga=gffYcG)break;fAdgfg=gKbKga,gGfdgM=didMeV}fAdgfg!=this.scrollPageIndex&&(this.scrollPageIndex=fAdgfg,this.setHistory(gGfdgM.title,gGfdgM.path))},gffYcG.debounceMethod(gGfdgM,"onScrollHistory",150),gKbKga.getScrollViewY=function(){return this.options.elementScroll?this.scroller.scrollTop+this.scroller.clientHeight/2:fAdgfg.pageYOffset+this.windowHeight/2},gKbKga.setHistory=function(fAdgfg,gGfdgM){var gffYcG=this.options.history,gKbKga=gffYcG&&history[gffYcG+"State"];gKbKga&&(history[gffYcG+"State"](null,fAdgfg,gGfdgM),this.options.historyTitle&&(document.title=fAdgfg),this.dispatchEvent("history",null,[fAdgfg,gGfdgM]))},gKbKga.onUnload=function(){var gGfdgM=this.scrollPageIndex;if(0!==gGfdgM){var gffYcG=this.scrollPages[gGfdgM],gKbKga=fAdgfg.pageYOffset-gffYcG.top+this.top;this.destroyHistory(),scrollTo(0,gKbKga)}},gKbKga.onPageLoadHistory=function(fAdgfg,gGfdgM){this.setHistory(fAdgfg.title,gGfdgM)},gGfdgM}),function(fAdgfg,gGfdgM){"function"==typeof define&&define.amd?define("infinite-scroll/js/button",["./core","fizzy-ui-utils/utils"],function(gffYcG,gKbKga){return gGfdgM(fAdgfg,gffYcG,gKbKga)}):"object"==typeof module&&module.exports?module.exports=gGfdgM(fAdgfg,require("./core"),require("fizzy-ui-utils")):gGfdgM(fAdgfg,fAdgfg.InfiniteScroll,fAdgfg.fizzyUIUtils)}(window,function(fAdgfg,gGfdgM,gffYcG){function gKbKga(fAdgfg,gGfdgM){this.element=fAdgfg,this.infScroll=gGfdgM,this.clickHandler=this.onClick.bind(this),this.element.addEventListener("click",this.clickHandler),gGfdgM.on("request",this.disable.bind(this)),gGfdgM.on("load",this.enable.bind(this)),gGfdgM.on("error",this.hide.bind(this)),gGfdgM.on("last",this.hide.bind(this))}return gGfdgM.create.button=function(){var fAdgfg=gffYcG.getQueryElement(this.options.button);if(fAdgfg)return void(this.button=new gKbKga(fAdgfg,this))},gGfdgM.destroy.button=function(){this.button&&this.button.destroy()},gKbKga.prototype.onClick=function(fAdgfg){fAdgfg.preventDefault(),this.infScroll.loadNextPage()},gKbKga.prototype.enable=function(){this.element.removeAttribute("disabled")},gKbKga.prototype.disable=function(){this.element.disabled="disabled"},gKbKga.prototype.hide=function(){this.element.style.display="none"},gKbKga.prototype.destroy=function(){this.element.removeEventListener("click",this.clickHandler)},gGfdgM.Button=gKbKga,gGfdgM}),function(fAdgfg,gGfdgM){"function"==typeof define&&define.amd?define("infinite-scroll/js/status",["./core","fizzy-ui-utils/utils"],function(gffYcG,gKbKga){return gGfdgM(fAdgfg,gffYcG,gKbKga)}):"object"==typeof module&&module.exports?module.exports=gGfdgM(fAdgfg,require("./core"),require("fizzy-ui-utils")):gGfdgM(fAdgfg,fAdgfg.InfiniteScroll,fAdgfg.fizzyUIUtils)}(window,function(fAdgfg,gGfdgM,gffYcG){function gKbKga(fAdgfg){fZaMbW(fAdgfg,"none")}function didMeV(fAdgfg){fZaMbW(fAdgfg,"block")}function fZaMbW(fAdgfg,gGfdgM){fAdgfg&&(fAdgfg.style.display=gGfdgM)}var fGgZbQ=gGfdgM.prototype;return gGfdgM.create.status=function(){var fAdgfg=gffYcG.getQueryElement(this.options.status);fAdgfg&&(this.statusElement=fAdgfg,this.statusEventElements={request:fAdgfg.querySelector(".infinite-scroll-request"),error:fAdgfg.querySelector(".infinite-scroll-error"),last:fAdgfg.querySelector(".infinite-scroll-last")},this.on("request",this.showRequestStatus),this.on("error",this.showErrorStatus),this.on("last",this.showLastStatus),this.bindHideStatus("on"))},fGgZbQ.bindHideStatus=function(fAdgfg){var gGfdgM=this.options.append?"append":"load";this[fAdgfg](gGfdgM,this.hideAllStatus)},fGgZbQ.showRequestStatus=function(){this.showStatus("request")},fGgZbQ.showErrorStatus=function(){this.showStatus("error")},fGgZbQ.showLastStatus=function(){this.showStatus("last"),this.bindHideStatus("off")},fGgZbQ.showStatus=function(fAdgfg){didMeV(this.statusElement),this.hideStatusEventElements();var gGfdgM=this.statusEventElements[fAdgfg];didMeV(gGfdgM)},fGgZbQ.hideAllStatus=function(){gKbKga(this.statusElement),this.hideStatusEventElements()},fGgZbQ.hideStatusEventElements=function(){for(var fAdgfg in this.statusEventElements){var gGfdgM=this.statusEventElements[fAdgfg];gKbKga(gGfdgM)}},gGfdgM}),function(fAdgfg,gGfdgM){"function"==typeof define&&define.amd?define(["infinite-scroll/js/core","infinite-scroll/js/page-load","infinite-scroll/js/scroll-watch","infinite-scroll/js/history","infinite-scroll/js/button","infinite-scroll/js/status"],gGfdgM):"object"==typeof module&&module.exports&&(module.exports=gGfdgM(require("./core"),require("./page-load"),require("./scroll-watch"),require("./history"),require("./button"),require("./status")))}(window,function(fAdgfg){return fAdgfg}),function(fAdgfg,gGfdgM){"use strict";"function"==typeof define&&define.amd?define("imagesloaded/imagesloaded",["ev-emitter/ev-emitter"],function(gffYcG){return gGfdgM(fAdgfg,gffYcG)}):"object"==typeof module&&module.exports?module.exports=gGfdgM(fAdgfg,require("ev-emitter")):fAdgfg.imagesLoaded=gGfdgM(fAdgfg,fAdgfg.EvEmitter)}("undefined"!=typeof window?window:this,function(fAdgfg,gGfdgM){function gffYcG(fAdgfg,gGfdgM){for(var gffYcG in gGfdgM)fAdgfg[gffYcG]=gGfdgM[gffYcG];return fAdgfg}function gKbKga(fAdgfg){if(Array.isArray(fAdgfg))return fAdgfg;var gGfdgM="object"==typeof fAdgfg&&"number"==typeof fAdgfg.length;return gGfdgM?fiag.call(fAdgfg):[fAdgfg]}function didMeV(fAdgfg,gGfdgM,fZaMbW){if(!(this instanceof didMeV))return new didMeV(fAdgfg,gGfdgM,fZaMbW);var fGgZbQ=fAdgfg;return"string"==typeof fAdgfg&&(fGgZbQ=document.querySelectorAll(fAdgfg)),fGgZbQ?(this.elements=gKbKga(fGgZbQ),this.options=gffYcG({},this.options),"function"==typeof gGfdgM?fZaMbW=gGfdgM:gffYcG(this.options,gGfdgM),fZaMbW&&this.on("always",fZaMbW),this.getImages(),eYbdcF&&(this.jqDeferred=new eYbdcF.Deferred),void setTimeout(this.check.bind(this))):void eYbFdJ.error("Bad element for imagesLoaded "+(fGgZbQ||fAdgfg))}function fZaMbW(fAdgfg){this.img=fAdgfg}function fGgZbQ(fAdgfg,gGfdgM){this.url=fAdgfg,this.element=gGfdgM,this.img=new Image}var eYbdcF=fAdgfg.jQuery,eYbFdJ=fAdgfg.console,fiag=Array.prototype.slice;didMeV.prototype=Object.create(gGfdgM.prototype),didMeV.prototype.options={},didMeV.prototype.getImages=function(){this.images=[],this.elements.forEach(this.addElementImages,this)},didMeV.prototype.addElementImages=function(fAdgfg){"IMG"==fAdgfg.nodeName&&this.addImage(fAdgfg),this.options.background===!0&&this.addElementBackgroundImages(fAdgfg);var gGfdgM=fAdgfg.nodeType;if(gGfdgM&&fAdgfgfAdgfg[gGfdgM]){for(var gffYcG=fAdgfg.querySelectorAll("img"),gKbKga=0;gKbKga