// source --> https://kasunlondon.com/wp-content/plugins/productsize-chart-for-woocommerce/public/js/remodal.js?ver=1.1.0 
/*
 *  Remodal - v1.0.3
 *  Responsive, lightweight, fast, synchronized with CSS animations, fully customizable modal window plugin with declarative configuration and hash tracking.
 *  http://vodkabears.github.io/remodal/
 *
 *  Made by Ilya Makarov
 *  Under MIT License
 */

! (function(root, factory) {
	if (typeof define === 'function' && define.amd) {
		define(
			['jquery'],
			function($) {
				return factory( root, $ );
			}
		);
	} else if (typeof exports === 'object') {
		factory( root, require( 'jquery' ) );
	} else {
		factory( root, root.jQuery || root.Zepto );
	}
})(
	this,
	function(global, $) {

		'use strict';

		/**
		 * Name of the plugin
		 *
		 * @private
		 * @const
		 * @type {String}
		 */
		var PLUGIN_NAME = 'remodal';

		/**
		 * Namespace for CSS and events
		 *
		 * @private
		 * @const
		 * @type {String}
		 */
		var NAMESPACE = global.REMODAL_GLOBALS && global.REMODAL_GLOBALS.NAMESPACE || PLUGIN_NAME;

		/**
		 * Animationstart event with vendor prefixes
		 *
		 * @private
		 * @const
		 * @type {String}
		 */
		var ANIMATIONSTART_EVENTS = $.map(
			['animationstart', 'webkitAnimationStart', 'MSAnimationStart', 'oAnimationStart'],
			function(eventName) {
				return eventName + '.' + NAMESPACE;
			}
		).join( ' ' );

		/**
		 * Animationend event with vendor prefixes
		 *
		 * @private
		 * @const
		 * @type {String}
		 */
		var ANIMATIONEND_EVENTS = $.map(
			['animationend', 'webkitAnimationEnd', 'MSAnimationEnd', 'oAnimationEnd'],
			function(eventName) {
				return eventName + '.' + NAMESPACE;
			}
		).join( ' ' );

		/**
		 * Default settings
		 *
		 * @private
		 * @const
		 * @type {Object}
		 */
		var DEFAULTS = $.extend(
			{
				hashTracking: true,
				closeOnConfirm: true,
				closeOnCancel: true,
				closeOnEscape: true,
				closeOnOutsideClick: true,
				modifier: ''
			},
			global.REMODAL_GLOBALS && global.REMODAL_GLOBALS.DEFAULTS
		);

		/**
		 * States of the Remodal
		 *
		 * @private
		 * @const
		 * @enum {String}
		 */
		var STATES = {
			CLOSING: 'closing',
			CLOSED: 'closed',
			OPENING: 'opening',
			OPENED: 'opened'
		};

		/**
		 * Reasons of the state change.
		 *
		 * @private
		 * @const
		 * @enum {String}
		 */
		var STATE_CHANGE_REASONS = {
			CONFIRMATION: 'confirmation',
			CANCELLATION: 'cancellation'
		};

		/**
		 * Is animation supported?
		 *
		 * @private
		 * @const
		 * @type {Boolean}
		 */
		var IS_ANIMATION = (function() {
			var style = document.createElement( 'div' ).style;

			return style.animationName !== undefined ||
			style.WebkitAnimationName !== undefined ||
			style.MozAnimationName !== undefined ||
			style.msAnimationName !== undefined ||
			style.OAnimationName !== undefined;
		})();

		/**
		 * Current modal
		 *
		 * @private
		 * @type {Remodal}
		 */
		var current;

		/**
		 * Scrollbar position
		 *
		 * @private
		 * @type {Number}
		 */
		var scrollTop;

		/**
		 * Returns an animation duration
		 *
		 * @private
		 * @param {jQuery} $elem
		 * @returns {Number}
		 */
		function getAnimationDuration($elem) {
			if (
			IS_ANIMATION &&
			$elem.css( 'animation-name' ) === 'none' &&
			$elem.css( '-webkit-animation-name' ) === 'none' &&
			$elem.css( '-moz-animation-name' ) === 'none' &&
			$elem.css( '-o-animation-name' ) === 'none' &&
			$elem.css( '-ms-animation-name' ) === 'none'
			) {
				return 0;
			}

			var duration = $elem.css( 'animation-duration' ) ||
			$elem.css( '-webkit-animation-duration' ) ||
			$elem.css( '-moz-animation-duration' ) ||
			$elem.css( '-o-animation-duration' ) ||
			$elem.css( '-ms-animation-duration' ) ||
			'0s';

			var delay = $elem.css( 'animation-delay' ) ||
			$elem.css( '-webkit-animation-delay' ) ||
			$elem.css( '-moz-animation-delay' ) ||
			$elem.css( '-o-animation-delay' ) ||
			$elem.css( '-ms-animation-delay' ) ||
			'0s';

			var iterationCount = $elem.css( 'animation-iteration-count' ) ||
			$elem.css( '-webkit-animation-iteration-count' ) ||
			$elem.css( '-moz-animation-iteration-count' ) ||
			$elem.css( '-o-animation-iteration-count' ) ||
			$elem.css( '-ms-animation-iteration-count' ) ||
			'1';

			var max;
			var len;
			var num;
			var i;

			duration       = duration.split( ', ' );
			delay          = delay.split( ', ' );
			iterationCount = iterationCount.split( ', ' );

			// The 'duration' size is the same as the 'delay' size
			for (i = 0, len = duration.length, max = Number.NEGATIVE_INFINITY; i < len; i++) {
				num = parseFloat( duration[i] ) * parseInt( iterationCount[i], 10 ) + parseFloat( delay[i] );

				if (num > max) {
					max = num;
				}
			}

			return num;
		}

		/**
		 * Returns a scrollbar width
		 *
		 * @private
		 * @returns {Number}
		 */
		function getScrollbarWidth() {
			if ($( document.body ).height() <= $( window ).height()) {
				return 0;
			}

			var outer = document.createElement( 'div' );
			var inner = document.createElement( 'div' );
			var widthNoScroll;
			var widthWithScroll;

			outer.style.visibility = 'hidden';
			outer.style.width      = '100px';
			document.body.appendChild( outer );

			widthNoScroll = outer.offsetWidth;

			// Force scrollbars
			outer.style.overflow = 'scroll';

			// Add inner div
			inner.style.width = '100%';
			outer.appendChild( inner );

			widthWithScroll = inner.offsetWidth;

			// Remove divs
			outer.parentNode.removeChild( outer );

			return widthNoScroll - widthWithScroll;
		}

		/**
		 * Locks the screen
		 *
		 * @private
		 */
		function lockScreen() {
			var $html       = $( 'html' );
			var lockedClass = namespacify( 'is-locked' );
			var paddingRight;
			var $body;

			if ( ! $html.hasClass( lockedClass )) {
				$body = $( document.body );

				// Zepto does not support '-=', '+=' in the `css` method
				paddingRight = parseInt( $body.css( 'padding-right' ), 10 ) + getScrollbarWidth();

				$body.css( 'padding-right', paddingRight + 'px' );
				$html.addClass( lockedClass );
			}
		}

		/**
		 * Unlocks the screen
		 *
		 * @private
		 */
		function unlockScreen() {
			var $html       = $( 'html' );
			var lockedClass = namespacify( 'is-locked' );
			var paddingRight;
			var $body;

			if ($html.hasClass( lockedClass )) {
				$body = $( document.body );

				// Zepto does not support '-=', '+=' in the `css` method
				paddingRight = parseInt( $body.css( 'padding-right' ), 10 ) - getScrollbarWidth();

				$body.css( 'padding-right', paddingRight + 'px' );
				$html.removeClass( lockedClass );
			}
		}

		/**
		 * Sets a state for an instance
		 *
		 * @private
		 * @param {Remodal} instance
		 * @param {STATES} state
		 * @param {Boolean} isSilent If true, Remodal does not trigger events
		 * @param {String} Reason of a state change.
		 */
		function setState(instance, state, isSilent, reason) {

			var newState  = namespacify( 'is', state );
			var allStates = [namespacify( 'is', STATES.CLOSING ),
					 namespacify( 'is', STATES.OPENING ),
					 namespacify( 'is', STATES.CLOSED ),
					 namespacify( 'is', STATES.OPENED )].join( ' ' );

			instance.$bg
			.removeClass( allStates )
			.addClass( newState );

			instance.$overlay
			.removeClass( allStates )
			.addClass( newState );

			instance.$wrapper
			.removeClass( allStates )
			.addClass( newState );

			instance.$modal
			.removeClass( allStates )
			.addClass( newState );

			instance.state = state;
			! isSilent && instance.$modal.trigger(
				{
					type: state,
					reason: reason
				},
				[{ reason: reason }]
			);
		}

		/**
		 * Synchronizes with the animation
		 *
		 * @param {Function} doBeforeAnimation
		 * @param {Function} doAfterAnimation
		 * @param {Remodal} instance
		 */
		function syncWithAnimation(doBeforeAnimation, doAfterAnimation, instance) {
			var runningAnimationsCount = 0;

			var handleAnimationStart = function(e) {
				if (e.target !== this) {
					return;
				}

				runningAnimationsCount++;
			};

			var handleAnimationEnd = function(e) {
				if (e.target !== this) {
					return;
				}

				if (--runningAnimationsCount === 0) {

					// Remove event listeners
					$.each(
						['$bg', '$overlay', '$wrapper', '$modal'],
						function(index, elemName) {
							instance[elemName].off( ANIMATIONSTART_EVENTS + ' ' + ANIMATIONEND_EVENTS );
						}
					);

					doAfterAnimation();
				}
			};

			$.each(
				['$bg', '$overlay', '$wrapper', '$modal'],
				function(index, elemName) {
					instance[elemName]
					.on( ANIMATIONSTART_EVENTS, handleAnimationStart )
					.on( ANIMATIONEND_EVENTS, handleAnimationEnd );
				}
			);

			doBeforeAnimation();

			// If the animation is not supported by a browser or its duration is 0
			if (
			getAnimationDuration( instance.$bg ) === 0 &&
			getAnimationDuration( instance.$overlay ) === 0 &&
			getAnimationDuration( instance.$wrapper ) === 0 &&
			getAnimationDuration( instance.$modal ) === 0
			) {

				// Remove event listeners
				$.each(
					['$bg', '$overlay', '$wrapper', '$modal'],
					function(index, elemName) {
						instance[elemName].off( ANIMATIONSTART_EVENTS + ' ' + ANIMATIONEND_EVENTS );
					}
				);

				  doAfterAnimation();
			}
		}

		/**
		 * Closes immediately
		 *
		 * @private
		 * @param {Remodal} instance
		 */
		function halt(instance) {
			if (instance.state === STATES.CLOSED) {
				return;
			}

			$.each(
				['$bg', '$overlay', '$wrapper', '$modal'],
				function(index, elemName) {
					instance[elemName].off( ANIMATIONSTART_EVENTS + ' ' + ANIMATIONEND_EVENTS );
				}
			);

			instance.$bg.removeClass( instance.settings.modifier );
			instance.$overlay.removeClass( instance.settings.modifier ).hide();
			instance.$wrapper.hide();
			unlockScreen();
			setState( instance, STATES.CLOSED, true );
		}

		/**
		 * Parses a string with options
		 *
		 * @private
		 * @param str
		 * @returns {Object}
		 */
		function parseOptions(str) {
			var obj = {};
			var arr;
			var len;
			var val;
			var i;

			// Remove spaces before and after delimiters
			str = str.replace( /\s*:\s*/g, ':' ).replace( /\s*,\s*/g, ',' );

			// Parse a string
			arr = str.split( ',' );
			for (i = 0, len = arr.length; i < len; i++) {
				arr[i] = arr[i].split( ':' );
				val    = arr[i][1];

				// Convert a string value if it is like a boolean
				if (typeof val === 'string' || val instanceof String) {
					  val = val === 'true' || (val === 'false' ? false : val);
				}

				// Convert a string value if it is like a number
				if (typeof val === 'string' || val instanceof String) {
					val = ! isNaN( val ) ? +val : val;
				}

				obj[arr[i][0]] = val;
			}

			return obj;
		}

		/**
		 * Generates a string separated by dashes and prefixed with NAMESPACE
		 *
		 * @private
		 * @param {...String}
		 * @returns {String}
		 */
		function namespacify() {
			var result = NAMESPACE;

			for (var i = 0; i < arguments.length; ++i) {
				result += '-' + arguments[i];
			}

			return result;
		}

		/**
		 * Handles the hashchange event
		 *
		 * @private
		 * @listens hashchange
		 */
		function handleHashChangeEvent() {
			var id = location.hash.replace( '#', '' );
			var instance;
			var $elem;

			if ( ! id) {

				// Check if we have currently opened modal and animation was completed
				if (current && current.state === STATES.OPENED && current.settings.hashTracking) {
					  current.close();
				}
			} else {

				// Catch syntax error if your hash is bad
				try {
					$elem = $(
						'[data-' + PLUGIN_NAME + '-id=' +
						id.replace( new RegExp( '/', 'g' ), '\\/' ) + ']'
					);
				} catch (err) {
				}

				if ($elem && $elem.length) {
					instance = $[PLUGIN_NAME].lookup[$elem.data( PLUGIN_NAME )];

					if (instance && instance.settings.hashTracking) {
						instance.open();
					}
				}

			}
		}

		/**
		 * Remodal constructor
		 *
		 * @constructor
		 * @param {jQuery} $modal
		 * @param {Object} options
		 */
		function Remodal($modal, options) {
			var $body   = $( document.body );
			var remodal = this;

			remodal.settings = $.extend( {}, DEFAULTS, options );
			remodal.index    = $[PLUGIN_NAME].lookup.push( remodal ) - 1;
			remodal.state    = STATES.CLOSED;

			remodal.$overlay = $( '.' + namespacify( 'overlay' ) );

			if ( ! remodal.$overlay.length) {
				remodal.$overlay = $( '<div>' ).addClass( namespacify( 'overlay' ) + ' ' + namespacify( 'is', STATES.CLOSED ) ).hide();
				$body.append( remodal.$overlay );
			}

			remodal.$bg = $( '.' + namespacify( 'bg' ) ).addClass( namespacify( 'is', STATES.CLOSED ) );

			remodal.$modal = $modal
			.addClass(
				NAMESPACE + ' ' +
				namespacify( 'is-initialized' ) + ' ' +
				remodal.settings.modifier + ' ' +
				namespacify( 'is', STATES.CLOSED )
			)
			.attr( 'tabindex', '-1' );

			remodal.$wrapper = $( '<div>' )
			.addClass(
				namespacify( 'wrapper' ) + ' ' +
				remodal.settings.modifier + ' ' +
				namespacify( 'is', STATES.CLOSED )
			)
			.hide()
			.append( remodal.$modal );
			$body.append( remodal.$wrapper );

			// Add the event listener for the close button
			remodal.$wrapper.on(
				'click.' + NAMESPACE,
				'[data-' + PLUGIN_NAME + '-action="close"]',
				function(e) {
					e.preventDefault();

					remodal.close();
				}
			);

			// Add the event listener for the cancel button
			remodal.$wrapper.on(
				'click.' + NAMESPACE,
				'[data-' + PLUGIN_NAME + '-action="cancel"]',
				function(e) {
					e.preventDefault();

					remodal.$modal.trigger( STATE_CHANGE_REASONS.CANCELLATION );

					if (remodal.settings.closeOnCancel) {
						remodal.close( STATE_CHANGE_REASONS.CANCELLATION );
					}
				}
			);

			// Add the event listener for the confirm button
			remodal.$wrapper.on(
				'click.' + NAMESPACE,
				'[data-' + PLUGIN_NAME + '-action="confirm"]',
				function(e) {
					e.preventDefault();

					remodal.$modal.trigger( STATE_CHANGE_REASONS.CONFIRMATION );

					if (remodal.settings.closeOnConfirm) {
						remodal.close( STATE_CHANGE_REASONS.CONFIRMATION );
					}
				}
			);

			// Add the event listener for the overlay
			remodal.$wrapper.on(
				'click.' + NAMESPACE,
				function(e) {
					var $target = $( e.target );

					if ( ! $target.hasClass( namespacify( 'wrapper' ) )) {
						return;
					}

					if (remodal.settings.closeOnOutsideClick) {
						remodal.close();
					}
				}
			);
		}

		/**
		 * Opens a modal window
		 *
		 * @public
		 */
		Remodal.prototype.open = function() {
			var remodal = this;
			var id;

			// Check if the animation was completed
			if (remodal.state === STATES.OPENING || remodal.state === STATES.CLOSING) {
				return;
			}

			id = remodal.$modal.attr( 'data-' + PLUGIN_NAME + '-id' );

			if (id && remodal.settings.hashTracking) {
				scrollTop     = $( window ).scrollTop();
				location.hash = id;
			}

			if (current && current !== remodal) {
				halt( current );
			}

			current = remodal;
			lockScreen();
			remodal.$bg.addClass( remodal.settings.modifier );
			remodal.$overlay.addClass( remodal.settings.modifier ).show();
			remodal.$wrapper.show().scrollTop( 0 );
			remodal.$modal.focus();

			syncWithAnimation(
				function() {
					setState( remodal, STATES.OPENING );
				},
				function() {
					setState( remodal, STATES.OPENED );
				},
				remodal
			);
		};

		/**
		 * Closes a modal window
		 *
		 * @public
		 * @param {String} reason
		 */
		Remodal.prototype.close = function(reason) {
			var remodal = this;

			// Check if the animation was completed
			if (remodal.state === STATES.OPENING || remodal.state === STATES.CLOSING) {
				return;
			}

			if (
			remodal.settings.hashTracking &&
			remodal.$modal.attr( 'data-' + PLUGIN_NAME + '-id' ) === location.hash.substr( 1 )
			) {
				location.hash = '';
				$( window ).scrollTop( scrollTop );
			}

			syncWithAnimation(
				function() {
					setState( remodal, STATES.CLOSING, false, reason );
				},
				function() {
					remodal.$bg.removeClass( remodal.settings.modifier );
					remodal.$overlay.removeClass( remodal.settings.modifier ).hide();
					remodal.$wrapper.hide();
					unlockScreen();

					setState( remodal, STATES.CLOSED, false, reason );
				},
				remodal
			);
		};

		/**
		 * Returns a current state of a modal
		 *
		 * @public
		 * @returns {STATES}
		 */
		Remodal.prototype.getState = function() {
			return this.state;
		};

		/**
		 * Destroys a modal
		 *
		 * @public
		 */
		Remodal.prototype.destroy = function() {
			var lookup = $[PLUGIN_NAME].lookup;
			var instanceCount;

			halt( this );
			this.$wrapper.remove();

			delete lookup[this.index];
			instanceCount = $.grep(
				lookup,
				function(instance) {
					return ! ! instance;
				}
			).length;

			if (instanceCount === 0) {
				this.$overlay.remove();
				this.$bg.removeClass(
					namespacify( 'is', STATES.CLOSING ) + ' ' +
					namespacify( 'is', STATES.OPENING ) + ' ' +
					namespacify( 'is', STATES.CLOSED ) + ' ' +
					namespacify( 'is', STATES.OPENED )
				);
			}
		};

		/**
		 * Special plugin object for instances
	   *
		 * @public
		 * @type {Object}
		 */
		$[PLUGIN_NAME] = {
			lookup: []
		};

		/**
		 * Plugin constructor
	   *
		 * @constructor
		 * @param {Object} options
		 * @returns {JQuery}
		 */
		$.fn[PLUGIN_NAME] = function(opts) {
			var instance;
			var $elem;

			this.each(
				function(index, elem) {
					$elem = $( elem );

					if ($elem.data( PLUGIN_NAME ) == null) {
						instance = new Remodal( $elem, opts );
						$elem.data( PLUGIN_NAME, instance.index );

						if (
						instance.settings.hashTracking &&
						$elem.attr( 'data-' + PLUGIN_NAME + '-id' ) === location.hash.substr( 1 )
						) {
							instance.open();
						}
					} else {
						instance = $[PLUGIN_NAME].lookup[$elem.data( PLUGIN_NAME )];
					}
				}
			);

			return instance;
		};

		$( document ).ready(
			function() {

				// data-remodal-target opens a modal window with the special Id
				$( document ).on(
					'click',
					'[data-' + PLUGIN_NAME + '-target]',
					function(e) {
						e.preventDefault();

						var elem    = e.currentTarget;
						var id      = elem.getAttribute( 'data-' + PLUGIN_NAME + '-target' );
						var $target = $( '[data-' + PLUGIN_NAME + '-id=' + id + ']' );

						$[PLUGIN_NAME].lookup[$target.data( PLUGIN_NAME )].open();
					}
				);

				// Auto initialization of modal windows
				// They should have the 'remodal' class attribute
				// Also you can write the `data-remodal-options` attribute to pass params into the modal
				$( document ).find( '.' + NAMESPACE ).each(
					function(i, container) {
						var $container = $( container );
						var options    = $container.data( PLUGIN_NAME + '-options' );

						if ( ! options) {
							options = {};
						} else if (typeof options === 'string' || options instanceof String) {
							options = parseOptions( options );
						}

						$container[PLUGIN_NAME]( options );
					}
				);

				// Handles the keydown event
				$( document ).on(
					'keydown.' + NAMESPACE,
					function(e) {
						if (current && current.settings.closeOnEscape && current.state === STATES.OPENED && e.keyCode === 27) {
							current.close();
						}
					}
				);

				// Handles the hashchange event
				$( window ).on( 'hashchange.' + NAMESPACE, handleHashChangeEvent );
			}
		);
	}
);