var liquid = {

callApi : function(url, params, callback)
			{				
				
				if(callback && callback.after)
				{
					callback = callback.after;
				}
				
				var reqdata = params;
				reqdata.PageState = _pageState;

				var ajx = $.ajax(
				{
					'url': url,
					'data': JSON.stringify(reqdata),
					'contentType': 'application/json; charset=utf-8',
					'dataType': 'json',
					'type': 'POST',
					'success': function (result)
					{
						var dta;
						if(result.Data)
						{
							dta = result.Data;
						}
						else
						{
							dta = result;
						}
						
						if(dta.exception)
						{
							showException(dta.errorMessage, dta.data);
						}
						else
						{
							if(callback)
							{
								callback(dta, params);
							}
						}
					},
					error: function (jqXHR, textStatus, errorThrown)
					{
						if (jqXHR.statusText && jqXHR.statusText == 'abort')
						{
							// call aborted!
						}
						else
						{
							//showException(url + jqXHR.responseText, errorThrown);
						}
					}
				});
				
				return ajx;
			}
};
var _cw =
{
	lastRequest : null,
	lastResponse : null,
	debugLastRequest : function()
	{
		var request = _cw.lastRequest;
		var response = _cw.lastResponse;
		
		var message = '';//'REQUEST:\n' + JSON.stringify(request, null, 4);
		//message += '\n\n----------------------------------\n\n';
		message += '\nRESPONSE:\n' + JSON.stringify(response, null, 4);
		
		alert(message);
	},
	proxy : null,
	base : {},
	func:
	{
		callApi : function(url, params, args, baseBeforeHandler, baseAfterHandler)
		{
			var doRequest = true;
			
			//Args
			var before = null;
			var after = null;
			var skipBase = false;
			
			if(args)
			{
				before = args.before;
				after = args.after;
				skipBase = args.skipBase;
			}
			
			//Base
			if(!skipBase && baseBeforeHandler && !baseBeforeHandler(params))
			{
				console.log('Canceled by base: ' + url);
				doRequest = false;
			}
			
			//Anon
			if(doRequest && before && !before(params))
			{
				console.log('Canceled by anon: ' + url);
				doRequest = false;
			}
			
			if(doRequest)
			{
				var reqdata = params;
				reqdata.PageState = _pageState;

				_cw.lastRequest = reqdata;
				
				var ajx = serverPostJson(url,
							reqdata,
							function (result)
							{
								//Set Data
								var dta;
								if(result.Data)
								{
									dta = result.Data;
								}
								else
								{
									dta = result;
								}
								
								
								//TODO:SessionState terug zetten enzo
								
								if(dta.exception)
								{
									showException(dta.errorMessage, dta.data);
								}
								else
								{
									_cw.lastResponse = dta;
									
									//1. Base
									if(baseAfterHandler)
									{
										baseAfterHandler(dta, params);
									}
							
									//2. Anon
									if(after)
									{
										after(dta, params);
									}
								}
							}
				);
				
				return ajx;
			}
			else
			{
				return null;
			}
		}
	}
};




/*

$(document).ready(function()
{
	$.Shortcuts.add({
    type: 'down',
    mask: 'Ctrl+F12',
    handler: function()
	{
        _.liquid.setDebugMode({debugMode : null}, {after: function()
		{
			location.reload();
		}});
    }});
	
	$.Shortcuts.start();
});

*/
production = true;

function showException(error, trace)
{
	if(production){
		console.error("Error has occured");
		console.log(error);
		console.log(trace);
	} else {
		$('.exception .message span').text(error);
		$('.exception .message .trace').text(trace);
		$('div.exception').fadeIn(500);
	}
}

$('.exception div.close').click(function()
{
	$('div.exception').fadeOut(500);
});

$(document).ready()
{
	var total = 0;
	$('#diag table tr').each(function(i, e)
	{
		var name = $(e).data('name');
		var time = $(e).data('time');
		total += time;
		
	});
	
	total = Math.round(total);

	$('#diag table tr').each(function(i, e)
	{
		var name = $(e).data('name');
		var time = $(e).data('time');
		var percent = (100/total) * time;
		
		var cssPercent = Math.round(percent);
		
		
		
		if(time > 200)
		{
			$(e).find('div.bar').addClass('fail');
		}
		else if(time > 100)
		{
			$(e).find('div.bar').addClass('warn');
		}
		
		$(e).find('div.bar').animate({'width' : cssPercent + '%'});
		$(e).find('div.bar, span.ms').attr('title', Math.round(percent) + '%' + ' (' + time + 'ms)');
	});
	
	$('#diag .total span').text(total);
	if(total > 300)
	{
		$('#diag .total').addClass('fail');
	}
	else if(total > 200)
	{
		$('#diag .total').addClass('warn');
	}
	else
	{
		$('#diag .total').addClass('ok');
	}
	$('#diag .total').show();
};


$(document).keypress(function(e) {
  if(e.keyCode == 96 && e.AltKey && e.CtrlKey )
  {
	  alert('test');
  }
});

// usage: log('inside coolFunc', this, arguments);
// paulirish.com/2009/log-a-lightweight-wrapper-for-consolelog/
window.log = function(){
  log.history = log.history || [];   // store logs to an array for reference
  log.history.push(arguments);
  if(this.console) {
    arguments.callee = arguments.callee.caller;
    var newarr = [].slice.call(arguments);
    (typeof console.log === 'object' ? log.apply.call(console.log, console, newarr) : console.log.apply(console, newarr));
  }
};

// make it safe to use console.log always
(function(b){function c(){}for(var d="assert,count,debug,dir,dirxml,error,exception,group,groupCollapsed,groupEnd,info,log,timeStamp,profile,profileEnd,time,timeEnd,trace,warn".split(","),a;a=d.pop();){b[a]=b[a]||c}})((function(){try
{console.log();return window.console;}catch(err){return window.console={};}})());


// place any jQuery/helper plugins in here, instead of separate, slower script files.


//----------------------------------------------
//  (c)2011 - TranCon bv.
//----------------------------------------------

function serverGetJson(uri, pars, delegate) {
    return $.getJSON(uri, pars, function (result) { delegate(result); })
}

function serverPostJson(uri, pars, delegate) {
    //$("#debug").append(uri + "<br />");
    $("#ajaxactivity").show();
    window.setTimeout('$("#ajaxactivity").fadeOut();', 250);
    return $.ajax({
        url: uri,
        data: JSON.stringify(pars),
        contentType: 'application/json; charset=utf-8',
        dataType: 'json',
        type: 'POST',
        success: function (r) { delegate(r); },
        error: function (data, textStatus) {
            if (data.statusText && data.statusText == 'abort') {
                // call aborted!
            } else {
                $("#errortext").html(data.responseText);
                $("#error").show();
            }
        }
    });
}

function serverPostJsonWithContext(uri, pars, delegate, context) {
    return $.ajax({
        url: uri,
        data: JSON.stringify(pars),
        contentType: 'application/json',
        dataType: 'json',
        type: 'POST',
        success: function (r) { delegate(r, context); },
        error: function (data, textStatus) {
            //alert(textStatus); 
        }
    });
}

$(document).ready(function()
{
	//Submit
	$("form.validate").bind('validate', function(event, callback)
	{
		validateForm(null, $(this), true, callback);
	});
	
	//Focus Lost (all inputs)
	$("form.validate input[type=text], form.validate textarea").on('blur', function()
	{
		var form = $(this).closest('form');
		validateForm($(this), form, false);
	});

	//Focus Lost (password inputs)
	$("form.validate input[type=password]").on('blur', function()
	{
		var form = $(this).closest('form');
		validateForm($(this), form, false);
	});

	//Select (Combobox)
	$("form.validate select").on('change', function()
	{
		var form = $(this).closest('form');
		$(this).blur();
		validateForm($(this), form, false);
	});
	
	//Change (Checkbox/Radio)
	$("form.validate input[type=checkbox], form.validate input[type=radio]").on('change', function() //TODO:Radio button
	{
		$(this).data('touched', '1');
		var form = $(this).closest('form');
		validateForm($(this), form, false);
	});
	
	//Touch on focus (All inputs)
	$("form.validate :input").on('focus', function()
	{
		$(this).data('touched', '1');
	});
	
	//Validate all forms on load.
	$("form.validate").each(function (i, e)
	{
		validateForm(null, $(e), false);
	});
});


function validateForm(input, form, submit, callback)
{
	var formName = form.attr('name');
		
	var fields = [];
	var emptyRadios = [];
	
	var inputs = form.find(':input');
	inputs.each(function(i, e)
	{
		//Get field info
		var name = $(e).attr('name');
		var labels = form.find('label[for='+name+']');
		var placeholder = $(e).data('placeholder'); //TODO: Omzetten neer echt placeholder attribute
		var labelText = $(e).data('label'); //TODO:fallback op <label> tag
		
		var localName = e.tagName.toLowerCase();
		var type = localName == 'input' ? $(e).attr('type') : localName;
		
		var touched = $(e).data('touched') == 1;
		var skip = false;
		
		var value;
		switch(type)
		{
			case 'checkbox':
				value = ($(e).is(':checked') ? 'on' : 'off');
			break;
			
			case 'radio':
				if($(e).is(':checked'))
				{
					
					value = $(e).val();
				}
				else
				{
					skip = true;
				}
			break;
			
			default:
				value = $(e).val();
			break;
		}
		
		
		
		
		/* Placeholder Fix (TODO: Zorgen dat dit niet meer nodig is...)*/
		if($(e).hasClass('placeholder'))
		{
			value = '';
		}
		
		if(name) /* Skip inputs without name attribute */
		{
			if(!skip)
			{
				fields.push({
					'type' : type,
					'name' : name,
					'value' : value,
					'label' : labelText,
					'touched' : touched
					});
			}
		}
	});

	var inputName = null;
	if(input)
	{
		input.removeClass('error');
		inputName = input.attr('name');
	}

	_.validation.validateForm({'formName': formName, 'fieldName' : inputName, 'fields' : fields, 'submit' : submit},
	{
		after : function(result, params)
		{
			if(formName == 'pp-order'){
				$('#proceed').prop('disabled',false);
			}
			form.trigger('aftervalidate', {'result' : result, 'params' : params});
			if(result.success)
			{ 
                // hack to hide error menu
                if(result.data.validation.valid){
					$('#onSubmitErrorText').hide();
				}
				//Loop trough feedback
				$(result.data.validation.fields).each(function(i, e)
				{
					//Find input / labels
					var fields = form.find(':input[name='+ e.field +']');
					
					fields.each(function(i, el)
					{
						var field = $(el);
						var labels = form.find('label[for=\''+field.attr('id')+'\']');
						
						//Check if valid
						if(!e.valid && (field.data('touched') || e.submit))
						{
							//Field is not valid
							field.addClass('error');
							field.attr('title', e.message);
							$(labels).addClass('error');
						}
						else
						{
							//Field is valid
							field.removeClass('error');
							field.attr('title', '');
							$(labels).removeClass('error');
						}
						
						//Check if required
						if(e.required)
						{
							//Field is required (add * to label and add css class)
							field.attr('required', 'required');
							
							if(field.attr('type') != 'radio')
							{
								labels.each(function(li, le)
								{
									var labelText = $(le).html().replace('*', '');
									labelText += '*';
									$(le).html(labelText);
								});
							}
						}
						else
						{
							//Field is optional (remove * form label and remove css class)
							field.removeAttr('required', '');
							if(field.attr('type') != 'radio')
							{
								labels.each(function(li, le)
								{
									var labelText = $(le).html().replace('*', '');
									$(le).html(labelText);
								});
							}
						}
					});
				});
			}
			if(callback)
			{
				callback(result.data.validation);
			}
		}
	});
}
function findBootstrapDeviceSize() {
  var dsize = ['lg', 'md', 'sm', 'xs'];
  for (var i = dsize.length - 1; i >= 0; i--) {

    // Need to add &nbsp; for Chrome. Works fine in Firefox/Safari/Opera without it.
    // Chrome seem to have an issue with empty div's
    $el = $('<div id="sizeTest" class="hidden-'+dsize[i]+'"></div>');
    $el.appendTo($('body'));

    if ($el.is(':hidden')) {
      $el.remove();
      return dsize[i];
    }
	$el.remove();
  }

  return 'unknown';
}

function setDeviceClass()
{
	var test = findBootstrapDeviceSize();
	$('body').removeClass('lg');
	$('body').removeClass('md');
	$('body').removeClass('sm');
	$('body').removeClass('xs');
	$('body').addClass(test);
}

$(function()
{
	setDeviceClass();
	$(window).resize(function(){
		setDeviceClass();
	});
});



var checkoutcart =
  {
    reload: function (callback) {
      _.liquid.getTemplateHtml({ 'template': 'checkout-cart' }, function (result) {
        if (result.success) {
          $('#checkoutcart').html(result.html);
        }
        if (callback) {
          callback();
        }
      });
    },

    setItemCount: function (order) {
      //TODO:
    },

    remove: function (orderlineid) {
      var that = this;
      _.sapi.removeOrderline({ 'id': orderlineid }, function (result) {
        var order = result.data.model;
        $('#itemcount').html(result.data.model.itemCount);
        if (order.orderLines.length == 0) {
          document.location = '/';
        }
        else {
          that.reload();
        }
      });
    },

    refreshTotal: function (order) {
      $('div.subtot span.price').html(order.subTotalDisplay);
      $('div.delbedrag span.price').html(order.deliveryCostsDisplay);
      $('div.totalbedrag span.price').html(order.grandTotalDisplay);
    },

    updateQty: function (orderlineid, quantity) {
      var that = this;
      if (quantity != 0) {
        _.sapi.updateOrderQTY(
          {
            'orderLineID': orderlineid,
            'quantity': quantity
          },
          function (result) {
            $('#itemcount').html(result.data.model.itemCount);
          }
        );
      }
    }
  };


$('form').on('aftervalidate', function (e, response) {
  if (response == null || response.result == null || response.result.data == null || response.result.data.validation == null) {
    return;
  }
  if (!response.result.data.validation.valid) {
    for (var idx = 0; idx < response.result.data.validation.fields.length; idx++) {
      var fld = response.result.data.validation.fields[idx];
      if (fld.field == 'email') {
        if (fld.message == 'The e-mail address already exists. Either log in or choose a different e-mail address.' && $('#createaccount').prop('checked')) {
          $('#existing_email_error').show();
        }
        else {
          $('#existing_email_error').hide();
        }
      }
    }
  }

  if (response.result.data.validation.valid && response.result.data.validation.submit) {
    //Ogone
    _.liquid.getTemplateHtml({ 'template': 'ogone-form' }, function (result) {
      $('#paymentform').html(result.html);
      if (!$('body').hasClass('debug-1')) {
        $('#paymentform').find('form').submit();
      }
    });
  }
});

$('#proceed').on('click', function () {
  validateForm(null, $('form.validate.order'), true, afterProceedValidation);
});

$('input[name=\'createaccount\']').on('change', function () {
  $('#accountfields').hide();
  if ($(this).is(':checked')) {
    $('#accountfields').show();
  }
});

$("#productoverview").on("click", ".delete-orderline", function () {
  var that = $(this);
  var orderlineid = $(this).data("line");
  _.sapi.removeOrderline({ 'id': orderlineid }, function (result) {
    $(that).closest(".row.product").remove();
    if ($(".row.product").size() == 0) {
      window.location.reload(false);
    } else {
      refreshOrderDetails();
    };
  });

});

function autofillcart() {
  $("input[name='name']").val("Maximiliaan Sjors");
  $("input[name='surname']").val("van Limburg-Overbeecke");
  $("input[name='email'],input[name='email2']").val("joel@trancon.nl");
  $("input[name='telephone']").val("0676767676");
  $("input[name='orderaddressline']").val("Kalverstraat 123");
  $("input[name='orderpostalcode']").val("1060LB");
  $("input[name='ordercity']").val("Amsterdam");
  $("input[name='ordercountrycode']").val("NL");
  $('input[name=agree]').click();
  $('input[name="deliverymethod"][value="BZF"]').click();
  $('input[name="paymentmethod"][value="Banktransfer NL"]').click();
}

function reloadNavBar() {
  _.liquid.getTemplateHtml({ 'template': 'navbar' }, function (result) {
    if (result.success) {
      $('#nav_main').html(result.html);
    }
  });
}

$('.autofill').each(function () {
  var $el = $(this);
  var filledByName = $el.data('fillby');
  var $filledByEl = $('input[name=\'' + filledByName + '\']');
  var lastValue = $filledByEl.val();
  $filledByEl.change(function () {
    if ($el.val() == '' || lastValue == $el.val()) {
      $el.val($filledByEl.val());
      var form = $el.closest('form');
      validateForm($el, form, false);
    }
    lastValue = $filledByEl.val();
  });
})

var $coupon = $("input[name='coupon']")

$coupon.blur(function () {
  var value = $coupon.val();
  if (value) {
    _.sapi.addCoupon({ couponCode: value }, function (data) {
      console.log(data);
      if (!data.success) {
        $coupon.parent().next().show();
      } else {
        window.location.reload();
      }
    });
  }
});
$coupon.keydown(function () {
  $coupon.parent().next().hide();
});

var $discounts = $('.remove-discount');

$discounts.click(function () {
  var value = $(this).data('line');
  _.sapi.removeDiscount({ orderlineId: value }, function () {
    window.location.reload();
  });
});

//copied away from checkout page:

if ($('body').hasClass('checkout-page')) {
  var countrychanged = false;
  $('select[name=ordercountrycode]').change(function () {
    //debugger;
    countrychanged = true;
    return true;
  });

  $(document).ready(function () {
    refreshDeliveryAndPaymentMethods();
  });
  $('#createaccount').change(function () {
    //debugger;
    $('input[name=email]').blur();
  });


  $('form').on('aftervalidate', function () {
    if (countrychanged) {
      countrychanged = false;
      _.sapi.setDeliveryMethod({ 'code': '' }, function (result) {
        _.sapi.setPaymentMethod({ 'code': '' }, function (result) {
          refreshDeliveryAndPaymentMethods();
          refreshOrderDetails();
        });
      });
    }
		/*else
		{
				refreshDeliveryAndPaymentMethods();
		}*/

    if ($('input[name=email]').val() == $('input[name=email2]').val()) {
      $('#error-algemeen').hide();
    } else {
      $('#error-algemeen').show();
    }
  });

  $('#proceed').click(function () { $('#sameaddress').change() });
  $('#sameaddress, input[name=deliveryaddressline], input[name=deliverypostalcode], input[name=deliverycity], select[name=deliverycountrycode]').change(function () {
    var selector = 'input[name=deliveryaddressline], input[name=deliverypostalcode], input[name=deliverycity], select[name=deliverycountrycode]';
    //Set Disabled/Enabled
    $(selector).prop('disabled', $(this).is(':checked'));
    //debugger;
    $('select[name=deliverycountrycode]').val($('select[name=ordercountrycode]').val());
    if ($(this).is(':checked')) {
      $('input[name=deliveryaddressline]').val($('input[name=orderaddressline]').val());
      $('input[name=deliverypostalcode]').val($('input[name=orderpostalcode]').val());
      $('input[name=deliverycity]').val($('input[name=ordercity]').val());
      $(selector).hide();
      $(selector).parents('.input-group').hide();
      $(selector).parents('.input-group').find('.input-group-addon').hide();
    }
    else {
      $(selector).show();
      $(selector).parents('.input-group').show();
      $(selector).parents('.input-group').find('.input-group-addon').show();
    }
  });


  $('#orderlines').on('change', '.qty', function () {
    var params = {
      'orderLineID': $(this).data('lineid'),
      'quantity': $(this).val()
    };

    if ($(this).val() == 0) {
      $(this).parents('.product').remove();
      _.sapi.removeOrderline({ 'id': $(this).data('lineid') }, function (result) {
        refreshOrderDetails();
        refreshDeliveryAndPaymentMethods();
      });
    }
    else {
      _.sapi.updateOrderQTY(params, function (result) {
        refreshOrderDetails();
        refreshDeliveryAndPaymentMethods();
      });
    }
  });


  $("form[name='pp-order']").on("change", "input[name='deliverymethod']", function () {
    var code = $(this).attr("value");
    _.sapi.setDeliveryMethod({ 'code': code }, function (result) {
      //debugger;
      refreshDeliveryAndPaymentMethods();
      refreshOrderDetails();
    });
  });

  $("form[name='pp-order']").on("change", "input[name='paymentmethod']", function () {
    var code = $(this).attr("value");
    _.sapi.setPaymentMethod({ 'code': code }, function (result) {
      //debugger;
      refreshDeliveryAndPaymentMethods();
      refreshOrderDetails();
    });
  });


  function refreshOrderDetails() {
    $('#total_rows').css("color", "#ddd");
    _.sapi.getCurrentOrder("", function (result) {
      $(result.data.model.orderLines).each(function (idx, line) {
        var lineRow = $('#line_' + line.orderLineID);

        lineRow.find('.subtotal').html(line.subTotalDisplay);
      });

      _.liquid.getTemplateHtml({ template: 'checkout-total' }, function (result) {
        $('#total_rows').html(result.html);
        $('#total_rows').css("color", "");
        reloadNavBar();
      });
    });
  }

  function refreshDeliveryAndPaymentMethods() {
    _.liquid.getTemplateHtml({ template: 'checkout-delivery' }, function (result) {
      $('#deliverymethods').html(result.html);
      _.liquid.getTemplateHtml({ template: 'checkout-payment' }, function (result) {
        $('#paymentmethods').html(result.html);
        updateRadios();
      });
    });
  }

  function updateRadios() {
    var radios = $("form[name='pp-order'] input[type='radio']");
    for (idx = 0; idx < radios.length; idx++) {
      var classValue = $(radios[idx]).attr("class");
      var panel = $(radios[idx]).closest(".panel");
      panel.removeClass("error");
      if (classValue != null) {
        if (classValue == 'error') {
          panel.addClass("error");
        }
      }
    }
  }

  function afterProceedValidation(result) {
    updateRadios();
    if (!result.valid) {
      $('#onSubmitErrorText').show();
    } else {
      $('#onSubmitErrorText').hide();
    }
    console.log(result);
  }
}
if(true){
	
var x = document.getElementById("demo");
function getLocation() {
    if (navigator.geolocation) {
        navigator.geolocation.getCurrentPosition(showPosition);
    } else {
        x.innerHTML = "Geolocation is not supported by this browser.";
    }
}
function showPosition(position) {
    x.innerHTML = "Latitude: " + position.coords.latitude + 
    "<br>Longitude: " + position.coords.longitude; 
}

}
$(function(){

$('.panel').on('hidden.bs.collapse', function (e) {	
    $(e.currentTarget).addClass('collapsed');
});

$('.panel').on('show.bs.collapse', function (e) {	
    $(e.currentTarget).removeClass('collapsed');
});

   $('#sidebar .panel-heading:after').on('click', function (e) {	
	   console.log($(this));
    $(this).parent().next().collapse('toggle');
});

   

    $('.dropdown-menu input, .dropdown-menu label, .dropdown-menu button').click(function(e) {
        e.stopPropagation();
    });
	
	function showProfileView() {
		$('#loggedInName').html($('#loginUserName').val());
		$('#loginView').hide();
		$('#profileView').show();		
    }
	
	function showLoginView() {
		$('#loggedInName').html($('#loggedInName').data('defaulttext'));
		$('#loginView').show();
		$('#profileView').hide();		
    }
	
	//Login
	function login()
	{	
		_.sapi.login({'username': $('#loginUserName').val(), 'password': $('#loginUserPwd').val()}, function(args)
		{
			if(args.errorMessage) {
			 //show error	
			 $("#loginErrorMessage").html(args.errorMessage);
			}			
			if(args.success) {				
			 //showProfileView();
			 //$('#loginUserName').val('');
			 //$('#loginUserPwd').val('');
			 window.location.reload(false);
			}
		});
	}
	
	//Logout
	function logout()
	{
		_.sapi.logout({}, function(args)
		{
			//if(args.success) {
			 //showLoginView();
			 window.location.reload(false);
			//}
		});
	}
	
	//Order Item
	function orderItem(itemcode, amount, cb)
	{
		if(!amount) { amount=1;}
		_.sapi.orderItem({'normalizedItemcode': itemcode, 'quantity': amount}, function(args)
		{
			var itemcount = args.data.order.itemCount;
			
			$('#p-product .roller-item.active').effect('transfer', {to:$('#menu_cart a').eq(0), complete: function(){
			$('#cart_itemcount').html(itemcount);
			}}, 300);
            $('.navbar-toggle').removeClass('animation-shake');
            $('#p-product .roller-item.active').effect('transfer', {to:$('.navbar-toggle'), complete: function(){
                $('.navbar-toggle').addClass('animation-shake');;
                
            }},300)
            
		});
	}
	
	
	$('#btnLogin').on('click', function (e) {	
     e.preventDefault();
	 login();
    });
	
	$('#btnLogout').on('click', function (e) {	
     e.preventDefault();
	 logout();
    });
	
	
	$('.add-to-cart').on('click', function (e) {	
      e.preventDefault();
	   if($(this).data('itemcode')) {
		 orderItem($(this).data('itemcode'), $(this).data('itemamount'));
	   }
    });
	
	$('.share-button-wishlist').on('click', function (e)
		{	
			var that = this;
			e.preventDefault();
			if($(this).data('itemcode'))
			{		 
			_.item.toggleList({'itemcode': $(this).data('itemcode'), 'listTypeCode': 'FAVLIST'}, function()
			{
				$(that).toggleClass('isfav');
			});
		}
	});

	
	

	

});
$(function () {
  $(window).resize(function () {
    $(".expandizer").removeClass("selected");
    $(".expand-zone").addClass("hidden");
  });
});

$(document).ready(function () {
  $(".expand-onclick").on("click", function () {
    var img = $(this);
    var $containerDiv = $(this).parent();
    var breakpoint = findBootstrapDeviceSize();
    var expandZone = $containerDiv.nextAll(".expand-zone[data-breakpoint='" + breakpoint + "']:first");
    var group = $containerDiv.parent()

    if ($containerDiv.hasClass("selected")) {
      // we're selected, hide all
      $(".expand-zone", group).addClass("hidden");
      $(".expandizer", group).removeClass("selected");
    } else {
      // hide relics
      $(".expand-zone", group).addClass("hidden");
      $(".expandizer", group).removeClass("selected");

      $containerDiv.toggleClass("selected");
      expandZone.find("h3").html($containerDiv.data("fullname"));
      expandZone.find("p").html($containerDiv.data("body"));
      expandZone.find("a.products").attr('href', $containerDiv.data("products"));
      var $img = expandZone.find(".img");
      if ($containerDiv.data("image2")) {
        $img.html('<img class="img-responsive" src="' + $containerDiv.data("image2") + '"/>');
      } else {
        $img.html(' ');
      }
      expandZone.toggleClass("hidden");
    }
  });
});


$('.nav .dropdown-toggle, .nav .dropdown-menu > li > a').click(function (ev) {
    //only click open on mobile or when no class open yet on desktop (when no mouse). see code below
    if ($(window).width() < 768){
      if(!$(this).parent().hasClass('open')){
        $(this).parent().addClass('open')
        ev.preventDefault();
        ev.stopPropagation();
      } else {
        if(!$(this).attr('href') || $(this).attr('href') == '#'){
          $(this).parent().removeClass('open')
          ev.preventDefault();
          ev.stopPropagation();
          return;
        } 
        $('.navbar-toggle').addClass('collapsed'); //quick close for #links
        $('.navbar-collapse').removeClass('in');
      }
      return;
    }
    if(!$(this).parent().hasClass('open') && !$(this).parent().hasClass('clicked-open') && $(this).hasClass('dropdown-toggle')){
       ev.preventDefault();
      //$(this).parent().toggleClass('clicked-open');
      return;
    }
    if(!$(this).attr('href') || $(this).attr('href') == '#'){
       ev.preventDefault();
      //$(this).parent().toggleClass('clicked-open'); 
    }
});

$('.nav .dropdown').mouseenter(function (event) {
  if ($(window).width() >= 768) $(this).addClass('open')
});
$('.nav .dropdown').mouseleave(function (event) {
  if ($(window).width() >= 768) $(this).removeClass('open')
});

/*!
 * Isotope PACKAGED v2.0.1
 * Filter & sort magical layouts
 * http://isotope.metafizzy.co
 */

