text: var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
  
  var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
  
  (function (global, factory) {
  	(typeof exports === 'undefined' ? 'undefined' : _typeof(exports)) === 'object' && typeof module !== 'undefined' ? module.exports = factory() : typeof define === 'function' && define.amd ? define(factory) : global.LazyLoad = factory();
  })(this, function () {
  	'use strict';
  
  	var defaultSettings = {
  		elements_selector: "img",
  		container: window,
  		threshold: 300,
  		throttle: 150,
  		data_src: "original",
  		data_srcset: "originalSet",
  		class_loading: "loading",
  		class_loaded: "loaded",
  		class_error: "error",
  		class_initial: "initial",
  		skip_invisible: true,
  		callback_load: null,
  		callback_error: null,
  		callback_set: null,
  		callback_processed: null
  	};
  
  	var isBot = !("onscroll" in window) || /glebot/.test(navigator.userAgent);
  
  	var callCallback = function callCallback(callback, argument) {
  		if (callback) {
  			callback(argument);
  		}
  	};
  
  	var getTopOffset = function getTopOffset(element) {
  		return element.getBoundingClientRect().top + window.pageYOffset - element.ownerDocument.documentElement.clientTop;
  	};
  
  	var isBelowViewport = function isBelowViewport(element, container, threshold) {
  		var fold = container === window ? window.innerHeight + window.pageYOffset : getTopOffset(container) + container.offsetHeight;
  		return fold <= getTopOffset(element) - threshold;
  	};
  
  	var getLeftOffset = function getLeftOffset(element) {
  		return element.getBoundingClientRect().left + window.pageXOffset - element.ownerDocument.documentElement.clientLeft;
  	};
  
  	var isAtRightOfViewport = function isAtRightOfViewport(element, container, threshold) {
  		var documentWidth = window.innerWidth;
  		var fold = container === window ? documentWidth + window.pageXOffset : getLeftOffset(container) + documentWidth;
  		return fold <= getLeftOffset(element) - threshold;
  	};
  
  	var isAboveViewport = function isAboveViewport(element, container, threshold) {
  		var fold = container === window ? window.pageYOffset : getTopOffset(container);
  		return fold >= getTopOffset(element) + threshold + element.offsetHeight;
  	};
  
  	var isAtLeftOfViewport = function isAtLeftOfViewport(element, container, threshold) {
  		var fold = container === window ? window.pageXOffset : getLeftOffset(container);
  		return fold >= getLeftOffset(element) + threshold + element.offsetWidth;
  	};
  
  	var isInsideViewport = function isInsideViewport(element, container, threshold) {
  		return !isBelowViewport(element, container, threshold) && !isAboveViewport(element, container, threshold) && !isAtRightOfViewport(element, container, threshold) && !isAtLeftOfViewport(element, container, threshold);
  	};
  
  	/* Creates instance and notifies it through the window element */
  	var createInstance = function createInstance(classObj, options) {
  		var instance = new classObj(options);
  		var event = new CustomEvent("LazyLoad::Initialized", { detail: { instance: instance } });
  		window.dispatchEvent(event);
  	};
  
  	/* Auto initialization of one or more instances of lazyload, depending on the 
  		options passed in (plain object or an array) */
  	var autoInitialize = function autoInitialize(classObj, options) {
  		var optsLength = options.length;
  		if (!optsLength) {
  			// Plain object
  			createInstance(classObj, options);
  		} else {
  			// Array of objects
  			for (var i = 0; i < optsLength; i++) {
  				createInstance(classObj, options[i]);
  			}
  		}
  	};
  
  	var setSourcesForPicture = function setSourcesForPicture(element, srcsetDataAttribute) {
  		var parent = element.parentElement;
  		if (parent.tagName !== "PICTURE") {
  			return;
  		}
  		for (var i = 0; i < parent.children.length; i++) {
  			var pictureChild = parent.children[i];
  			if (pictureChild.tagName === "SOURCE") {
  				var sourceSrcset = getData(pictureChild, srcsetDataAttribute);
  				if (sourceSrcset) {
  					pictureChild.setAttribute("srcset", sourceSrcset);
  				}
  			}
  		}
  	};
  
  	var setSources = function setSources(element, srcsetDataAttribute, srcDataAttribute) {
  		var tagName = element.tagName;
  		var elementSrc = getData(element, srcDataAttribute);
  		if (tagName === "IMG") {
  			setSourcesForPicture(element, srcsetDataAttribute);
  			var imgSrcset = getData(element, srcsetDataAttribute);
  			if (imgSrcset) {
  				element.setAttribute("srcset", imgSrcset);
  			}
  			if (elementSrc) {
  				element.setAttribute("src", elementSrc);
  			}
  			return;
  		}
  		if (tagName === "IFRAME") {
  			if (elementSrc) {
  				element.setAttribute("src", elementSrc);
  			}
  			return;
  		}
  		if (elementSrc) {
  			element.style.backgroundImage = 'url("' + elementSrc + '")';
  		}
  	};
  
  	function setData(element, key, value) {
  		window.jQuery ? $(element).data(key, value) : element.dataset[key] = value;
  	}
  
  	function getData(element, key) {
  		return window.jQuery ? $(element).data(key) : element.dataset[key];
  	}
  
  	function removeClass(element, className) {
  		window.jQuery ? $(element).removeClass(className) : element.classList.remove(className);
  	}
  
  	function addClass(element, className) {
  		window.jQuery ? $(element).addClass(className) : element.classList.add(className);
  	}
  
  	/*
  	* Constructor
  	*/
  
  	var LazyLoad = function LazyLoad(instanceSettings) {
  		this._settings = _extends({}, defaultSettings, instanceSettings);
  		this._queryOriginNode = this._settings.container === window ? document : this._settings.container;
  
  		this._previousLoopTime = 0;
  		this._loopTimeout = null;
  		this._boundHandleScroll = this.handleScroll.bind(this);
  
  		this._isFirstLoop = true;
  		window.addEventListener("resize", this._boundHandleScroll);
  		this.update();
  	};
  
  	LazyLoad.prototype = {
  
  		/*
  		* Private methods
  		*/
  
  		_reveal: function _reveal(element) {
  			var settings = this._settings;
  
  			var errorCallback = function errorCallback() {
  				/* As this method is asynchronous, it must be protected against external destroy() calls */
  				if (!settings) {
  					return;
  				}
  				element.removeEventListener("load", loadCallback);
  				element.removeEventListener("error", errorCallback);
  				removeClass(element, settings.class_loading);
  				addClass(element, settings.class_error);
  				callCallback(settings.callback_error, element);
  			};
  
  			var loadCallback = function loadCallback() {
  				/* As this method is asynchronous, it must be protected against external destroy() calls */
  				if (!settings) {
  					return;
  				}
  				removeClass(element, settings.class_loading);
  				addClass(element, settings.class_loaded);
  				element.removeEventListener("load", loadCallback);
  				element.removeEventListener("error", errorCallback);
  				/* Calling LOAD callback */
  				callCallback(settings.callback_load, element);
  			};
  
  			if (element.tagName === "IMG" || element.tagName === "IFRAME") {
  				element.addEventListener("load", loadCallback);
  				element.addEventListener("error", errorCallback);
  				addClass(element, settings.class_loading);
  			}
  
  			setSources(element, settings.data_srcset, settings.data_src);
  			/* Calling SET callback */
  			callCallback(settings.callback_set, element);
  		},
  
  		_loopThroughElements: function _loopThroughElements() {
  			var settings = this._settings,
  				elements = this._elements,
  				elementsLength = !elements ? 0 : elements.length;
  			var i = void 0,
  				processedIndexes = [],
  				firstLoop = this._isFirstLoop;
  
  			for (i = 0; i < elementsLength; i++) {
  				var element = elements[i];
  				/* If must skip_invisible and element is invisible, skip it */
  				if (settings.skip_invisible && element.offsetParent === null) {
  					continue;
  				}
  
  				if (isBot || isInsideViewport(element, settings.container, settings.threshold)) {
  					if (firstLoop) {
  						addClass(element, settings.class_initial);
  					}
  					/* Start loading the image */
  					this._reveal(element);
  					/* Marking the element as processed. */
  					processedIndexes.push(i);
  					setData(element, 'wasProcessed', true);
  				}
  			}
  			/* Removing processed elements from this._elements. */
  			while (processedIndexes.length) {
  				elements.splice(processedIndexes.pop(), 1);
  				/* Calling the end loop callback */
  				callCallback(settings.callback_processed, elements.length);
  			}
  			/* Stop listening to scroll event when 0 elements remains */
  			if (elementsLength === 0) {
  				this._stopScrollHandler();
  			}
  			/* Sets isFirstLoop to false */
  			if (firstLoop) {
  				this._isFirstLoop = false;
  			}
  		},
  
  		_purgeElements: function _purgeElements() {
  			var elements = this._elements,
  				elementsLength = elements.length;
  			var i = void 0,
  				elementsToPurge = [];
  
  			for (i = 0; i < elementsLength; i++) {
  				var element = elements[i];
  				/* If the element has already been processed, skip it */
  				if (getData(element, 'wasProcessed')) {
  					elementsToPurge.push(i);
  				}
  			}
  			/* Removing elements to purge from this._elements. */
  			while (elementsToPurge.length > 0) {
  				elements.splice(elementsToPurge.pop(), 1);
  			}
  		},
  
  		_startScrollHandler: function _startScrollHandler() {
  			if (!this._isHandlingScroll) {
  				this._isHandlingScroll = true;
  				this._settings.container.addEventListener("scroll", this._boundHandleScroll);
  			}
  		},
  
  		_stopScrollHandler: function _stopScrollHandler() {
  			if (this._isHandlingScroll) {
  				this._isHandlingScroll = false;
  				this._settings.container.removeEventListener("scroll", this._boundHandleScroll);
  			}
  		},
  
  		/* 
  		* Public methods
  		*/
  
  		handleScroll: function handleScroll() {
  			var throttle = this._settings.throttle;
  
  			if (throttle !== 0) {
  				var now = Date.now();
  				var remainingTime = throttle - (now - this._previousLoopTime);
  				if (remainingTime <= 0 || remainingTime > throttle) {
  					if (this._loopTimeout) {
  						clearTimeout(this._loopTimeout);
  						this._loopTimeout = null;
  					}
  					this._previousLoopTime = now;
  					this._loopThroughElements();
  				} else if (!this._loopTimeout) {
  					this._loopTimeout = setTimeout(function () {
  						this._previousLoopTime = Date.now();
  						this._loopTimeout = null;
  						this._loopThroughElements();
  					}.bind(this), remainingTime);
  				}
  			} else {
  				this._loopThroughElements();
  			}
  		},
  
  		update: function update() {
  			// Converts to array the nodeset obtained querying the DOM from _queryOriginNode with elements_selector
  			this._elements = Array.prototype.slice.call(this._queryOriginNode.querySelectorAll(this._settings.elements_selector));
  			this._purgeElements();
  			this._loopThroughElements();
  			this._startScrollHandler();
  		},
  
  		destroy: function destroy() {
  			window.removeEventListener("resize", this._boundHandleScroll);
  			if (this._loopTimeout) {
  				clearTimeout(this._loopTimeout);
  				this._loopTimeout = null;
  			}
  			this._stopScrollHandler();
  			this._elements = null;
  			this._queryOriginNode = null;
  			this._settings = null;
  		}
  	};
  
  	/* Automatic instances creation if required (useful for async script loading!) */
  	var autoInitOptions = window.lazyLoadOptions;
  	if (autoInitOptions) {
  		autoInitialize(LazyLoad, autoInitOptions);
  	}
  
  	return LazyLoad;
  });