(function(t){function e(){}function i(t){function i(e){e.prototype.option||(e.prototype.option=function(e){t.isPlainObject(e)&&(this.options=t.extend(!0,this.options,e))})}function n(e,i){t.fn[e]=function(n){if("string"==typeof n){for(var s=o.call(arguments,1),a=0,u=this.length;u>a;a++){var p=this[a],h=t.data(p,e);if(h)if(t.isFunction(h[n])&&"_"!==n.charAt(0)){var f=h[n].apply(h,s);if(void 0!==f)return f}else r("no such method '"+n+"' for "+e+" instance");else r("cannot call methods on "+e+" prior to initialization; "+"attempted to call '"+n+"'")}return this}return this.each(function(){var o=t.data(this,e);o?(o.option(n),o._init()):(o=new i(this,n),t.data(this,e,o))})}}if(t){var r="undefined"==typeof console?e:function(t){console.error(t)};return t.bridget=function(t,e){i(e),n(t,e)},t.bridget}}var o=Array.prototype.slice;"function"==typeof define&&define.amd?define("jquery-bridget/jquery.bridget",["jquery"],i):i(t.jQuery)})(window),function(t){function e(e){var i=t.event;return i.target=i.target||i.srcElement||e,i}var i=document.documentElement,o=function(){};i.addEventListener?o=function(t,e,i){t.addEventListener(e,i,!1)}:i.attachEvent&&(o=function(t,i,o){t[i+o]=o.handleEvent?function(){var i=e(t);o.handleEvent.call(o,i)}:function(){var i=e(t);o.call(t,i)},t.attachEvent("on"+i,t[i+o])});var n=function(){};i.removeEventListener?n=function(t,e,i){t.removeEventListener(e,i,!1)}:i.detachEvent&&(n=function(t,e,i){t.detachEvent("on"+e,t[e+i]);try{delete t[e+i]}catch(o){t[e+i]=void 0}});var r={bind:o,unbind:n};"function"==typeof define&&define.amd?define("eventie/eventie",r):"object"==typeof exports?module.exports=r:t.eventie=r}(this),function(t){function e(t){"function"==typeof t&&(e.isReady?t():r.push(t))}function i(t){var i="readystatechange"===t.type&&"complete"!==n.readyState;if(!e.isReady&&!i){e.isReady=!0;for(var o=0,s=r.length;s>o;o++){var a=r[o];a()}}}function o(o){return o.bind(n,"DOMContentLoaded",i),o.bind(n,"readystatechange",i),o.bind(t,"load",i),e}var n=t.document,r=[];e.isReady=!1,"function"==typeof define&&define.amd?(e.isReady="function"==typeof requirejs,define("doc-ready/doc-ready",["eventie/eventie"],o)):t.docReady=o(t.eventie)}(this),function(){function t(){}function e(t,e){for(var i=t.length;i--;)if(t[i].listener===e)return i;return-1}function i(t){return function(){return this[t].apply(this,arguments)}}var o=t.prototype,n=this,r=n.EventEmitter;o.getListeners=function(t){var e,i,o=this._getEvents();if(t instanceof RegExp){e={};for(i in o)o.hasOwnProperty(i)&&t.test(i)&&(e[i]=o[i])}else e=o[t]||(o[t]=[]);return e},o.flattenListeners=function(t){var e,i=[];for(e=0;t.length>e;e+=1)i.push(t[e].listener);return i},o.getListenersAsObject=function(t){var e,i=this.getListeners(t);return i instanceof Array&&(e={},e[t]=i),e||i},o.addListener=function(t,i){var o,n=this.getListenersAsObject(t),r="object"==typeof i;for(o in n)n.hasOwnProperty(o)&&-1===e(n[o],i)&&n[o].push(r?i:{listener:i,once:!1});return this},o.on=i("addListener"),o.addOnceListener=function(t,e){return this.addListener(t,{listener:e,once:!0})},o.once=i("addOnceListener"),o.defineEvent=function(t){return this.getListeners(t),this},o.defineEvents=function(t){for(var e=0;t.length>e;e+=1)this.defineEvent(t[e]);return this},o.removeListener=function(t,i){var o,n,r=this.getListenersAsObject(t);for(n in r)r.hasOwnProperty(n)&&(o=e(r[n],i),-1!==o&&r[n].splice(o,1));return this},o.off=i("removeListener"),o.addListeners=function(t,e){return this.manipulateListeners(!1,t,e)},o.removeListeners=function(t,e){return this.manipulateListeners(!0,t,e)},o.manipulateListeners=function(t,e,i){var o,n,r=t?this.removeListener:this.addListener,s=t?this.removeListeners:this.addListeners;if("object"!=typeof e||e instanceof RegExp)for(o=i.length;o--;)r.call(this,e,i[o]);else for(o in e)e.hasOwnProperty(o)&&(n=e[o])&&("function"==typeof n?r.call(this,o,n):s.call(this,o,n));return this},o.removeEvent=function(t){var e,i=typeof t,o=this._getEvents();if("string"===i)delete o[t];else if(t instanceof RegExp)for(e in o)o.hasOwnProperty(e)&&t.test(e)&&delete o[e];else delete this._events;return this},o.removeAllListeners=i("removeEvent"),o.emitEvent=function(t,e){var i,o,n,r,s=this.getListenersAsObject(t);for(n in s)if(s.hasOwnProperty(n))for(o=s[n].length;o--;)i=s[n][o],i.once===!0&&this.removeListener(t,i.listener),r=i.listener.apply(this,e||[]),r===this._getOnceReturnValue()&&this.removeListener(t,i.listener);return this},o.trigger=i("emitEvent"),o.emit=function(t){var e=Array.prototype.slice.call(arguments,1);return this.emitEvent(t,e)},o.setOnceReturnValue=function(t){return this._onceReturnValue=t,this},o._getOnceReturnValue=function(){return this.hasOwnProperty("_onceReturnValue")?this._onceReturnValue:!0},o._getEvents=function(){return this._events||(this._events={})},t.noConflict=function(){return n.EventEmitter=r,t},"function"==typeof define&&define.amd?define("eventEmitter/EventEmitter",[],function(){return t}):"object"==typeof module&&module.exports?module.exports=t:this.EventEmitter=t}.call(this),function(t){function e(t){if(t){if("string"==typeof o[t])return t;t=t.charAt(0).toUpperCase()+t.slice(1);for(var e,n=0,r=i.length;r>n;n++)if(e=i[n]+t,"string"==typeof o[e])return e}}var i="Webkit Moz ms Ms O".split(" "),o=document.documentElement.style;"function"==typeof define&&define.amd?define("get-style-property/get-style-property",[],function(){return e}):"object"==typeof exports?module.exports=e:t.getStyleProperty=e}(window),function(t){function e(t){var e=parseFloat(t),i=-1===t.indexOf("%")&&!isNaN(e);return i&&e}function i(){for(var t={width:0,height:0,innerWidth:0,innerHeight:0,outerWidth:0,outerHeight:0},e=0,i=s.length;i>e;e++){var o=s[e];t[o]=0}return t}function o(t){function o(t){if("string"==typeof t&&(t=document.querySelector(t)),t&&"object"==typeof t&&t.nodeType){var o=r(t);if("none"===o.display)return i();var n={};n.width=t.offsetWidth,n.height=t.offsetHeight;for(var h=n.isBorderBox=!(!p||!o[p]||"border-box"!==o[p]),f=0,d=s.length;d>f;f++){var l=s[f],c=o[l];c=a(t,c);var y=parseFloat(c);n[l]=isNaN(y)?0:y}var m=n.paddingLeft+n.paddingRight,g=n.paddingTop+n.paddingBottom,v=n.marginLeft+n.marginRight,_=n.marginTop+n.marginBottom,I=n.borderLeftWidth+n.borderRightWidth,L=n.borderTopWidth+n.borderBottomWidth,z=h&&u,S=e(o.width);S!==!1&&(n.width=S+(z?0:m+I));var b=e(o.height);return b!==!1&&(n.height=b+(z?0:g+L)),n.innerWidth=n.width-(m+I),n.innerHeight=n.height-(g+L),n.outerWidth=n.width+v,n.outerHeight=n.height+_,n}}function a(t,e){if(n||-1===e.indexOf("%"))return e;var i=t.style,o=i.left,r=t.runtimeStyle,s=r&&r.left;return s&&(r.left=t.currentStyle.left),i.left=e,e=i.pixelLeft,i.left=o,s&&(r.left=s),e}var u,p=t("boxSizing");return function(){if(p){var t=document.createElement("div");t.style.width="200px",t.style.padding="1px 2px 3px 4px",t.style.borderStyle="solid",t.style.borderWidth="1px 2px 3px 4px",t.style[p]="border-box";var i=document.body||document.documentElement;i.appendChild(t);var o=r(t);u=200===e(o.width),i.removeChild(t)}}(),o}var n=t.getComputedStyle,r=n?function(t){return n(t,null)}:function(t){return t.currentStyle},s=["paddingLeft","paddingRight","paddingTop","paddingBottom","marginLeft","marginRight","marginTop","marginBottom","borderLeftWidth","borderRightWidth","borderTopWidth","borderBottomWidth"];"function"==typeof define&&define.amd?define("get-size/get-size",["get-style-property/get-style-property"],o):"object"==typeof exports?module.exports=o(require("get-style-property")):t.getSize=o(t.getStyleProperty)}(window),function(t,e){function i(t,e){return t[a](e)}function o(t){if(!t.parentNode){var e=document.createDocumentFragment();e.appendChild(t)}}function n(t,e){o(t);for(var i=t.parentNode.querySelectorAll(e),n=0,r=i.length;r>n;n++)if(i[n]===t)return!0;return!1}function r(t,e){return o(t),i(t,e)}var s,a=function(){if(e.matchesSelector)return"matchesSelector";for(var t=["webkit","moz","ms","o"],i=0,o=t.length;o>i;i++){var n=t[i],r=n+"MatchesSelector";if(e[r])return r}}();if(a){var u=document.createElement("div"),p=i(u,"div");s=p?i:r}else s=n;"function"==typeof define&&define.amd?define("matches-selector/matches-selector",[],function(){return s}):window.matchesSelector=s}(this,Element.prototype),function(t){function e(t,e){for(var i in e)t[i]=e[i];return t}function i(t){for(var e in t)return!1;return e=null,!0}function o(t){return t.replace(/([A-Z])/g,function(t){return"-"+t.toLowerCase()})}function n(t,n,r){function a(t,e){t&&(this.element=t,this.layout=e,this.position={x:0,y:0},this._create())}var u=r("transition"),p=r("transform"),h=u&&p,f=!!r("perspective"),d={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"otransitionend",transition:"transitionend"}[u],l=["transform","transition","transitionDuration","transitionProperty"],c=function(){for(var t={},e=0,i=l.length;i>e;e++){var o=l[e],n=r(o);n&&n!==o&&(t[o]=n)}return t}();e(a.prototype,t.prototype),a.prototype._create=function(){this._transn={ingProperties:{},clean:{},onEnd:{}},this.css({position:"absolute"})},a.prototype.handleEvent=function(t){var e="on"+t.type;this[e]&&this[e](t)},a.prototype.getSize=function(){this.size=n(this.element)},a.prototype.css=function(t){var e=this.element.style;for(var i in t){var o=c[i]||i;e[o]=t[i]}},a.prototype.getPosition=function(){var t=s(this.element),e=this.layout.options,i=e.isOriginLeft,o=e.isOriginTop,n=parseInt(t[i?"left":"right"],10),r=parseInt(t[o?"top":"bottom"],10);n=isNaN(n)?0:n,r=isNaN(r)?0:r;var a=this.layout.size;n-=i?a.paddingLeft:a.paddingRight,r-=o?a.paddingTop:a.paddingBottom,this.position.x=n,this.position.y=r},a.prototype.layoutPosition=function(){var t=this.layout.size,e=this.layout.options,i={};e.isOriginLeft?(i.left=this.position.x+t.paddingLeft+"px",i.right=""):(i.right=this.position.x+t.paddingRight+"px",i.left=""),e.isOriginTop?(i.top=this.position.y+t.paddingTop+"px",i.bottom=""):(i.bottom=this.position.y+t.paddingBottom+"px",i.top=""),this.css(i),this.emitEvent("layout",[this])};var y=f?function(t,e){return"translate3d("+t+"px, "+e+"px, 0)"}:function(t,e){return"translate("+t+"px, "+e+"px)"};a.prototype._transitionTo=function(t,e){this.getPosition();var i=this.position.x,o=this.position.y,n=parseInt(t,10),r=parseInt(e,10),s=n===this.position.x&&r===this.position.y;if(this.setPosition(t,e),s&&!this.isTransitioning)return this.layoutPosition(),void 0;var a=t-i,u=e-o,p={},h=this.layout.options;a=h.isOriginLeft?a:-a,u=h.isOriginTop?u:-u,p.transform=y(a,u),this.transition({to:p,onTransitionEnd:{transform:this.layoutPosition},isCleaning:!0})},a.prototype.goTo=function(t,e){this.setPosition(t,e),this.layoutPosition()},a.prototype.moveTo=h?a.prototype._transitionTo:a.prototype.goTo,a.prototype.setPosition=function(t,e){this.position.x=parseInt(t,10),this.position.y=parseInt(e,10)},a.prototype._nonTransition=function(t){this.css(t.to),t.isCleaning&&this._removeStyles(t.to);for(var e in t.onTransitionEnd)t.onTransitionEnd[e].call(this)},a.prototype._transition=function(t){if(!parseFloat(this.layout.options.transitionDuration))return this._nonTransition(t),void 0;var e=this._transn;for(var i in t.onTransitionEnd)e.onEnd[i]=t.onTransitionEnd[i];for(i in t.to)e.ingProperties[i]=!0,t.isCleaning&&(e.clean[i]=!0);if(t.from){this.css(t.from);var o=this.element.offsetHeight;o=null}this.enableTransition(t.to),this.css(t.to),this.isTransitioning=!0};var m=p&&o(p)+",opacity";a.prototype.enableTransition=function(){this.isTransitioning||(this.css({transitionProperty:m,transitionDuration:this.layout.options.transitionDuration}),this.element.addEventListener(d,this,!1))},a.prototype.transition=a.prototype[u?"_transition":"_nonTransition"],a.prototype.onwebkitTransitionEnd=function(t){this.ontransitionend(t)},a.prototype.onotransitionend=function(t){this.ontransitionend(t)};var g={"-webkit-transform":"transform","-moz-transform":"transform","-o-transform":"transform"};a.prototype.ontransitionend=function(t){if(t.target===this.element){var e=this._transn,o=g[t.propertyName]||t.propertyName;if(delete e.ingProperties[o],i(e.ingProperties)&&this.disableTransition(),o in e.clean&&(this.element.style[t.propertyName]="",delete e.clean[o]),o in e.onEnd){var n=e.onEnd[o];n.call(this),delete e.onEnd[o]}this.emitEvent("transitionEnd",[this])}},a.prototype.disableTransition=function(){this.removeTransitionStyles(),this.element.removeEventListener(d,this,!1),this.isTransitioning=!1},a.prototype._removeStyles=function(t){var e={};for(var i in t)e[i]="";this.css(e)};var v={transitionProperty:"",transitionDuration:""};return a.prototype.removeTransitionStyles=function(){this.css(v)},a.prototype.removeElem=function(){this.element.parentNode.removeChild(this.element),this.emitEvent("remove",[this])},a.prototype.remove=function(){if(!u||!parseFloat(this.layout.options.transitionDuration))return this.removeElem(),void 0;var t=this;this.on("transitionEnd",function(){return t.removeElem(),!0}),this.hide()},a.prototype.reveal=function(){delete this.isHidden,this.css({display:""});var t=this.layout.options;this.transition({from:t.hiddenStyle,to:t.visibleStyle,isCleaning:!0})},a.prototype.hide=function(){this.isHidden=!0,this.css({display:""});var t=this.layout.options;this.transition({from:t.visibleStyle,to:t.hiddenStyle,isCleaning:!0,onTransitionEnd:{opacity:function(){this.isHidden&&this.css({display:"none"})}}})},a.prototype.destroy=function(){this.css({position:"",left:"",right:"",top:"",bottom:"",transition:"",transform:""})},a}var r=t.getComputedStyle,s=r?function(t){return r(t,null)}:function(t){return t.currentStyle};"function"==typeof define&&define.amd?define("outlayer/item",["eventEmitter/EventEmitter","get-size/get-size","get-style-property/get-style-property"],n):(t.Outlayer={},t.Outlayer.Item=n(t.EventEmitter,t.getSize,t.getStyleProperty))}(window),function(t){function e(t,e){for(var i in e)t[i]=e[i];return t}function i(t){return"[object Array]"===f.call(t)}function o(t){var e=[];if(i(t))e=t;else if(t&&"number"==typeof t.length)for(var o=0,n=t.length;n>o;o++)e.push(t[o]);else e.push(t);return e}function n(t,e){var i=l(e,t);-1!==i&&e.splice(i,1)}function r(t){return t.replace(/(.)([A-Z])/g,function(t,e,i){return e+"-"+i}).toLowerCase()}function s(i,s,f,l,c,y){function m(t,i){if("string"==typeof t&&(t=a.querySelector(t)),!t||!d(t))return u&&u.error("Bad "+this.constructor.namespace+" element: "+t),void 0;this.element=t,this.options=e({},this.constructor.defaults),this.option(i);var o=++g;this.element.outlayerGUID=o,v[o]=this,this._create(),this.options.isInitLayout&&this.layout()}var g=0,v={};return m.namespace="outlayer",m.Item=y,m.defaults={containerStyle:{position:"relative"},isInitLayout:!0,isOriginLeft:!0,isOriginTop:!0,isResizeBound:!0,isResizingContainer:!0,transitionDuration:"0.4s",hiddenStyle:{opacity:0,transform:"scale(0.001)"},visibleStyle:{opacity:1,transform:"scale(1)"}},e(m.prototype,f.prototype),m.prototype.option=function(t){e(this.options,t)},m.prototype._create=function(){this.reloadItems(),this.stamps=[],this.stamp(this.options.stamp),e(this.element.style,this.options.containerStyle),this.options.isResizeBound&&this.bindResize()},m.prototype.reloadItems=function(){this.items=this._itemize(this.element.children)},m.prototype._itemize=function(t){for(var e=this._filterFindItemElements(t),i=this.constructor.Item,o=[],n=0,r=e.length;r>n;n++){var s=e[n],a=new i(s,this);o.push(a)}return o},m.prototype._filterFindItemElements=function(t){t=o(t);for(var e=this.options.itemSelector,i=[],n=0,r=t.length;r>n;n++){var s=t[n];if(d(s))if(e){c(s,e)&&i.push(s);for(var a=s.querySelectorAll(e),u=0,p=a.length;p>u;u++)i.push(a[u])}else i.push(s)}return i},m.prototype.getItemElements=function(){for(var t=[],e=0,i=this.items.length;i>e;e++)t.push(this.items[e].element);return t},m.prototype.layout=function(){this._resetLayout(),this._manageStamps();var t=void 0!==this.options.isLayoutInstant?this.options.isLayoutInstant:!this._isLayoutInited;this.layoutItems(this.items,t),this._isLayoutInited=!0},m.prototype._init=m.prototype.layout,m.prototype._resetLayout=function(){this.getSize()},m.prototype.getSize=function(){this.size=l(this.element)},m.prototype._getMeasurement=function(t,e){var i,o=this.options[t];o?("string"==typeof o?i=this.element.querySelector(o):d(o)&&(i=o),this[t]=i?l(i)[e]:o):this[t]=0},m.prototype.layoutItems=function(t,e){t=this._getItemsForLayout(t),this._layoutItems(t,e),this._postLayout()},m.prototype._getItemsForLayout=function(t){for(var e=[],i=0,o=t.length;o>i;i++){var n=t[i];n.isIgnored||e.push(n)}return e},m.prototype._layoutItems=function(t,e){function i(){o.emitEvent("layoutComplete",[o,t])}var o=this;if(!t||!t.length)return i(),void 0;this._itemsOn(t,"layout",i);for(var n=[],r=0,s=t.length;s>r;r++){var a=t[r],u=this._getItemLayoutPosition(a);u.item=a,u.isInstant=e||a.isLayoutInstant,n.push(u)}this._processLayoutQueue(n)},m.prototype._getItemLayoutPosition=function(){return{x:0,y:0}},m.prototype._processLayoutQueue=function(t){for(var e=0,i=t.length;i>e;e++){var o=t[e];this._positionItem(o.item,o.x,o.y,o.isInstant)}},m.prototype._positionItem=function(t,e,i,o){o?t.goTo(e,i):t.moveTo(e,i)},m.prototype._postLayout=function(){this.resizeContainer()},m.prototype.resizeContainer=function(){if(this.options.isResizingContainer){var t=this._getContainerSize();t&&(this._setContainerMeasure(t.width,!0),this._setContainerMeasure(t.height,!1))}},m.prototype._getContainerSize=h,m.prototype._setContainerMeasure=function(t,e){if(void 0!==t){var i=this.size;i.isBorderBox&&(t+=e?i.paddingLeft+i.paddingRight+i.borderLeftWidth+i.borderRightWidth:i.paddingBottom+i.paddingTop+i.borderTopWidth+i.borderBottomWidth),t=Math.max(t,0),this.element.style[e?"width":"height"]=t+"px"}},m.prototype._itemsOn=function(t,e,i){function o(){return n++,n===r&&i.call(s),!0}for(var n=0,r=t.length,s=this,a=0,u=t.length;u>a;a++){var p=t[a];p.on(e,o)}},m.prototype.ignore=function(t){var e=this.getItem(t);e&&(e.isIgnored=!0)},m.prototype.unignore=function(t){var e=this.getItem(t);e&&delete e.isIgnored},m.prototype.stamp=function(t){if(t=this._find(t)){this.stamps=this.stamps.concat(t);for(var e=0,i=t.length;i>e;e++){var o=t[e];this.ignore(o)}}},m.prototype.unstamp=function(t){if(t=this._find(t))for(var e=0,i=t.length;i>e;e++){var o=t[e];n(o,this.stamps),this.unignore(o)}},m.prototype._find=function(t){return t?("string"==typeof t&&(t=this.element.querySelectorAll(t)),t=o(t)):void 0},m.prototype._manageStamps=function(){if(this.stamps&&this.stamps.length){this._getBoundingRect();for(var t=0,e=this.stamps.length;e>t;t++){var i=this.stamps[t];this._manageStamp(i)}}},m.prototype._getBoundingRect=function(){var t=this.element.getBoundingClientRect(),e=this.size;this._boundingRect={left:t.left+e.paddingLeft+e.borderLeftWidth,top:t.top+e.paddingTop+e.borderTopWidth,right:t.right-(e.paddingRight+e.borderRightWidth),bottom:t.bottom-(e.paddingBottom+e.borderBottomWidth)}},m.prototype._manageStamp=h,m.prototype._getElementOffset=function(t){var e=t.getBoundingClientRect(),i=this._boundingRect,o=l(t),n={left:e.left-i.left-o.marginLeft,top:e.top-i.top-o.marginTop,right:i.right-e.right-o.marginRight,bottom:i.bottom-e.bottom-o.marginBottom};return n},m.prototype.handleEvent=function(t){var e="on"+t.type;this[e]&&this[e](t)},m.prototype.bindResize=function(){this.isResizeBound||(i.bind(t,"resize",this),this.isResizeBound=!0)},m.prototype.unbindResize=function(){this.isResizeBound&&i.unbind(t,"resize",this),this.isResizeBound=!1},m.prototype.onresize=function(){function t(){e.resize(),delete e.resizeTimeout}this.resizeTimeout&&clearTimeout(this.resizeTimeout);var e=this;this.resizeTimeout=setTimeout(t,100)},m.prototype.resize=function(){this.isResizeBound&&this.needsResizeLayout()&&this.layout()},m.prototype.needsResizeLayout=function(){var t=l(this.element),e=this.size&&t;return e&&t.innerWidth!==this.size.innerWidth},m.prototype.addItems=function(t){var e=this._itemize(t);return e.length&&(this.items=this.items.concat(e)),e},m.prototype.appended=function(t){var e=this.addItems(t);e.length&&(this.layoutItems(e,!0),this.reveal(e))},m.prototype.prepended=function(t){var e=this._itemize(t);if(e.length){var i=this.items.slice(0);this.items=e.concat(i),this._resetLayout(),this._manageStamps(),this.layoutItems(e,!0),this.reveal(e),this.layoutItems(i)}},m.prototype.reveal=function(t){var e=t&&t.length;if(e)for(var i=0;e>i;i++){var o=t[i];o.reveal()}},m.prototype.hide=function(t){var e=t&&t.length;if(e)for(var i=0;e>i;i++){var o=t[i];o.hide()}},m.prototype.getItem=function(t){for(var e=0,i=this.items.length;i>e;e++){var o=this.items[e];if(o.element===t)return o}},m.prototype.getItems=function(t){if(t&&t.length){for(var e=[],i=0,o=t.length;o>i;i++){var n=t[i],r=this.getItem(n);r&&e.push(r)}return e}},m.prototype.remove=function(t){t=o(t);var e=this.getItems(t);if(e&&e.length){this._itemsOn(e,"remove",function(){this.emitEvent("removeComplete",[this,e])});for(var i=0,r=e.length;r>i;i++){var s=e[i];s.remove(),n(s,this.items)}}},m.prototype.destroy=function(){var t=this.element.style;t.height="",t.position="",t.width="";for(var e=0,i=this.items.length;i>e;e++){var o=this.items[e];o.destroy()}this.unbindResize(),delete this.element.outlayerGUID,p&&p.removeData(this.element,this.constructor.namespace)},m.data=function(t){var e=t&&t.outlayerGUID;return e&&v[e]},m.create=function(t,i){function o(){m.apply(this,arguments)}return Object.create?o.prototype=Object.create(m.prototype):e(o.prototype,m.prototype),o.prototype.constructor=o,o.defaults=e({},m.defaults),e(o.defaults,i),o.prototype.settings={},o.namespace=t,o.data=m.data,o.Item=function(){y.apply(this,arguments)},o.Item.prototype=new y,s(function(){for(var e=r(t),i=a.querySelectorAll(".js-"+e),n="data-"+e+"-options",s=0,h=i.length;h>s;s++){var f,d=i[s],l=d.getAttribute(n);try{f=l&&JSON.parse(l)}catch(c){u&&u.error("Error parsing "+n+" on "+d.nodeName.toLowerCase()+(d.id?"#"+d.id:"")+": "+c);continue}var y=new o(d,f);p&&p.data(d,t,y)}}),p&&p.bridget&&p.bridget(t,o),o},m.Item=y,m}var a=t.document,u=t.console,p=t.jQuery,h=function(){},f=Object.prototype.toString,d="object"==typeof HTMLElement?function(t){return t instanceof HTMLElement}:function(t){return t&&"object"==typeof t&&1===t.nodeType&&"string"==typeof t.nodeName},l=Array.prototype.indexOf?function(t,e){return t.indexOf(e)}:function(t,e){for(var i=0,o=t.length;o>i;i++)if(t[i]===e)return i;return-1};"function"==typeof define&&define.amd?define("outlayer/outlayer",["eventie/eventie","doc-ready/doc-ready","eventEmitter/EventEmitter","get-size/get-size","matches-selector/matches-selector","./item"],s):t.Outlayer=s(t.eventie,t.docReady,t.EventEmitter,t.getSize,t.matchesSelector,t.Outlayer.Item)}(window),function(t){function e(t){function e(){t.Item.apply(this,arguments)}e.prototype=new t.Item,e.prototype._create=function(){this.id=this.layout.itemGUID++,t.Item.prototype._create.call(this),this.sortData={}},e.prototype.updateSortData=function(){if(!this.isIgnored){this.sortData.id=this.id,this.sortData["original-order"]=this.id,this.sortData.random=Math.random();var t=this.layout.options.getSortData,e=this.layout._sorters;for(var i in t){var o=e[i];this.sortData[i]=o(this.element,this)}}};var i=e.prototype.destroy;return e.prototype.destroy=function(){i.apply(this,arguments),this.css({display:""})},e}"function"==typeof define&&define.amd?define("isotope/js/item",["outlayer/outlayer"],e):(t.Isotope=t.Isotope||{},t.Isotope.Item=e(t.Outlayer))}(window),function(t){function e(t,e){function i(t){this.isotope=t,t&&(this.options=t.options[this.namespace],this.element=t.element,this.items=t.filteredItems,this.size=t.size)}return function(){function t(t){return function(){return e.prototype[t].apply(this.isotope,arguments)}}for(var o=["_resetLayout","_getItemLayoutPosition","_manageStamp","_getContainerSize","_getElementOffset","needsResizeLayout"],n=0,r=o.length;r>n;n++){var s=o[n];i.prototype[s]=t(s)}}(),i.prototype.needsVerticalResizeLayout=function(){var e=t(this.isotope.element),i=this.isotope.size&&e;return i&&e.innerHeight!==this.isotope.size.innerHeight},i.prototype._getMeasurement=function(){this.isotope._getMeasurement.apply(this,arguments)},i.prototype.getColumnWidth=function(){this.getSegmentSize("column","Width")},i.prototype.getRowHeight=function(){this.getSegmentSize("row","Height")},i.prototype.getSegmentSize=function(t,e){var i=t+e,o="outer"+e;if(this._getMeasurement(i,o),!this[i]){var n=this.getFirstItemSize();this[i]=n&&n[o]||this.isotope.size["inner"+e]}},i.prototype.getFirstItemSize=function(){var e=this.isotope.filteredItems[0];return e&&e.element&&t(e.element)},i.prototype.layout=function(){this.isotope.layout.apply(this.isotope,arguments)},i.prototype.getSize=function(){this.isotope.getSize(),this.size=this.isotope.size},i.modes={},i.create=function(t,e){function o(){i.apply(this,arguments)}return o.prototype=new i,e&&(o.options=e),o.prototype.namespace=t,i.modes[t]=o,o},i}"function"==typeof define&&define.amd?define("isotope/js/layout-mode",["get-size/get-size","outlayer/outlayer"],e):(t.Isotope=t.Isotope||{},t.Isotope.LayoutMode=e(t.getSize,t.Outlayer))}(window),function(t){function e(t,e){var o=t.create("masonry");return o.prototype._resetLayout=function(){this.getSize(),this._getMeasurement("columnWidth","outerWidth"),this._getMeasurement("gutter","outerWidth"),this.measureColumns();var t=this.cols;for(this.colYs=[];t--;)this.colYs.push(0);this.maxY=0},o.prototype.measureColumns=function(){if(this.getContainerWidth(),!this.columnWidth){var t=this.items[0],i=t&&t.element;this.columnWidth=i&&e(i).outerWidth||this.containerWidth}this.columnWidth+=this.gutter,this.cols=Math.floor((this.containerWidth+this.gutter)/this.columnWidth),this.cols=Math.max(this.cols,1)},o.prototype.getContainerWidth=function(){var t=this.options.isFitWidth?this.element.parentNode:this.element,i=e(t);this.containerWidth=i&&i.innerWidth},o.prototype._getItemLayoutPosition=function(t){t.getSize();var e=t.size.outerWidth%this.columnWidth,o=e&&1>e?"round":"ceil",n=Math[o](t.size.outerWidth/this.columnWidth);n=Math.min(n,this.cols);for(var r=this._getColGroup(n),s=Math.min.apply(Math,r),a=i(r,s),u={x:this.columnWidth*a,y:s},p=s+t.size.outerHeight,h=this.cols+1-r.length,f=0;h>f;f++)this.colYs[a+f]=p;return u},o.prototype._getColGroup=function(t){if(2>t)return this.colYs;for(var e=[],i=this.cols+1-t,o=0;i>o;o++){var n=this.colYs.slice(o,o+t);e[o]=Math.max.apply(Math,n)}return e},o.prototype._manageStamp=function(t){var i=e(t),o=this._getElementOffset(t),n=this.options.isOriginLeft?o.left:o.right,r=n+i.outerWidth,s=Math.floor(n/this.columnWidth);s=Math.max(0,s);var a=Math.floor(r/this.columnWidth);a-=r%this.columnWidth?0:1,a=Math.min(this.cols-1,a);for(var u=(this.options.isOriginTop?o.top:o.bottom)+i.outerHeight,p=s;a>=p;p++)this.colYs[p]=Math.max(u,this.colYs[p])},o.prototype._getContainerSize=function(){this.maxY=Math.max.apply(Math,this.colYs);var t={height:this.maxY};return this.options.isFitWidth&&(t.width=this._getContainerFitWidth()),t},o.prototype._getContainerFitWidth=function(){for(var t=0,e=this.cols;--e&&0===this.colYs[e];)t++;return(this.cols-t)*this.columnWidth-this.gutter},o.prototype.needsResizeLayout=function(){var t=this.containerWidth;return this.getContainerWidth(),t!==this.containerWidth},o}var i=Array.prototype.indexOf?function(t,e){return t.indexOf(e)}:function(t,e){for(var i=0,o=t.length;o>i;i++){var n=t[i];if(n===e)return i}return-1};"function"==typeof define&&define.amd?define("masonry/masonry",["outlayer/outlayer","get-size/get-size"],e):t.Masonry=e(t.Outlayer,t.getSize)}(window),function(t){function e(t,e){for(var i in e)t[i]=e[i];return t}function i(t,i){var o=t.create("masonry"),n=o.prototype._getElementOffset,r=o.prototype.layout,s=o.prototype._getMeasurement;e(o.prototype,i.prototype),o.prototype._getElementOffset=n,o.prototype.layout=r,o.prototype._getMeasurement=s;var a=o.prototype.measureColumns;o.prototype.measureColumns=function(){this.items=this.isotope.filteredItems,a.call(this)};var u=o.prototype._manageStamp;return o.prototype._manageStamp=function(){this.options.isOriginLeft=this.isotope.options.isOriginLeft,this.options.isOriginTop=this.isotope.options.isOriginTop,u.apply(this,arguments)},o}"function"==typeof define&&define.amd?define("isotope/js/layout-modes/masonry",["../layout-mode","masonry/masonry"],i):i(t.Isotope.LayoutMode,t.Masonry)}(window),function(t){function e(t){var e=t.create("fitRows");return e.prototype._resetLayout=function(){this.x=0,this.y=0,this.maxY=0},e.prototype._getItemLayoutPosition=function(t){t.getSize(),0!==this.x&&t.size.outerWidth+this.x>this.isotope.size.innerWidth&&(this.x=0,this.y=this.maxY);var e={x:this.x,y:this.y};return this.maxY=Math.max(this.maxY,this.y+t.size.outerHeight),this.x+=t.size.outerWidth,e},e.prototype._getContainerSize=function(){return{height:this.maxY}},e}"function"==typeof define&&define.amd?define("isotope/js/layout-modes/fit-rows",["../layout-mode"],e):e(t.Isotope.LayoutMode)}(window),function(t){function e(t){var e=t.create("vertical",{horizontalAlignment:0});return e.prototype._resetLayout=function(){this.y=0},e.prototype._getItemLayoutPosition=function(t){t.getSize();var e=(this.isotope.size.innerWidth-t.size.outerWidth)*this.options.horizontalAlignment,i=this.y;return this.y+=t.size.outerHeight,{x:e,y:i}},e.prototype._getContainerSize=function(){return{height:this.y}},e}"function"==typeof define&&define.amd?define("isotope/js/layout-modes/vertical",["../layout-mode"],e):e(t.Isotope.LayoutMode)}(window),function(t){function e(t,e){for(var i in e)t[i]=e[i];return t}function i(t){return"[object Array]"===h.call(t)}function o(t){var e=[];if(i(t))e=t;else if(t&&"number"==typeof t.length)for(var o=0,n=t.length;n>o;o++)e.push(t[o]);else e.push(t);return e}function n(t,e){var i=f(e,t);-1!==i&&e.splice(i,1)}function r(t,i,r,u,h){function f(t,e){return function(i,o){for(var n=0,r=t.length;r>n;n++){var s=t[n],a=i.sortData[s],u=o.sortData[s];if(a>u||u>a){var p=void 0!==e[s]?e[s]:e,h=p?1:-1;return(a>u?1:-1)*h}}return 0}}var d=t.create("isotope",{layoutMode:"masonry",isJQueryFiltering:!0,sortAscending:!0});d.Item=u,d.LayoutMode=h,d.prototype._create=function(){this.itemGUID=0,this._sorters={},this._getSorters(),t.prototype._create.call(this),this.modes={},this.filteredItems=this.items,this.sortHistory=["original-order"];for(var e in h.modes)this._initLayoutMode(e)},d.prototype.reloadItems=function(){this.itemGUID=0,t.prototype.reloadItems.call(this)},d.prototype._itemize=function(){for(var e=t.prototype._itemize.apply(this,arguments),i=0,o=e.length;o>i;i++){var n=e[i];n.id=this.itemGUID++}return this._updateItemsSortData(e),e},d.prototype._initLayoutMode=function(t){var i=h.modes[t],o=this.options[t]||{};this.options[t]=i.options?e(i.options,o):o,this.modes[t]=new i(this)},d.prototype.layout=function(){return!this._isLayoutInited&&this.options.isInitLayout?(this.arrange(),void 0):(this._layout(),void 0)},d.prototype._layout=function(){var t=this._getIsInstant();this._resetLayout(),this._manageStamps(),this.layoutItems(this.filteredItems,t),this._isLayoutInited=!0},d.prototype.arrange=function(t){this.option(t),this._getIsInstant(),this.filteredItems=this._filter(this.items),this._sort(),this._layout()},d.prototype._init=d.prototype.arrange,d.prototype._getIsInstant=function(){var t=void 0!==this.options.isLayoutInstant?this.options.isLayoutInstant:!this._isLayoutInited;return this._isInstant=t,t},d.prototype._filter=function(t){function e(){f.reveal(n),f.hide(r)}var i=this.options.filter;i=i||"*";for(var o=[],n=[],r=[],s=this._getFilterTest(i),a=0,u=t.length;u>a;a++){var p=t[a];if(!p.isIgnored){var h=s(p);h&&o.push(p),h&&p.isHidden?n.push(p):h||p.isHidden||r.push(p)}}var f=this;return this._isInstant?this._noTransition(e):e(),o},d.prototype._getFilterTest=function(t){return s&&this.options.isJQueryFiltering?function(e){return s(e.element).is(t)}:"function"==typeof t?function(e){return t(e.element)}:function(e){return r(e.element,t)}},d.prototype.updateSortData=function(t){this._getSorters(),t=o(t);
var e=this.getItems(t);e=e.length?e:this.items,this._updateItemsSortData(e)},d.prototype._getSorters=function(){var t=this.options.getSortData;for(var e in t){var i=t[e];this._sorters[e]=l(i)}},d.prototype._updateItemsSortData=function(t){for(var e=0,i=t.length;i>e;e++){var o=t[e];o.updateSortData()}};var l=function(){function t(t){if("string"!=typeof t)return t;var i=a(t).split(" "),o=i[0],n=o.match(/^\[(.+)\]$/),r=n&&n[1],s=e(r,o),u=d.sortDataParsers[i[1]];return t=u?function(t){return t&&u(s(t))}:function(t){return t&&s(t)}}function e(t,e){var i;return i=t?function(e){return e.getAttribute(t)}:function(t){var i=t.querySelector(e);return i&&p(i)}}return t}();d.sortDataParsers={parseInt:function(t){return parseInt(t,10)},parseFloat:function(t){return parseFloat(t)}},d.prototype._sort=function(){var t=this.options.sortBy;if(t){var e=[].concat.apply(t,this.sortHistory),i=f(e,this.options.sortAscending);this.filteredItems.sort(i),t!==this.sortHistory[0]&&this.sortHistory.unshift(t)}},d.prototype._mode=function(){var t=this.options.layoutMode,e=this.modes[t];if(!e)throw Error("No layout mode: "+t);return e.options=this.options[t],e},d.prototype._resetLayout=function(){t.prototype._resetLayout.call(this),this._mode()._resetLayout()},d.prototype._getItemLayoutPosition=function(t){return this._mode()._getItemLayoutPosition(t)},d.prototype._manageStamp=function(t){this._mode()._manageStamp(t)},d.prototype._getContainerSize=function(){return this._mode()._getContainerSize()},d.prototype.needsResizeLayout=function(){return this._mode().needsResizeLayout()},d.prototype.appended=function(t){var e=this.addItems(t);if(e.length){var i=this._filterRevealAdded(e);this.filteredItems=this.filteredItems.concat(i)}},d.prototype.prepended=function(t){var e=this._itemize(t);if(e.length){var i=this.items.slice(0);this.items=e.concat(i),this._resetLayout(),this._manageStamps();var o=this._filterRevealAdded(e);this.layoutItems(i),this.filteredItems=o.concat(this.filteredItems)}},d.prototype._filterRevealAdded=function(t){var e=this._noTransition(function(){return this._filter(t)});return this.layoutItems(e,!0),this.reveal(e),t},d.prototype.insert=function(t){var e=this.addItems(t);if(e.length){var i,o,n=e.length;for(i=0;n>i;i++)o=e[i],this.element.appendChild(o.element);var r=this._filter(e);for(this._noTransition(function(){this.hide(r)}),i=0;n>i;i++)e[i].isLayoutInstant=!0;for(this.arrange(),i=0;n>i;i++)delete e[i].isLayoutInstant;this.reveal(r)}};var c=d.prototype.remove;return d.prototype.remove=function(t){t=o(t);var e=this.getItems(t);if(c.call(this,t),e&&e.length)for(var i=0,r=e.length;r>i;i++){var s=e[i];n(s,this.filteredItems)}},d.prototype.shuffle=function(){for(var t=0,e=this.items.length;e>t;t++){var i=this.items[t];i.sortData.random=Math.random()}this.options.sortBy="random",this._sort(),this._layout()},d.prototype._noTransition=function(t){var e=this.options.transitionDuration;this.options.transitionDuration=0;var i=t.call(this);return this.options.transitionDuration=e,i},d.prototype.getFilteredItemElements=function(){for(var t=[],e=0,i=this.filteredItems.length;i>e;e++)t.push(this.filteredItems[e].element);return t},d}var s=t.jQuery,a=String.prototype.trim?function(t){return t.trim()}:function(t){return t.replace(/^\s+|\s+$/g,"")},u=document.documentElement,p=u.textContent?function(t){return t.textContent}:function(t){return t.innerText},h=Object.prototype.toString,f=Array.prototype.indexOf?function(t,e){return t.indexOf(e)}:function(t,e){for(var i=0,o=t.length;o>i;i++)if(t[i]===e)return i;return-1};"function"==typeof define&&define.amd?define(["outlayer/outlayer","get-size/get-size","matches-selector/matches-selector","isotope/js/item","isotope/js/layout-mode","isotope/js/layout-modes/masonry","isotope/js/layout-modes/fit-rows","isotope/js/layout-modes/vertical"],r):t.Isotope=r(t.Outlayer,t.getSize,t.matchesSelector,t.Isotope.Item,t.Isotope.LayoutMode)}(window);
/*
 * jQuery resize event - v1.1 - 3/14/2010
 * http://benalman.com/projects/jquery-resize-plugin/
 * 
 * Copyright (c) 2010 "Cowboy" Ben Alman
 * Dual licensed under the MIT and GPL licenses.
 * http://benalman.com/about/license/
 */
(function($,h,c){var a=$([]),e=$.resize=$.extend($.resize,{}),i,k="setTimeout",j="resize",d=j+"-special-event",b="delay",f="throttleWindow";e[b]=250;e[f]=true;$.event.special[j]={setup:function(){if(!e[f]&&this[k]){return false}var l=$(this);a=a.add(l);$.data(this,d,{w:l.width(),h:l.height()});if(a.length===1){g()}},teardown:function(){if(!e[f]&&this[k]){return false}var l=$(this);a=a.not(l);l.removeData(d);if(!a.length){clearTimeout(i)}},add:function(l){if(!e[f]&&this[k]){return false}var n;function m(s,o,p){var q=$(this),r=$.data(this,d);r.w=o!==c?o:q.width();r.h=p!==c?p:q.height();n.apply(this,arguments)}if($.isFunction(l)){n=l;return m}else{n=l.handler;l.handler=m}}};function g(){i=h[k](function(){a.each(function(){var n=$(this),m=n.width(),l=n.height(),o=$.data(this,d);if(m!==o.w||l!==o.h){n.trigger(j,[o.w=m,o.h=l])}});g()},e[b])}})(jQuery,this);
/* 
 * Roller v3.1.4 - 2014-05-30 
 * A jQuery plugin for simple content carousels. Part of the Formstone Library. 
 * http://formstone.it/roller/ 
 * 
 * Copyright 2014 Ben Plum; MIT Licensed 
 */ 

;(function ($, window) {
	"use strict";

	/**
	 * @options
	 * @param autoAdvance [boolean] <false> "Flag to auto advance items"
	 * @param autoTime [int] <8000> "Auto advance time"
	 * @param autoWidth [boolean] <false> "Flag to fit items to viewport width"
	 * @param controls [boolean] <true> "Flag to draw controls"
	 * @param customClass [string] <''> "Class applied to instance"
	 * @param infinite [boolean] <false> "Flag for looping items"
	 * @param labels.next [string] <'Next'> "Control text"
	 * @param labels.previous [string] <'Previous'> "Control text"
	 * @param maxWidth [string] <'Infinity'> "Width at which to auto-disable plugin"
	 * @param minWidth [string] <'0'> "Width at which to auto-disable plugin"
	 * @param paged [boolean] <false> "Flag for paged items"
	 * @param pagination [boolean] <true> "Flag to draw pagination"
	 * @param single [boolean] <false> "Flag for single items"
	 * @param touchPaged [boolean] <true> "Flag for paged touch interaction"
	 * @param useMargin [boolean] <false> "Use margins instead of css transitions (legacy browser support)"
	 */
	var options = {
		autoAdvance: false,
		autoTime: 8000,
		autoWidth: false,
		controls: true,
		customClass: "",
		infinite: true,
		labels: {
			next: "Next",
			previous: "Previous"
		},
		maxWidth: Infinity,
		minWidth: '0px',
		paged: false,
		pagination: true,
		single: false,
		touchPaged: true,
		useMargin: false
	};

	/**
	 * @events
	 * @event update.roller "Canister position updated"
	 */

	var pub = {

		/**
		 * @method
		 * @name defaults
		 * @description Sets default plugin options
		 * @param opts [object] <{}> "Options object"
		 * @example $.roller("defaults", opts);
		 */
		defaults: function(opts) {
			options = $.extend(options, opts || {});
			return $(this);
		},

		/**
		 * @method
		 * @name destroy
		 * @description Removes instance of plugin
		 * @example $(".target").roller("destroy");
		 */
		destroy: function() {
			return $(this).each(function() {
				var data = $(this).data("roller");

				if (data) {
					_clearTimer(data.autoTimer);

					if (!data.single) {
						if (data.viewport) {
							data.$items.unwrap();
						}
						if (data.canister) {
							data.$items.unwrap();
						} else {
							data.$canister.attr("style", null);
						}
					}

					data.$items.removeClass("visible");

					if (data.pagination) {
						data.$pagination.remove();
					}
					if (data.controls) {
						data.$controls.remove();
					}

					data.$roller.removeClass("roller enabled " + (data.single ? "single " : "") + data.customClass)
								.off(".roller")
								.data("roller", null);
				}
			});
		},

		/**
		 * @method
		 * @name disable
		 * @description Disables instance of plugin
		 * @example $(".target").roller("disable");
		 */
		disable: function() {
			return $(this).each(function() {
				var data = $(this).data("roller");

				if (data && data.enabled) {
					_clearTimer(data.autoTimer);

					data.enabled = false;

					data.$roller.removeClass("enabled")
								.off("touchstart.roller click.roller");

					data.$canister.attr("style", "")
								  .css( _prefix("transition", "none") )
								  .off("touchstart.roller");

					data.$controls.removeClass("visible");
					data.$pagination.removeClass("visible")
									.html("");

					if (data.useMargin) {
						data.$canister.css({ marginLeft: "" });
					} else {
						data.$canister.css( _prefix("transform", "translate3d(0px, 0, 0)") );
					}

					data.index = 0;
				}
			});
		},

		/**
		 * @method
		 * @name enable
		 * @description Enables instance of plugin
		 * @example $(".target").roller("enable");
		 */
		enable: function() {
			return $(this).each(function() {
				var data = $(this).data("roller");

				if (data && !data.enabled) {
					data.enabled = true;

					data.$roller.addClass("enabled")
								.on("touchstart.roller click.roller", ".roller-control", data, _onAdvance)
								.on("touchstart.roller click.roller", ".roller-page", data, _onSelect);

					data.$canister.css( _prefix("transition", "") );

					pub.resize.apply(data.$roller);

					if (!data.single) {
						data.$canister.on("touchstart.roller", data, _onTouchStart);
					}
				}
			});
		},

		/**
		 * @method
		 * @name jump
		 * @description Jump instance of plugin to specific page
		 * @example $(".target").roller("jump", 1);
		 */
		jump: function(index) {
			return $(this).each(function() {
				var data = $(this).data("roller");

				if (data && data.enabled) {
					_clearTimer(data.autoTimer);
					_position(data, index-1);
				}
			});
		},

		/**
		 * @method
		 * @name resize
		 * @description Resizes each instance
		 * @example $(".target").roller("resize");
		 */
		resize: function() {
			return $(this).each(function() {
				var data = $(this).data("roller");

				if (data && data.enabled) {
					data.count = data.$items.length;

					if (data.count < 1) { // avoid empty rollers
						return;
					}

					data.viewportWidth = data.$viewport.outerWidth(false);
					data.itemMargin = parseInt(data.$items.eq(0).css("margin-left"), 10) + parseInt(data.$items.eq(0).css("margin-right"), 10);

					if (data.autoWidth) {
						data.$items.css({ width: data.viewportWidth });
					}

					if (data.single) {
						data.perPage = 1;
						data.pageCount = data.count - 1;
					} else if (data.paged) {
						data.canisterWidth = 0;
						for (var i = 0; i < data.count; i++) {
							data.canisterWidth += data.$items.eq(i).outerWidth() + data.itemMargin;
						}
						data.perPage = 1;
						data.pageCount = (data.canisterWidth > data.viewportWidth) ? data.count - 1 : 0;
					} else {
						data.itemWidth = data.$items.eq(0).outerWidth(false) + data.itemMargin;
						data.perPage = Math.floor(data.viewportWidth / data.itemWidth);
						if (data.perPage < 1) {
							data.perPage = 1;
						}
						data.pageCount = Math.ceil(data.count / data.perPage) - 1;
						data.pageMove = data.itemWidth * data.perPage;
						data.canisterWidth = data.itemWidth * data.count;
					}

					data.maxMove = -data.canisterWidth + data.viewportWidth + data.itemMargin;
					if (data.maxMove > 0) {
						data.maxMove = 0;
					}

					// Reset Page Count
					if (data.pageCount !== Infinity) {
						var html = '';
						for (var j = 0; j <= data.pageCount; j++) {
							html += '<span class="roller-page">' + (j + 1) + '</span>';
						}
						data.$pagination.html(html);
					}

					if (data.pageCount < 1) {
						data.$controls.removeClass("visible");
						data.$pagination.removeClass("visible");
					} else {
						data.$controls.addClass("visible");
						data.$pagination.addClass("visible");
					}
					data.$paginationItems = data.$roller.find(".roller-page");

					if (!data.single) {
						data.$canister.css({ width: data.canisterWidth });
					}

					_position(data, _calculateIndex(data), false);
				}
			});
		},

		/**
		 * @method
		 * @name reset
		 * @description Resets instance after item change
		 * @example $(".target").roller("reset");
		 */
		reset: function() {
			return $(this).each(function() {
				var data = $(this).data("roller");

				if (data && data.enabled) {
					data.$items = data.$roller.find(".roller-item");
					pub.resize.apply(data.$roller);
				}
			});
		}
	};

	/**
	 * @method private
	 * @name _init
	 * @description Initializes plugin
	 * @param opts [object] "Initialization options"
	 */
	function _init(opts) {
		// Settings
		opts = $.extend({}, options, opts);

		// Apply to each element
		var $items = $(this);
		for (var i = 0, count = $items.length; i < count; i++) {
			_build($items.eq(i), opts);
		}

		return $items;
	}

	/**
	 * @method private
	 * @name _build
	 * @description Builds each instance
	 * @param $roller [jQuery object] "Target jQuery object"
	 * @param opts [object] <{}> "Options object"
	 */
	function _build($roller, opts) {
		if (!$roller.data("roller")) {
			opts = $.extend({}, opts, $roller.data("roller-options"));

			// Legacy browser support
			if (!opts.useMargin && !_getTransform3DSupport()) {
				opts.useMargin = true;
			}

			if (!opts.single) {
				// Verify viewport and canister are available
				if (!$roller.find(".roller-viewport").length) {
					$roller.wrapInner('<div class="roller-viewport"></div>');
					opts.viewport = true;
				}
				if (!$roller.find(".roller-canister").length) {
					$roller.find(".roller-viewport")
						   .wrapInner('<div class="roller-canister"></div>');
					opts.canister = true;
				}
			}

			// Build controls and pagination
			var html = '';
			if (opts.controls && !$roller.find(".roller-controls").length) {
				html += '<div class="roller-controls">';
				html += '<span class="roller-control previous">' + opts.labels.previous + '</span>';
				html += '<span class="roller-control next">' + opts.labels.next + '</span>';
				html += '</div>';
			}
			if (opts.pagination && !$roller.find(".roller-pagination").length) {
				html += '<div class="roller-pagination">';
				html += '</div>';
			}

			// Modify target
			$roller.addClass("roller " + (opts.single ? "single " : "") + opts.customClass)
				   .append(html);

			var data = $.extend({}, {
				$roller: $roller,
				$viewport: $roller.find(".roller-viewport").eq(0),
				$canister: $roller.find(".roller-canister").eq(0),
				$captions: $roller.find(".roller-captions").eq(0),
				$controls: $roller.find(".roller-controls").eq(0),
				$pagination: $roller.find(".roller-pagination").eq(0),
				index: 0,
				deltaX: null,
				deltaY: null,
				leftPosition: 0,
				xStart: 0,
				yStart: 0,
				enabled: false,
				touchstart: 0,
				touchEnd: 0
			}, opts);

			data.$items = (data.single) ? data.$roller.find(".roller-item") : data.$canister.children(".roller-item");
			data.$captionItems = data.$captions.find(".roller-caption");
			data.$controlItems = data.$controls.find(".roller-control");
			data.$paginationItems = data.$pagination.find(".roller-page");
			data.$images = data.$canister.find("img");

			data.totalImages = data.$images.length;

			$roller.data("roller", data);

			// Navtive MQ Support
			if (window.matchMedia !== undefined) {
				data.maxWidth = data.maxWidth === Infinity ? "100000px" : data.maxWidth;
				data.mediaQuery = window.matchMedia("(min-width:" + data.minWidth + ") and (max-width:" + data.maxWidth + ")");
				// Make sure we stay in context
				data.mediaQuery.addListener(function() {
					_onRespond.apply(data.$roller);
				});
				_onRespond.apply(data.$roller);
			}

			// Watch images
			if (data.totalImages > 0) {
				data.loadedImages = 0;
				for (var i = 0; i < data.totalImages; i++) {
					var $img = data.$images.eq(i);
					$img.one("load.roller", data, _onImageLoad);
					if ($img[0].complete || $img[0].height) {
						$img.trigger("load.roller");
					}
				}
			}

			// Auto timer
			if (data.autoAdvance || data.auto) { // backwards compatibility
				data.autoTimer = _startTimer(data.autoTimer, data.autoTime, function() {
					_autoAdvance(data);
				}, true);
			}
		}
	}

	/**
	 * @method private
	 * @name _onImageLoad
	 * @description Handles child image load
	 * @param e [object] "Event data"
	 */
	function _onImageLoad(e) {
		var data = e.data;
		data.loadedImages++;
		if (data.loadedImages === data.totalImages) {
			pub.resize.apply(data.$roller);
		}
	}

	/**
	 * @method private
	 * @name _onTouchStart
	 * @description Handles touchstart event
	 * @param e [object] "Event data"
	 */
	function _onTouchStart(e) {
		e.stopPropagation();

		var data = e.data;

		_clearTimer(data.autoTimer);

		data.touchStart = new Date().getTime();
		data.$canister.css( _prefix("transition", "none") );

		var touch = (typeof e.originalEvent.targetTouches !== "undefined") ? e.originalEvent.targetTouches[0] : null;
		data.xStart = (touch) ? touch.pageX : e.clientX;
		data.yStart = (touch) ? touch.pageY : e.clientY;

		data.$canister.on("touchmove.roller", data, _onTouchMove)
					  .one("touchend.roller touchcancel.roller", data, _onTouchEnd);
	}

	/**
	 * @method private
	 * @name _onTouchMove
	 * @description Handles touchmove event
	 * @param e [object] "Event data"
	 */
	function _onTouchMove(e) {
		e.stopPropagation();

		var data = e.data,
			touch = (typeof e.originalEvent.targetTouches !== "undefined") ? e.originalEvent.targetTouches[0] : null;

		data.deltaX = data.xStart - ((touch) ? touch.pageX : e.clientX);
		data.deltaY = data.yStart - ((touch) ? touch.pageY : e.clientY);

		if (data.deltaX < -10 || data.deltaX > 10) {
			e.preventDefault();
		}

		data.touchLeft = data.leftPosition - data.deltaX;
		if (data.touchLeft > 0) {
			data.touchLeft = 0;
		}
		if (data.touchLeft < data.maxMove) {
			data.touchLeft = data.maxMove;
		}

		if (data.useMargin) {
			data.$canister.css({ marginLeft: data.touchLeft });
		} else {
			data.$canister.css( _prefix("transform", "translate3d("+data.touchLeft+"px, 0, 0)") );
		}
	}

	/**
	 * @method private
	 * @name _onTouchEnd
	 * @description Handles touchend event
	 * @param e [object] "Event data"
	 */
	function _onTouchEnd(e) {
		var data = e.data;

		data.touchEnd = new Date().getTime();
		data.leftPosition = data.touchLeft;
		data.$canister.css( _prefix("transition", "") );

		data.$canister.off("touchmove.roller touchend.roller touchcancel.roller");

		// only update index if we actually moved
		var index = (data.deltaX > -10 && data.deltaX < 10) ? data.index : _calculateIndex(data);

		if (data.touchPaged && !data.swipe) {
			_position(data, index);
		} else {
			data.index = index;
			_updateControls(data);
		}
		data.deltaX = null;
		data.touchStart = 0;
		data.touchEnd = 0;
	}

	/**
	 * @method private
	 * @name _autoAdvance
	 * @description Handles auto advancement
	 * @param data [object] "Instance data"
	 */
	function _autoAdvance(data) {
		var index = data.index + 1;
		if (index > data.pageCount) {
			index = 0;
		}
		_position(data, index);
	}

	/**
	 * @method private
	 * @name _onAdvance
	 * @description Handles item advancement
	 * @param e [object] "Event data"
	 */
	function _onAdvance(e) {
		e.preventDefault();
		e.stopPropagation();

		var data = e.data,
			index = data.index + (($(e.currentTarget).hasClass("next")) ? 1 : -1);

		_clearTimer(data.autoTimer);
		_position(data, index);
	}

	/**
	 * @method private
	 * @name _onSelect
	 * @description Handles item select
	 * @param e [object] "Event data"
	 */
	function _onSelect(e) {
		e.preventDefault();
		e.stopPropagation();

		var data = e.data,
			index = data.$paginationItems.index($(e.currentTarget));

		_clearTimer(data.autoTimer);
		_position(data, index);
	}

	/**
	 * @method private
	 * @name _position
	 * @description Handles updating instance position
	 * @param data [object] "Instance data"
	 * @param index [int] "Item index"
	 */
	function _position(data, index, animate) {
		if (index < 0) {
			index = (data.infinite) ? data.pageCount : 0;
		}
		if (index > data.pageCount) {
			index = (data.infinite) ? 0 : data.pageCount;
		}

		if (data.single) {
			data.$items.removeClass("active")
					   .eq(index)
					   .addClass("active");
		} else {
			if (data.paged) {
				var offset = data.$items.eq(index).position();
				if (offset) {
					data.leftPosition = -offset.left;
				}
			} else {
				data.leftPosition = -(index * data.pageMove);
			}

			if (data.leftPosition < data.maxMove) {
				data.leftPosition = data.maxMove;
			}

			if (isNaN(data.leftPosition)) {
				data.leftPosition = 0;
			}

			if (data.useMargin) {
				data.$canister.css({ marginLeft: data.leftPosition });
			} else {
				if (animate === false) {
					data.$canister.css( _prefix("transition", "none") )
								  .css( _prefix("transform", "translate3d("+data.leftPosition+"px, 0, 0)") );

					// Slight delay before adding transitions backs
					data.resizeTimer = _startTimer(data.resizeTimer, 5, function() {
						data.$canister.css( _prefix("transition", "") );
					}, false);
				} else {
					data.$canister.css( _prefix("transform", "translate3d("+data.leftPosition+"px, 0, 0)") );
				}
			}
		}

		data.$items.removeClass("visible");
		if (!data.single && data.perPage !== Infinity) {
			for (var i = 0; i < data.perPage; i++) {
				if (data.leftPosition === data.maxMove) {
					data.$items.eq(data.count - 1 - i).addClass("visible");
				} else {
					data.$items.eq((data.perPage * index) + i).addClass("visible");
				}
			}
		}

		if (index !== data.index && animate !== false) {
			data.$roller.trigger("update.roller", [ index ]);
		}
		data.index = index;

		_updateControls(data);
	}

	/**
	 * @method private
	 * @name _updateControls
	 * @description Handles updating instance controls
	 * @param data [object] "Instance data"
	 */
	function _updateControls(data) {
		data.$captionItems.filter(".active").removeClass("active");
		data.$captionItems.eq(data.index).addClass("active");

		data.$paginationItems.filter(".active").removeClass("active");
		data.$paginationItems.eq(data.index).addClass("active");

		if (data.infinite) {
			data.$controlItems.addClass("enabled");
		} else if (data.pageCount <= 0) {
			data.$controlItems.removeClass("enabled");
		} else {
			data.$controlItems.addClass("enabled");
			if (data.index <= 0) {
				data.$controlItems.filter(".previous").removeClass("enabled");
			} else if (data.index >= data.pageCount || data.leftPosition === data.maxMove) {
				data.$controlItems.filter(".next").removeClass("enabled");
			}
		}
	}

	/**
	 * @method private
	 * @name _onRespond
	 * @description Handles media query match change
	 */
	function _onRespond() {
		var data = $(this).data("roller");

		if (data.mediaQuery.matches) {
			pub.enable.apply(data.$roller);
		} else {
			pub.disable.apply(data.$roller);
		}
	}

	/**
	 * @method private
	 * @name _calculateIndex
	 * @description Determines new index based on current position
	 * @param data [object] "Instance data"
	 * @return [int] "New item index"
	 */
	function _calculateIndex(data) {
		if (data.single) {
			return data.index;
		} if ((data.deltaX > 20 || data.deltaX < -20) && (data.touchStart && data.touchEnd) && data.touchEnd - data.touchStart < 200) {
			// Swipe
			return data.index + ((data.deltaX > 0) ? 1 : -1);
		} else if (data.paged) {
			// Find page
			var goal = Infinity;
			if (data.leftPosition === data.maxMove) {
				return data.$items.length - 1;
			} else {
				var index = 0;
				data.$items.each(function(i) {
					var offset = $(this).position(),
						check = offset.left + data.leftPosition;

					if (check < 0) {
						check = -check;
					}

					if (check < goal) {
						goal = check;
						index = i;
					}
				});
				return index;
			}
		} else {
			// Free scrolling
			return Math.round( -data.leftPosition / data.viewportWidth);
		}
	}

	/**
	 * @method private
	 * @name _prefix
	 * @description Builds vendor-prefixed styles
	 * @param property [string] "Property to prefix"
	 * @param value [string] "Property value"
	 * @return [string] "Vendor-prefixed styles"
	 */
	function _prefix(property, value) {
		var r = {};

		r["-webkit-" + property] = value;
		r[   "-moz-" + property] = value;
		r[    "-ms-" + property] = value;
		r[     "-o-" + property] = value;
		r[             property] = value;

		return r;
	}

	/**
	 * @method private
	 * @name _startTimer
	 * @description Starts an internal timer
	 * @param timer [int] "Timer ID"
	 * @param time [int] "Time until execution"
	 * @param callback [int] "Function to execute"
	 * @param interval [boolean] "Flag for recurring interval"
	 */
	function _startTimer(timer, time, func, interval) {
		_clearTimer(timer, interval);
		if (interval === true) {
			return setInterval(func, time);
		} else {
			return setTimeout(func, time);
		}
	}

	/**
	 * @method private
	 * @name _clearTimer
	 * @description Clears an internal timer
	 * @param timer [int] "Timer ID"
	 */
	function _clearTimer(timer) {
		if (timer !== null) {
			clearInterval(timer);
			timer = null;
		}
	}

	/**
	 * @method private
	 * @name _getTransform3DSupport
	 * @description Determines if transforms are support
	 * @return [boolean] "True if transforms supported"
	 */
	function _getTransform3DSupport() {
		/* http://stackoverflow.com/questions/11628390/how-to-detect-css-translate3d-without-the-webkit-context */
		var prop = "transform",
			val = "translate3d(0px, 0px, 0px)",
			test = /translate3d\(0px, 0px, 0px\)/g,
			$div = $("<div>");

		$div.css(_prefix(prop, val));

		var check = $div[0].style.cssText.match(test);

		return (check !== null && check.length === 1);
	}


	$.fn.roller = function(method) {
		if (pub[method]) {
			return pub[method].apply(this, Array.prototype.slice.call(arguments, 1));
		} else if (typeof method === 'object' || !method) {
			return _init.apply(this, arguments);
		}
		return this;
	};

	$.roller = function(method) {
		if (method === "defaults") {
			pub.defaults.apply(this, Array.prototype.slice.call(arguments, 1));
		}
	};
})(jQuery, window);
/* 
 * Rubberband v3.0.3 - 2014-02-02 
 * A jQuery plugin for responsive media query events. Part of the Formstone Library. 
 * http://formstone.it/rubberband/ 
 * 
 * Copyright 2014 Ben Plum; MIT Licensed 
 */ 

;(function ($, window) {
	"use strict";

	var nativeSupport = (window.matchMedia !== undefined),
		currentState = null,
		mqMatches = {},
		mqStrings = {
			minWidth: "min-width",
			maxWidth: "max-width",
			minHeight: "min-height",
			maxHeight: "max-height"
		},
		bindings = [];
		//deferred = new $.Deferred();

	/**
	 * @options
	 * @param minWidth [array] <[ 0 ]> "Array of min-widths"
	 * @param maxWidth [array] <[ Infinity ]> "Array of max-widths"
	 * @param minHeight [array] <[ 0 ]> "Array of min-heights"
	 * @param maxHeight [array] <[ Infinity ]> "Array of max-heights"
	 * @param unit [string] <'px'> "Unit to use when matching widths and heights"
	 */
	var options = {
			//mediaQueries: [],  * @param mediaQueries [array] <[]> "Array of custom media queries to match against"
			minWidth: [0],
			maxWidth: [Infinity],
			minHeight: [0],
			maxHeight: [Infinity],
			unit: "px"
		};


	var pub = {

		/**
		 * @method
		 * @name bind
		 * @description Binds callbacks to media query matching
		 * @param media [string] "Media query to match"
		 * @param data [object] "Object containing 'enter' and 'leave' callbacks"
		 * @example $.rubberband("bind", "(min-width: 500px)", { ... });
		 */
		bind: function(media, data) {
			if (!bindings[media]) {
				bindings[media] = {
					mq: window.matchMedia(media),
					active: false,
					enter: [],
					leave: []
				};

				bindings[media].mq.addListener(_onBindingRespond);
			}

			for (var i in data) {
				if (data.hasOwnProperty(i) && bindings[media].hasOwnProperty(i)) {
					bindings[media][i].push(data[i]);
				}
			}

			_onBindingRespond(bindings[media].mq);

			return this;
		},

		/**
		 * @method
		 * @name defaults
		 * @description Sets default plugin options
		 * @param opts [object] <{}> "Options object"
		 * @example $.rubberband("defaults", opts);
		 */
		defaults: function(opts) {
			options = $.extend(options, opts || {});
		},

		/*
		ready: function() {
			return deferred.promise();
		},
		*/

		/**
		 * @method
		 * @name state
		 * @description Returns the current state
		 * @return [object] "Current state object"
		 * @example var state = $.rubberband("state");
		 */
		state: function () {
			return currentState;
		},

		/**
		 * @method
		 * @name unbind
		 * @description Unbinds all callbacks from media query
		 * @param media [string] "Media query to match"
		 * @example $.rubberband("unbind", "(min-width: 500px)", { ... });
		 */
		unbind: function(media) {
			if (bindings[media]) {
				bindings[media].mq.removeListener(_onBindingRespond);
				bindings = bindings.splice(bindings.indexOf(bindings[media]), 1);
			}

			return this;
		}
	};

	/**
	 * @method private
	 * @name _init
	 * @description Initializes plugin
	 * @param opts [object] "Initialization options"
	 */
	function _init(opts) {
		opts = opts || {};

		for (var i in mqStrings) {
			if (mqStrings.hasOwnProperty(i)) {
				options[i] = (opts[i]) ? $.merge(opts[i], options[i]) : options[i];
			}
		}
		options = $.extend(options, opts);

		// Do some sorting
		options.minWidth.sort(_sortDesc);
		options.maxWidth.sort(_sortAsc);
		options.minHeight.sort(_sortDesc);
		options.maxHeight.sort(_sortAsc);

		// Bind events to specific media query events
		for (var j in mqStrings) {
			if (mqStrings.hasOwnProperty(j)) {
				mqMatches[j] = {};
				for (var k in options[j]) {
					if (options[j].hasOwnProperty(k)) {
						var _mq = window.matchMedia( "(" + mqStrings[j] + ": " + (options[j][k] === Infinity ? 100000 : options[j][k]) + options.unit + ")" );
						_mq.addListener(_onRespond);
						mqMatches[j][ options[j][k] ] = _mq;
					}
				}
			}
		}

		// Fire initial event
		_onRespond();
	}

	/**
	 * @method private
	 * @name _onRespond
	 * @description Handles media query changes
	 */
	function _onRespond() {
		_setState();
		$(window).trigger("snap", [ currentState ]);
		//deferred.resolve();
	}

	/**
	 * @method private
	 * @name _setState
	 * @description Sets current media query match state
	 */
	function _setState() {
		currentState = {
			unit: options.unit
		};

		for (var i in mqStrings) {
			if (mqStrings.hasOwnProperty(i)) {
				for (var j in mqMatches[i]) {
					if (mqMatches[i].hasOwnProperty(j)) {
						if (mqMatches[i][j].matches) {
							var state = (j === "Infinity" ? Infinity : parseInt(j, 10));
							if (i.indexOf("max") > -1) {
								if (!currentState[i] || state < currentState[i]) {
									currentState[i] = state;
								}
							} else {
								if (!currentState[i] || state > currentState[i]) {
									currentState[i] = state;
								}
							}
						}
					}
				}
			}
		}
	}

	/**
	 * @method private
	 * @name _onBindingRespond
	 * @description Handles a binding's media query change
	 */
	function _onBindingRespond(mq) {
		var binding = bindings[mq.media],
			event = mq.matches ? "enter" : "leave";

		if (binding.active || (!binding.active && mq.matches)) {
			for (var i in binding[event]) {
				if (binding[event].hasOwnProperty(i)) {
					binding[event][i].apply(binding.mq);
				}
			}

			binding.active = true;
		}
	}

	/**
	 * @method private
	 * @name _sortAsc
	 * @description Sorts an array (ascending)
	 * @param a [mixed] "First value"
	 * @param b [mixed] "Second value"
	 * @return Difference between second and first values
	 */
	function _sortAsc(a, b) {
		return (b - a);
	}

	/**
	 * @method private
	 * @name _sortDesc
	 * @description Sorts an array (descending)
	 * @param a [mixed] "First value"
	 * @param b [mixed] "Second value"
	 * @return Difference between first and second values
	 */
	function _sortDesc(a, b) {
		return (a - b);
	}

	$.rubberband = function(method) {
		if (nativeSupport) {
			if (pub[method]) {
				return pub[method].apply(this, Array.prototype.slice.call(arguments, 1));
			} else if (typeof method === "object" || !method) {
				return _init.apply(this, arguments);
			}
		}
		return this;
	};
})(jQuery, window);
/*!
imgLiquid v0.9.944 / 03-05-2013
jQuery plugin to resize images to fit in a container.
Copyright (c) 2012 Alejandro Emparan (karacas) @krc_ale
Dual licensed under the MIT and GPL licenses
https://github.com/karacas/imgLiquid
**/
/*
ex:
	$('.imgLiquid').imgLiquid({fill:true});

	// OPTIONS:

	> js:
			fill: true,
			verticalAlign:		// 'center' //	'top'	//	'bottom' // '50%'  // '10%'
			horizontalAlign:	// 'center' //	'left'	//	'right'  // '50%'  // '10%'

	> CallBacks:
			onStart:		function(){},
			onFinish:		function(){},
			onItemStart:	function(index, container, img){},
			onItemFinish:	function(index, container, img){}

	> hml5 data attr (overwrite all)
			data-imgLiquid-fill='true'
			data-imgLiquid-horizontalAlign='center'
			data-imgLiquid-verticalAlign='center'
*/
//


var imgLiquid = imgLiquid || {VER: '0.9.944'};
imgLiquid.bgs_Available = false;
imgLiquid.bgs_CheckRunned = false;
imgLiquid.injectCss = '.imgLiquid img {visibility:hidden}';


(function ($) {

	// ___________________________________________________________________

	function checkBgsIsavailable() {
		if (imgLiquid.bgs_CheckRunned) return;
		else imgLiquid.bgs_CheckRunned = true;

		var spanBgs = $('<span style="background-size:cover" />');
		$('body').append(spanBgs);

		!function () {
			var bgs_Check = spanBgs[0];
			if (!bgs_Check || !window.getComputedStyle) return;
			var compStyle = window.getComputedStyle(bgs_Check, null);
			if (!compStyle || !compStyle.backgroundSize) return;
			imgLiquid.bgs_Available = (compStyle.backgroundSize === 'cover');
		}();

		spanBgs.remove();
	}





	// ___________________________________________________________________

	$.fn.extend({
		imgLiquid: function (options) {

			this.defaults = {
				fill: true,
				verticalAlign: 'center',			//	'top'	//	'bottom' // '50%'  // '10%'
				horizontalAlign: 'center',			//	'left'	//	'right'  // '50%'  // '10%'
				useBackgroundSize: true,
				useDataHtmlAttr: true,

				responsive: true,					/* Only for use with BackgroundSize false (or old browsers) */
				delay: 0,							/* Only for use with BackgroundSize false (or old browsers) */
				fadeInTime: 0,						/* Only for use with BackgroundSize false (or old browsers) */
				removeBoxBackground: true,			/* Only for use with BackgroundSize false (or old browsers) */
				hardPixels: true,					/* Only for use with BackgroundSize false (or old browsers) */
				responsiveCheckTime: 500,			/* Only for use with BackgroundSize false (or old browsers) */ /* time to check div resize */
				timecheckvisibility: 500,			/* Only for use with BackgroundSize false (or old browsers) */ /* time to recheck if visible/loaded */

				// CALLBACKS
				onStart: null,						// no-params
				onFinish: null,						// no-params
				onItemStart: null,					// params: (index, container, img )
				onItemFinish: null,					// params: (index, container, img )
				onItemError: null					// params: (index, container, img )
			};


			checkBgsIsavailable();
			var imgLiquidRoot = this;

			// Extend global settings
			this.options = options;
			this.settings = $.extend({}, this.defaults, this.options);

			// CallBack
			if (this.settings.onStart) this.settings.onStart();




			// ___________________________________________________________________

			return this.each(function ($i) {

				// MAIN >> each for image

				var settings = imgLiquidRoot.settings,
				$imgBoxCont = $(this),
				$img = $('img:first',$imgBoxCont);
				if (!$img.length) {onError(); return;}


				// Extend settings
				if (!$img.data('imgLiquid_settings')) {
					// First time
					settings = $.extend({}, imgLiquidRoot.settings, getSettingsOverwrite());
				} else {
					// Recall
					// Remove Classes
					$imgBoxCont.removeClass('imgLiquid_error').removeClass('imgLiquid_ready');
					settings = $.extend({}, $img.data('imgLiquid_settings'), imgLiquidRoot.options);
				}
				$img.data('imgLiquid_settings', settings);


				// Start CallBack
				if (settings.onItemStart) settings.onItemStart($i, $imgBoxCont, $img); /* << CallBack */


				// Process
				if (imgLiquid.bgs_Available && settings.useBackgroundSize)
					processBgSize();
				else
					processOldMethod();


				// END MAIN <<




				// ___________________________________________________________________

				function processBgSize() {

					// Check change img src
					if ($imgBoxCont.css('background-image').indexOf(encodeURI($img.attr('src'))) === -1) {
						// Change
						$imgBoxCont.css({'background-image': 'url("' + encodeURI($img.attr('src')) + '")'});
					}

					$imgBoxCont.css({
						'background-size':		(settings.fill) ? 'cover' : 'contain',
						'background-position':	(settings.horizontalAlign + ' ' + settings.verticalAlign).toLowerCase(),
						'background-repeat':	'no-repeat'
					});

					$('a:first', $imgBoxCont).css({
						'display':	'block',
						'width':	'100%',
						'height':	'100%'
					});

					$('img', $imgBoxCont).css({'display': 'none'});

					if (settings.onItemFinish) settings.onItemFinish($i, $imgBoxCont, $img); /* << CallBack */

					$imgBoxCont.addClass('imgLiquid_bgSize');
					$imgBoxCont.addClass('imgLiquid_ready');
					checkFinish();
				}




				// ___________________________________________________________________

				function processOldMethod() {

					// Check change img src
					if ($img.data('oldSrc') && $img.data('oldSrc') !== $img.attr('src')) {

						/* Clone & Reset img */
						var $imgCopy = $img.clone().removeAttr('style');
						$imgCopy.data('imgLiquid_settings', $img.data('imgLiquid_settings'));
						$img.parent().prepend($imgCopy);
						$img.remove();
						$img = $imgCopy;
						$img[0].width = 0;

						// Bug ie with > if (!$img[0].complete && $img[0].width) onError();
						setTimeout(processOldMethod, 10);
						return;
					}


					// Reproceess?
					if ($img.data('imgLiquid_oldProcessed')) {
						makeOldProcess(); return;
					}


					// Set data
					$img.data('imgLiquid_oldProcessed', false);
					$img.data('oldSrc', $img.attr('src'));


					// Hide others images
					$('img:not(:first)', $imgBoxCont).css('display', 'none');


					// CSSs
					$imgBoxCont.css({'overflow': 'hidden'});
					$img.fadeTo(0, 0).removeAttr('width').removeAttr('height').css({
						'visibility': 'visible',
						'max-width': 'none',
						'max-height': 'none',
						'width': 'auto',
						'height': 'auto',
						'display': 'block'
					});


					// CheckErrors
					$img.on('error', onError);
					$img[0].onerror = onError;


					// loop until load
					function onLoad() {
						if ($img.data('imgLiquid_error') || $img.data('imgLiquid_loaded') || $img.data('imgLiquid_oldProcessed')) return;
						if ($imgBoxCont.is(':visible') && $img[0].complete && $img[0].width > 0 && $img[0].height > 0) {
							$img.data('imgLiquid_loaded', true);
							setTimeout(makeOldProcess, $i * settings.delay);
						} else {
							setTimeout(onLoad, settings.timecheckvisibility);
						}
					}


					onLoad();
					checkResponsive();
				}




				// ___________________________________________________________________

				function checkResponsive() {

					/* Only for oldProcessed method (background-size dont need) */

					if (!settings.responsive && !$img.data('imgLiquid_oldProcessed')) return;
					if (!$img.data('imgLiquid_settings')) return;

					settings = $img.data('imgLiquid_settings');

					$imgBoxCont.actualSize = $imgBoxCont.get(0).offsetWidth + ($imgBoxCont.get(0).offsetHeight / 10000);
					if ($imgBoxCont.sizeOld && $imgBoxCont.actualSize !== $imgBoxCont.sizeOld) makeOldProcess();

					$imgBoxCont.sizeOld = $imgBoxCont.actualSize;
					setTimeout(checkResponsive, settings.responsiveCheckTime);
				}




				// ___________________________________________________________________

				function onError() {
					$img.data('imgLiquid_error', true);
					$imgBoxCont.addClass('imgLiquid_error');
					if (settings.onItemError) settings.onItemError($i, $imgBoxCont, $img); /* << CallBack */
					checkFinish();
				}




				// ___________________________________________________________________

				function getSettingsOverwrite() {
					var SettingsOverwrite = {};

					if (imgLiquidRoot.settings.useDataHtmlAttr) {
						var dif = $imgBoxCont.attr('data-imgLiquid-fill'),
						ha =  $imgBoxCont.attr('data-imgLiquid-horizontalAlign'),
						va =  $imgBoxCont.attr('data-imgLiquid-verticalAlign');

						if (dif === 'true' || dif === 'false') SettingsOverwrite.fill = Boolean (dif === 'true');
						if (ha !== undefined && (ha === 'left' || ha === 'center' || ha === 'right' || ha.indexOf('%') !== -1)) SettingsOverwrite.horizontalAlign = ha;
						if (va !== undefined && (va === 'top' ||  va === 'bottom' || va === 'center' || va.indexOf('%') !== -1)) SettingsOverwrite.verticalAlign = va;
					}

					if (imgLiquid.isIE && imgLiquidRoot.settings.ieFadeInDisabled) SettingsOverwrite.fadeInTime = 0; //ie no anims
					return SettingsOverwrite;
				}





				// ___________________________________________________________________

				function makeOldProcess() { /* Only for old browsers, or useBackgroundSize seted false */

					// Calculate size
					var w, h, wn, hn, ha, va, hdif, vdif,
					margT = 0,
					margL = 0,
					$imgCW = $imgBoxCont.width(),
					$imgCH = $imgBoxCont.height();


					// Save original sizes
					if ($img.data('owidth')	=== undefined) $img.data('owidth',	$img[0].width);
					if ($img.data('oheight') === undefined) $img.data('oheight', $img[0].height);


					// Compare ratio
					if (settings.fill === ($imgCW / $imgCH) >= ($img.data('owidth') / $img.data('oheight'))) {
						w = '100%';
						h = 'auto';
						wn = Math.floor($imgCW);
						hn = Math.floor($imgCW * ($img.data('oheight') / $img.data('owidth')));
					} else {
						w = 'auto';
						h = '100%';
						wn = Math.floor($imgCH * ($img.data('owidth') / $img.data('oheight')));
						hn = Math.floor($imgCH);
					}

					// Align X
					ha = settings.horizontalAlign.toLowerCase();
					hdif = $imgCW - wn;
					if (ha === 'left') margL = 0;
					if (ha === 'center') margL = hdif * 0.5;
					if (ha === 'right') margL = hdif;
					if (ha.indexOf('%') !== -1){
						ha = parseInt (ha.replace('%',''), 10);
						if (ha > 0) margL = hdif * ha * 0.01;
					}


					// Align Y
					va = settings.verticalAlign.toLowerCase();
					vdif = $imgCH - hn;
					if (va === 'top') margT = 0;
					if (va === 'center') margT = vdif * 0.5;
					if (va === 'bottom') margT = vdif;
					if (va.indexOf('%') !== -1){
						va = parseInt (va.replace('%',''), 10);
						if (va > 0) margT = vdif * va * 0.01;
					}


					// Add Css
					if (settings.hardPixels) {w = wn; h = hn;}
					$img.css({
						'width': w,
						'height': h,
						'margin-left': Math.floor(margL),
						'margin-top': Math.floor(margT)
					});


					// FadeIn > Only first time
					if (!$img.data('imgLiquid_oldProcessed')) {
						$img.fadeTo(settings.fadeInTime, 1);
						$img.data('imgLiquid_oldProcessed', true);
						if (settings.removeBoxBackground) $imgBoxCont.css('background-image', 'none');
						$imgBoxCont.addClass('imgLiquid_nobgSize');
						$imgBoxCont.addClass('imgLiquid_ready');
					}


					if (settings.onItemFinish) settings.onItemFinish($i, $imgBoxCont, $img); /* << CallBack */
					checkFinish();
				}




				// ___________________________________________________________________

				function checkFinish() { /* Check callBack */
					if ($i === imgLiquidRoot.length - 1) if (imgLiquidRoot.settings.onFinish) imgLiquidRoot.settings.onFinish();
				}


			});
		}
	});
})(jQuery);



// Inject css styles ______________________________________________________
!function () {
	var css = imgLiquid.injectCss,
	head = document.getElementsByTagName('head')[0],
	style = document.createElement('style');
	style.type = 'text/css';
	if (style.styleSheet) {
		style.styleSheet.cssText = css;
	} else {
		style.appendChild(document.createTextNode(css));
	}
	head.appendChild(style);
}();

/**
 * jQuery Geocoding and Places Autocomplete Plugin - V 1.6.5
 *
 * @author Martin Kleppe <kleppe@ubilabs.net>, 2014
 * @author Ubilabs http://ubilabs.net, 2014
 * @license MIT License <http://www.opensource.org/licenses/mit-license.php>
 */

// # $.geocomplete()
// ## jQuery Geocoding and Places Autocomplete Plugin
//
// * https://github.com/ubilabs/geocomplete/
// * by Martin Kleppe <kleppe@ubilabs.net>

(function($, window, document, undefined){

  // ## Options
  // The default options for this plugin.
  //
  // * `map` - Might be a selector, an jQuery object or a DOM element. Default is `false` which shows no map.
  // * `details` - The container that should be populated with data. Defaults to `false` which ignores the setting.
  // * 'detailsScope' - Allows you to scope the 'details' container and have multiple geocomplete fields on one page. Must be a parent of the input. Default is 'null'
  // * `location` - Location to initialize the map on. Might be an address `string` or an `array` with [latitude, longitude] or a `google.maps.LatLng`object. Default is `false` which shows a blank map.
  // * `bounds` - Whether to snap geocode search to map bounds. Default: `true` if false search globally. Alternatively pass a custom `LatLngBounds object.
  // * `autoselect` - Automatically selects the highlighted item or the first item from the suggestions list on Enter.
  // * `detailsAttribute` - The attribute's name to use as an indicator. Default: `"name"`
  // * `mapOptions` - Options to pass to the `google.maps.Map` constructor. See the full list [here](http://code.google.com/apis/maps/documentation/javascript/reference.html#MapOptions).
  // * `mapOptions.zoom` - The inital zoom level. Default: `14`
  // * `mapOptions.scrollwheel` - Whether to enable the scrollwheel to zoom the map. Default: `false`
  // * `mapOptions.mapTypeId` - The map type. Default: `"roadmap"`
  // * `markerOptions` - The options to pass to the `google.maps.Marker` constructor. See the full list [here](http://code.google.com/apis/maps/documentation/javascript/reference.html#MarkerOptions).
  // * `markerOptions.draggable` - If the marker is draggable. Default: `false`. Set to true to enable dragging.
  // * `markerOptions.disabled` - Do not show marker. Default: `false`. Set to true to disable marker.
  // * `maxZoom` - The maximum zoom level too zoom in after a geocoding response. Default: `16`
  // * `types` - An array containing one or more of the supported types for the places request. Default: `['geocode']` See the full list [here](http://code.google.com/apis/maps/documentation/javascript/places.html#place_search_requests).
  // * `blur` - Trigger geocode when input loses focus.
  // * `geocodeAfterResult` - If blur is set to true, choose whether to geocode if user has explicitly selected a result before blur.
  // * `restoreValueAfterBlur` - Restores the input's value upon blurring. Default is `false` which ignores the setting.

  var defaults = {
    bounds: true,
    country: null,
    map: false,
    details: false,
    detailsAttribute: "name",
    detailsScope: null,
    autoselect: true,
    location: false,

    mapOptions: {
      zoom: 14,
      scrollwheel: false,
      mapTypeId: "roadmap"
    },

    markerOptions: {
      draggable: false
    },

    maxZoom: 16,
    types: ['geocode'],
    blur: false,
    geocodeAfterResult: false,
    restoreValueAfterBlur: false
  };

  // See: [Geocoding Types](https://developers.google.com/maps/documentation/geocoding/#Types)
  // on Google Developers.
  var componentTypes = ("street_address route intersection political " +
    "country administrative_area_level_1 administrative_area_level_2 " +
    "administrative_area_level_3 colloquial_area locality sublocality " +
    "neighborhood premise subpremise postal_code natural_feature airport " +
    "park point_of_interest post_box street_number floor room " +
    "lat lng viewport location " +
    "formatted_address location_type bounds").split(" ");

  // See: [Places Details Responses](https://developers.google.com/maps/documentation/javascript/places#place_details_responses)
  // on Google Developers.
  var placesDetails = ("id place_id url website vicinity reference name rating " +
    "international_phone_number icon formatted_phone_number").split(" ");

  // The actual plugin constructor.
  function GeoComplete(input, options) {

    this.options = $.extend(true, {}, defaults, options);

    this.input = input;
    this.$input = $(input);

    this._defaults = defaults;
    this._name = 'geocomplete';

    this.init();
  }

  // Initialize all parts of the plugin.
  $.extend(GeoComplete.prototype, {
    init: function(){
      this.initMap();
      this.initMarker();
      this.initGeocoder();
      this.initDetails();
      this.initLocation();
    },

    // Initialize the map but only if the option `map` was set.
    // This will create a `map` within the given container
    // using the provided `mapOptions` or link to the existing map instance.
    initMap: function(){
      if (!this.options.map){ return; }

      if (typeof this.options.map.setCenter == "function"){
        this.map = this.options.map;
        return;
      }

      this.map = new google.maps.Map(
        $(this.options.map)[0],
        this.options.mapOptions
      );

      // add click event listener on the map
      google.maps.event.addListener(
        this.map,
        'click',
        $.proxy(this.mapClicked, this)
      );
 
      // add dragend even listener on the map
      google.maps.event.addListener(
        this.map,
        'dragend',
        $.proxy(this.mapDragged, this)
      );
      
      // add idle even listener on the map
      google.maps.event.addListener(
        this.map,
        'idle',
        $.proxy(this.mapIdle, this)
      );

      google.maps.event.addListener(
        this.map,
        'zoom_changed',
        $.proxy(this.mapZoomed, this)
      );
    },

    // Add a marker with the provided `markerOptions` but only
    // if the option was set. Additionally it listens for the `dragend` event
    // to notify the plugin about changes.
    initMarker: function(){
      if (!this.map){ return; }
      var options = $.extend(this.options.markerOptions, { map: this.map });

      if (options.disabled){ return; }

      this.marker = new google.maps.Marker(options);

      google.maps.event.addListener(
        this.marker,
        'dragend',
        $.proxy(this.markerDragged, this)
      );
    },

    // Associate the input with the autocompleter and create a geocoder
    // to fall back when the autocompleter does not return a value.
    initGeocoder: function(){

      // Indicates is user did select a result from the dropdown.
      var selected = false;

      var options = {
        types: this.options.types,
        bounds: this.options.bounds === true ? null : this.options.bounds,
        componentRestrictions: this.options.componentRestrictions
      };

      if (this.options.country){
        options.componentRestrictions = {country: this.options.country};
      }

      this.autocomplete = new google.maps.places.Autocomplete(
        this.input, options
      );

      this.geocoder = new google.maps.Geocoder();

      // Bind autocomplete to map bounds but only if there is a map
      // and `options.bindToMap` is set to true.
      if (this.map && this.options.bounds === true){
        this.autocomplete.bindTo('bounds', this.map);
      }

      // Watch `place_changed` events on the autocomplete input field.
      google.maps.event.addListener(
        this.autocomplete,
        'place_changed',
        $.proxy(this.placeChanged, this)
      );

      // Prevent parent form from being submitted if user hit enter.
      this.$input.on('keypress.' + this._name, function(event){
        if (event.keyCode === 13){ return false; }
      });

      // Assume that if user types anything after having selected a result,
      // the selected location is not valid any more.
      if (this.options.geocodeAfterResult === true){
        this.$input.bind('keypress.' + this._name, $.proxy(function(){
          if (event.keyCode != 9 && this.selected === true){
              this.selected = false;
          }
        }, this));
      }

      // Listen for "geocode" events and trigger find action.
      this.$input.bind('geocode.' + this._name, $.proxy(function(){
        this.find();
      }, this));

      // Saves the previous input value
      this.$input.bind('geocode:result.' + this._name, $.proxy(function(){
        this.lastInputVal = this.$input.val();
      }, this));

      // Trigger find action when input element is blurred out and user has
      // not explicitly selected a result.
      // (Useful for typing partial location and tabbing to the next field
      // or clicking somewhere else.)
      if (this.options.blur === true){
        this.$input.on('blur.' + this._name, $.proxy(function(){
          if (this.options.geocodeAfterResult === true && this.selected === true) { return; }

          if (this.options.restoreValueAfterBlur === true && this.selected === true) {
            setTimeout($.proxy(this.restoreLastValue, this), 0);
          } else {
            this.find();
          }
        }, this));
      }
    },

    // Prepare a given DOM structure to be populated when we got some data.
    // This will cycle through the list of component types and map the
    // corresponding elements.
    initDetails: function(){
      if (!this.options.details){ return; }

      if(this.options.detailsScope) {
        var $details = $(this.input).parents(this.options.detailsScope).find(this.options.details);
      } else {
        var $details = $(this.options.details);
      }

      var attribute = this.options.detailsAttribute,
        details = {};

      function setDetail(value){
        details[value] = $details.find("[" +  attribute + "=" + value + "]");
      }

      $.each(componentTypes, function(index, key){
        setDetail(key);
        setDetail(key + "_short");
      });

      $.each(placesDetails, function(index, key){
        setDetail(key);
      });

      this.$details = $details;
      this.details = details;
    },

    // Set the initial location of the plugin if the `location` options was set.
    // This method will care about converting the value into the right format.
    initLocation: function() {

      var location = this.options.location, latLng;

      if (!location) { return; }

      if (typeof location == 'string') {
        this.find(location);
        return;
      }

      if (location instanceof Array) {
        latLng = new google.maps.LatLng(location[0], location[1]);
      }

      if (location instanceof google.maps.LatLng){
        latLng = location;
      }

      if (latLng){
        if (this.map){ this.map.setCenter(latLng); }
        if (this.marker){ this.marker.setPosition(latLng); }
      }
    },

    destroy: function(){
      if (this.map) {
        google.maps.event.clearInstanceListeners(this.map);
        google.maps.event.clearInstanceListeners(this.marker);
      }

      this.autocomplete.unbindAll();
      google.maps.event.clearInstanceListeners(this.autocomplete);
      google.maps.event.clearInstanceListeners(this.input);
      this.$input.removeData();
      this.$input.off(this._name);
      this.$input.unbind('.' + this._name);
    },

    // Look up a given address. If no `address` was specified it uses
    // the current value of the input.
    find: function(address){
      this.geocode({
        address: address || this.$input.val()
      });
    },

    // Requests details about a given location.
    // Additionally it will bias the requests to the provided bounds.
    geocode: function(request){
      // Don't geocode if the requested address is empty
      if (!request.address) {
        return;
      }
      if (this.options.bounds && !request.bounds){
        if (this.options.bounds === true){
          request.bounds = this.map && this.map.getBounds();
        } else {
          request.bounds = this.options.bounds;
        }
      }

      if (this.options.country){
        request.region = this.options.country;
      }

      this.geocoder.geocode(request, $.proxy(this.handleGeocode, this));
    },

    // Get the selected result. If no result is selected on the list, then get
    // the first result from the list.
    selectFirstResult: function() {
      //$(".pac-container").hide();

      var selected = '';
      // Check if any result is selected.
      if ($(".pac-item-selected")[0]) {
        selected = '-selected';
      }

      // Get the first suggestion's text.
      var $span1 = $(".pac-container:last .pac-item" + selected + ":first span:nth-child(2)").text();
      var $span2 = $(".pac-container:last .pac-item" + selected + ":first span:nth-child(3)").text();

      // Adds the additional information, if available.
      var firstResult = $span1;
      if ($span2) {
        firstResult += " - " + $span2;
      }

      this.$input.val(firstResult);

      return firstResult;
    },

    // Restores the input value using the previous value if it exists
    restoreLastValue: function() {
      if (this.lastInputVal){ this.$input.val(this.lastInputVal); }
    },

    // Handles the geocode response. If more than one results was found
    // it triggers the "geocode:multiple" events. If there was an error
    // the "geocode:error" event is fired.
    handleGeocode: function(results, status){
      if (status === google.maps.GeocoderStatus.OK) {
        var result = results[0];
        this.$input.val(result.formatted_address);
        this.update(result);

        if (results.length > 1){
          this.trigger("geocode:multiple", results);
        }

      } else {
        this.trigger("geocode:error", status);
      }
    },

    // Triggers a given `event` with optional `arguments` on the input.
    trigger: function(event, argument){
      this.$input.trigger(event, [argument]);
    },

    // Set the map to a new center by passing a `geometry`.
    // If the geometry has a viewport, the map zooms out to fit the bounds.
    // Additionally it updates the marker position.
    center: function(geometry){
      if (geometry.viewport){
        this.map.fitBounds(geometry.viewport);
        if (this.map.getZoom() > this.options.maxZoom){
          this.map.setZoom(this.options.maxZoom);
        }
      } else {
        this.map.setZoom(this.options.maxZoom);
        this.map.setCenter(geometry.location);
      }

      if (this.marker){
        this.marker.setPosition(geometry.location);
        this.marker.setAnimation(this.options.markerOptions.animation);
      }
    },

    // Update the elements based on a single places or geocoding response
    // and trigger the "geocode:result" event on the input.
    update: function(result){

      if (this.map){
        this.center(result.geometry);
      }

      if (this.$details){
        this.fillDetails(result);
      }

      this.trigger("geocode:result", result);
    },

    // Populate the provided elements with new `result` data.
    // This will lookup all elements that has an attribute with the given
    // component type.
    fillDetails: function(result){

      var data = {},
        geometry = result.geometry,
        viewport = geometry.viewport,
        bounds = geometry.bounds;

      // Create a simplified version of the address components.
      $.each(result.address_components, function(index, object){
        var name = object.types[0];

        $.each(object.types, function(index, name){
          data[name] = object.long_name;
          data[name + "_short"] = object.short_name;
        });
      });

      // Add properties of the places details.
      $.each(placesDetails, function(index, key){
        data[key] = result[key];
      });

      // Add infos about the address and geometry.
      $.extend(data, {
        formatted_address: result.formatted_address,
        location_type: geometry.location_type || "PLACES",
        viewport: viewport,
        bounds: bounds,
        location: geometry.location,
        lat: geometry.location.lat(),
        lng: geometry.location.lng()
      });

      // Set the values for all details.
      $.each(this.details, $.proxy(function(key, $detail){
        var value = data[key];
        this.setDetail($detail, value);
      }, this));

      this.data = data;
    },

    // Assign a given `value` to a single `$element`.
    // If the element is an input, the value is set, otherwise it updates
    // the text content.
    setDetail: function($element, value){

      if (value === undefined){
        value = "";
      } else if (typeof value.toUrlValue == "function"){
        value = value.toUrlValue();
      }

      if ($element.is(":input")){
        $element.val(value);
      } else {
        $element.text(value);
      }
    },

    // Fire the "geocode:dragged" event and pass the new position.
    markerDragged: function(event){
      this.trigger("geocode:dragged", event.latLng);
    },

    mapClicked: function(event) {
        this.trigger("geocode:click", event.latLng);
    },
   
    // Fire the "geocode:mapdragged" event and pass the current position of the map center.
    mapDragged: function(event) {
      this.trigger("geocode:mapdragged", this.map.getCenter());
    },

    // Fire the "geocode:idle" event and pass the current position of the map center.
    mapIdle: function(event) {
      this.trigger("geocode:idle", this.map.getCenter());
    },

    mapZoomed: function(event) {
      this.trigger("geocode:zoom", this.map.getZoom());
    },

    // Restore the old position of the marker to the last knwon location.
    resetMarker: function(){
      this.marker.setPosition(this.data.location);
      this.setDetail(this.details.lat, this.data.location.lat());
      this.setDetail(this.details.lng, this.data.location.lng());
    },

    // Update the plugin after the user has selected an autocomplete entry.
    // If the place has no geometry it passes it to the geocoder.
    placeChanged: function(){
      var place = this.autocomplete.getPlace();
      this.selected = true;

      if (!place.geometry){
        if (this.options.autoselect) {
          // Automatically selects the highlighted item or the first item from the
          // suggestions list.
          var autoSelection = this.selectFirstResult();
          this.find(autoSelection);
        }
      } else {
        // Use the input text if it already gives geometry.
        this.update(place);
      }
    }
  });

  // A plugin wrapper around the constructor.
  // Pass `options` with all settings that are different from the default.
  // The attribute is used to prevent multiple instantiations of the plugin.
  $.fn.geocomplete = function(options) {

    var attribute = 'plugin_geocomplete';

    // If you call `.geocomplete()` with a string as the first parameter
    // it returns the corresponding property or calls the method with the
    // following arguments.
    if (typeof options == "string"){

      var instance = $(this).data(attribute) || $(this).geocomplete().data(attribute),
        prop = instance[options];

      if (typeof prop == "function"){
        prop.apply(instance, Array.prototype.slice.call(arguments, 1));
        return $(this);
      } else {
        if (arguments.length == 2){
          prop = arguments[1];
        }
        return prop;
      }
    } else {
      return this.each(function() {
        // Prevent against multiple instantiations.
        var instance = $.data(this, attribute);
        if (!instance) {
          instance = new GeoComplete( this, options );
          $.data(this, attribute, instance);
        }
      });
    }
  };

})( jQuery, window, document );
/**
 * author Christopher Blum
 *    - based on the idea of Remy Sharp, http://remysharp.com/2009/01/26/element-in-view-event-plugin/
 *    - forked from http://github.com/zuk/jquery.inview/
 */
(function ($) {
  var inviewObjects = {}, viewportSize, viewportOffset,
      d = document, w = window, documentElement = d.documentElement, expando = $.expando;

  $.event.special.inview = {
    add: function(data) {
      inviewObjects[data.guid + "-" + this[expando]] = { data: data, $element: $(this) };
    },

    remove: function(data) {
      try { delete inviewObjects[data.guid + "-" + this[expando]]; } catch(e) {}
    }
  };

  function getViewportSize() {
    var mode, domObject, size = { height: w.innerHeight, width: w.innerWidth };

    // if this is correct then return it. iPad has compat Mode, so will
    // go into check clientHeight/clientWidth (which has the wrong value).
    if (!size.height) {
      mode = d.compatMode;
      if (mode || !$.support.boxModel) { // IE, Gecko
        domObject = mode === 'CSS1Compat' ?
          documentElement : // Standards
          d.body; // Quirks
        size = {
          height: domObject.clientHeight,
          width:  domObject.clientWidth
        };
      }
    }

    return size;
  }

  function getViewportOffset() {
    return {
      top:  w.pageYOffset || documentElement.scrollTop   || d.body.scrollTop,
      left: w.pageXOffset || documentElement.scrollLeft  || d.body.scrollLeft
    };
  }

  function checkInView() {
    var $elements = $(), elementsLength, i = 0;

    $.each(inviewObjects, function(i, inviewObject) {
      var selector  = inviewObject.data.selector,
          $element  = inviewObject.$element;
      $elements = $elements.add(selector ? $element.find(selector) : $element);
    });

    elementsLength = $elements.length;
    if (elementsLength) {
      viewportSize   = viewportSize   || getViewportSize();
      viewportOffset = viewportOffset || getViewportOffset();

      for (; i<elementsLength; i++) {
        // Ignore elements that are not in the DOM tree
        if (!$.contains(documentElement, $elements[i])) {
          continue;
        }

        var element       = $elements[i],
            $element      = $(element),
            elementSize   = { height: $element.height(), width: $element.width() },
            elementOffset = $element.offset(),
            inView        = $element.data('inview'),
            visiblePartX,
            visiblePartY,
            visiblePartsMerged;
        
        // Don't ask me why because I haven't figured out yet:
        // viewportOffset and viewportSize are sometimes suddenly null in Firefox 5.
        // Even though it sounds weird:
        // It seems that the execution of this function is interferred by the onresize/onscroll event
        // where viewportOffset and viewportSize are unset
        if (!viewportOffset || !viewportSize) {
          return;
        }
        
        if (element.offsetWidth > 0 && element.offsetHeight > 0 && element.style.display != "none" &&
            elementOffset.top + elementSize.height > viewportOffset.top &&
            elementOffset.top < viewportOffset.top + viewportSize.height &&
            elementOffset.left + elementSize.width > viewportOffset.left &&
            elementOffset.left < viewportOffset.left + viewportSize.width) {
          visiblePartX = (viewportOffset.left > elementOffset.left ?
            'right' : (viewportOffset.left + viewportSize.width) < (elementOffset.left + elementSize.width) ?
            'left' : 'both');
          visiblePartY = (viewportOffset.top > elementOffset.top ?
            'bottom' : (viewportOffset.top + viewportSize.height) < (elementOffset.top + elementSize.height) ?
            'top' : 'both');
          visiblePartsMerged = visiblePartX + "-" + visiblePartY;
          if (!inView || inView !== visiblePartsMerged) {
            $element.data('inview', visiblePartsMerged).trigger('inview', [true, visiblePartX, visiblePartY]);
          }
        } else if (inView) {
          $element.data('inview', false).trigger('inview', [false]);
        }
      }
    }
  }

  $(w).bind("scroll resize", function() {
    viewportSize = viewportOffset = null;
  });
  
  // IE < 9 scrolls to focused elements without firing the "scroll" event
  if (!documentElement.addEventListener && documentElement.attachEvent) {
    documentElement.attachEvent("onfocusin", function() {
      viewportOffset = null;
    });
  }

  // Use setInterval in order to also make sure this captures elements within
  // "overflow:scroll" elements or elements that appeared in the dom tree due to
  // dom manipulation and reflow
  // old: $(window).scroll(checkInView);
  //
  // By the way, iOS (iPad, iPhone, ...) seems to not execute, or at least delays
  // intervals while the user scrolls. Therefore the inview event might fire a bit late there
  setInterval(checkInView, 250);
})(jQuery);
/*!
 * skrollr core
 *
 * Alexander Prinzhorn - https://github.com/Prinzhorn/skrollr
 *
 * Free to use under terms of MIT license
 */
(function(window, document, undefined) {
	'use strict';

	/*
	 * Global api.
	 */
	var skrollr = {
		get: function() {
			return _instance;
		},
		//Main entry point.
		init: function(options) {
			return _instance || new Skrollr(options);
		},
		VERSION: '0.6.26'
	};

	//Minify optimization.
	var hasProp = Object.prototype.hasOwnProperty;
	var Math = window.Math;
	var getStyle = window.getComputedStyle;

	//They will be filled when skrollr gets initialized.
	var documentElement;
	var body;

	var EVENT_TOUCHSTART = 'touchstart';
	var EVENT_TOUCHMOVE = 'touchmove';
	var EVENT_TOUCHCANCEL = 'touchcancel';
	var EVENT_TOUCHEND = 'touchend';

	var SKROLLABLE_CLASS = 'skrollable';
	var SKROLLABLE_BEFORE_CLASS = SKROLLABLE_CLASS + '-before';
	var SKROLLABLE_BETWEEN_CLASS = SKROLLABLE_CLASS + '-between';
	var SKROLLABLE_AFTER_CLASS = SKROLLABLE_CLASS + '-after';

	var SKROLLR_CLASS = 'skrollr';
	var NO_SKROLLR_CLASS = 'no-' + SKROLLR_CLASS;
	var SKROLLR_DESKTOP_CLASS = SKROLLR_CLASS + '-desktop';
	var SKROLLR_MOBILE_CLASS = SKROLLR_CLASS + '-mobile';

	var DEFAULT_EASING = 'linear';
	var DEFAULT_DURATION = 1000;//ms
	var DEFAULT_MOBILE_DECELERATION = 0.004;//pixel/ms²

	var DEFAULT_SMOOTH_SCROLLING_DURATION = 200;//ms

	var ANCHOR_START = 'start';
	var ANCHOR_END = 'end';
	var ANCHOR_CENTER = 'center';
	var ANCHOR_BOTTOM = 'bottom';

	//The property which will be added to the DOM element to hold the ID of the skrollable.
	var SKROLLABLE_ID_DOM_PROPERTY = '___skrollable_id';

	var rxTouchIgnoreTags = /^(?:input|textarea|button|select)$/i;

	var rxTrim = /^\s+|\s+$/g;

	//Find all data-attributes. data-[_constant]-[offset]-[anchor]-[anchor].
	var rxKeyframeAttribute = /^data(?:-(_\w+))?(?:-?(-?\d*\.?\d+p?))?(?:-?(start|end|top|center|bottom))?(?:-?(top|center|bottom))?$/;

	var rxPropValue = /\s*(@?[\w\-\[\]]+)\s*:\s*(.+?)\s*(?:;|$)/gi;

	//Easing function names follow the property in square brackets.
	var rxPropEasing = /^(@?[a-z\-]+)\[(\w+)\]$/;

	var rxCamelCase = /-([a-z0-9_])/g;
	var rxCamelCaseFn = function(str, letter) {
		return letter.toUpperCase();
	};

	//Numeric values with optional sign.
	var rxNumericValue = /[\-+]?[\d]*\.?[\d]+/g;

	//Used to replace occurences of {?} with a number.
	var rxInterpolateString = /\{\?\}/g;

	//Finds rgb(a) colors, which don't use the percentage notation.
	var rxRGBAIntegerColor = /rgba?\(\s*-?\d+\s*,\s*-?\d+\s*,\s*-?\d+/g;

	//Finds all gradients.
	var rxGradient = /[a-z\-]+-gradient/g;

	//Vendor prefix. Will be set once skrollr gets initialized.
	var theCSSPrefix = '';
	var theDashedCSSPrefix = '';

	//Will be called once (when skrollr gets initialized).
	var detectCSSPrefix = function() {
		//Only relevant prefixes. May be extended.
		//Could be dangerous if there will ever be a CSS property which actually starts with "ms". Don't hope so.
		var rxPrefixes = /^(?:O|Moz|webkit|ms)|(?:-(?:o|moz|webkit|ms)-)/;

		//Detect prefix for current browser by finding the first property using a prefix.
		if(!getStyle) {
			return;
		}

		var style = getStyle(body, null);

		for(var k in style) {
			//We check the key and if the key is a number, we check the value as well, because safari's getComputedStyle returns some weird array-like thingy.
			theCSSPrefix = (k.match(rxPrefixes) || (+k == k && style[k].match(rxPrefixes)));

			if(theCSSPrefix) {
				break;
			}
		}

		//Did we even detect a prefix?
		if(!theCSSPrefix) {
			theCSSPrefix = theDashedCSSPrefix = '';

			return;
		}

		theCSSPrefix = theCSSPrefix[0];

		//We could have detected either a dashed prefix or this camelCaseish-inconsistent stuff.
		if(theCSSPrefix.slice(0,1) === '-') {
			theDashedCSSPrefix = theCSSPrefix;

			//There's no logic behind these. Need a look up.
			theCSSPrefix = ({
				'-webkit-': 'webkit',
				'-moz-': 'Moz',
				'-ms-': 'ms',
				'-o-': 'O'
			})[theCSSPrefix];
		} else {
			theDashedCSSPrefix = '-' + theCSSPrefix.toLowerCase() + '-';
		}
	};

	var polyfillRAF = function() {
		var requestAnimFrame = window.requestAnimationFrame || window[theCSSPrefix.toLowerCase() + 'RequestAnimationFrame'];

		var lastTime = _now();

		if(_isMobile || !requestAnimFrame) {
			requestAnimFrame = function(callback) {
				//How long did it take to render?
				var deltaTime = _now() - lastTime;
				var delay = Math.max(0, 1000 / 60 - deltaTime);

				return window.setTimeout(function() {
					lastTime = _now();
					callback();
				}, delay);
			};
		}

		return requestAnimFrame;
	};

	var polyfillCAF = function() {
		var cancelAnimFrame = window.cancelAnimationFrame || window[theCSSPrefix.toLowerCase() + 'CancelAnimationFrame'];

		if(_isMobile || !cancelAnimFrame) {
			cancelAnimFrame = function(timeout) {
				return window.clearTimeout(timeout);
			};
		}

		return cancelAnimFrame;
	};

	//Built-in easing functions.
	var easings = {
		begin: function() {
			return 0;
		},
		end: function() {
			return 1;
		},
		linear: function(p) {
			return p;
		},
		quadratic: function(p) {
			return p * p;
		},
		cubic: function(p) {
			return p * p * p;
		},
		swing: function(p) {
			return (-Math.cos(p * Math.PI) / 2) + 0.5;
		},
		sqrt: function(p) {
			return Math.sqrt(p);
		},
		outCubic: function(p) {
			return (Math.pow((p - 1), 3) + 1);
		},
		//see https://www.desmos.com/calculator/tbr20s8vd2 for how I did this
		bounce: function(p) {
			var a;

			if(p <= 0.5083) {
				a = 3;
			} else if(p <= 0.8489) {
				a = 9;
			} else if(p <= 0.96208) {
				a = 27;
			} else if(p <= 0.99981) {
				a = 91;
			} else {
				return 1;
			}

			return 1 - Math.abs(3 * Math.cos(p * a * 1.028) / a);
		}
	};

	/**
	 * Constructor.
	 */
	function Skrollr(options) {
		documentElement = document.documentElement;
		body = document.body;

		detectCSSPrefix();

		_instance = this;

		options = options || {};

		_constants = options.constants || {};

		//We allow defining custom easings or overwrite existing.
		if(options.easing) {
			for(var e in options.easing) {
				easings[e] = options.easing[e];
			}
		}

		_edgeStrategy = options.edgeStrategy || 'set';

		_listeners = {
			//Function to be called right before rendering.
			beforerender: options.beforerender,

			//Function to be called right after finishing rendering.
			render: options.render,

			//Function to be called whenever an element with the `data-emit-events` attribute passes a keyframe.
			keyframe: options.keyframe
		};

		//forceHeight is true by default
		_forceHeight = options.forceHeight !== false;

		if(_forceHeight) {
			_scale = options.scale || 1;
		}

		_mobileDeceleration = options.mobileDeceleration || DEFAULT_MOBILE_DECELERATION;

		_smoothScrollingEnabled = options.smoothScrolling !== false;
		_smoothScrollingDuration = options.smoothScrollingDuration || DEFAULT_SMOOTH_SCROLLING_DURATION;

		//Dummy object. Will be overwritten in the _render method when smooth scrolling is calculated.
		_smoothScrolling = {
			targetTop: _instance.getScrollTop()
		};

		//A custom check function may be passed.
		_isMobile = ((options.mobileCheck || function() {
			return (/Android|iPhone|iPad|iPod|BlackBerry/i).test(navigator.userAgent || navigator.vendor || window.opera);
		})());

		if(_isMobile) {
			_skrollrBody = document.getElementById('skrollr-body');

			//Detect 3d transform if there's a skrollr-body (only needed for #skrollr-body).
			if(_skrollrBody) {
				_detect3DTransforms();
			}

			_initMobile();
			_updateClass(documentElement, [SKROLLR_CLASS, SKROLLR_MOBILE_CLASS], [NO_SKROLLR_CLASS]);
		} else {
			_updateClass(documentElement, [SKROLLR_CLASS, SKROLLR_DESKTOP_CLASS], [NO_SKROLLR_CLASS]);
		}

		//Triggers parsing of elements and a first reflow.
		_instance.refresh();

		_addEvent(window, 'resize orientationchange', function() {
			var width = documentElement.clientWidth;
			var height = documentElement.clientHeight;

			//Only reflow if the size actually changed (#271).
			if(height !== _lastViewportHeight || width !== _lastViewportWidth) {
				_lastViewportHeight = height;
				_lastViewportWidth = width;

				_requestReflow = true;
			}
		});

		var requestAnimFrame = polyfillRAF();

		//Let's go.
		(function animloop(){
			_render();
			_animFrame = requestAnimFrame(animloop);
		}());

		return _instance;
	}

	/**
	 * (Re)parses some or all elements.
	 */
	Skrollr.prototype.refresh = function(elements) {
		var elementIndex;
		var elementsLength;
		var ignoreID = false;

		//Completely reparse anything without argument.
		if(elements === undefined) {
			//Ignore that some elements may already have a skrollable ID.
			ignoreID = true;

			_skrollables = [];
			_skrollableIdCounter = 0;

			elements = document.getElementsByTagName('*');
		} else if(elements.length === undefined) {
			//We also accept a single element as parameter.
			elements = [elements];
		}

		elementIndex = 0;
		elementsLength = elements.length;

		for(; elementIndex < elementsLength; elementIndex++) {
			var el = elements[elementIndex];
			var anchorTarget = el;
			var keyFrames = [];

			//If this particular element should be smooth scrolled.
			var smoothScrollThis = _smoothScrollingEnabled;

			//The edge strategy for this particular element.
			var edgeStrategy = _edgeStrategy;

			//If this particular element should emit keyframe events.
			var emitEvents = false;

			//If we're reseting the counter, remove any old element ids that may be hanging around.
			if(ignoreID && SKROLLABLE_ID_DOM_PROPERTY in el) {
				delete el[SKROLLABLE_ID_DOM_PROPERTY];
			}

			if(!el.attributes) {
				continue;
			}

			//Iterate over all attributes and search for key frame attributes.
			var attributeIndex = 0;
			var attributesLength = el.attributes.length;

			for (; attributeIndex < attributesLength; attributeIndex++) {
				var attr = el.attributes[attributeIndex];

				if(attr.name === 'data-anchor-target') {
					anchorTarget = document.querySelector(attr.value);

					if(anchorTarget === null) {
						throw 'Unable to find anchor target "' + attr.value + '"';
					}

					continue;
				}

				//Global smooth scrolling can be overridden by the element attribute.
				if(attr.name === 'data-smooth-scrolling') {
					smoothScrollThis = attr.value !== 'off';

					continue;
				}

				//Global edge strategy can be overridden by the element attribute.
				if(attr.name === 'data-edge-strategy') {
					edgeStrategy = attr.value;

					continue;
				}

				//Is this element tagged with the `data-emit-events` attribute?
				if(attr.name === 'data-emit-events') {
					emitEvents = true;

					continue;
				}

				var match = attr.name.match(rxKeyframeAttribute);

				if(match === null) {
					continue;
				}

				var kf = {
					props: attr.value,
					//Point back to the element as well.
					element: el,
					//The name of the event which this keyframe will fire, if emitEvents is
					eventType: attr.name.replace(rxCamelCase, rxCamelCaseFn)
				};

				keyFrames.push(kf);

				var constant = match[1];

				if(constant) {
					//Strip the underscore prefix.
					kf.constant = constant.substr(1);
				}

				//Get the key frame offset.
				var offset = match[2];

				//Is it a percentage offset?
				if(/p$/.test(offset)) {
					kf.isPercentage = true;
					kf.offset = (offset.slice(0, -1) | 0) / 100;
				} else {
					kf.offset = (offset | 0);
				}

				var anchor1 = match[3];

				//If second anchor is not set, the first will be taken for both.
				var anchor2 = match[4] || anchor1;

				//"absolute" (or "classic") mode, where numbers mean absolute scroll offset.
				if(!anchor1 || anchor1 === ANCHOR_START || anchor1 === ANCHOR_END) {
					kf.mode = 'absolute';

					//data-end needs to be calculated after all key frames are known.
					if(anchor1 === ANCHOR_END) {
						kf.isEnd = true;
					} else if(!kf.isPercentage) {
						//For data-start we can already set the key frame w/o calculations.
						//#59: "scale" options should only affect absolute mode.
						kf.offset = kf.offset * _scale;
					}
				}
				//"relative" mode, where numbers are relative to anchors.
				else {
					kf.mode = 'relative';
					kf.anchors = [anchor1, anchor2];
				}
			}

			//Does this element have key frames?
			if(!keyFrames.length) {
				continue;
			}

			//Will hold the original style and class attributes before we controlled the element (see #80).
			var styleAttr, classAttr;

			var id;

			if(!ignoreID && SKROLLABLE_ID_DOM_PROPERTY in el) {
				//We already have this element under control. Grab the corresponding skrollable id.
				id = el[SKROLLABLE_ID_DOM_PROPERTY];
				styleAttr = _skrollables[id].styleAttr;
				classAttr = _skrollables[id].classAttr;
			} else {
				//It's an unknown element. Asign it a new skrollable id.
				id = (el[SKROLLABLE_ID_DOM_PROPERTY] = _skrollableIdCounter++);
				styleAttr = el.style.cssText;
				classAttr = _getClass(el);
			}

			_skrollables[id] = {
				element: el,
				styleAttr: styleAttr,
				classAttr: classAttr,
				anchorTarget: anchorTarget,
				keyFrames: keyFrames,
				smoothScrolling: smoothScrollThis,
				edgeStrategy: edgeStrategy,
				emitEvents: emitEvents,
				lastFrameIndex: -1
			};

			_updateClass(el, [SKROLLABLE_CLASS], []);
		}

		//Reflow for the first time.
		_reflow();

		//Now that we got all key frame numbers right, actually parse the properties.
		elementIndex = 0;
		elementsLength = elements.length;

		for(; elementIndex < elementsLength; elementIndex++) {
			var sk = _skrollables[elements[elementIndex][SKROLLABLE_ID_DOM_PROPERTY]];

			if(sk === undefined) {
				continue;
			}

			//Parse the property string to objects
			_parseProps(sk);

			//Fill key frames with missing properties from left and right
			_fillProps(sk);
		}

		return _instance;
	};

	/**
	 * Transform "relative" mode to "absolute" mode.
	 * That is, calculate anchor position and offset of element.
	 */
	Skrollr.prototype.relativeToAbsolute = function(element, viewportAnchor, elementAnchor) {
		var viewportHeight = documentElement.clientHeight;
		var box = element.getBoundingClientRect();
		var absolute = box.top;

		//#100: IE doesn't supply "height" with getBoundingClientRect.
		var boxHeight = box.bottom - box.top;

		if(viewportAnchor === ANCHOR_BOTTOM) {
			absolute -= viewportHeight;
		} else if(viewportAnchor === ANCHOR_CENTER) {
			absolute -= viewportHeight / 2;
		}

		if(elementAnchor === ANCHOR_BOTTOM) {
			absolute += boxHeight;
		} else if(elementAnchor === ANCHOR_CENTER) {
			absolute += boxHeight / 2;
		}

		//Compensate scrolling since getBoundingClientRect is relative to viewport.
		absolute += _instance.getScrollTop();

		return (absolute + 0.5) | 0;
	};

	/**
	 * Animates scroll top to new position.
	 */
	Skrollr.prototype.animateTo = function(top, options) {
		options = options || {};

		var now = _now();
		var scrollTop = _instance.getScrollTop();

		//Setting this to a new value will automatically cause the current animation to stop, if any.
		_scrollAnimation = {
			startTop: scrollTop,
			topDiff: top - scrollTop,
			targetTop: top,
			duration: options.duration || DEFAULT_DURATION,
			startTime: now,
			endTime: now + (options.duration || DEFAULT_DURATION),
			easing: easings[options.easing || DEFAULT_EASING],
			done: options.done
		};

		//Don't queue the animation if there's nothing to animate.
		if(!_scrollAnimation.topDiff) {
			if(_scrollAnimation.done) {
				_scrollAnimation.done.call(_instance, false);
			}

			_scrollAnimation = undefined;
		}

		return _instance;
	};

	/**
	 * Stops animateTo animation.
	 */
	Skrollr.prototype.stopAnimateTo = function() {
		if(_scrollAnimation && _scrollAnimation.done) {
			_scrollAnimation.done.call(_instance, true);
		}

		_scrollAnimation = undefined;
	};

	/**
	 * Returns if an animation caused by animateTo is currently running.
	 */
	Skrollr.prototype.isAnimatingTo = function() {
		return !!_scrollAnimation;
	};

	Skrollr.prototype.isMobile = function() {
		return _isMobile;
	};

	Skrollr.prototype.setScrollTop = function(top, force) {
		_forceRender = (force === true);

		if(_isMobile) {
			_mobileOffset = Math.min(Math.max(top, 0), _maxKeyFrame);
		} else {
			window.scrollTo(0, top);
		}

		return _instance;
	};

	Skrollr.prototype.getScrollTop = function() {
		if(_isMobile) {
			return _mobileOffset;
		} else {
			return window.pageYOffset || documentElement.scrollTop || body.scrollTop || 0;
		}
	};

	Skrollr.prototype.getMaxScrollTop = function() {
		return _maxKeyFrame;
	};

	Skrollr.prototype.on = function(name, fn) {
		_listeners[name] = fn;

		return _instance;
	};

	Skrollr.prototype.off = function(name) {
		delete _listeners[name];

		return _instance;
	};

	Skrollr.prototype.destroy = function() {
		var cancelAnimFrame = polyfillCAF();
		cancelAnimFrame(_animFrame);
		_removeAllEvents();

		_updateClass(documentElement, [NO_SKROLLR_CLASS], [SKROLLR_CLASS, SKROLLR_DESKTOP_CLASS, SKROLLR_MOBILE_CLASS]);

		var skrollableIndex = 0;
		var skrollablesLength = _skrollables.length;

		for(; skrollableIndex < skrollablesLength; skrollableIndex++) {
			_reset(_skrollables[skrollableIndex].element);
		}

		documentElement.style.overflow = body.style.overflow = '';
		documentElement.style.height = body.style.height = '';

		if(_skrollrBody) {
			skrollr.setStyle(_skrollrBody, 'transform', 'none');
		}

		_instance = undefined;
		_skrollrBody = undefined;
		_listeners = undefined;
		_forceHeight = undefined;
		_maxKeyFrame = 0;
		_scale = 1;
		_constants = undefined;
		_mobileDeceleration = undefined;
		_direction = 'down';
		_lastTop = -1;
		_lastViewportWidth = 0;
		_lastViewportHeight = 0;
		_requestReflow = false;
		_scrollAnimation = undefined;
		_smoothScrollingEnabled = undefined;
		_smoothScrollingDuration = undefined;
		_smoothScrolling = undefined;
		_forceRender = undefined;
		_skrollableIdCounter = 0;
		_edgeStrategy = undefined;
		_isMobile = false;
		_mobileOffset = 0;
		_translateZ = undefined;
	};

	/*
		Private methods.
	*/

	var _initMobile = function() {
		var initialElement;
		var initialTouchY;
		var initialTouchX;
		var currentElement;
		var currentTouchY;
		var currentTouchX;
		var lastTouchY;
		var deltaY;

		var initialTouchTime;
		var currentTouchTime;
		var lastTouchTime;
		var deltaTime;

		_addEvent(documentElement, [EVENT_TOUCHSTART, EVENT_TOUCHMOVE, EVENT_TOUCHCANCEL, EVENT_TOUCHEND].join(' '), function(e) {
			var touch = e.changedTouches[0];

			currentElement = e.target;

			//We don't want text nodes.
			while(currentElement.nodeType === 3) {
				currentElement = currentElement.parentNode;
			}

			currentTouchY = touch.clientY;
			currentTouchX = touch.clientX;
			currentTouchTime = e.timeStamp;

			if(!rxTouchIgnoreTags.test(currentElement.tagName)) {
				e.preventDefault();
			}

			switch(e.type) {
				case EVENT_TOUCHSTART:
					//The last element we tapped on.
					if(initialElement) {
						initialElement.blur();
					}

					_instance.stopAnimateTo();

					initialElement = currentElement;

					initialTouchY = lastTouchY = currentTouchY;
					initialTouchX = currentTouchX;
					initialTouchTime = currentTouchTime;

					break;
				case EVENT_TOUCHMOVE:
					//Prevent default event on touchIgnore elements in case they don't have focus yet.
					if(rxTouchIgnoreTags.test(currentElement.tagName) && document.activeElement !== currentElement) {
						e.preventDefault();
					}

					deltaY = currentTouchY - lastTouchY;
					deltaTime = currentTouchTime - lastTouchTime;

					_instance.setScrollTop(_mobileOffset - deltaY, true);

					lastTouchY = currentTouchY;
					lastTouchTime = currentTouchTime;
					break;
				default:
				case EVENT_TOUCHCANCEL:
				case EVENT_TOUCHEND:
					var distanceY = initialTouchY - currentTouchY;
					var distanceX = initialTouchX - currentTouchX;
					var distance2 = distanceX * distanceX + distanceY * distanceY;

					//Check if it was more like a tap (moved less than 7px).
					if(distance2 < 49) {
						if(!rxTouchIgnoreTags.test(initialElement.tagName)) {
							initialElement.focus();

							//It was a tap, click the element.
							var clickEvent = document.createEvent('MouseEvents');
							clickEvent.initMouseEvent('click', true, true, e.view, 1, touch.screenX, touch.screenY, touch.clientX, touch.clientY, e.ctrlKey, e.altKey, e.shiftKey, e.metaKey, 0, null);
							initialElement.dispatchEvent(clickEvent);
						}

						return;
					}

					initialElement = undefined;

					var speed = deltaY / deltaTime;

					//Cap speed at 3 pixel/ms.
					speed = Math.max(Math.min(speed, 3), -3);

					var duration = Math.abs(speed / _mobileDeceleration);
					var targetOffset = speed * duration + 0.5 * _mobileDeceleration * duration * duration;
					var targetTop = _instance.getScrollTop() - targetOffset;

					//Relative duration change for when scrolling above bounds.
					var targetRatio = 0;

					//Change duration proportionally when scrolling would leave bounds.
					if(targetTop > _maxKeyFrame) {
						targetRatio = (_maxKeyFrame - targetTop) / targetOffset;

						targetTop = _maxKeyFrame;
					} else if(targetTop < 0) {
						targetRatio = -targetTop / targetOffset;

						targetTop = 0;
					}

					duration = duration * (1 - targetRatio);

					_instance.animateTo((targetTop + 0.5) | 0, {easing: 'outCubic', duration: duration});
					break;
			}
		});

		//Just in case there has already been some native scrolling, reset it.
		window.scrollTo(0, 0);
		documentElement.style.overflow = body.style.overflow = 'hidden';
	};

	/**
	 * Updates key frames which depend on others / need to be updated on resize.
	 * That is "end" in "absolute" mode and all key frames in "relative" mode.
	 * Also handles constants, because they may change on resize.
	 */
	var _updateDependentKeyFrames = function() {
		var viewportHeight = documentElement.clientHeight;
		var processedConstants = _processConstants();
		var skrollable;
		var element;
		var anchorTarget;
		var keyFrames;
		var keyFrameIndex;
		var keyFramesLength;
		var kf;
		var skrollableIndex;
		var skrollablesLength;
		var offset;
		var constantValue;

		//First process all relative-mode elements and find the max key frame.
		skrollableIndex = 0;
		skrollablesLength = _skrollables.length;

		for(; skrollableIndex < skrollablesLength; skrollableIndex++) {
			skrollable = _skrollables[skrollableIndex];
			element = skrollable.element;
			anchorTarget = skrollable.anchorTarget;
			keyFrames = skrollable.keyFrames;

			keyFrameIndex = 0;
			keyFramesLength = keyFrames.length;

			for(; keyFrameIndex < keyFramesLength; keyFrameIndex++) {
				kf = keyFrames[keyFrameIndex];

				offset = kf.offset;
				constantValue = processedConstants[kf.constant] || 0;

				kf.frame = offset;

				if(kf.isPercentage) {
					//Convert the offset to percentage of the viewport height.
					offset = offset * viewportHeight;

					//Absolute + percentage mode.
					kf.frame = offset;
				}

				if(kf.mode === 'relative') {
					_reset(element);

					kf.frame = _instance.relativeToAbsolute(anchorTarget, kf.anchors[0], kf.anchors[1]) - offset;

					_reset(element, true);
				}

				kf.frame += constantValue;

				//Only search for max key frame when forceHeight is enabled.
				if(_forceHeight) {
					//Find the max key frame, but don't use one of the data-end ones for comparison.
					if(!kf.isEnd && kf.frame > _maxKeyFrame) {
						_maxKeyFrame = kf.frame;
					}
				}
			}
		}

		//#133: The document can be larger than the maxKeyFrame we found.
		_maxKeyFrame = Math.max(_maxKeyFrame, _getDocumentHeight());

		//Now process all data-end keyframes.
		skrollableIndex = 0;
		skrollablesLength = _skrollables.length;

		for(; skrollableIndex < skrollablesLength; skrollableIndex++) {
			skrollable = _skrollables[skrollableIndex];
			keyFrames = skrollable.keyFrames;

			keyFrameIndex = 0;
			keyFramesLength = keyFrames.length;

			for(; keyFrameIndex < keyFramesLength; keyFrameIndex++) {
				kf = keyFrames[keyFrameIndex];

				constantValue = processedConstants[kf.constant] || 0;

				if(kf.isEnd) {
					kf.frame = _maxKeyFrame - kf.offset + constantValue;
				}
			}

			skrollable.keyFrames.sort(_keyFrameComparator);
		}
	};

	/**
	 * Calculates and sets the style properties for the element at the given frame.
	 * @param fakeFrame The frame to render at when smooth scrolling is enabled.
	 * @param actualFrame The actual frame we are at.
	 */
	var _calcSteps = function(fakeFrame, actualFrame) {
		//Iterate over all skrollables.
		var skrollableIndex = 0;
		var skrollablesLength = _skrollables.length;

		for(; skrollableIndex < skrollablesLength; skrollableIndex++) {
			var skrollable = _skrollables[skrollableIndex];
			var element = skrollable.element;
			var frame = skrollable.smoothScrolling ? fakeFrame : actualFrame;
			var frames = skrollable.keyFrames;
			var framesLength = frames.length;
			var firstFrame = frames[0];
			var lastFrame = frames[frames.length - 1];
			var beforeFirst = frame < firstFrame.frame;
			var afterLast = frame > lastFrame.frame;
			var firstOrLastFrame = beforeFirst ? firstFrame : lastFrame;
			var emitEvents = skrollable.emitEvents;
			var lastFrameIndex = skrollable.lastFrameIndex;
			var key;
			var value;

			//If we are before/after the first/last frame, set the styles according to the given edge strategy.
			if(beforeFirst || afterLast) {
				//Check if we already handled this edge case last time.
				//Note: using setScrollTop it's possible that we jumped from one edge to the other.
				if(beforeFirst && skrollable.edge === -1 || afterLast && skrollable.edge === 1) {
					continue;
				}

				//Add the skrollr-before or -after class.
				if(beforeFirst) {
					_updateClass(element, [SKROLLABLE_BEFORE_CLASS], [SKROLLABLE_AFTER_CLASS, SKROLLABLE_BETWEEN_CLASS]);

					//This handles the special case where we exit the first keyframe.
					if(emitEvents && lastFrameIndex > -1) {
						_emitEvent(element, firstFrame.eventType, _direction);
						skrollable.lastFrameIndex = -1;
					}
				} else {
					_updateClass(element, [SKROLLABLE_AFTER_CLASS], [SKROLLABLE_BEFORE_CLASS, SKROLLABLE_BETWEEN_CLASS]);

					//This handles the special case where we exit the last keyframe.
					if(emitEvents && lastFrameIndex < framesLength) {
						_emitEvent(element, lastFrame.eventType, _direction);
						skrollable.lastFrameIndex = framesLength;
					}
				}

				//Remember that we handled the edge case (before/after the first/last keyframe).
				skrollable.edge = beforeFirst ? -1 : 1;

				switch(skrollable.edgeStrategy) {
					case 'reset':
						_reset(element);
						continue;
					case 'ease':
						//Handle this case like it would be exactly at first/last keyframe and just pass it on.
						frame = firstOrLastFrame.frame;
						break;
					default:
					case 'set':
						var props = firstOrLastFrame.props;

						for(key in props) {
							if(hasProp.call(props, key)) {
								value = _interpolateString(props[key].value);

								//Set style or attribute.
								if(key.indexOf('@') === 0) {
									element.setAttribute(key.substr(1), value);
								} else {
									skrollr.setStyle(element, key, value);
								}
							}
						}

						continue;
				}
			} else {
				//Did we handle an edge last time?
				if(skrollable.edge !== 0) {
					_updateClass(element, [SKROLLABLE_CLASS, SKROLLABLE_BETWEEN_CLASS], [SKROLLABLE_BEFORE_CLASS, SKROLLABLE_AFTER_CLASS]);
					skrollable.edge = 0;
				}
			}

			//Find out between which two key frames we are right now.
			var keyFrameIndex = 0;

			for(; keyFrameIndex < framesLength - 1; keyFrameIndex++) {
				if(frame >= frames[keyFrameIndex].frame && frame <= frames[keyFrameIndex + 1].frame) {
					var left = frames[keyFrameIndex];
					var right = frames[keyFrameIndex + 1];

					for(key in left.props) {
						if(hasProp.call(left.props, key)) {
							var progress = (frame - left.frame) / (right.frame - left.frame);

							//Transform the current progress using the given easing function.
							progress = left.props[key].easing(progress);

							//Interpolate between the two values
							value = _calcInterpolation(left.props[key].value, right.props[key].value, progress);

							value = _interpolateString(value);

							//Set style or attribute.
							if(key.indexOf('@') === 0) {
								element.setAttribute(key.substr(1), value);
							} else {
								skrollr.setStyle(element, key, value);
							}
						}
					}

					//Are events enabled on this element?
					//This code handles the usual cases of scrolling through different keyframes.
					//The special cases of before first and after last keyframe are handled above.
					if(emitEvents) {
						//Did we pass a new keyframe?
						if(lastFrameIndex !== keyFrameIndex) {
							if(_direction === 'down') {
								_emitEvent(element, left.eventType, _direction);
							} else {
								_emitEvent(element, right.eventType, _direction);
							}

							skrollable.lastFrameIndex = keyFrameIndex;
						}
					}

					break;
				}
			}
		}
	};

	/**
	 * Renders all elements.
	 */
	var _render = function() {
		if(_requestReflow) {
			_requestReflow = false;
			_reflow();
		}

		//We may render something else than the actual scrollbar position.
		var renderTop = _instance.getScrollTop();

		//If there's an animation, which ends in current render call, call the callback after rendering.
		var afterAnimationCallback;
		var now = _now();
		var progress;

		//Before actually rendering handle the scroll animation, if any.
		if(_scrollAnimation) {
			//It's over
			if(now >= _scrollAnimation.endTime) {
				renderTop = _scrollAnimation.targetTop;
				afterAnimationCallback = _scrollAnimation.done;
				_scrollAnimation = undefined;
			} else {
				//Map the current progress to the new progress using given easing function.
				progress = _scrollAnimation.easing((now - _scrollAnimation.startTime) / _scrollAnimation.duration);

				renderTop = (_scrollAnimation.startTop + progress * _scrollAnimation.topDiff) | 0;
			}

			_instance.setScrollTop(renderTop, true);
		}
		//Smooth scrolling only if there's no animation running and if we're not forcing the rendering.
		else if(!_forceRender) {
			var smoothScrollingDiff = _smoothScrolling.targetTop - renderTop;

			//The user scrolled, start new smooth scrolling.
			if(smoothScrollingDiff) {
				_smoothScrolling = {
					startTop: _lastTop,
					topDiff: renderTop - _lastTop,
					targetTop: renderTop,
					startTime: _lastRenderCall,
					endTime: _lastRenderCall + _smoothScrollingDuration
				};
			}

			//Interpolate the internal scroll position (not the actual scrollbar).
			if(now <= _smoothScrolling.endTime) {
				//Map the current progress to the new progress using easing function.
				progress = easings.sqrt((now - _smoothScrolling.startTime) / _smoothScrollingDuration);

				renderTop = (_smoothScrolling.startTop + progress * _smoothScrolling.topDiff) | 0;
			}
		}

		//That's were we actually "scroll" on mobile.
		if(_isMobile && _skrollrBody) {
			//Set the transform ("scroll it").
			skrollr.setStyle(_skrollrBody, 'transform', 'translate(0, ' + -(_mobileOffset) + 'px) ' + _translateZ);
		}

		//Did the scroll position even change?
		if(_forceRender || _lastTop !== renderTop) {
			//Remember in which direction are we scrolling?
			_direction = (renderTop > _lastTop) ? 'down' : (renderTop < _lastTop ? 'up' : _direction);

			_forceRender = false;

			var listenerParams = {
				curTop: renderTop,
				lastTop: _lastTop,
				maxTop: _maxKeyFrame,
				direction: _direction
			};

			//Tell the listener we are about to render.
			var continueRendering = _listeners.beforerender && _listeners.beforerender.call(_instance, listenerParams);

			//The beforerender listener function is able the cancel rendering.
			if(continueRendering !== false) {
				//Now actually interpolate all the styles.
				_calcSteps(renderTop, _instance.getScrollTop());

				//Remember when we last rendered.
				_lastTop = renderTop;

				if(_listeners.render) {
					_listeners.render.call(_instance, listenerParams);
				}
			}

			if(afterAnimationCallback) {
				afterAnimationCallback.call(_instance, false);
			}
		}

		_lastRenderCall = now;
	};

	/**
	 * Parses the properties for each key frame of the given skrollable.
	 */
	var _parseProps = function(skrollable) {
		//Iterate over all key frames
		var keyFrameIndex = 0;
		var keyFramesLength = skrollable.keyFrames.length;

		for(; keyFrameIndex < keyFramesLength; keyFrameIndex++) {
			var frame = skrollable.keyFrames[keyFrameIndex];
			var easing;
			var value;
			var prop;
			var props = {};

			var match;

			while((match = rxPropValue.exec(frame.props)) !== null) {
				prop = match[1];
				value = match[2];

				easing = prop.match(rxPropEasing);

				//Is there an easing specified for this prop?
				if(easing !== null) {
					prop = easing[1];
					easing = easing[2];
				} else {
					easing = DEFAULT_EASING;
				}

				//Exclamation point at first position forces the value to be taken literal.
				value = value.indexOf('!') ? _parseProp(value) : [value.slice(1)];

				//Save the prop for this key frame with his value and easing function
				props[prop] = {
					value: value,
					easing: easings[easing]
				};
			}

			frame.props = props;
		}
	};

	/**
	 * Parses a value extracting numeric values and generating a format string
	 * for later interpolation of the new values in old string.
	 *
	 * @param val The CSS value to be parsed.
	 * @return Something like ["rgba(?%,?%, ?%,?)", 100, 50, 0, .7]
	 * where the first element is the format string later used
	 * and all following elements are the numeric value.
	 */
	var _parseProp = function(val) {
		var numbers = [];

		//One special case, where floats don't work.
		//We replace all occurences of rgba colors
		//which don't use percentage notation with the percentage notation.
		rxRGBAIntegerColor.lastIndex = 0;
		val = val.replace(rxRGBAIntegerColor, function(rgba) {
			return rgba.replace(rxNumericValue, function(n) {
				return n / 255 * 100 + '%';
			});
		});

		//Handle prefixing of "gradient" values.
		//For now only the prefixed value will be set. Unprefixed isn't supported anyway.
		if(theDashedCSSPrefix) {
			rxGradient.lastIndex = 0;
			val = val.replace(rxGradient, function(s) {
				return theDashedCSSPrefix + s;
			});
		}

		//Now parse ANY number inside this string and create a format string.
		val = val.replace(rxNumericValue, function(n) {
			numbers.push(+n);
			return '{?}';
		});

		//Add the formatstring as first value.
		numbers.unshift(val);

		return numbers;
	};

	/**
	 * Fills the key frames with missing left and right hand properties.
	 * If key frame 1 has property X and key frame 2 is missing X,
	 * but key frame 3 has X again, then we need to assign X to key frame 2 too.
	 *
	 * @param sk A skrollable.
	 */
	var _fillProps = function(sk) {
		//Will collect the properties key frame by key frame
		var propList = {};
		var keyFrameIndex;
		var keyFramesLength;

		//Iterate over all key frames from left to right
		keyFrameIndex = 0;
		keyFramesLength = sk.keyFrames.length;

		for(; keyFrameIndex < keyFramesLength; keyFrameIndex++) {
			_fillPropForFrame(sk.keyFrames[keyFrameIndex], propList);
		}

		//Now do the same from right to fill the last gaps

		propList = {};

		//Iterate over all key frames from right to left
		keyFrameIndex = sk.keyFrames.length - 1;

		for(; keyFrameIndex >= 0; keyFrameIndex--) {
			_fillPropForFrame(sk.keyFrames[keyFrameIndex], propList);
		}
	};

	var _fillPropForFrame = function(frame, propList) {
		var key;

		//For each key frame iterate over all right hand properties and assign them,
		//but only if the current key frame doesn't have the property by itself
		for(key in propList) {
			//The current frame misses this property, so assign it.
			if(!hasProp.call(frame.props, key)) {
				frame.props[key] = propList[key];
			}
		}

		//Iterate over all props of the current frame and collect them
		for(key in frame.props) {
			propList[key] = frame.props[key];
		}
	};

	/**
	 * Calculates the new values for two given values array.
	 */
	var _calcInterpolation = function(val1, val2, progress) {
		var valueIndex;
		var val1Length = val1.length;

		//They both need to have the same length
		if(val1Length !== val2.length) {
			throw 'Can\'t interpolate between "' + val1[0] + '" and "' + val2[0] + '"';
		}

		//Add the format string as first element.
		var interpolated = [val1[0]];

		valueIndex = 1;

		for(; valueIndex < val1Length; valueIndex++) {
			//That's the line where the two numbers are actually interpolated.
			interpolated[valueIndex] = val1[valueIndex] + ((val2[valueIndex] - val1[valueIndex]) * progress);
		}

		return interpolated;
	};

	/**
	 * Interpolates the numeric values into the format string.
	 */
	var _interpolateString = function(val) {
		var valueIndex = 1;

		rxInterpolateString.lastIndex = 0;

		return val[0].replace(rxInterpolateString, function() {
			return val[valueIndex++];
		});
	};

	/**
	 * Resets the class and style attribute to what it was before skrollr manipulated the element.
	 * Also remembers the values it had before reseting, in order to undo the reset.
	 */
	var _reset = function(elements, undo) {
		//We accept a single element or an array of elements.
		elements = [].concat(elements);

		var skrollable;
		var element;
		var elementsIndex = 0;
		var elementsLength = elements.length;

		for(; elementsIndex < elementsLength; elementsIndex++) {
			element = elements[elementsIndex];
			skrollable = _skrollables[element[SKROLLABLE_ID_DOM_PROPERTY]];

			//Couldn't find the skrollable for this DOM element.
			if(!skrollable) {
				continue;
			}

			if(undo) {
				//Reset class and style to the "dirty" (set by skrollr) values.
				element.style.cssText = skrollable.dirtyStyleAttr;
				_updateClass(element, skrollable.dirtyClassAttr);
			} else {
				//Remember the "dirty" (set by skrollr) class and style.
				skrollable.dirtyStyleAttr = element.style.cssText;
				skrollable.dirtyClassAttr = _getClass(element);

				//Reset class and style to what it originally was.
				element.style.cssText = skrollable.styleAttr;
				_updateClass(element, skrollable.classAttr);
			}
		}
	};

	/**
	 * Detects support for 3d transforms by applying it to the skrollr-body.
	 */
	var _detect3DTransforms = function() {
		_translateZ = 'translateZ(0)';
		skrollr.setStyle(_skrollrBody, 'transform', _translateZ);

		var computedStyle = getStyle(_skrollrBody);
		var computedTransform = computedStyle.getPropertyValue('transform');
		var computedTransformWithPrefix = computedStyle.getPropertyValue(theDashedCSSPrefix + 'transform');
		var has3D = (computedTransform && computedTransform !== 'none') || (computedTransformWithPrefix && computedTransformWithPrefix !== 'none');

		if(!has3D) {
			_translateZ = '';
		}
	};

	/**
	 * Set the CSS property on the given element. Sets prefixed properties as well.
	 */
	skrollr.setStyle = function(el, prop, val) {
		var style = el.style;

		//Camel case.
		prop = prop.replace(rxCamelCase, rxCamelCaseFn).replace('-', '');

		//Make sure z-index gets a <integer>.
		//This is the only <integer> case we need to handle.
		if(prop === 'zIndex') {
			if(isNaN(val)) {
				//If it's not a number, don't touch it.
				//It could for example be "auto" (#351).
				style[prop] = val;
			} else {
				//Floor the number.
				style[prop] = '' + (val | 0);
			}
		}
		//#64: "float" can't be set across browsers. Needs to use "cssFloat" for all except IE.
		else if(prop === 'float') {
			style.styleFloat = style.cssFloat = val;
		}
		else {
			//Need try-catch for old IE.
			try {
				//Set prefixed property if there's a prefix.
				if(theCSSPrefix) {
					style[theCSSPrefix + prop.slice(0,1).toUpperCase() + prop.slice(1)] = val;
				}

				//Set unprefixed.
				style[prop] = val;
			} catch(ignore) {}
		}
	};

	/**
	 * Cross browser event handling.
	 */
	var _addEvent = skrollr.addEvent = function(element, names, callback) {
		var intermediate = function(e) {
			//Normalize IE event stuff.
			e = e || window.event;

			if(!e.target) {
				e.target = e.srcElement;
			}

			if(!e.preventDefault) {
				e.preventDefault = function() {
					e.returnValue = false;
					e.defaultPrevented = true;
				};
			}

			return callback.call(this, e);
		};

		names = names.split(' ');

		var name;
		var nameCounter = 0;
		var namesLength = names.length;

		for(; nameCounter < namesLength; nameCounter++) {
			name = names[nameCounter];

			if(element.addEventListener) {
				element.addEventListener(name, callback, false);
			} else {
				element.attachEvent('on' + name, intermediate);
			}

			//Remember the events to be able to flush them later.
			_registeredEvents.push({
				element: element,
				name: name,
				listener: callback
			});
		}
	};

	var _removeEvent = skrollr.removeEvent = function(element, names, callback) {
		names = names.split(' ');

		var nameCounter = 0;
		var namesLength = names.length;

		for(; nameCounter < namesLength; nameCounter++) {
			if(element.removeEventListener) {
				element.removeEventListener(names[nameCounter], callback, false);
			} else {
				element.detachEvent('on' + names[nameCounter], callback);
			}
		}
	};

	var _removeAllEvents = function() {
		var eventData;
		var eventCounter = 0;
		var eventsLength = _registeredEvents.length;

		for(; eventCounter < eventsLength; eventCounter++) {
			eventData = _registeredEvents[eventCounter];

			_removeEvent(eventData.element, eventData.name, eventData.listener);
		}

		_registeredEvents = [];
	};

	var _emitEvent = function(element, name, direction) {
		if(_listeners.keyframe) {
			_listeners.keyframe.call(_instance, element, name, direction);
		}
	};

	var _reflow = function() {
		var pos = _instance.getScrollTop();

		//Will be recalculated by _updateDependentKeyFrames.
		_maxKeyFrame = 0;

		if(_forceHeight && !_isMobile) {
			//un-"force" the height to not mess with the calculations in _updateDependentKeyFrames (#216).
			body.style.height = '';
		}

		_updateDependentKeyFrames();

		if(_forceHeight && !_isMobile) {
			//"force" the height.
			body.style.height = (_maxKeyFrame + documentElement.clientHeight) + 'px';
		}

		//The scroll offset may now be larger than needed (on desktop the browser/os prevents scrolling farther than the bottom).
		if(_isMobile) {
			_instance.setScrollTop(Math.min(_instance.getScrollTop(), _maxKeyFrame));
		} else {
			//Remember and reset the scroll pos (#217).
			_instance.setScrollTop(pos, true);
		}

		_forceRender = true;
	};

	/*
	 * Returns a copy of the constants object where all functions and strings have been evaluated.
	 */
	var _processConstants = function() {
		var viewportHeight = documentElement.clientHeight;
		var copy = {};
		var prop;
		var value;

		for(prop in _constants) {
			value = _constants[prop];

			if(typeof value === 'function') {
				value = value.call(_instance);
			}
			//Percentage offset.
			else if((/p$/).test(value)) {
				value = (value.slice(0, -1) / 100) * viewportHeight;
			}

			copy[prop] = value;
		}

		return copy;
	};

	/*
	 * Returns the height of the document.
	 */
	var _getDocumentHeight = function() {
		var skrollrBodyHeight = (_skrollrBody && _skrollrBody.offsetHeight || 0);
		var bodyHeight = Math.max(skrollrBodyHeight, body.scrollHeight, body.offsetHeight, documentElement.scrollHeight, documentElement.offsetHeight, documentElement.clientHeight);

		return bodyHeight - documentElement.clientHeight;
	};

	/**
	 * Returns a string of space separated classnames for the current element.
	 * Works with SVG as well.
	 */
	var _getClass = function(element) {
		var prop = 'className';

		//SVG support by using className.baseVal instead of just className.
		if(window.SVGElement && element instanceof window.SVGElement) {
			element = element[prop];
			prop = 'baseVal';
		}

		return element[prop];
	};

	/**
	 * Adds and removes a CSS classes.
	 * Works with SVG as well.
	 * add and remove are arrays of strings,
	 * or if remove is ommited add is a string and overwrites all classes.
	 */
	var _updateClass = function(element, add, remove) {
		var prop = 'className';

		//SVG support by using className.baseVal instead of just className.
		if(window.SVGElement && element instanceof window.SVGElement) {
			element = element[prop];
			prop = 'baseVal';
		}

		//When remove is ommited, we want to overwrite/set the classes.
		if(remove === undefined) {
			element[prop] = add;
			return;
		}

		//Cache current classes. We will work on a string before passing back to DOM.
		var val = element[prop];

		//All classes to be removed.
		var classRemoveIndex = 0;
		var removeLength = remove.length;

		for(; classRemoveIndex < removeLength; classRemoveIndex++) {
			val = _untrim(val).replace(_untrim(remove[classRemoveIndex]), ' ');
		}

		val = _trim(val);

		//All classes to be added.
		var classAddIndex = 0;
		var addLength = add.length;

		for(; classAddIndex < addLength; classAddIndex++) {
			//Only add if el not already has class.
			if(_untrim(val).indexOf(_untrim(add[classAddIndex])) === -1) {
				val += ' ' + add[classAddIndex];
			}
		}

		element[prop] = _trim(val);
	};

	var _trim = function(a) {
		return a.replace(rxTrim, '');
	};

	/**
	 * Adds a space before and after the string.
	 */
	var _untrim = function(a) {
		return ' ' + a + ' ';
	};

	var _now = Date.now || function() {
		return +new Date();
	};

	var _keyFrameComparator = function(a, b) {
		return a.frame - b.frame;
	};

	/*
	 * Private variables.
	 */

	//Singleton
	var _instance;

	/*
		A list of all elements which should be animated associated with their the metadata.
		Exmaple skrollable with two key frames animating from 100px width to 20px:

		skrollable = {
			element: <the DOM element>,
			styleAttr: <style attribute of the element before skrollr>,
			classAttr: <class attribute of the element before skrollr>,
			keyFrames: [
				{
					frame: 100,
					props: {
						width: {
							value: ['{?}px', 100],
							easing: <reference to easing function>
						}
					},
					mode: "absolute"
				},
				{
					frame: 200,
					props: {
						width: {
							value: ['{?}px', 20],
							easing: <reference to easing function>
						}
					},
					mode: "absolute"
				}
			]
		};
	*/
	var _skrollables;

	var _skrollrBody;

	var _listeners;
	var _forceHeight;
	var _maxKeyFrame = 0;

	var _scale = 1;
	var _constants;

	var _mobileDeceleration;

	//Current direction (up/down).
	var _direction = 'down';

	//The last top offset value. Needed to determine direction.
	var _lastTop = -1;

	//The last time we called the render method (doesn't mean we rendered!).
	var _lastRenderCall = _now();

	//For detecting if it actually resized (#271).
	var _lastViewportWidth = 0;
	var _lastViewportHeight = 0;

	var _requestReflow = false;

	//Will contain data about a running scrollbar animation, if any.
	var _scrollAnimation;

	var _smoothScrollingEnabled;

	var _smoothScrollingDuration;

	//Will contain settins for smooth scrolling if enabled.
	var _smoothScrolling;

	//Can be set by any operation/event to force rendering even if the scrollbar didn't move.
	var _forceRender;

	//Each skrollable gets an unique ID incremented for each skrollable.
	//The ID is the index in the _skrollables array.
	var _skrollableIdCounter = 0;

	var _edgeStrategy;


	//Mobile specific vars. Will be stripped by UglifyJS when not in use.
	var _isMobile = false;

	//The virtual scroll offset when using mobile scrolling.
	var _mobileOffset = 0;

	//If the browser supports 3d transforms, this will be filled with 'translateZ(0)' (empty string otherwise).
	var _translateZ;

	//Will contain data about registered events by skrollr.
	var _registeredEvents = [];

	//Animation frame id returned by RequestAnimationFrame (or timeout when RAF is not supported).
	var _animFrame;

	//Expose skrollr as either a global variable or a require.js module
	if(typeof define === 'function' && define.amd) {
		define('skrollr', function () {
			return skrollr;
		});
	} else if (typeof module !== 'undefined' && module.exports) {
		module.exports = skrollr;
	} else {
		window.skrollr = skrollr;
	}

}(window, document));

/**
 * Smooth Scroll v4.7.0
 * Animate scrolling to anchor links, by Chris Ferdinandi.
 * http://gomakethings.com
 *
 * Additional contributors:
 * https://github.com/cferdinandi/smooth-scroll#contributors
 *
 * Free to use under the MIT License.
 * http://gomakethings.com/mit/
 */

(function (root, factory) {
	if ( typeof define === 'function' && define.amd ) {
		define(factory);
	} else if ( typeof exports === 'object' ) {
		module.exports = factory;
	} else {
		root.smoothScroll = factory(root);
	}
})(this, function (root) {

	'use strict';

	//
	// Variables
	//

	var exports = {}; // Object for public APIs
	var supports = !!document.querySelector && !!root.addEventListener; // Feature test

	// Default settings
	var defaults = {
		speed: 500,
		easing: 'easeInOutCubic',
		offset: 0,
		updateURL: false,
		callbackBefore: function () {},
		callbackAfter: function () {}
	};


	//
	// Methods
	//

	/**
	 * Merge defaults with user options
	 * @private
	 * @param {Object} defaults Default settings
	 * @param {Object} options User options
	 * @returns {Object} Merged values of defaults and options
	 */
	var extend = function ( defaults, options ) {
		for ( var key in options ) {
			if (Object.prototype.hasOwnProperty.call(options, key)) {
				defaults[key] = options[key];
			}
		}
		return defaults;
	};

	/**
	 * A simple forEach() implementation for Arrays, Objects and NodeLists
	 * @private
	 * @param {Array|Object|NodeList} collection Collection of items to iterate
	 * @param {Function} callback Callback function for each iteration
	 * @param {Array|Object|NodeList} scope Object/NodeList/Array that forEach is iterating over (aka `this`)
	 */
	var forEach = function (collection, callback, scope) {
		if (Object.prototype.toString.call(collection) === '[object Object]') {
			for (var prop in collection) {
				if (Object.prototype.hasOwnProperty.call(collection, prop)) {
					callback.call(scope, collection[prop], prop, collection);
				}
			}
		} else {
			for (var i = 0, len = collection.length; i < len; i++) {
				callback.call(scope, collection[i], i, collection);
			}
		}
	};

	/**
	 * Calculate the easing pattern
	 * @private
	 * @param {String} type Easing pattern
	 * @param {Number} time Time animation should take to complete
	 * @returns {Number}
	 */
	var easingPattern = function ( type, time ) {
		var pattern;
		if ( type === 'easeInQuad' ) pattern = time * time; // accelerating from zero velocity
		if ( type === 'easeOutQuad' ) pattern = time * (2 - time); // decelerating to zero velocity
		if ( type === 'easeInOutQuad' ) pattern = time < 0.5 ? 2 * time * time : -1 + (4 - 2 * time) * time; // acceleration until halfway, then deceleration
		if ( type === 'easeInCubic' ) pattern = time * time * time; // accelerating from zero velocity
		if ( type === 'easeOutCubic' ) pattern = (--time) * time * time + 1; // decelerating to zero velocity
		if ( type === 'easeInOutCubic' ) pattern = time < 0.5 ? 4 * time * time * time : (time - 1) * (2 * time - 2) * (2 * time - 2) + 1; // acceleration until halfway, then deceleration
		if ( type === 'easeInQuart' ) pattern = time * time * time * time; // accelerating from zero velocity
		if ( type === 'easeOutQuart' ) pattern = 1 - (--time) * time * time * time; // decelerating to zero velocity
		if ( type === 'easeInOutQuart' ) pattern = time < 0.5 ? 8 * time * time * time * time : 1 - 8 * (--time) * time * time * time; // acceleration until halfway, then deceleration
		if ( type === 'easeInQuint' ) pattern = time * time * time * time * time; // accelerating from zero velocity
		if ( type === 'easeOutQuint' ) pattern = 1 + (--time) * time * time * time * time; // decelerating to zero velocity
		if ( type === 'easeInOutQuint' ) pattern = time < 0.5 ? 16 * time * time * time * time * time : 1 + 16 * (--time) * time * time * time * time; // acceleration until halfway, then deceleration
		return pattern || time; // no easing, no acceleration
	};

	/**
	 * Calculate how far to scroll
	 * @private
	 * @param {Element} anchor The anchor element to scroll to
	 * @param {Number} headerHeight Height of a fixed header, if any
	 * @param {Number} offset Number of pixels by which to offset scroll
	 * @returns {Number}
	 */
	var getEndLocation = function ( anchor, headerHeight, offset ) {
		var location = 0;
		if (anchor.offsetParent) {
			do {
				location += anchor.offsetTop;
				anchor = anchor.offsetParent;
			} while (anchor);
		}
		location = location - headerHeight - offset;
		return location >= 0 ? location : 0;
	};

	/**
	 * Determine the document's height
	 * @private
	 * @returns {Number}
	 */
	var getDocumentHeight = function () {
		return Math.max(
			document.body.scrollHeight, document.documentElement.scrollHeight,
			document.body.offsetHeight, document.documentElement.offsetHeight,
			document.body.clientHeight, document.documentElement.clientHeight
		);
	};

	/**
	 * Remove whitespace from a string
	 * @private
	 * @param {String} string
	 * @returns {String}
	 */
	var trim = function ( string ) {
		return string.replace(/^\s+|\s+$/g, '');
	};

	/**
	 * Convert data-options attribute into an object of key/value pairs
	 * @private
	 * @param {String} options Link-specific options as a data attribute string
	 * @returns {Object}
	 */
	var getDataOptions = function ( options ) {
		var settings = {};
		// Create a key/value pair for each setting
		if ( options ) {
			options = options.split(';');
			options.forEach( function(option) {
				option = trim(option);
				if ( option !== '' ) {
					option = option.split(':');
					settings[option[0]] = trim(option[1]);
				}
			});
		}
		return settings;
	};

	/**
	 * Update the URL
	 * @private
	 * @param {Element} anchor The element to scroll to
	 * @param {Boolean} url Whether or not to update the URL history
	 */
	var updateUrl = function ( anchor, url ) {
		if ( history.pushState && (url || url === 'true') ) {
			history.pushState( {
				pos: anchor.id
			}, '', anchor );
		}
	};

	/**
	 * Start/stop the scrolling animation
	 * @public
	 * @param {Element} toggle The element that toggled the scroll event
	 * @param {Element} anchor The element to scroll to
	 * @param {Object} settings
	 * @param {Event} event
	 */
	exports.animateScroll = function ( toggle, anchor, options, event ) {

		// Options and overrides
		var settings = extend( defaults, options || {} ); // Merge user options with defaults
		var overrides = getDataOptions( toggle ? toggle.getAttribute('data-options') : null );
		settings = extend( settings, overrides );

		// Selectors and variables
		var fixedHeader = document.querySelector('[data-scroll-header]'); // Get the fixed header
		var headerHeight = fixedHeader === null ? 0 : (fixedHeader.offsetHeight + fixedHeader.offsetTop); // Get the height of a fixed header if one exists
		var startLocation = root.pageYOffset; // Current location on the page
		var endLocation = getEndLocation( document.querySelector(anchor), headerHeight, parseInt(settings.offset, 10) ); // Scroll to location
		var animationInterval; // interval timer
		var distance = endLocation - startLocation; // distance to travel
		var documentHeight = getDocumentHeight();
		var timeLapsed = 0;
		var percentage, position;

		// Prevent default click event
		if ( toggle && toggle.tagName.toLowerCase() === 'a' && event ) {
			event.preventDefault();
		}

		// Update URL
		updateUrl(anchor, settings.updateURL);

		/**
		 * Stop the scroll animation when it reaches its target (or the bottom/top of page)
		 * @private
		 * @param {Number} position Current position on the page
		 * @param {Number} endLocation Scroll to location
		 * @param {Number} animationInterval How much to scroll on this loop
		 */
		var stopAnimateScroll = function (position, endLocation, animationInterval) {
			var currentLocation = root.pageYOffset;
			if ( position == endLocation || currentLocation == endLocation || ( (root.innerHeight + currentLocation) >= documentHeight ) ) {
				clearInterval(animationInterval);
				settings.callbackAfter( toggle, anchor ); // Run callbacks after animation complete
			}
		};

		/**
		 * Loop scrolling animation
		 * @private
		 */
		var loopAnimateScroll = function () {
			timeLapsed += 16;
			percentage = ( timeLapsed / parseInt(settings.speed, 10) );
			percentage = ( percentage > 1 ) ? 1 : percentage;
			position = startLocation + ( distance * easingPattern(settings.easing, percentage) );
			root.scrollTo( 0, Math.floor(position) );
			stopAnimateScroll(position, endLocation, animationInterval);
		};

		/**
		 * Set interval timer
		 * @private
		 */
		var startAnimateScroll = function () {
			settings.callbackBefore( toggle, anchor ); // Run callbacks before animating scroll
			animationInterval = setInterval(loopAnimateScroll, 16);
		};

		/**
		 * Reset position to fix weird iOS bug
		 * @link https://github.com/cferdinandi/smooth-scroll/issues/45
		 */
		if ( root.pageYOffset === 0 ) {
			root.scrollTo( 0, 0 );
		}

		// Start scrolling animation
		startAnimateScroll();

	};

	/**
	 * Initialize Smooth Scroll
	 * @public
	 * @param {Object} options User settings
	 */
	exports.init = function ( options ) {

		// feature test
		if ( !supports ) return;

		// Selectors and variables
		var settings = extend( defaults, options || {} ); // Merge user options with defaults
		var toggles = document.querySelectorAll('[data-scroll]'); // Get smooth scroll toggles

		// When a toggle is clicked, run the click handler
		forEach(toggles, function (toggle) {
			toggle.addEventListener('click', exports.animateScroll.bind( null, toggle, toggle.getAttribute('href'), settings ), false);
		});

	};


	//
	// Public APIs
	//

	return exports;

});

/* Simple min-height-masonry layout plugin.
Like masonry column shift, but works. */
;(function($) {

	'use strict';

	var cssPrefix = detectCSSPrefix();

	var Waterfall = function(el, opts) {
		this.$el = $(el);
		this.el = el[0];
		this._create(opts);
	};

	Waterfall.defaultClass = 'waterfall';

	$.extend(Waterfall.prototype, {
		options: {
			colMinWidth: 300, //width of column, used to calculate number of columns possible to display
			defaultContainerWidth: window.clientWidth,
			autoresize: true,
			maxCols: 16, //used to restrict max number of columns
			updateDelay: 45, //how often to reflow layout on window resize
			useCalc: undefined, //set width through -prefix-calc value. Values: true, false, undefined. Autodetection.
			useTranslate3d: undefined, //place items through translate3d instead of top/left. Values: true, false, undefined. Autodetection
			animateShow: false, //whether to animate appending items (causes browser extra-reflows, slows down rendering)

			//callbacks
			reflow: null
		},

		_create: function(opts) {
			var self = this,
				o = self.options = $.extend({}, self.options, opts);

			this.items = [];

			//init some vars
			self.lastHeights = [];
			self.lastItems = [];
			self.colPriority = []; //most left = most minimal column
			self.baseOrder = [];

			var cStyle = getComputedStyle(self.el);
			self.el.hidden = true;
			self.el.style.minHeight = cStyle.height; //prevent scrollbar width changing
			if (self.$el.css('position') === 'static') self.el.style.position = 'relative';

			//detect placing mode needed
			if (o.useCalc === undefined) {
				//transform calc detect
				this.prefixedCalc = (function() {
					var dummy = document.createElement('div'),
						props = ['calc', '-webkit-calc', '-moz-calc', '-o-calc'];
					for (var i = 0; i < props.length; ++i) {
						var prop = props[i], propStr =  prop + '(1px)';
						dummy.style.cssText = cssPrefix + 'transform: translate3d(' + [propStr, propStr, propStr].join(',') +');';
						//console.log(dummy.style[cssPrefix + 'transform'])
						if (dummy.style.length && dummy.style[cssPrefix + 'transform'].length > 14) {
							return prop;
						}
					}
				})();
				o.useCalc = !!this.prefixedCalc;
			}
			//console.log(this.prefixedCalc);
			if (o.useTranslate3d === undefined) {
				this.prefixedTranslate3d = (function() {
					var dummy = document.createElement('div');
					var props = ['translate3d', '-webkit-translate3d', '-moz-translate3d', '-o-translate3d'];
					for (var i = 0; i < props.length; ++i) {
						var prop = props[i];
						dummy.style.cssText = cssPrefix + 'transform:' + prop + '(1px, 0, 0);';
						if (dummy.style.length)
							return prop;
					}
				})();
				o.useTranslate3d = !! this.prefixedTranslate3d;
			}
			//console.log(this.prefixedTranslate3d)

			//populate items
			var items;
			{
				items = self.$el.children();
			}

			//remove text nodes
			for (var i = 0; i < self.el.childNodes.length;){
				if (self.el.childNodes[i].nodeType !== 1){
					self.el.removeChild(self.el.childNodes[i]);
				} else i++;
			}

			items.each(function(i, e) {
				//self.items[i].data('id', i);
				self._addItem(e);
				self._initItem(e);
			});

			self.lastItem = self.items[self.items.length - 1];

			self.el.removeAttribute("hidden");

			self._update();

			if (o.autoresize) {
				$(window)
					.resize(self.reflow.bind(self));
			}

			this._observeMutations();
		},

		_addItem: function(item){
			if (item.getAttribute("data-exclude")) return;
			this.items.push(item);
		},

		_observeMutations: function() {
			//Make Node changing observer - the fastest way to add items
			if (window.MutationObserver) {
				//FF, chrome
				this.observer = new MutationObserver(function(mutations) {
					var mNum = mutations.length;
					for (var i = 0; i < mNum; i++) {
						//console.log(mutations[i])
						if (mutations[i].removedNodes.length) {
							this._removedItems(Array.prototype.slice.apply(mutations[i].removedNodes));
						}
						if (mutations[i].addedNodes.length) {
							var nodes = Array.prototype.slice.apply(mutations[i].addedNodes);
							if (mutations[i].nextSibling) {
								this._insertedItems(nodes);
							} else {
								this._appendedItems(nodes);
							}
						}
					}
				}.bind(this));

				this.observer.observe(this.el, {
					attributes: false,
					childList: true,
					characterData: false
				});
			} else {
				//opera, ie
				this.$el.on('DOMNodeInserted', function(e) {
					var evt = (e.originalEvent || e),
						target = evt.target;

					if (target.nodeType !== 1) return;
					if (target.parentNode !== this.el) return; //if insertee is below container
					//console.log("--------" + target.className + " next:" + target.nextSibling + " prev:" + target.previousSibling)

					if (target.previousSibling && target.previousSibling.span && (!target.nextSibling || !target.nextSibling.span)) {
						this._appendedItems([target]); //append specific case, times faster than _insertedItems
					} else {
						this._insertedItems([target]);
					}
				}.bind(this)).on('DOMNodeRemoved', function(e) {
					var el = (e.originalEvent || e).target;

					if (el.nodeType !== 1) return;
					if (el.parentNode !== this.el) return; //if insertee is below container

					this._removedItems([el]);
				}.bind(this));
			}
		},

		//==========================API
		//Ensures column number correct, reallocates items
		reflow: function() {
			var self = this,
				o = self.options;

			window.clearTimeout(self._updateInterval);
			self._updateInterval = window.setTimeout(self._update.bind(self), o.updateDelay);

			return self;
		},

		//========================= Techs
		//called by mutation observer
		_appendedItems: function(items) {
			var l = items.length,
				i = 0;
			//console.log("append: " + this.items.length)
			for (; i < l; i++) {
				var el = items[i];
				if (el.nodeType !== 1) continue;
				this._addItem(el);
				this._initItem(el); //TODO: optimize
				this._setItemWidth(el);
			}

			for (i = 0; i < l; i++) {
				this._placeItem(items[i]);
			}

			this.lastItem = this.items[this.items.length - 1];

			this._maximizeHeight();
		},

		//if new items inserted somewhere inside the list
		_insertedItems: function(items) {
			//console.log("insert: " + this.items.length)
			//clear old items
			this.items.length = 0;

			//init new items
			var l = items.length;
			for (var i = 0; i < l; i++) {
				var el = items[i];
				if (el.nodeType !== 1) continue;
				this._initItem(el); //TODO: optimize
				this._setItemWidth(el);
			}

			//reinit all items
			var children = this.el.childNodes,
				itemsL = children.length;

			for (var i = 0; i < itemsL; i++){
				if (children[i].nodeType !== 1) continue;
				if (!children[i].span) continue;
				this._addItem(children[i]);
			}
			this.lastItem = this.items[this.items.length - 1];

			this.reflow();
		},

		//called by mutation observer
		_removedItems: function(items) {
			var childItems = this.el.childNodes,
				cl = childItems.length;
			//console.log("before removed: " + this.items.length)

			//reinit items
			for (var i = 0; i < items.length; i++){
				this.items.splice(this.items.indexOf(items[i]), 1);
			}

			//console.log("after remove:" + this.items.length)
			this.lastItem = this.items[this.items.length - 1];

			this.reflow();
		},

		//simple trigger routine
		_trigger: function(cbName, arg) {
			try {
				if (this.options[cbName]) this.options[cbName].call(this.$el, arg);
				this.$el.trigger(cbName, [arg]);
			} catch (err) {
				throw (err);
			}
		},

		//init item properties once item appended
		_initItem: function(el) {
			var o = this.options,
				span = el.getAttribute('data-span') || 1,
				floatVal = el.getAttribute('data-float') || el.getAttribute('data-column');

			//set span
			span = (span === 'all' ? o.maxCols : Math.max(0, Math.min(~~(span), o.maxCols)));
			el.span = span; //quite bad, but no choice: dataset is sloow

			//save heavy style-attrs
			var style = getComputedStyle(el);
			el.mr = ~~(style.marginRight.slice(0, -2));
			el.ml = ~~(style.marginLeft.slice(0, -2));
			el.bt = ~~(style.borderTopWidth.slice(0, -2));
			el.bb = ~~(style.borderBottomWidth.slice(0, -2));
			el.mt = ~~(style.marginTop.slice(0, -2)); //ignored because of offsetTop instead of style.top
			el.mb = ~~(style.marginBottom.slice(0, -2));

			//set style
			el.style.position = 'absolute';
			//this._setItemWidth(el); //make it external action to not to init frominside create

			//parset float
			switch (floatVal) {
				case null: //no float
					el.floatCol = null;
					break;
				case 'right':
				case 'last':
					el.floatCol = -span;
					break;
				case 'left':
				case 'first':
					el.floatCol = 0;
					break;
				default: //int column
					el.floatCol = ~~(floatVal) - 1;
					break;
			}

			if (o.animateShow) {
				if (o.useTranslate3d) {
					//TODO: this below crashes chrome
					//el.style[cssPrefix+'translate'] = 'translate3d(0, ' + this.lastHeights[this.colPriority[0]] + 'px ,0)'
				} else {
					el.style.top = this.lastHeights[this.colPriority[this.colPriority.length - 1]] + 'px';
					el.style.left = this.colWidth * this.colPriority[this.colPriority.length - 1] + 'px';
				}
				el.removeAttribute('hidden');
			}
		},

		_initLayoutParams: function() {
			var self = this,
				o = self.options,
				cStyle = window.getComputedStyle(self.el),
				i = 0,
				prevCols = self.lastItems.length;

			self.pl = ~~(cStyle.paddingLeft.slice(0, -2));
			self.pt = ~~(cStyle.paddingTop.slice(0, -2));
			self.pr = ~~(cStyle.paddingRight.slice(0, -2));
			self.pb = ~~(cStyle.paddingBottom.slice(0, -2));

			self.lastHeights.length = 0;
			self.colPriority.length = 0; //most left = most minimal column
			self.baseOrder.length = 0;

			self.colWidth = self.el.clientWidth - self.pl - self.pr;

			self.lastItems.length = ~~(self.colWidth / o.colMinWidth) || 1; //needed length
			console.log(o.colMinWidth)

			var top = o.useTranslate3d ? 0 : self.pt;
			for (i = 0; i < self.lastItems.length; i++) {
				self.lastHeights.push(top);
				self.baseOrder.push(i);
				self.colPriority.push(i);
			}

			self.colWidth /= self.lastItems.length;

			//console.log(prevCols + '->' + self.lastItems.length);
			if (!o.useCalc || prevCols !== self.lastItems.length) {
				//set item widths carefully - if columns changed or px widths used
				for (i = self.items.length; i--;) {
					this._setItemWidth(self.items[i]);
				}
			}

			return self.lastItems.length;
		},

		//full update of layout
		_updateInterval: 0,
		_update: function(from, to) {
			//window.start = Date.now()
			var self = this,
				i = 0,
				start = from || 0,
				end = to || self.items.length,
				colsNeeded = self._initLayoutParams();

			//console.log('beforePlace:' + this.lastItems.length)
			for (i = start; i < end; i++) {
				self._placeItem(self.items[i]);
			}
			//console.log('afterPlace:' + this.lastItems.length)

			self._maximizeHeight();
			self._trigger('reflow');
			//console.log('time elapsed: ' + (Date.now() - window.start) + 'ms')
		},

		//set item width based on span/colWidth
		_setItemWidth: function(el) {
			var span = el.span > this.lastItems.length ? this.lastItems.length : el.span,
				cols = this.lastItems.length,
				colWeight = span / cols;
			if (this.options.useCalc) {
				el.w = (100 * colWeight);
				el.style.width = this.prefixedCalc + '(' + (100 * colWeight) + '% - ' + (el.mr + el.ml + (this.pl + this.pr) * colWeight) + 'px)';
			} else {
				//el.w = ~~(this.colWidth * span - (el.ml + el.mr));
				el.style.width = el.w + 'px';
			}
		},

		_placeItem: function(e) {
			var self = this,
				o = self.options;

			var lastHeights = self.lastHeights,
				lastItems = self.lastItems,
				colPriority = self.colPriority,
				minCol = 0,
				minH = 0,
				h = 0,
				c = 0,
				t = 0,
				end = 0,
				start = 0,
				span = e.span > lastItems.length ? lastItems.length : e.span,
				newH = 0,
				spanCols = [], //numbers of spanned columns
				spanHeights = [], //heights of spanned columns
				style,
				floatCol = e.floatCol;

			//console.log('------ item:' + e.innerHTML)
			//console.log('span:'+span)			

			//Find pro?per column to place item
			//console.log(colPriority)
			if (floatCol) {
				floatCol = floatCol > 0 ? Math.min(floatCol, lastItems.length - span) : (lastItems.length + floatCol);
			}
			if (span === 1) {
				//Single-span element
				if (floatCol === null) {
					//no align
					minCol = colPriority.shift();
				} else {
					//predefined column to align
					minCol = floatCol;
					for (c = 0; c < colPriority.length; c++) {
						if (colPriority[c] == minCol) {
							colPriority.splice(c, 1);
							break;
						}
					}
				}
				spanCols.push(minCol);
				minH = lastHeights[minCol];
			} else if (span >= lastItems.length) { //Full-span element
				minCol = 0;
				minH = lastHeights[colPriority[colPriority.length - 1]];
				spanCols = self.baseOrder.slice();
				spanCols.length = lastHeights.length;
				colPriority.length = 0;
			} else { //Some-span element
				if (floatCol !== null) {
					minCol = floatCol;
					minH = Math.max.apply(Math, lastHeights.slice(minCol, minCol + span));
					//console.log(lastHeights.slice(minCol, span))
					//console.log('fCol:' + floatCol + ' minH: ' + minH)
				} else {
					//Make span heights alternatives
					spanHeights.length = 0;
					minH = Infinity;
					minCol = 0;
					for (c = 0; c <= lastItems.length - span; c++) {
						spanHeights[c] = Math.max.apply(Math, lastHeights.slice(c, c + span));
						if (spanHeights[c] < minH) {
							minCol = c;
							minH = spanHeights[c];
						}
					}
				}
				//Replace priorities
				for (c = 0; c < colPriority.length;) {
					if (colPriority[c] >= minCol && colPriority[c] < minCol + span) {
						spanCols.push(colPriority.splice(c, 1)[0]);
					} else c++;
				}
			}

			//console.log(spanCols)
			//console.log(lastHeights)
			//console.log('? spanCols to ?')

			//TODO: correct to work ok with options
			e.top = ~~minH; //stupid save value for translate3d
			if (o.useTranslate3d) {
				var offset = (100 * minCol / span) + '% + ' + ~~((e.ml + e.mr) * minCol / span) + 'px';
				if (o.useCalc) {
					e.style[cssPrefix + 'transform'] = this.prefixedTranslate3d + '( ' + this.prefixedCalc + '(' + offset + '), ' + e.top + 'px, 0)';
				} else {
					//Safari won't set -webkit-calc in element.style
					e.style[cssPrefix + 'transform'] = this.prefixedTranslate3d + '(' + ~~(self.colWidth * minCol) + 'px, ' + e.top + 'px, 0)';
				}
			} else {
				e.style.top = e.top + 'px';
				e.style.left = self.colWidth * minCol + self.pl + 'px';
			}
			//console.log(e.style[cssPrefix + 'transform'])

			//if element was added first time and is out of flow - show it
			//e.style.opacity = 1;
			e.removeAttribute('hidden');

			newH = self._getBottom(e); //this is the most difficult operation (e.clientHeight)
			for (t = 0; t < spanCols.length; t++) {
				lastItems[spanCols[t]] = e;
				self.lastHeights[spanCols[t]] = newH;
			}

			//console.log(lastItems)
			//console.log('? self.lastHeights to ?')
			//console.log(self.lastHeights)
			//console.log('minCol:'+minCol+' minH:'+minH+' newH:'+newH)
			//console.log(colPriority)
			//console.log('? colPriorities to ?')

			//Update colPriority
			for (c = colPriority.length; c--;) {
				h = self.lastHeights[colPriority[c]];
				if (newH >= h) {
					Array.prototype.splice.apply(colPriority, [c + 1, 0].concat(spanCols));
					break;
				}
			}
			if (colPriority.length < lastHeights.length) {
				Array.prototype.unshift.apply(colPriority, spanCols);
				//self.colPriority = spanCols.concat(colPriority)
			}
		},

		_getBottom: function(e) {
			if (!e) return 0; //this.pt;
			//TODO: memrize height, look for height change to avoid reflow
			return e.top + e.clientHeight + e.bt + e.bb + e.mb + e.mt;
		},

		_maximizeHeight: function() {
			var top = this.options.useTranslate3d ? this.pt : 0;
			this.el.style.minHeight = this.lastHeights[this.colPriority[this.colPriority.length - 1]] + this.pb + top + 'px';
		}

	});


	$.fn.waterfall = function(arg, arg2) {
		if (typeof arg == 'string') { //Call API method
			return $(this).each(function(i, el) {
					$(el).data('waterfall')[arg](arg2);
				});
		} else {
			if (!this.length) {
				throw new Error("No element passed to waterfall")
				return false;
			};
			var $this = $(this),
				opts = $.extend({}, {"colMinWidth": ~~$this[0].getAttribute("data-col-min-width") ||~~$this[0].getAttribute("data-width")}, arg);
			if (opts.width && !opts.colMinWidth) {
				opts.colMinWidth = opts.width;
			}
			var wf = new Waterfall($this, opts);
			if (!$this.data('waterfall')) $this.data('waterfall', wf);
			return wf;
		}
	};

	//prefix/features detector

	function detectCSSPrefix(property) {
		if (!property) property = 'transform';

		
		if(document.defaultView)
		{
			var style = document.defaultView.getComputedStyle(document.body, '');
			if (style[property]) return '';
			if (style['-webkit-' + property]) return '-webkit-';
			if (style['-moz-' + property]) return '-moz-';
			if (style['-o-' + property]) return '-o-';
			if (style['-khtml-' + property]) return '-khtml-';
		}
		return false;
	}

	//autostart
	$(function() {
		var defClass = window.waterfall && window.waterfall.defaultClass || Waterfall.defaultClass;

		$('.' + defClass)
			.each(function(i, e) {
				var $e = $(e),
					opts = window.waterfall || {};
				$e.waterfall(opts);
			});
	});

})(window.jQuery || window.Zepto);

// scrolling
if (window.MasterSlider && document.getElementById('masterslider')) {
  var slider = new MasterSlider();
  slider.setup('masterslider', {
    width: 1900,    // slider standard width
    height: 1280, //1280,   // slider standard height
    space: 1,
    layout: "fillwidth",
    loop: true,
    autoplay: true
  });
  // adds Arrows navigation control to the slider.
  slider.control('arrows');
  if(slider.api)
    slider.api.addEventListener(MSSliderEvent.CHANGE_START, function () {
      var index = slider.api.index();

      $('.slideproducts').hide();
      $('#slide' + index).show();
    });
}

$("a[href^='#']").on('click', function (e) {
     if(this.hash === ""){
         return;
     }
  // prevent default anchor click behavior
  e.preventDefault();

  // store hash
  var hash = this.hash;

  // animate
  $('html, body').animate({
    scrollTop: $(this.hash).offset().top - 100
  }, 300, function () {

    // when done, add hash to url
    // (default click behaviour)
    //window.location.hash = hash;
  });

});


$(window).scroll(function () {
  if ($(this).scrollTop() > 400) {
    $('.to-top').fadeIn();
  } else {
    $('.to-top').fadeOut();
  }
});
  
/* Modernizr 2.8.3 (Custom Build) | MIT & BSD
 * Build: http://modernizr.com/download/#-fontface-backgroundsize-borderimage-borderradius-boxshadow-flexbox-flexboxlegacy-hsla-multiplebgs-opacity-rgba-textshadow-cssanimations-csscolumns-generatedcontent-cssgradients-cssreflections-csstransforms-csstransforms3d-csstransitions-applicationcache-canvas-canvastext-draganddrop-hashchange-history-audio-video-indexeddb-input-inputtypes-localstorage-postmessage-sessionstorage-websockets-websqldatabase-webworkers-touch-shiv-mq-cssclasses-teststyles-testprop-testallprops-hasevent-prefixes-domprefixes-load
 */
;window.Modernizr=function(a,b,c){function C(a){j.cssText=a}function D(a,b){return C(n.join(a+";")+(b||""))}function E(a,b){return typeof a===b}function F(a,b){return!!~(""+a).indexOf(b)}function G(a,b){for(var d in a){var e=a[d];if(!F(e,"-")&&j[e]!==c)return b=="pfx"?e:!0}return!1}function H(a,b,d){for(var e in a){var f=b[a[e]];if(f!==c)return d===!1?a[e]:E(f,"function")?f.bind(d||b):f}return!1}function I(a,b,c){var d=a.charAt(0).toUpperCase()+a.slice(1),e=(a+" "+p.join(d+" ")+d).split(" ");return E(b,"string")||E(b,"undefined")?G(e,b):(e=(a+" "+q.join(d+" ")+d).split(" "),H(e,b,c))}function J(){e.input=function(c){for(var d=0,e=c.length;d<e;d++)t[c[d]]=c[d]in k;return t.list&&(t.list=!!b.createElement("datalist")&&!!a.HTMLDataListElement),t}("autocomplete autofocus list placeholder max min multiple pattern required step".split(" ")),e.inputtypes=function(a){for(var d=0,e,f,h,i=a.length;d<i;d++)k.setAttribute("type",f=a[d]),e=k.type!=="text",e&&(k.value=l,k.style.cssText="position:absolute;visibility:hidden;",/^range$/.test(f)&&k.style.WebkitAppearance!==c?(g.appendChild(k),h=b.defaultView,e=h.getComputedStyle&&h.getComputedStyle(k,null).WebkitAppearance!=="textfield"&&k.offsetHeight!==0,g.removeChild(k)):/^(search|tel)$/.test(f)||(/^(url|email)$/.test(f)?e=k.checkValidity&&k.checkValidity()===!1:e=k.value!=l)),s[a[d]]=!!e;return s}("search tel url email datetime date month week time datetime-local number range color".split(" "))}var d="2.8.3",e={},f=!0,g=b.documentElement,h="modernizr",i=b.createElement(h),j=i.style,k=b.createElement("input"),l=":)",m={}.toString,n=" -webkit- -moz- -o- -ms- ".split(" "),o="Webkit Moz O ms",p=o.split(" "),q=o.toLowerCase().split(" "),r={},s={},t={},u=[],v=u.slice,w,x=function(a,c,d,e){var f,i,j,k,l=b.createElement("div"),m=b.body,n=m||b.createElement("body");if(parseInt(d,10))while(d--)j=b.createElement("div"),j.id=e?e[d]:h+(d+1),l.appendChild(j);return f=["&#173;",'<style id="s',h,'">',a,"</style>"].join(""),l.id=h,(m?l:n).innerHTML+=f,n.appendChild(l),m||(n.style.background="",n.style.overflow="hidden",k=g.style.overflow,g.style.overflow="hidden",g.appendChild(n)),i=c(l,a),m?l.parentNode.removeChild(l):(n.parentNode.removeChild(n),g.style.overflow=k),!!i},y=function(b){var c=a.matchMedia||a.msMatchMedia;if(c)return c(b)&&c(b).matches||!1;var d;return x("@media "+b+" { #"+h+" { position: absolute; } }",function(b){d=(a.getComputedStyle?getComputedStyle(b,null):b.currentStyle)["position"]=="absolute"}),d},z=function(){function d(d,e){e=e||b.createElement(a[d]||"div"),d="on"+d;var f=d in e;return f||(e.setAttribute||(e=b.createElement("div")),e.setAttribute&&e.removeAttribute&&(e.setAttribute(d,""),f=E(e[d],"function"),E(e[d],"undefined")||(e[d]=c),e.removeAttribute(d))),e=null,f}var a={select:"input",change:"input",submit:"form",reset:"form",error:"img",load:"img",abort:"img"};return d}(),A={}.hasOwnProperty,B;!E(A,"undefined")&&!E(A.call,"undefined")?B=function(a,b){return A.call(a,b)}:B=function(a,b){return b in a&&E(a.constructor.prototype[b],"undefined")},Function.prototype.bind||(Function.prototype.bind=function(b){var c=this;if(typeof c!="function")throw new TypeError;var d=v.call(arguments,1),e=function(){if(this instanceof e){var a=function(){};a.prototype=c.prototype;var f=new a,g=c.apply(f,d.concat(v.call(arguments)));return Object(g)===g?g:f}return c.apply(b,d.concat(v.call(arguments)))};return e}),r.flexbox=function(){return I("flexWrap")},r.flexboxlegacy=function(){return I("boxDirection")},r.canvas=function(){var a=b.createElement("canvas");return!!a.getContext&&!!a.getContext("2d")},r.canvastext=function(){return!!e.canvas&&!!E(b.createElement("canvas").getContext("2d").fillText,"function")},r.touch=function(){var c;return"ontouchstart"in a||a.DocumentTouch&&b instanceof DocumentTouch?c=!0:x(["@media (",n.join("touch-enabled),("),h,")","{#modernizr{top:9px;position:absolute}}"].join(""),function(a){c=a.offsetTop===9}),c},r.postmessage=function(){return!!a.postMessage},r.websqldatabase=function(){return!!a.openDatabase},r.indexedDB=function(){return!!I("indexedDB",a)},r.hashchange=function(){return z("hashchange",a)&&(b.documentMode===c||b.documentMode>7)},r.history=function(){return!!a.history&&!!history.pushState},r.draganddrop=function(){var a=b.createElement("div");return"draggable"in a||"ondragstart"in a&&"ondrop"in a},r.websockets=function(){return"WebSocket"in a||"MozWebSocket"in a},r.rgba=function(){return C("background-color:rgba(150,255,150,.5)"),F(j.backgroundColor,"rgba")},r.hsla=function(){return C("background-color:hsla(120,40%,100%,.5)"),F(j.backgroundColor,"rgba")||F(j.backgroundColor,"hsla")},r.multiplebgs=function(){return C("background:url(https://),url(https://),red url(https://)"),/(url\s*\(.*?){3}/.test(j.background)},r.backgroundsize=function(){return I("backgroundSize")},r.borderimage=function(){return I("borderImage")},r.borderradius=function(){return I("borderRadius")},r.boxshadow=function(){return I("boxShadow")},r.textshadow=function(){return b.createElement("div").style.textShadow===""},r.opacity=function(){return D("opacity:.55"),/^0.55$/.test(j.opacity)},r.cssanimations=function(){return I("animationName")},r.csscolumns=function(){return I("columnCount")},r.cssgradients=function(){var a="background-image:",b="gradient(linear,left top,right bottom,from(#9f9),to(white));",c="linear-gradient(left top,#9f9, white);";return C((a+"-webkit- ".split(" ").join(b+a)+n.join(c+a)).slice(0,-a.length)),F(j.backgroundImage,"gradient")},r.cssreflections=function(){return I("boxReflect")},r.csstransforms=function(){return!!I("transform")},r.csstransforms3d=function(){var a=!!I("perspective");return a&&"webkitPerspective"in g.style&&x("@media (transform-3d),(-webkit-transform-3d){#modernizr{left:9px;position:absolute;height:3px;}}",function(b,c){a=b.offsetLeft===9&&b.offsetHeight===3}),a},r.csstransitions=function(){return I("transition")},r.fontface=function(){var a;return x('@font-face {font-family:"font";src:url("https://")}',function(c,d){var e=b.getElementById("smodernizr"),f=e.sheet||e.styleSheet,g=f?f.cssRules&&f.cssRules[0]?f.cssRules[0].cssText:f.cssText||"":"";a=/src/i.test(g)&&g.indexOf(d.split(" ")[0])===0}),a},r.generatedcontent=function(){var a;return x(["#",h,"{font:0/0 a}#",h,':after{content:"',l,'";visibility:hidden;font:3px/1 a}'].join(""),function(b){a=b.offsetHeight>=3}),a},r.video=function(){var a=b.createElement("video"),c=!1;try{if(c=!!a.canPlayType)c=new Boolean(c),c.ogg=a.canPlayType('video/ogg; codecs="theora"').replace(/^no$/,""),c.h264=a.canPlayType('video/mp4; codecs="avc1.42E01E"').replace(/^no$/,""),c.webm=a.canPlayType('video/webm; codecs="vp8, vorbis"').replace(/^no$/,"")}catch(d){}return c},r.audio=function(){var a=b.createElement("audio"),c=!1;try{if(c=!!a.canPlayType)c=new Boolean(c),c.ogg=a.canPlayType('audio/ogg; codecs="vorbis"').replace(/^no$/,""),c.mp3=a.canPlayType("audio/mpeg;").replace(/^no$/,""),c.wav=a.canPlayType('audio/wav; codecs="1"').replace(/^no$/,""),c.m4a=(a.canPlayType("audio/x-m4a;")||a.canPlayType("audio/aac;")).replace(/^no$/,"")}catch(d){}return c},r.localstorage=function(){try{return localStorage.setItem(h,h),localStorage.removeItem(h),!0}catch(a){return!1}},r.sessionstorage=function(){try{return sessionStorage.setItem(h,h),sessionStorage.removeItem(h),!0}catch(a){return!1}},r.webworkers=function(){return!!a.Worker},r.applicationcache=function(){return!!a.applicationCache};for(var K in r)B(r,K)&&(w=K.toLowerCase(),e[w]=r[K](),u.push((e[w]?"":"no-")+w));return e.input||J(),e.addTest=function(a,b){if(typeof a=="object")for(var d in a)B(a,d)&&e.addTest(d,a[d]);else{a=a.toLowerCase();if(e[a]!==c)return e;b=typeof b=="function"?b():b,typeof f!="undefined"&&f&&(g.className+=" "+(b?"":"no-")+a),e[a]=b}return e},C(""),i=k=null,function(a,b){function l(a,b){var c=a.createElement("p"),d=a.getElementsByTagName("head")[0]||a.documentElement;return c.innerHTML="x<style>"+b+"</style>",d.insertBefore(c.lastChild,d.firstChild)}function m(){var a=s.elements;return typeof a=="string"?a.split(" "):a}function n(a){var b=j[a[h]];return b||(b={},i++,a[h]=i,j[i]=b),b}function o(a,c,d){c||(c=b);if(k)return c.createElement(a);d||(d=n(c));var g;return d.cache[a]?g=d.cache[a].cloneNode():f.test(a)?g=(d.cache[a]=d.createElem(a)).cloneNode():g=d.createElem(a),g.canHaveChildren&&!e.test(a)&&!g.tagUrn?d.frag.appendChild(g):g}function p(a,c){a||(a=b);if(k)return a.createDocumentFragment();c=c||n(a);var d=c.frag.cloneNode(),e=0,f=m(),g=f.length;for(;e<g;e++)d.createElement(f[e]);return d}function q(a,b){b.cache||(b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag()),a.createElement=function(c){return s.shivMethods?o(c,a,b):b.createElem(c)},a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+m().join().replace(/[\w\-]+/g,function(a){return b.createElem(a),b.frag.createElement(a),'c("'+a+'")'})+");return n}")(s,b.frag)}function r(a){a||(a=b);var c=n(a);return s.shivCSS&&!g&&!c.hasCSS&&(c.hasCSS=!!l(a,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),k||q(a,c),a}var c="3.7.0",d=a.html5||{},e=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,f=/^(?: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,g,h="_html5shiv",i=0,j={},k;(function(){try{var a=b.createElement("a");a.innerHTML="<xyz></xyz>",g="hidden"in a,k=a.childNodes.length==1||function(){b.createElement("a");var a=b.createDocumentFragment();return typeof a.cloneNode=="undefined"||typeof a.createDocumentFragment=="undefined"||typeof a.createElement=="undefined"}()}catch(c){g=!0,k=!0}})();var s={elements:d.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output progress section summary template time video",version:c,shivCSS:d.shivCSS!==!1,supportsUnknownElements:k,shivMethods:d.shivMethods!==!1,type:"default",shivDocument:r,createElement:o,createDocumentFragment:p};a.html5=s,r(b)}(this,b),e._version=d,e._prefixes=n,e._domPrefixes=q,e._cssomPrefixes=p,e.mq=y,e.hasEvent=z,e.testProp=function(a){return G([a])},e.testAllProps=I,e.testStyles=x,g.className=g.className.replace(/(^|\s)no-js(\s|$)/,"$1$2")+(f?" js "+u.join(" "):""),e}(this,this.document),function(a,b,c){function d(a){return"[object Function]"==o.call(a)}function e(a){return"string"==typeof a}function f(){}function g(a){return!a||"loaded"==a||"complete"==a||"uninitialized"==a}function h(){var a=p.shift();q=1,a?a.t?m(function(){("c"==a.t?B.injectCss:B.injectJs)(a.s,0,a.a,a.x,a.e,1)},0):(a(),h()):q=0}function i(a,c,d,e,f,i,j){function k(b){if(!o&&g(l.readyState)&&(u.r=o=1,!q&&h(),l.onload=l.onreadystatechange=null,b)){"img"!=a&&m(function(){t.removeChild(l)},50);for(var d in y[c])y[c].hasOwnProperty(d)&&y[c][d].onload()}}var j=j||B.errorTimeout,l=b.createElement(a),o=0,r=0,u={t:d,s:c,e:f,a:i,x:j};1===y[c]&&(r=1,y[c]=[]),"object"==a?l.data=c:(l.src=c,l.type=a),l.width=l.height="0",l.onerror=l.onload=l.onreadystatechange=function(){k.call(this,r)},p.splice(e,0,u),"img"!=a&&(r||2===y[c]?(t.insertBefore(l,s?null:n),m(k,j)):y[c].push(l))}function j(a,b,c,d,f){return q=0,b=b||"j",e(a)?i("c"==b?v:u,a,b,this.i++,c,d,f):(p.splice(this.i++,0,a),1==p.length&&h()),this}function k(){var a=B;return a.loader={load:j,i:0},a}var l=b.documentElement,m=a.setTimeout,n=b.getElementsByTagName("script")[0],o={}.toString,p=[],q=0,r="MozAppearance"in l.style,s=r&&!!b.createRange().compareNode,t=s?l:n.parentNode,l=a.opera&&"[object Opera]"==o.call(a.opera),l=!!b.attachEvent&&!l,u=r?"object":l?"script":"img",v=l?"script":u,w=Array.isArray||function(a){return"[object Array]"==o.call(a)},x=[],y={},z={timeout:function(a,b){return b.length&&(a.timeout=b[0]),a}},A,B;B=function(a){function b(a){var a=a.split("!"),b=x.length,c=a.pop(),d=a.length,c={url:c,origUrl:c,prefixes:a},e,f,g;for(f=0;f<d;f++)g=a[f].split("="),(e=z[g.shift()])&&(c=e(c,g));for(f=0;f<b;f++)c=x[f](c);return c}function g(a,e,f,g,h){var i=b(a),j=i.autoCallback;i.url.split(".").pop().split("?").shift(),i.bypass||(e&&(e=d(e)?e:e[a]||e[g]||e[a.split("/").pop().split("?")[0]]),i.instead?i.instead(a,e,f,g,h):(y[i.url]?i.noexec=!0:y[i.url]=1,f.load(i.url,i.forceCSS||!i.forceJS&&"css"==i.url.split(".").pop().split("?").shift()?"c":c,i.noexec,i.attrs,i.timeout),(d(e)||d(j))&&f.load(function(){k(),e&&e(i.origUrl,h,g),j&&j(i.origUrl,h,g),y[i.url]=2})))}function h(a,b){function c(a,c){if(a){if(e(a))c||(j=function(){var a=[].slice.call(arguments);k.apply(this,a),l()}),g(a,j,b,0,h);else if(Object(a)===a)for(n in m=function(){var b=0,c;for(c in a)a.hasOwnProperty(c)&&b++;return b}(),a)a.hasOwnProperty(n)&&(!c&&!--m&&(d(j)?j=function(){var a=[].slice.call(arguments);k.apply(this,a),l()}:j[n]=function(a){return function(){var b=[].slice.call(arguments);a&&a.apply(this,b),l()}}(k[n])),g(a[n],j,b,n,h))}else!c&&l()}var h=!!a.test,i=a.load||a.both,j=a.callback||f,k=j,l=a.complete||f,m,n;c(h?a.yep:a.nope,!!i),i&&c(i)}var i,j,l=this.yepnope.loader;if(e(a))g(a,0,l,0);else if(w(a))for(i=0;i<a.length;i++)j=a[i],e(j)?g(j,0,l,0):w(j)?B(j):Object(j)===j&&h(j,l);else Object(a)===a&&h(a,l)},B.addPrefix=function(a,b){z[a]=b},B.addFilter=function(a){x.push(a)},B.errorTimeout=1e4,null==b.readyState&&b.addEventListener&&(b.readyState="loading",b.addEventListener("DOMContentLoaded",A=function(){b.removeEventListener("DOMContentLoaded",A,0),b.readyState="complete"},0)),a.yepnope=k(),a.yepnope.executeStack=h,a.yepnope.injectJs=function(a,c,d,e,i,j){var k=b.createElement("script"),l,o,e=e||B.errorTimeout;k.src=a;for(o in d)k.setAttribute(o,d[o]);c=j?h:c||f,k.onreadystatechange=k.onload=function(){!l&&g(k.readyState)&&(l=1,c(),k.onload=k.onreadystatechange=null)},m(function(){l||(l=1,c(1))},e),i?k.onload():n.parentNode.insertBefore(k,n)},a.yepnope.injectCss=function(a,c,d,e,g,i){var e=b.createElement("link"),j,c=i?h:c||f;e.href=a,e.rel="stylesheet",e.type="text/css";for(j in d)e.setAttribute(j,d[j]);g||(n.parentNode.insertBefore(e,n),m(c,0))}}(this,document),Modernizr.load=function(){yepnope.apply(window,[].slice.call(arguments,0))};

if(!Modernizr.touch){
	$('body').addClass('desktop');
}

if($('body.checkout-page').length){
  $(document).ready(function() {
  if(!Modernizr.input.placeholder){
      $("input").each(
          function(){
              if($(this).val()=="" && $(this).attr("placeholder")!=""){
                  $(this).val($(this).attr("placeholder"));
                  $(this).focus(function(){
                      if($(this).val()==$(this).attr("placeholder")) $(this).val("");
                  });
                  $(this).blur(function(){
                      if($(this).val()=="") $(this).val($(this).attr("placeholder"));
                  });
              }
      });
  }
});
}


//order throughputter
(function($){
	$('.putThrough').click(function(){
		var $el = $(this);
		var $tr = $el.closest('tr');
		_.sapi.pushOrderThrough({orderId : $tr.data('id')},function(data){
			if(data.success)
				$tr.remove();
		});
		return false;
	});
	
	$('.cancelOrder').click(function(){
		var $el = $(this);
		var $tr = $el.closest('tr');
		_.sapi.cancelOrderPayment({orderId : $tr.data('id')},function(data){
			if(data.success)
				$tr.remove();
		});
		return false;
	});
	
})($);

if(document.body.className.indexOf('product-detail') !== -1)
{
$(function(){ 
 
 smoothScroll.init({
			speed: 700,
			easing: 'easeOutCubic',
			offset: $('.navbar-fixed-top').height(),
			updateURL: true
		});

 //smoothScroll.animateScroll( null, '#p-designer' );
 
 
$("#geocomplete").geocomplete({
  map: ".map_canvas",
  location: "amsterdam"
});
 
 function liquidImage() {
 $(".imgLiquidFill").imgLiquid({
    verticalAlign:'top',
	horizontalAlign: 'center', fill:true
   });
  }
  liquidImage();
 
 
 function vCenter() {
  var imgH=$('.v-center-h').height();
  $('.v-center').css({height: imgH });
 }
  vCenter();
 
 function applyResize(img, offset) {
  var wH=$(window).height();
  if(typeof offset === 'undefined') { offset=0; }
  var h = (wH-offset);
  $('#content').height(h);
  $('#bimg').height(h);     
  liquidImage();
  $("#go-to-designers").css({top: h-200});
  }
  
  $('#product-info-gallery').resize(function() {
  //applyResize(imgg);
  
});

   //agjust only when specs are visible
  function fixShortDetailsPosition() {
    if($('#product-specs').is(':visible')) {
	 var $cn=$('#product-details');  
	 $cn.css({left:($('#product-specs').position().left-350)});  
	}
  }
  
  applyResize(imgg);
  
$(window).resize(function() {
  applyResize(imgg);  
  vCenter();
  //fixShortDetailsPosition();
	log('resize: '+$('#bimg').data('oldposition'));
	$('#bimg').css('background-position-y', $('#bimg').data('oldposition'));
});


var iniDLocation=0;//$('#product-details').position().left;

function slideInSpecs() {
  var $cn=$('#product-details');  
  $('#product-specs').css({right:0});
  $('#product-specs').show();
  $cn.css({left:($cn.position().left-300)});  
}

function slideOutSpecs() {
  $('#product-specs').hide();
  $('#product-specs').css({right:-2000});
  $('#product-details').css({left:''});  
}

   $('.more-spec').on('click',function(e){
     e.preventDefault();
	 $('.more-spec').hide();
	 $('.less-spec').show();
	 slideInSpecs();
   });
   
   $('.less-spec').on('click',function(e){
     e.preventDefault();
	 $('.less-spec').hide();
	 $('.more-spec').show();
	 slideOutSpecs();
   });
  
  
//  <!--Piet: Uitgezet omdat het crash gaf in IE (Geen idee waar dit voor is, volgens mij is het legacy)
  /*
  $.rubberband("bind", "(max-width: 768px)", {
	enter: function() {
		$('#product-specs').hide();
        $('#product-specs').css({right:-2000});
		$('#product-details').css({left:''});
		$('.less-spec').hide();
	    $('.more-spec').show();
	},
	leave: function() {
		console.log('leave 768');		
	}
 });
*/



      $(".rolled").roller({
	   single:true,
	   pagination:false, 
	   autoWidth:true, labels: { previous: 'vorige', next:'volgende' }
	  });

				$(window).on("snap", function() {
					$(".rolled").roller("reset");
				});
	  
	  
});

function log(input){
	//console.log(input);
}
		<!-- Scroll Animation -->
		$(function()
		{
			$("a[href^='#']").on('click', function(e) {

			   // prevent default anchor click behavior
               if(this.hash === "#"){
                   return;
               }
			   e.preventDefault();

			   // store hash
			   var hash = this.hash;
			   
			   // animate
			   $('html, body').animate({
			       scrollTop: $(this.hash).offset().top - 100
			     }, 300, function(){

			       // when done, add hash to url
			       // (default click behaviour)
			       //window.location.hash = hash;
			     });

			});



			$('#p-product').on('mousemove', '.roller-item.active', function(evt)
			{	
			
				var y = evt.pageY - $(this).offset().top;
				var percent = (y / $(this).height()) * 100;
				log('mouse move: '+ percent);
				$('#bimg').css('background-position-y', percent + '%');
			
				
			});

			$('#p-product').on('mouseenter', '.roller-item.active', function()
			{
				log('mouse enter');
				$(this).data('old-background-position-y', $(this).data('oldposition'));
				var src = $(this).find('img').data('full');				
				$('#bimg').css('background-image', 'url(\'' + src  + '\')');
			});

			$('#p-product').on('mouseleave', '.roller-item.active', function()
			{
				
				var oldBg = $('#product-image').attr('src');
				$('#bimg').css('background-image', 'url(\'' + oldBg + '\')');
				log('mouseleave: '+$('#bimg').data('oldposition'));
				$('#bimg').css('background-position-y', $('#bimg').data('oldposition'));
	
			});

		});
		$(document).ready(function(){
			var oldBg = $('#product-image').attr('src');
			$('#bimg').css('background-image', 'url(\'' + oldBg + '\')');
			log('ready: ' + $('#bimg').data('oldposition'));
			$('#bimg').css('background-position-y', $('#bimg').data('oldposition'));
		});

$(document).ready(function(){
	$('.twitterShare').attr('href',"//twitter.com/intent/tweet?url="+polsUrl+"&amp;text="+description);
	$('.pinterestShare').attr('href',"//pinterest.com/pin/create/button/?url="+polsUrl+"&amp;media="+pinterestMedia+"&amp;description="+description);
	$('.facebookShare').attr('href',"https://www.facebook.com/sharer/sharer.php?u="+polsUrl);

});

}
/* Auto generated on 5-5-2020 09:57:23 */

var _ = {
  'mailinglist' : {
          'subscribe' : function(pars, callback){/* email, firstName, lastName, listId,  */if(!pars){pars={};}return liquid.callApi('/api/mailinglist/subscribe', {'Email':pars.email, 'FirstName':pars.firstName, 'LastName':pars.lastName, 'ListId':pars.listId}, callback)},
          'unSubscribe' : function(pars, callback){/* email, listId,  */if(!pars){pars={};}return liquid.callApi('/api/mailinglist/unsubscribe', {'Email':pars.email, 'ListId':pars.listId}, callback)}
},
  'api' : {
},
  'item' : {
          'addToList' : function(pars, callback){/* itemcode, listTypeCode,  */if(!pars){pars={};}return liquid.callApi('/api/item/addtolist', {'Itemcode':pars.itemcode, 'ListTypeCode':pars.listTypeCode}, callback)},
          'removeFromList' : function(pars, callback){/* itemcode, listTypeCode,  */if(!pars){pars={};}return liquid.callApi('/api/item/removefromlist', {'Itemcode':pars.itemcode, 'ListTypeCode':pars.listTypeCode}, callback)},
          'toggleList' : function(pars, callback){/* itemcode, listTypeCode,  */if(!pars){pars={};}return liquid.callApi('/api/item/togglelist', {'Itemcode':pars.itemcode, 'ListTypeCode':pars.listTypeCode}, callback)}
},
  'sapi' : {
          'pushOrderThrough' : function(pars, callback){/* orderId,  */if(!pars){pars={};}return liquid.callApi('/api/sapi/pushorderthrough', {'OrderId':pars.orderId}, callback)},
          'cancelOrderPayment' : function(pars, callback){/* orderId,  */if(!pars){pars={};}return liquid.callApi('/api/sapi/cancelorderpayment', {'OrderId':pars.orderId}, callback)},
          'getPaymentMethods' : function(pars, callback){/* template, countryCode,  */if(!pars){pars={};}return liquid.callApi('/api/sapi/getpaymentmethods', {'Template':pars.template, 'CountryCode':pars.countryCode}, callback)},
          'getPaymentForm' : function(pars, callback){/* template,  */if(!pars){pars={};}return liquid.callApi('/api/sapi/getpaymentform', {'Template':pars.template}, callback)},
          'getDeliveryMethods' : function(pars, callback){/* template, countryCode,  */if(!pars){pars={};}return liquid.callApi('/api/sapi/getdeliverymethods', {'Template':pars.template, 'CountryCode':pars.countryCode}, callback)},
          'getCart' : function(pars, callback){/* template,  */if(!pars){pars={};}return liquid.callApi('/api/sapi/getcart', {'Template':pars.template}, callback)},
          'getCurrentOrder' : function(pars, callback){/* chars, length,  */if(!pars){pars={};}return liquid.callApi('/api/sapi/getcurrentorder', {'Chars':pars.chars, 'Length':pars.length}, callback)},
          'orderItem' : function(pars, callback){/* normalizedItemcode, quantity,  */if(!pars){pars={};}return liquid.callApi('/api/sapi/orderitem', {'NormalizedItemcode':pars.normalizedItemcode, 'Quantity':pars.quantity}, callback)},
          'updateOrderQTY' : function(pars, callback){/* orderLineID, quantity,  */if(!pars){pars={};}return liquid.callApi('/api/sapi/updateorderqty', {'OrderLineID':pars.orderLineID, 'Quantity':pars.quantity}, callback)},
          'getOrderDock' : function(pars, callback){/*  */if(!pars){pars={};}return liquid.callApi('/api/sapi/getorderdock', {}, callback)},
          'getCartOrder' : function(pars, callback){/*  */if(!pars){pars={};}return liquid.callApi('/api/sapi/getcartorder', {}, callback)},
          'switchLanguage' : function(pars, callback){/*  */if(!pars){pars={};}return liquid.callApi('/api/sapi/switchlanguage', {}, callback)},
          'addCoupon' : function(pars, callback){/* couponCode,  */if(!pars){pars={};}return liquid.callApi('/api/sapi/addcoupon', {'CouponCode':pars.couponCode}, callback)},
          'removeDiscount' : function(pars, callback){/* orderlineId,  */if(!pars){pars={};}return liquid.callApi('/api/sapi/removediscount', {'OrderlineId':pars.orderlineId}, callback)},
          'validateCart' : function(pars, callback){/*  */if(!pars){pars={};}return liquid.callApi('/api/sapi/validatecart', {}, callback)},
          'removeOrderline' : function(pars, callback){/* id,  */if(!pars){pars={};}return liquid.callApi('/api/sapi/removeorderline', {'Id':pars.id}, callback)},
          'updateAccount' : function(pars, callback){/* firstName, lastName, birthDate, phoneHome, phoneMobile, phoneWork, shippingAddressId, shippingStreet, shippingPostal, shippingCity, shippingCountry, invoiceAddressId, invoiceStreet, invoicePostal, invoiceCity, invoiceCountry,  */if(!pars){pars={};}return liquid.callApi('/api/sapi/updateaccount', {'FirstName':pars.firstName, 'LastName':pars.lastName, 'BirthDate':pars.birthDate, 'PhoneHome':pars.phoneHome, 'PhoneMobile':pars.phoneMobile, 'PhoneWork':pars.phoneWork, 'ShippingAddressId':pars.shippingAddressId, 'ShippingStreet':pars.shippingStreet, 'ShippingPostal':pars.shippingPostal, 'ShippingCity':pars.shippingCity, 'ShippingCountry':pars.shippingCountry, 'InvoiceAddressId':pars.invoiceAddressId, 'InvoiceStreet':pars.invoiceStreet, 'InvoicePostal':pars.invoicePostal, 'InvoiceCity':pars.invoiceCity, 'InvoiceCountry':pars.invoiceCountry}, callback)},
          'getVariantProposal' : function(pars, callback){/* itemCode, selectedValues,  */if(!pars){pars={};}return liquid.callApi('/api/sapi/getvariantproposal', {'ItemCode':pars.itemCode, 'SelectedValues':pars.selectedValues}, callback)},
          'login' : function(pars, callback){/* username, password,  */if(!pars){pars={};}return liquid.callApi('/api/sapi/login', {'Username':pars.username, 'Password':pars.password}, callback)},
          'logout' : function(pars, callback){/*  */if(!pars){pars={};}return liquid.callApi('/api/sapi/logout', {}, callback)},
          'testOrderconfirmation' : function(pars, callback){/*  */if(!pars){pars={};}return liquid.callApi('/api/sapi/testorderconfirmation', {}, callback)},
          'setDeliveryMethod' : function(pars, callback){/* code,  */if(!pars){pars={};}return liquid.callApi('/api/sapi/setdeliverymethod', {'Code':pars.code}, callback)},
          'setPaymentMethod' : function(pars, callback){/* code,  */if(!pars){pars={};}return liquid.callApi('/api/sapi/setpaymentmethod', {'Code':pars.code}, callback)},
          'sendConfirmation' : function(pars, callback){/* orderId,  */if(!pars){pars={};}return liquid.callApi('/api/sapi/sendconfirmation', {'OrderId':pars.orderId}, callback)}
},
  'search' : {
          'popupTemplate' : function(pars, callback){/* query,  */if(!pars){pars={};}return liquid.callApi('/api/search/popuptemplate', {'Query':pars.query}, callback)}
},
  'servicepoints' : {
          'setServicepoint' : function(pars, callback){/* servicepointID, temp, template,  */if(!pars){pars={};}return liquid.callApi('/api/servicepoints/setservicepoint', {'ServicepointID':pars.servicepointID, 'Temp':pars.temp, 'Template':pars.template}, callback)},
          'cancelTempServicepoint' : function(pars, callback){/*  */if(!pars){pars={};}return liquid.callApi('/api/servicepoints/canceltempservicepoint', {}, callback)},
          'useTempServicepoint' : function(pars, callback){/*  */if(!pars){pars={};}return liquid.callApi('/api/servicepoints/usetempservicepoint', {}, callback)},
          'clearGeoCache' : function(pars, callback){/*  */if(!pars){pars={};}return liquid.callApi('/api/servicepoints/cleargeocache', {}, callback)},
          'setKeyword' : function(pars, callback){/* keyword,  */if(!pars){pars={};}return liquid.callApi('/api/servicepoints/setkeyword', {'Keyword':pars.keyword}, callback)}
},
  'ladybird' : {
          'search' : function(pars, callback){/* keywords,  */if(!pars){pars={};}return liquid.callApi('/api/ladybird/search', {'Keywords':pars.keywords}, callback)},
          'createOrder' : function(pars, callback){/* order,  */if(!pars){pars={};}return liquid.callApi('/api/ladybird/createorder', {'Order':pars.order}, callback)}
},
  'migration' : {
          'runMigrations' : function(pars, callback){/* stage,  */if(!pars){pars={};}return liquid.callApi('/api/migration/runmigrations', {'Stage':pars.stage}, callback)},
          'retryMigrations' : function(pars, callback){/* stage,  */if(!pars){pars={};}return liquid.callApi('/api/migration/retrymigrations', {'Stage':pars.stage}, callback)},
          'runSingle' : function(pars, callback){/* filename,  */if(!pars){pars={};}return liquid.callApi('/api/migration/runsingle', {'Filename':pars.filename}, callback)}
},
  'translation' : {
          'downloadTranslations' : function(pars, callback){/*  */if(!pars){pars={};}return liquid.callApi('/api/translation/downloadtranslations', {}, callback)}
},
  'deploy' : {
          'deployT4' : function(pars, callback){/*  */if(!pars){pars={};}return liquid.callApi('/api/deploy/deployt4', {}, callback)}
},
  'liquid' : {
          'setDebugMode' : function(pars, callback){/* debugMode,  */if(!pars){pars={};}return liquid.callApi('/api/liquid/setdebugmode', {'DebugMode':pars.debugMode}, callback)},
          'setStage' : function(pars, callback){/* stage,  */if(!pars){pars={};}return liquid.callApi('/api/liquid/setstage', {'Stage':pars.stage}, callback)},
          'refreshTranslations' : function(pars, callback){/*  */if(!pars){pars={};}return liquid.callApi('/api/liquid/refreshtranslations', {}, callback)},
          'reloadSettings' : function(pars, callback){/*  */if(!pars){pars={};}return liquid.callApi('/api/liquid/reloadsettings', {}, callback)},
          'switchLanguage' : function(pars, callback){/*  */if(!pars){pars={};}return liquid.callApi('/api/liquid/switchlanguage', {}, callback)},
          'clearTemplateCache' : function(pars, callback){/* debugMode,  */if(!pars){pars={};}return liquid.callApi('/api/liquid/cleartemplatecache', {'DebugMode':pars.debugMode}, callback)},
          'login' : function(pars, callback){/* username, password,  */if(!pars){pars={};}return liquid.callApi('/api/liquid/login', {'Username':pars.username, 'Password':pars.password}, callback)},
          'logout' : function(pars, callback){/*  */if(!pars){pars={};}return liquid.callApi('/api/liquid/logout', {}, callback)},
          'changePassword' : function(pars, callback){/* oldPassword, newPassword,  */if(!pars){pars={};}return liquid.callApi('/api/liquid/changepassword', {'OldPassword':pars.oldPassword, 'NewPassword':pars.newPassword}, callback)},
          'requestResetPassword' : function(pars, callback){/* email, template,  */if(!pars){pars={};}return liquid.callApi('/api/liquid/requestresetpassword', {'Email':pars.email, 'Template':pars.template}, callback)},
          'resetPassword' : function(pars, callback){/* resetCode, newPassword,  */if(!pars){pars={};}return liquid.callApi('/api/liquid/resetpassword', {'ResetCode':pars.resetCode, 'NewPassword':pars.newPassword}, callback)},
          'getTemplateHtml' : function(pars, callback){/* template,  */if(!pars){pars={};}return liquid.callApi('/api/liquid/gettemplatehtml', {'Template':pars.template}, callback)}
},
  'liquidsessionless' : {
          'getTemplateHtml' : function(pars, callback){/* template,  */if(!pars){pars={};}return liquid.callApi('/api/liquidsessionless/gettemplatehtml', {'Template':pars.template}, callback)}
},
  'liquidstudio' : {
          'getAvailableModels' : function(pars, callback){/*  */if(!pars){pars={};}return liquid.callApi('/api/liquidstudio/getavailablemodels', {}, callback)},
          'saveTemplate' : function(pars, callback){/* templateName, body, description, className, includes, liquidStudioUserKey,  */if(!pars){pars={};}return liquid.callApi('/api/liquidstudio/savetemplate', {'TemplateName':pars.templateName, 'Body':pars.body, 'Description':pars.description, 'ClassName':pars.className, 'Includes':pars.includes, 'LiquidStudioUserKey':pars.liquidStudioUserKey}, callback)}
},
  'validation' : {
          'validateForm' : function(pars, callback){/* formName, fieldName, fields, submit,  */if(!pars){pars={};}return liquid.callApi('/api/validation/validateform', {'FormName':pars.formName, 'FieldName':pars.fieldName, 'Fields':pars.fields, 'Submit':pars.submit}, callback)}
}
};

$(function()
{
	$('#searchbox').keypress(function(e)
	{
		if(e.which == 13)
		{
			document.location = '/search/' + $(this).val();
		}
	});
	
	
	$('#searchbutton').click(function()
	{
		document.location = '/search/' + $('#searchbox').val();
	});
});

	$('ol.breadcrumb li.filter').click(function()
	{
		var specCode = $(this).data('spec');
		var valueCode = $(this).data('valuecode');
		
		var input = $("input[name='"+specCode+"'][value='"+valueCode+"']");
		input.attr("checked", false);
		specform.submit();
	});
