Monitus UI Library

Yahoo!  4

Monitus UI Library > yahoo > jmui_yahoo.js (source view)
Search:
 
Filters
/**
 * The YAHOO module provides utilities to be used on Yahoo! stores.
 * 
 * @module yahoo
 * @title Yahoo!
 * @namespace jMUI
 * @requires util, ga
 */

/**
 * The YAHOO module provides utilities to be used on Yahoo! stores.
 *
 * @class yahoo
 * @namespace jMUI
 * @static
 */
jMUI.ready = false;
jMUI.yahoo = jMUI.yahoo || {};
//jMUI.yahoo._ga_trackers = jMUI.yahoo._ga_trackers || [];
jMUI.yahoo.ga = jMUI.yahoo.ga || [];
jMUI.yahoo._gaq = jMUI.yahoo._gaq || [];

jMUI.yahoo.set_cookie_value = jMUI.yahoo.set_cookie_value || function(pName, pHours, pPath, pValue) {
	jMUI.util.set_cookie_value(pName, pHours, pPath, jMUI.yahoo.cookie_domain(), pValue);
};
jMUI.yahoo.cookie_value = jMUI.yahoo.cookie_value || function(pName, pDefault, pDelete) {
	var cookie = jMUI.util.cookie_value(pName, pDefault);
	if(pDelete) jMUI.yahoo.set_cookie_value(pName, "x", "/", "");
	return cookie;
};

/**
 * Get a broad enough domain to be used for cookies on a Yahoo! store.
 *
 * @method cookie_domain
 *
 * @param {string} pDomain the domain OR null OR "auto". If not null, this simply returns the passed domain.
 *
 * @return {string} a domain broad enough to be used for store cookies.
 *
 * @static
 */
jMUI.yahoo.cookie_domain = jMUI.yahoo.cookie_domain || function(pDomain) {
	if(!pDomain || (pDomain == "auto")) {
		pDomain = null;
		if(location.hostname.match(/stores\.yahoo\.net$/i)) pDomain = '.stores.yahoo.net';
		else if(location.hostname.match(/yahoo\.net$/i)) pDomain = '.store.yahoo.net';
		else if(location.hostname.match(/(search|lib)\.store\.yahoo\.com$/i)) pDomain = '.store.yahoo.com';
		else pDomain = location.hostname.replace(/(?:^|.+\.)([^\.]+\.[^\.]+)$/i, "$1");
	}
	return pDomain;
};
/**
 * Grab the current page's ID; on the store domain, will be the product ID. 
 * On the checkout side, it will be the "sectionId" value. (ysco.cart, ysco.ship-bill, ...)
 * 
 * @method current_page_id
 *
 * @return {object} the current page's ID.
 *
 * @static
 */
jMUI.yahoo.current_page_id = jMUI.yahoo.current_page_id || function() {
	var vTokens = window.location.search.match(/sectionId\=([^&]*)/);
	if(vTokens || window.location.pathname.match(/\/(wg\-order|MetaController)/)) {
		if(vTokens) return vTokens[1];
		else return "ysco.cart";
	} else {
		vTokens = window.location.pathname.match(/([^\/\.]+)\..+?$/);
		if(vTokens) return vTokens[1];
		else return "homepage";
	}
};
/**
 * Save the current referrer in a cookie, so it can be read later.
 * Particularely useful for javascript redirects: use this before you do the redirect, and then
 * use jMUI.util.cookie_value("_mrrf", null); on the new landing page to grab the initial referrer.
 * <strong>Note: </strong> since this mechanism uses cookies, it will only work if the redirect happens on the same root domain.
 *
 * @method save_referrer_for_redirect
 *
 * @static
 */
jMUI.yahoo.save_referrer_for_redirect = jMUI.yahoo.save_referrer_for_redirect || function() { jMUI.yahoo.set_cookie_value("_mrrf", ".", "/", document.referrer); };
/**
 * Clear the saved referrer from the cookies; should be called as soon as you have used the referrer info.
 *
 * @method clear_referrer_for_redirect
 *
 * @static
 */
jMUI.yahoo.clear_referrer_for_redirect = jMUI.yahoo.clear_referrer_for_redirect || function() { jMUI.yahoo.set_cookie_value("_mrrf", "x", "/", ""); };
/**
 * Create a Monitus-compatible tracking object for Google Analytics. This ensures that your tracking object
 * does not interfere with the Monitus one, or pollute the cookie space, etc...
 * 
 * <p>This call will also automatically grab and use the saved referrer, if set.</p>
 * <p>If the Facebook or Twitter javascript objects exists when the object is created, Social NEtowrk tracking will happen automatically.</p>
 *
 * @method create_ga_tracking_object
 *
 * @param {string|object} pProfileID the GA profile ID (UA-xxxxxx-x); string is for _gaq profile only, but you can pass an object to use one or both of _gaq or ga: {gaq: "UA-...", ga: "U-..."}
 * @param {array} pIgnoredReferers list of ignored referrers; maps to GA's &quot;_addIgnoredRef&quot; function. Optional.
 * @param {number} pMaxVars maximum number of custom variables allowed on the page; maps to GA's &quot;_setMaxCustomVariables&quot; function. Optional.
 * @param {number} pSessionTimeout session timeout value (in milliseconds); maps to GA's &quot;_setSessionCookieTimeout&quot; function. Optional.
 * @param {string} pTrackerName GA tracker name. Optional.
 * @param {bool} pEnhancedEcomm enhanced e-commerce tracking. Optional.
 *
 * @return {object} a GA tracker object.
 *
 * @static
 */
jMUI.yahoo.create_ga_tracking_object = jMUI.yahoo.create_ga_tracking_object || function(pProfileID, pIgnoredReferers, pMaxVars, pSessionTimeout, pTrackerName, pEnhancedEcomm) {
	if(typeof(pProfileID) == "string") pProfileID = {gaq: pProfileID};
	
	var vDomain = document.location.host;
	var vTokens = vDomain.match(/(store\.yahoo\.(com|net))/i);
	if(vTokens) vDomain = vTokens[1];
	else {
		vTokens = document.location.host.match(/.*\.([^\.]+\.[^\.]+)\/?$/i);
		if(vTokens) vDomain = vTokens[1];
	}
	var vIgnoredReferers = [vDomain, "paypal.com", "edit.store.yahoo.net", "edit.store.luminate.net", "edit.store.luminatestores.net", "stores.yahoo.net", "order.store.yahoo.net", "search.store.yahoo.com", "search.store.yahoo.net"];
	if(pIgnoredReferers) vIgnoredReferers = vIgnoredReferers.concat(pIgnoredReferers);
	var vOverridenReferrer = jMUI.util.cookie_value("_mrrf", null);
	var trackerName = pTrackerName || "";
	var gaq = [];
	
	if(pProfileID) {
		// track ga
		jMUI.internal._debug("ga: " + pProfileID.ga + ", " + typeof(window.ga));
		if(pProfileID.ga && (typeof(window.ga) != "undefined")) {
			if(!window.GoogleAnalyticsObject) window.GoogleAnalyticsObject = "ga";
			if(!window.ga_monitus && (typeof(window.ga) != "undefined") && (typeof(window.ga.getByName) != "undefined")) {
				var tracker = window.ga.getByName(trackerName);
				if(!tracker) tracker = window.ga.getAll();
				if(tracker) tracker = tracker[0];
				if(tracker && (typeof(tracker.get) == "function")) {
					tracker = tracker.get("trackingId");
					if((typeof(tracker) == "string") && (!tracker.match(/^[ua\-x]+$/i)) && (tracker != pProfileID.ga)) trackerName += pProfileID.ga.replace(/[^UA\d]+/g, '');
				}
			}
			
			var prefix = trackerName + ((trackerName && (trackerName != "")) ? "." : "");
			var prefs = {cookieDomain: vDomain, legacyCookieDomain: vDomain, allowLinker: true};
			if(trackerName && (trackerName != "")) prefs.name = trackerName;
			if(vOverridenReferrer) prefs.referrer = vOverridenReferrer;
			
			var ga_q = function(){gaq.push(arguments)};
			
			ga_q("create", pProfileID.ga, prefs);
			jMUI.yahoo._ga_ec = pEnhancedEcomm;
			if(jMUI.yahoo._ga_ec) ga_q('require', 'ec', 'ec.js'); // used on store too!
			if(typeof(orderNum) != "undefined") ga_q('require', 'ecommerce', 'ecommerce.js');
			if(vOverridenReferrer) ga_q("set", "referrer", vOverridenReferrer);
			// * pSessionTimeout is now a UA property setting
			if(typeof(jMUI.monitus) != "undefined") jMUI.monitus.refAnalyzer.setup_ga(prefix, ga_q); // **** a lot of properties in there I think, that are no longer available?
			
			// * vIgnoredReferers is now a UA property setting
			// * pMaxVars is obsolete
			
			if((typeof(FB) != "undefined") && (typeof(FB.Event) != "undefined")) {
				FB.Event.subscribe('edge.create', function(pTargetURL) { window.ga('send', 'social', {socialNetwork: 'facebook', socialAction: 'like', socialTarget: pTargetURL}); });
				FB.Event.subscribe('edge.remove', function(pTargetURL) { window.ga('send', 'social', {socialNetwork: 'facebook', socialAction: 'unlike', socialTarget: pTargetURL}); });
				FB.Event.subscribe('message.send', function(pTargetURL) { window.ga('send', 'social', {socialNetwork: 'facebook', socialAction: 'send', socialTarget: pTargetURL}); });
			}
			if((typeof(twttr) != "undefined") && (typeof(twttr.events) != "undefined")) {
				twttr.events.bind('tweet', function(pEvent) {
					if(pEvent) {
						var vTargetURL;
						if(pEvent.target && pEvent.target.nodeName.match(/iframe/i)) vTargetURL = jMUI.util.url_parameter(pEvent.target.src, 'url', null);
						window.ga('send', 'social', {socialNetwork: 'twitter', socialAction: 'tweet', socialTarget: vTargetURL});
					}
				});
			}
			if((typeof(addthis) != "undefined") && (typeof(addthis.addEventListener) != "undefined")) {
				addthis.addEventListener('addthis.menu.share', function(pEvent) {
					window.ga('send', 'social', {socialNetwork: 'pEvent.data.service', socialAction: 'addthis'});
				});
			}
			if(typeof(jMUI.yahoo.ga) == "undefined") jMUI.yahoo.ga = [];
			jMUI.yahoo.ga = gaq.concat(jMUI.yahoo.ga);
			if(window.ga_monitus) {
				window.ga = window.ga_monitus;
				window.ga_monitus = null;
				var max = jMUI.yahoo.ga.length;
				var max = Math.min(max, 1000); // just in case
				for(var loop = 0; loop < max; loop++) {
					window.ga.apply(window.ga, jMUI.yahoo.ga[loop]);
				}
			} else window.ga.q = jMUI.yahoo.ga; // it's ok to loose the "push" override here - the tracker is initialized and when ga loads, it will slurp the whole _gaq array
			jMUI.yahoo.ga = null;
		}
		
		// track _gaq
		jMUI.internal._debug("gaq: " + pProfileID.gaq + ", " + typeof(_gaq));
		if(pProfileID.gaq && (typeof(_gaq) != "undefined")) {
			if((typeof(_gat) != "undefined") && (typeof(_gat._getTrackerByName) == "function")) {
				var tracker = _gat._getTrackerByName(trackerName);
				if(tracker && (typeof(tracker._getAccount) == "function")) {
					tracker = tracker._getAccount();
					if((typeof(tracker) == "string") && (!tracker.match(/^[ua\-x]+$/i)) && (tracker != pProfileID.gaq)) trackerName += pProfileID.gaq.replace(/[^UA\d]+/g, '');
				}
			}
			var prefix = trackerName + ((trackerName && (trackerName != "")) ? "." : "");
			gaq.push([prefix + '_setAccount', pProfileID.gaq]);
			gaq.push([prefix + '_setAllowHash', false]);
			if(pSessionTimeout) gaq.push([prefix + '_setSessionCookieTimeout', pSessionTimeout]);
			gaq.push([prefix + '_setDomainName', vDomain]);
			gaq.push([prefix + '_setAllowLinker', true]);
			if(typeof(jMUI.monitus) != "undefined") jMUI.monitus.refAnalyzer.setup_ga(prefix, gaq);
			if(jMUI.yahoo.current_page_id().match(/ysco\./)) gaq.push([prefix + '_setSiteSpeedSampleRate', 20]);
			
			for(var vLoop = 0; vLoop < vIgnoredReferers.length; vLoop++) gaq.push([prefix + '_addIgnoredRef', vIgnoredReferers[vLoop]]);
			if(pMaxVars && (pMaxVars != 5)) gaq.push([prefix + '_setMaxCustomVariables', pMaxVars]);
			if(vOverridenReferrer) gaq.push([prefix + '_setReferrerOverride', vOverridenReferrer]);
			
			if((typeof(FB) != "undefined") && (typeof(FB.Event) != "undefined")) {
				FB.Event.subscribe('edge.create', function(pTargetURL) { window._gaq.push(['_trackSocial', 'facebook', 'like', pTargetURL]); });
				FB.Event.subscribe('edge.remove', function(pTargetURL) { window._gaq.push(['_trackSocial', 'facebook', 'unlike', pTargetURL]); });
				FB.Event.subscribe('message.send', function(pTargetURL) { window._gaq.push(['_trackSocial', 'facebook', 'send', pTargetURL]); });
			}
			if((typeof(twttr) != "undefined") && (typeof(twttr.events) != "undefined")) {
				twttr.events.bind('tweet', function(pEvent) {
					if(pEvent) {
						var vTargetURL;
						if(pEvent.target && pEvent.target.nodeName.match(/iframe/i)) vTargetURL = jMUI.util.url_parameter(pEvent.target.src, 'url', null);
						window._gaq.push(['_trackSocial', 'twitter', 'tweet', vTargetURL]);
					}
				});
			}
			if((typeof(addthis) != "undefined") && (typeof(addthis.addEventListener) != "undefined")) {
				addthis.addEventListener('addthis.menu.share', function(pEvent) {
					window._gaq.push(['_trackSocial', pEvent.data.service, 'addthis', null]);
				});
			}
			
			window._gaq = window._gaq || [];
			if(typeof(jMUI.yahoo._gaq) == "undefined") jMUI.yahoo._gaq = [];
			jMUI.yahoo._gaq = gaq.concat(jMUI.yahoo._gaq);
			if(Object.prototype.toString.call(window._gaq) == "[object Object]") {
				if(window._gaq.monitus_push) {
					window._gaq.push = window._gaq.monitus_push;
					window._gaq.monitus_push = null;
				}
				for(var loop = 0; loop < jMUI.yahoo._gaq.length; loop++) window._gaq.push(jMUI.yahoo._gaq[loop]);
			} else window._gaq = jMUI.yahoo._gaq; // it's ok to loose the "push" override here - the tracker is initialized and when ga loads, it will slurp the whole _gaq array
			jMUI.yahoo._gaq = null;
		}
	}
};
/**
 * Builds new order variables that are cleaned-up. On the confirmation page, Yahoo! gives javascript developers
 * a series of variables that hold the items ordered, quantity ordered, etc... Except that it does not create a list of unique product IDs.
 * So if a customer orders a product, but with different options, for instance, this creates 2 lines in Yahoo!'s arrays, 
 * even though we do not have the actual options that could differentiate the ordered items... So this function
 * makes sure that this product will only show once in the list of ordered products, and adjusts the quantity accordingly.
 *
 * <strong>Note: </strong> This also considered the price of the items. So if certain options cost more, then the product will
 * be kept on two lines.
 * 
 * The new arrays to use are: mon_order_ids, mon_order_items, mon_order_codes, mon_order_price, mon_order_qtys
 * 
 * @method cleanup_order_data
 *
 * @static
 */
jMUI.yahoo.cleanup_order_data = jMUI.yahoo.cleanup_order_data || function() {
	if(typeof(window.mon_order_ids) != "undefined") return;
	window.mon_order_ids = new Array();
	window.mon_order_items = new Array();
	window.mon_order_codes = new Array();
	window.mon_order_price = new Array();
	window.mon_order_qtys = new Array();
	if(typeof(window.ids) != "undefined") {
		var vMerged = new Array();
		for(var vLoop = 0; vLoop < window.ids.length; vLoop++) {
			var vIndex = "item_" + window.ids[vLoop] + ";" + window.price[vLoop];
			if(typeof(vMerged[vIndex]) != "undefined") {
				vMerged[vIndex].qty += parseInt(window.qtys[vLoop]);
			} else {
				vMerged[vIndex] = {id: window.ids[vLoop], item: window.items[vLoop], code: window.codes[vLoop], price: window.price[vLoop], qty: parseInt(window.qtys[vLoop])};
			}
		}
		for(var vLoop in vMerged) {
			if((typeof(vLoop) == "string") && vLoop.match(/^item_/)) {
				var vRecord = vMerged[vLoop];
				window.mon_order_ids.push(vRecord.id);
				window.mon_order_items.push(vRecord.item);
				window.mon_order_codes.push(vRecord.code);
				window.mon_order_price.push(vRecord.price);
				window.mon_order_qtys.push(vRecord.qty);
			}
		}
	}
};
/**
 * Attaches an onclick event handler to the "Update" button on the cart page, so the click can be tracked as a custom variable
 * in Google Analytics.
 *
 * @method install_track_cart_update
 *
 * @param {string|object} pTrackerObject the name of the tracker object variable, or the actual tracker object. Should now alawys be "_gaq".
 * @param {string} pVariable the variable to use ('metric7', 'dimension14'...)
 * @param {array} pOptionalSourceArray the array to use. (usually ids or codes) Default: ids
 * @param {number} pVariableSlot the variable's slot number. (GA only: 1-5)
 * @param {string} pOptionalVariableName the vairable's name. (GA only) Default: &quot;Crt&quot;
 * @param {number} pOptionalVariableScope the variable's scope. (GA only) One of: jMUI.ga.kvariable_scope_visitor, jMUI.ga.kvariable_scope_session or jMUI.ga.kvariable_scope_page. Default: jMUI.ga.kvariable_scope_session
 *
 * @static
 */
jMUI.yahoo.track_cart_content = jMUI.yahoo.track_cart_content || function(pTrackerObject, pVariable, pOptionalSourceArray, pVariableSlot, pOptionalVariableName, pOptionalVariableScope) {
	if(typeof(ids) == "undefined") return;
	if(typeof(pVariable) == "number") {
		/* OLD SCHOOL: jMUI.yahoo.track_cart_content(pTrackerObject, pVariableSlot, pOptionalVariableName, pOptionalVariableScope, pOptionalSourceArray) */
		pOptionalSourceArray = (arguments.length >= 5 ? arguments[4] : undefined);
		pVariableSlot = arguments[1];
		pOptionalVariableName = (arguments.length >= 3 ? arguments[2] : undefined);
		pOptionalVariableScope = (arguments.length >= 4 ? arguments[3] : undefined);
		pVariable = pOptionalVariableName;
	}
	if(typeof(pOptionalVariableName) == "undefined") pOptionalVariableName = "Crt";
	if(typeof(pOptionalVariableScope) == "undefined") pOptionalVariableScope = jMUI.ga.kvariable_scope_session;
	if(typeof(pOptionalSourceArray) == "undefined") pOptionalSourceArray = ids;
	
	var vValue ="";
	var vMyIDs = pOptionalSourceArray.slice();
	if(vMyIDs) {
		do{
			vValue = vMyIDs.join("|");
			vMyIDs.pop();
		} while((vMyIDs.length > 0) && (vValue.length > 125));
	}
	
	var gaq = jMUI.ga.gaqTracker(pTrackerObject);
	if(gaq !== null) {
		if(typeof(window._gaq) != "undefined") window._gaq.push([gaq + "_setCustomVar", pVariableSlot, pOptionalVariableName, vValue, pOptionalVariableScope]);
		//if(typeof(window.ga) == "function") window.ga("send", "event", ...);
	} else {
		var vTracker = null;
		if(typeof(pTrackerObject) == "string") {
			try{
				vTracker = eval(pTrackerObject);
			} catch(e){}
		} else vTracker = pTrackerObject;
		if(!vTracker || (typeof(vTracker) == "undefined") || (typeof(vTracker._setCustomVar) != "function")) jMUI.ga.queue_variable(pVariable, vValue, pVariableSlot, pOptionalVariableScope, pOptionalVariableName);
		else vTracker._setCustomVar(pVariableSlot, pOptionalVariableName, vValue, pOptionalVariableScope);
	}
};
/**
 * Attaches an onclick event handler to the "Update" button on the cart page, so the click can be tracked as an event
 * in Google Analytics.
 *
 * @method install_track_cart_update
 *
 * @param {string|object} pTrackerObject the name of the tracker object variable, or the actual tracker object. Should now alawys be "_gaq".
 * @param {string} pOptionalEventCategory the category for this event; can be an inflatable template. Default: &quot;Update Cart&quot;
 * @param {string} pOptionalEventAction the action for this event; can be an inflatable template. Default: &quot;&quot;
 * @param {string} pOptionalEventLabel the label for this event; can be an inflatable template. Default: &quot;Checkout Button Clicked&quot;
 * @param {bool} pNonInteraction when false, event has an impact on bounce rate. When true, the event will not be used in bounce rate calculations. Default: &quot;true&quot;
 *
 * @static
 */
jMUI.yahoo.install_track_cart_update = jMUI.yahoo.install_track_cart_update || function(pTrackerObject, pOptionalEventAction, pOptionalEventLabel, pOptionalEventCategory, pNonInteraction, waiting) {
	if(typeof(pNonInteraction) == "undefined") pNonInteraction = true;
	var vPage = jMUI.yahoo.current_page_id();
	if(vPage.match(/ysco\./)) {
		var vButton = jMUI.$('input[name="eventName.updateEvent"]');
		if(vButton.length == 0) {
			if(waiting) return true;
			jMUI.internal._wait(function(w) { return jMUI.yahoo.install_track_cart_update(pTrackerObject, pOptionalEventAction, pOptionalEventLabel, pOptionalEventCategory, pNonInteraction, w); });
		} else {
			pOptionalEventAction = jMUI.util.string.non_null_string(pOptionalEventAction, "Update Cart");
			pOptionalEventLabel = jMUI.util.string.non_null_string(pOptionalEventLabel);
			pOptionalEventCategory = jMUI.util.string.non_null_string(pOptionalEventCategory, "Checkout Button Clicked");
			jMUI.ga.attach_tracking_info(vButton, pTrackerObject, pOptionalEventCategory, pOptionalEventAction, pOptionalEventLabel, undefined, pNonInteraction);
			vButton.click(function() { return jMUI.ga.track_event_attached_to_object(vButton); });
		}
	}
	return false;
};
/**
 * Attaches an onclick event handler to the Shipping Calculator button on the checkout, so the click can be tracked as an event
 * in Google Analytics.
 *
 * @method install_track_ship_update
 *
 * @param {string|object} pTrackerObject the name of the tracker object variabl, or the actual tracker object. Should now alawys be "_gaq".
 * @param {string} pOptionalEventCategory the category for this event; can be an inflatable template. Default: &quot;Update Shipping - [page ID] page'&quot;
 * @param {string} pOptionalEventAction the action for this event; can be an inflatable template. Default: &quot;[zip code] - [state] - [shipping method]&quot;
 * @param {string} pOptionalEventLabel the label for this event; can be an inflatable template. Default: &quot;Checkout Button Clicked&quot;
 * @param {bool} pNonInteraction when false, event has an impact on bounce rate. When true, the event will not be used in bounce rate calculations. Default: &quot;true&quot;
 *
 * @static
 */
jMUI.yahoo.install_track_ship_update = jMUI.yahoo.install_track_ship_update || function(pTrackerObject, pOptionalEventAction, pOptionalEventLabel, pOptionalEventCategory, pNonInteraction, waiting) {
	if(typeof(pNonInteraction) == "undefined") pNonInteraction = true;
	var vPage = jMUI.yahoo.current_page_id();
	if(vPage.match(/ysco\./)) {
		var vButton = jMUI.$('input[name="eventName.updateShippingMethodEvent"]');
		if(vButton.length == 0) {
			if(waiting) return true;
			jMUI.internal._wait(function(w) { return jMUI.yahoo.install_track_ship_update(pTrackerObject, pOptionalEventAction, pOptionalEventLabel, pOptionalEventCategory, pNonInteraction, w); });
		} else {
			vPage = vPage.replace(/ysco\./, '');
			var vDefaultLabel = "%shipping-zip% - %shipping-state";
			if(vPage == "cart") vDefaultLabel += "-for-shipping-calculator";
			vDefaultLabel += "% - %name='shippingOptionsDS.shipping_options_ROW0_shipping_method_id'%";
			pOptionalEventCategory = jMUI.util.string.non_null_string(pOptionalEventCategory, "Checkout Button Clicked");
			pOptionalEventAction = jMUI.util.string.non_null_string(pOptionalEventAction, "Update Shipping - " + vPage + " page");
			pOptionalEventLabel = jMUI.util.string.non_null_string(pOptionalEventLabel, vDefaultLabel);
			
			jMUI.ga.attach_tracking_info(vButton, pTrackerObject, pOptionalEventCategory, pOptionalEventAction, pOptionalEventLabel, undefined, pNonInteraction);
			vButton.click(function() { return jMUI.ga.track_event_attached_to_object(vButton); });
		}
	}
	return false;
};
/**
 * Track an event when the user clicks the "Add to cart" button. To be used in an "onclick" function.
 *
 * @method track_add_to_cart
 *
 * @param {string|object} pTrackerObject the name of the tracker object variabl, or the actual tracker object. Should now alawys be "_gaq".
 * @param {string} pOptionalEventCategory the category for this event; can be an inflatable template. Default: &quot;[page ID]'&quot;
 * @param {string} pOptionalEventAction the action for this event; can be an inflatable template. Default: &quot;&quot;
 * @param {string} pOptionalEventLabel the label for this event; can be an inflatable template. Default: &quot;Add to Cart&quot;
 * @param {bool} pNonInteraction when false, event has an impact on bounce rate. When true, the event will not be used in bounce rate calculations. Default: &quot;true&quot;
 *
 * @return {true} returns TRUE so it can easily be used in an onclick or onsubmit handler.
 *
 * @static
 */
jMUI.yahoo.track_add_to_cart = jMUI.yahoo.track_add_to_cart || function(pTrackerObject, pOptionalEventAction, pOptionalEventLabel, pOptionalEventCategory, pNonInteraction) {
	if(typeof(pNonInteraction) == "undefined") pNonInteraction = true;
	jMUI.ga.track_event(pTrackerObject, jMUI.util.string.non_null_string(pOptionalEventCategory, "Add to Cart"), jMUI.util.string.non_null_string(pOptionalEventAction, jMUI.yahoo.current_page_id()), jMUI.util.string.non_null_string(pOptionalEventLabel), undefined, pNonInteraction);
	return true;
};
/**
 * Track an event when the user clicks a "Click to enlarge" button. To be used in the "onclick" function.
 *
 * @method track_click_to_enlarge
 *
 * @param {string|object} pTrackerObject the name of the tracker object variabl, or the actual tracker object. Should now alawys be "_gaq".
 * @param {string} pOptionalEventCategory the category for this event; can be an inflatable template. Default: &quot;[page ID]'&quot;
 * @param {string} pOptionalEventAction the action for this event; can be an inflatable template. Default: &quot;clicked&quot;
 * @param {string} pOptionalEventLabel the label for this event; can be an inflatable template. Default: &quot;Click to enlarge&quot;
 * @param {bool} pNonInteraction when false, event has an impact on bounce rate. When true, the event will not be used in bounce rate calculations. Default: &quot;true&quot;
 *
 * @return {true} returns TRUE so it can easily be used in an onclick or onsubmit handler.
 *
 * @static
 */
jMUI.yahoo.track_click_to_enlarge = jMUI.yahoo.track_click_to_enlarge || function(pTrackerObject, pOptionalEventAction, pOptionalEventLabel, pOptionalEventCategory, pNonInteraction) {
	if(typeof(pNonInteraction) == "undefined") pNonInteraction = true;
	jMUI.ga.track_event(pTrackerObject, jMUI.util.string.non_null_string(pOptionalEventCategory, "Click to enlarge"), jMUI.util.string.non_null_string(pOptionalEventAction, "clicked"), jMUI.util.string.non_null_string(pOptionalEventLabel, jMUI.yahoo.current_page_id()), undefined, pNonInteraction);
	return true;
};
/**
 * Changes the image of a checkout button.
 *
 * @method checkout_button_image_swap
 *
 * @param {string} pImageName the name of the image that will be swapped. (input of type "button")
 * @param {url} pNewImageURL the url of the image to load instead.
 *
 * @static
 */
jMUI.yahoo.checkout_button_image_swap = jMUI.yahoo.checkout_button_image_swap || function(pImageName, pNewImageURL, waiting) {
	var vButton = jMUI.$('input[name="' + pImageName + '"]');
	if(vButton.length == 0) {
		if(waiting) return true;
		jMUI.internal._wait(function(w) { return jMUI.yahoo.checkout_button_image_swap(pImageName,  pNewImageURL, w); });
	} else {
		try {
			if(vButton.type.match(/image/i)) vButton.src = pNewImageURL;
		} catch(e) { }
	}
	return false;
};
/**
 * Changes a checkout button's caption.
 *
 * @method checkout_button_caption_swap
 *
 * @param {string} pButtonName the name of the button that will be targeted. (input of type "submit")
 * @param {url} pNewCaption the new caption for the button.
 *
 * @static
 */
jMUI.yahoo.checkout_button_caption_swap = jMUI.yahoo.checkout_button_caption_swap || function(pButtonName, pNewCaption, waiting) {
	var vButton = jMUI.$('input[name="' + pButtonName + '"]');
	if(vButton.length == 0) {
		if(waiting) return true;
		jMUI.internal._wait(function(w) { return jMUI.yahoo.checkout_button_caption_swap(pButtonName, pNewCaption, w); });
	} else {
		try {
			if(vButton.type.match(/submit/i)) vButton.value = pNewCaption;
		} catch(e) { }
	}
	return false;
};
/**
 * Move a subsection to another section on the checkout page. 
 * The subsection will be added before the subsection at position "position".
 *
 * @method checkout_move_subsection
 *
 * @param {string} pSubSectionSelector the jQuery selector of the section to move.
 * @param {string} pNewSectionSelector the jQuery selector of the new section to move it to.
 * @param {number} pPosition the position of the moved subsection in the new section; zero-based.
 *
 * @static
 */
jMUI.yahoo.checkout_move_subsection = jMUI.yahoo.checkout_move_subsection || function(pSubSectionSelector, pNewSectionSelector, pPosition, waiting) {
	var vSubSection = jMUI.$(pSubSectionSelector);
	var vNewSection = jMUI.$(pNewSectionSelector);
	if((vSubSection .length == 0) || (vNewSection.length == 0)) {
		if(waiting) return true;
		jMUI.internal._wait(function(w) { return jMUI.yahoo.checkout_move_subsection(pSubSectionSelector, pNewSectionSelector, pPosition, w); });
	} else {
		try {
			var vSibling = vSubSection;
			var vSubSectionHeader = vSubSection.prevAll(".ys_subSectionHeader:first");
			if(vSubSectionHeader.length > 0) {
				var vHeaders = vNewSection.find("h4");
				if((vHeaders.length == 0) || (pPosition >= vHeaders.length)) {
					vNewSection.append(vSubSectionHeader);
					vNewSection.append(vSubSection);
				} else {
					vHeaders.eq(pPosition).before(vSubSection);
					vSubSection.before(vSubSectionHeader);
				}
			}
		} catch(e) { }
	}
	return false;
};
/**
 * Create a new section on the checkout page. The new section will be added before the placeholder section.
 *
 * @method checkout_create_new_section
 *
 * @param {string} pBeforeSectionSelector the jQuery selector of the section to use a a placeholder.
 * @param {string} pNewSectionID the ID of the new section.
 * @param {string} pTitle the title of the new section.
 * @param {string} pSubTitle the title of the new section's first sub-section.
 *
 * @static
 */
jMUI.yahoo.checkout_create_new_section = jMUI.yahoo.checkout_create_new_section || function(pBeforeSectionSelector, pNewSectionID, pTitle, pSubTitle, waiting) {
	var vPlaceholder = jMUI.$(pBeforeSectionSelector);
	if(vPlaceholder.length == 0) {
		if(waiting) return true;
		jMUI.internal._wait(function(w) { return jMUI.yahoo.checkout_create_new_section(pBeforeSectionSelector, pNewSectionID, pTitle, pSubTitle, w); });
	} else {
		vPlaceholder.before('<div id="' + pNewSectionID + '" class="ys_majorSection"></div>');
		var vNewDiv = jMUI.$("#" + pNewSectionID);
		vNewDiv.append('<h3 class="ys_sectionHeader">' + pTitle + '</h3>');
		if(pSubTitle) vNewDiv.append('<h4 class="ys_subSectionHeader">' + pSubTitle + '</h4>');
		vNewDiv.append('<div id="' + pNewSectionID + '_subsection" class="ys_subSection"><fieldset><span id="' + pNewSectionID + '_placeholder"></span></fieldset></div>');
	}
	return false;
};
/**
 * Creates 3 fields (MM / DD / YYYY) to enter dates, and will update the original field's value accordingly. 
 * The original field is usually a hidden field.
 *
 * @method checkout_create_date_fields_for_field
 *
 * @param {string} pFieldSelector the jQuery selector of the parent field, normally a hidden field.
 *
 * @static
 */
jMUI.yahoo.checkout_create_date_fields_for_field = jMUI.yahoo.checkout_create_date_fields_for_field || function(pFieldSelector, waiting) {
	var vPlaceholder = jMUI.$(pFieldSelector);
	if(vPlaceholder.length == 0) {
		if(waiting) return true;
		jMUI.internal._wait(function(w) { return jMUI.yahoo.checkout_create_date_fields_for_field(pFieldSelector, w); });
	} else {
		var vPlaceholderID = vPlaceholder.attr("id");
		vPlaceholder.hide().val("");
		var vUpdate = function() {
			vPlaceholder.val("");
			try {
				var vMonth = parseInt(jMUI.$("#m-" + vPlaceholderID).val());
				var vDay = parseInt(jMUI.$("#d-" + vPlaceholderID).val());
				var vYear = parseInt(jMUI.$("#y-" + vPlaceholderID).val());
				if(!isNaN(vYear) && !isNaN(vMonth) && !isNaN(vDay)) {
					vMonth = vMonth - 1;
					if(vYear < 100) vYear += 2000;
					var vDate = new Date(vYear, vMonth, vDay, 0, 0, 0, 0);
					if((vDate.getFullYear() == vYear) && (vDate.getMonth() == vMonth) && (vDate.getDate() == vDay)) vPlaceholder.val((vDate.getMonth() + 1) + "/" + vDate.getDate() + "/" + vDate.getFullYear());
				}
			} catch (e) { }
		};
		
		var vTable = '<table><tbody>';
		vTable += '<tr><td><input id="m-' + vPlaceholderID + '" type="text" maxLength="2" size="2" /></td><td>/</td><td><input id="d-' + vPlaceholderID + '" type="text" maxLength="2" size="2" /></td><td>/</td><td><input id="y-' + vPlaceholderID + '" type="text" maxLength="4" size="4" /></td></tr>';
		vTable += '<tr><td style="text-align: center;"><span style="color: #ccc;">MM</span></td><td> </td><td style="text-align: center;"><span style="color: #ccc;">DD</span></td><td> </td><td style="text-align: center;"><span style="color: #ccc;">YYYY</span></td></tr>';
		vTable += '</tbody></table>';
		vPlaceholder.parent().next().before(vTable).find('input[id$="-' + vPlaceholderID + '"]').change(vUpdate);
	}
	return false;
};
/**
 * Duplicate a button on the checkout page. The new button will be added before or after the placeholder element.
 *
 * @method checkout_duplicate_button
 *
 * @param {string} pNewNextSiblingSelector the jQuery selector of the placeholder.
 * @param {string} pTargetSelector the jQuery selector to the button to duplicate.
 * @param {bool} pAppend place the copied button before (false, default) or after (true) the placeholder.
 *
 * @static
 */
jMUI.yahoo.checkout_duplicate_button = jMUI.yahoo.checkout_duplicate_button || function(pNewNextSiblingSelector, pTargetSelector, pAppend, waiting) {
	var vNewSibling = jMUI.$(pNewNextSiblingSelector);
	if(vNewSibling.length == 0) {
		if(waiting) return true;
		jMUI.internal._wait(function(w) { return jMUI.yahoo.checkout_duplicate_button(pNewNextSiblingSelector, pTargetSelector, pAppend, w); });
	} else {
		var vTarget = jMUI.$(pTargetSelector);
		try {
			var vNewNode = vTarget.clone(true);
			if(pAppend) vNewSibling.append(vNewNode);
			else vNewSibling.before(vNewNode);
			if(typeof(jMUI.yahoo.node_duplicated) == "function") jMUI.yahoo.node_duplicated(vNewNode.get(0)); // legacy
			if(typeof(jMUI.yahoo.callback) == "function") jMUI.yahoo.callback("node_duplicated", vNewNode);
		} catch(e) { }
	}
	return false;
};
/**
 * Make a Yahoo!-mandatory field optional, like the Phone field on the checkout...
 *
 * @method checkout_mandatory_to_optional_field
 *
 * @param {string} pTargetSelector the jQuery selector of the targeted element.
 * @param {string} pActiveLinkSelector the jQuery selector of the *field* element.
 * @param {string} pEmptyValue the value to place in the field so Y! thinks it is not empty.
 *
 * @static
 */
jMUI.yahoo.checkout_mandatory_to_optional_field = jMUI.yahoo.checkout_mandatory_to_optional_field || function(pTargetSelector, pActiveLinkSelector, pEmptyValue, waiting) {
	var vTarget = jMUI.$(pTargetSelector);
	if(vTarget.length == 0) {
		if(waiting) return true;
		jMUI.internal._wait(function(w) { return jMUI.yahoo.checkout_mandatory_to_optional_field(pTargetSelector, pActiveLinkSelector, pEmptyValue, w); });
	} else {
		try {
			var vNewNode = vTarget.clone(true);
			vTarget.before(vNewNode);
			vNewNode.addClass("monitus");
			
			var vActiveLink1 = jMUI.$(pActiveLinkSelector);
			var vActiveLink2 = jMUI.$(pActiveLinkSelector + " .monitus");
			if(vActiveLink1 && vActiveLink2 && (vActiveLink1.get(0) != vActiveLink2.get(0))) {
				vActiveLink2.data("empty_value", pEmptyValue);
				if(vActiveLink1.val() == "") vActiveLink1.val(pEmptyValue);
				else if(vActiveLink1.val() == pEmptyValue) vActiveLink2.val("");
				
				var vBaseID = pActiveLinkSelector;
				vFc = function(event) {
					var f = jMUI.$(pActiveLinkSelector + " .monitus");
					jMUI.$(pActiveLinkSelector).val((f.val() != "") ? f.val() : f.data("empty_value")).trigger("blur");
				};
				vActiveLink2.change(vFc);
				vActiveLink2.blur(vFc);
				
				jMUI.$('form[name="CheckoutForm"]').submit(function() {
					var f = jMUI.$(pActiveLinkSelector + " .monitus");
					jMUI.$(pActiveLinkSelector).val((f.val() != "") ? f.val() : f.data("empty_value"));
				});
				
				vTarget.hide();
				vActiveLink1.hide();
			}
		} catch(e) { }
	}
	return false;
};
/**
 * Duplicate a field on a checkout page.
 *
 * @method checkout_duplicate_field
 *
 * @param {string} pNewNextSiblingSelector the jQuery selector of the placeholder element.
 * @param {string} pTargetSelector the jQuery selector of the targeted element.
 * @param {string} pActiveLinkSelector the jQuery selector of the *field* element.
 * @param {bool} pFocus should the new field have focus?
 * @param {bool} pHideOriginal should the original copy be hidden?
 *
 * @static
 */
jMUI.yahoo.checkout_duplicate_field = jMUI.yahoo.checkout_duplicate_field || function(pNewNextSiblingSelector, pTargetSelector, pActiveLinkSelector, pFocus, pHideOriginal, waiting) {
	var vNewSibling = jMUI.$(pNewNextSiblingSelector);
	var vTarget = jMUI.$(pTargetSelector);
	if((vNewSibling.length == 0) || (vTarget.length == 0)) {
		if(waiting) return true;
		jMUI.internal._wait(function(w) { return jMUI.yahoo.checkout_duplicate_field(pNewNextSiblingSelector, pTargetSelector, pActiveLinkSelector, pFocus, pHideOriginal, w); });
	} else {
		try {
			var vNewNode = vTarget.clone(true);
			var re_id = function(object) {
				object.attr("id", object.attr("id") + "_monitus");
			};
			re_id(vNewNode);
			vNewSibling.before(vNewNode);
			vNewNode = jMUI.$(pTargetSelector + "_monitus");
			vNewNode.find("[id]").each(function(){ re_id(jMUI.$(this)); });
			
			var vActiveLink1 = jMUI.$(pActiveLinkSelector); // link active links
			var vActiveLink2 = jMUI.$(pActiveLinkSelector + "_monitus");
			if(vActiveLink1 && vActiveLink2 && (vActiveLink1.get(0) != vActiveLink2.get(0))) {
				var vBaseID = pActiveLinkSelector;
				if(vActiveLink1.attr("type") == "checkbox") {
					vActiveLink1.click(function() { vActiveLink2.attr("checked", vActiveLink1.attr("checked")); });
					vActiveLink2.click(function() {
						vActiveLink1.attr("checked", vActiveLink2.attr("checked")).trigger("click");
					});
				} else {
					var vFc = function(event) { vActiveLink2.val(vActiveLink1.val()); };
					vActiveLink1.change(vFc);
					vActiveLink1.blur(vFc);
					vFc = function(event) { vActiveLink1.val(vActiveLink2.val()).trigger(event.type); };
					vActiveLink2.change(vFc);
					vActiveLink2.blur(vFc);
					
					jMUI.$('form[name="CheckoutForm"]').submit(function() { vActiveLink1.val(vActiveLink2.val()); });
				}
				if(pFocus) vActiveLink2.focus();
				if(pHideOriginal) {
					vTarget.hide();
					vActiveLink1.hide();
				}
				if(typeof(jMUI.yahoo.node_duplicated) == "function") jMUI.yahoo.node_duplicated(vNewNode.get(0)); // legacy
				if(typeof(jMUI.yahoo.callback) == "function") jMUI.yahoo.callback("node_duplicated", vNewNode);
			}
		} catch(e) { }
	}
	return false;
};
/**
 * Moves a field on a checkout page.
 *
 * @method checkout_move_field
 *
 * @param {string} pNewNextSiblingSelector the jQuery selector of the placeholder element.
 * @param {string} pTargetSelector the jQuery selector of the targeted element.
 * @param {string} pPosition "before" or "after" the placeholder (default: "before")
 * @param {bool} pFocus should the new field have focus? (default: false)
 *
 * @static
 */
jMUI.yahoo.checkout_move_field = jMUI.yahoo.checkout_move_field || function(pNewNextSiblingSelector, pTargetSelector, pPosition, pFocus, waiting) {
	var vNewSibling = jMUI.$(pNewNextSiblingSelector);
	var vTarget = jMUI.$(pTargetSelector);
	if(!pPosition) pPosition = "before";
	if((vNewSibling.length == 0) || (vTarget.length == 0)) {
		if(waiting) return true;
		jMUI.internal._wait(function(w) { return jMUI.yahoo.checkout_move_field(pNewNextSiblingSelector, pTargetSelector, pPosition, pFocus, w); });
	} else vNewSibling[pPosition](vTarget);
	return false;
};
jMUI.yahoo.checkout_validation = jMUI.yahoo.checkout_validation || function(pMarkerCallback, pValidationCallback, pValidationFailedCallback, pIgnoredFields) {
	try {
		var vForm = jMUI.$('form[name="CheckoutForm"]');
		if(vForm) {
			var vRequiredFields = new Array();
			var vBillingFields = new Array();
			var vBillingInputsDiv = jMUI.$("#ys_billingInputs");
			
			if(!pMarkerCallback) {
				// preloading
				var vImageURL = document.location.protocol + "//live.monitus.net/images/bullet_star.png";
				var vImage = new Image(1,1);
				vImage.src = vImageURL;
				
				pMarkerCallback = function(pRequiredField, pShowMarker) {
					pRequiredField = $(pRequiredField);
					var vID = pRequiredField.attr("name") + "_req";
					var vMarker = jMUI.$("#" + vID);
					if(pShowMarker && (vMarker.length == 0)) pRequiredField.before('<img id="' + vID + '" src="' + vImageURL + '" style="margin-right: 3px" />');
					else if(!pShowMarker && (vMarker.length != 0)) vMarker.remove();
				};
			}
			if(!pValidationCallback) {
				// preloading
				var vImageURL = document.location.protocol + "//live.monitus.net/images/bullet_error.png";
				var vImage = new Image(1,1);
				vImage.src = vImageURL;
				
				pValidationCallback = function(pRequiredField, pValid) {
					pRequiredField = $(pRequiredField);
					var vID = pRequiredField.attr("name") + "_req";
					var vMarker = jMUI.$("#" + vID);
					if(vMarker.length != 0) vMarker.attr("src", document.location.protocol+"//live.monitus.net/images/bullet_" + (pValid ? "star" : "error") + ".png").toggle(!pValid);
				};
			}
			if(!pValidationFailedCallback) {
				pValidationFailedCallback = function() {
					alert("Some required fields were not filled-out correctly. Please complete all fields before proceeding.");
				};
			}
			if(!pIgnoredFields) pIgnoredFields = new Array();
			
			vForm.find("input[type!='hidden'],select,textarea").each(function() {
				var vElement = jMUI.$(this);
				var vElementName = vElement.attr("name");
				if(jMUI.util.indexOfInArray(vElementName, pIgnoredFields) < 0) {
					var vValueElement = jMUI.$('input[name="' + vElementName + '_ymixval"]');
					if(vValueElement.length == 0) vValueElement = jMUI.$('input[name="' + vElementName.replace(/_monitus/i, "_ymixval_monitus") + '"]');
					if((vValueElement.length > 0) && vValueElement.val() && vValueElement.val().match(/(^|,)req(,|$)/i)) {
						vRequiredFields.push(vElement);
						vElement.blur(function() {
							var vObject = jMUI.$(this);
							pValidationCallback(vObject, (vObject.attr("disabled") || (vObject.val() != "")));
						});
						if(vBillingInputsDiv && (
							(vBillingInputsDiv.find('input[name="' + vElementName + '"]').length > 0) ||
							(vBillingInputsDiv.find('select[name="' + vElementName + '"]').length > 0) ||
							(vBillingInputsDiv.find('textarea[name="' + vElementName + '"]').length > 0)
						)) vBillingFields.push(vElement);
					}
				}
			});
			
			for(var vLoop = 0; vLoop < vRequiredFields.length; vLoop++) pMarkerCallback(vRequiredFields[vLoop], true);
			
			if(vBillingInputsDiv) {
				var vShipBillToggle = function() {
					var vBillingRadio = jMUI.$("#useBillingRadio");
					if(vBillingRadio) {
						for(var vLoop = 0; vLoop < vBillingFields.length; vLoop++) pMarkerCallback(vBillingFields[vLoop], vBillingRadio.attr("checked"));
					}
				};
				vShipBillToggle();
				jMUI.$("#useShippingRadio").click(vShipBillToggle);
				jMUI.$("#useBillingRadio").click(vShipBillToggle);
			}
			
			vForm.submit(function() {
				var vResult = true;
				for(var vLoop = 0; vLoop < vRequiredFields.length; vLoop++) {
					if(!pValidationCallback(vRequiredFields[vLoop], (vRequiredFields[vLoop].attr("disabled") || (vRequiredFields[vLoop].val() != "")))) vResult = false;
				}
				if(!vResult) pValidationFailedCallback();
				return vResult;
			});
		}
	} catch(e) { }
};
/**
 * Create a pop-up div; these pop-ups are not blocked by pop-up blockers, as they are not in a separate window. This version (as opposed to jMUI.util.create_popup) will center the popup on the screen by default.
 * 
 * @method create_pop_up
 *
 * @param {string} pText title of the button to show the pop-up.
 * @param {url} pImage url of the image used on the button. Optional.
 * @param {string} pPlaceholderSelector jQuery selector of the element into which the button shoudl be placed.
 * @param {string} pPopUpID id of the div to show as the pop-up content. If the div does not exist, one will be created.
 * @param {function} pPopUpFc function to be called when the button is clicked. Optional; by default, this function centers the popup on the screen. <em>Note: </em> For the automatic popUp function to work, make sure the YAHOO.util.Dom library is loaded on the page.
 *
 * @return {button} a reference to the created button; the button will have a &quot;popup&quot; property, for quick access to the popup div.
 *
 * @static
 */
jMUI.yahoo.create_pop_up = jMUI.yahoo.create_pop_up || function(pText, pImage, pPlaceholderSelector, pPopUpID, pPopUpFc) {
	if(!pPopUpFc) {
		pPopUpFc = function() {
			var vPopUp = jMUI.$(this).data("popup");
			if(vPopUp) {
				vPopUp.show();
				vPopUp.center();
			}
		};
	}
	var vButton = jMUI.util.ui.create_pop_up(pText, pImage, pPlaceholderSelector, pPopUpID, pPopUpFc);
	if(vButton) vButton.data("popup").css({"zIndex": "100000"});
};
/**
 * Push coupon(s) through a non-blocking pop-up. The button will be added right after the coupon field on the checkout.
 * 
 * @method coupon_pusher
 *
 * @param {string} pText title of the button to show the coupon(s) pop-up.
 * @param {url} pImage url of the image used on the button. Optional.
 * @param {string} pPopUpID id of the div to show as the pop-up content. If the div does not exist, one will be created.
 * @param {function} pPopUpFc function to be called when the button is clicked.
 *
 * @static
 */
jMUI.yahoo.coupon_pusher = jMUI.yahoo.coupon_pusher || function(pText, pImage, pPopUpID, pPopUpFc) {
	jMUI.yahoo.create_pop_up(pText, pImage, "#gc-redemption-code", pPopUpID, pPopUpFc);
};
/**
 * Automatically apply a coupon code to the current cart; useful to use as links on coupon codes. This will not only set the coupon code in the right field, it will also hit the "Apply" button for the user, so the coupon is actually applied.
 * 
 * @method coupon_apply
 *
 * @param {string} pCoupon the coupon code to apply.
 *
 * @static
 */
jMUI.yahoo.coupon_apply = jMUI.yahoo.coupon_apply || function(pCoupon) {
	try {
		var vObject = jMUI.$("#gc-redemption-code");
		if(vObject.length != 0) {
			vObject.val(pCoupon);
			jMUI.$('input[name="eventName.updateGiftCertDataEvent"]').trigger("click");
		}
	} catch(e) {}
};
/**
 * "Keep Shopping" Handler: for one-page carts, make sure the "Keep Shopping" link works and takes the customer back to the last store page they saw before coming ot the checkout.
 * 
 * @method keep_shopping_handler
 *
 * @param {string|object} pOptionalTrackerObject the name of the tracker object variable, or the actual tracker object. Should now alawys be "_gaq". Default: null (no event tracking);
 * @param {string} pOptionalEventCategory the category for this event; can be an inflatable template. Default: &quot;[page ID]'&quot;
 * @param {string} pOptionalEventAction the action for this event; can be an inflatable template. Default: &quot;&quot;
 * @param {string} pOptionalEventLabel the label for this event; can be an inflatable template. Default: &quot;Add to Cart&quot;
 * @param {bool} pNonInteraction when false, event has an impact on bounce rate. When true, the event will not be used in bounce rate calculations. Default: &quot;true&quot;
 *
 * @static
 */
jMUI.yahoo.keep_shopping_handler = jMUI.yahoo.keep_shopping_handler || function(pOptionalTrackerObject, pOptionalEventCategory, pOptionalEventAction, pOptionalEventLabel, pNonInteraction) {
	if(typeof(pNonInteraction) == "undefined") pNonInteraction = true;
	var vElement = null;
	var vCurrentDomain = jMUI.yahoo.cookie_domain();
	if(vCurrentDomain.match(/\.yahoo\./i)) {
		if(!document.referrer.match(/https?\:\/\/[^\/]*?\.yahoo\.(com|net)/i)) jMUI.yahoo.set_cookie_value("_mkpshpg", ".", "/", document.referrer);
		
		jMUI.$('li.ys_first a[href*="eventName.cancelEvent"]').each(function() {
			var vElement = jMUI.$(this);
			var vCookieValue = jMUI.util.cookie_value("_mkpshpg", null);
			if(vCookieValue) {
				if(pOptionalTrackerObject) {
					jMUI.ga.attach_tracking_info(vElement, pOptionalTrackerObject, pOptionalEventAction, pOptionalEventLabel, pOptionalEventCategory, undefined, pNonInteraction);
					vElement.click(function() { jMUI.ga.track_event_attached_to_object(vElement); setTimeout('window.location="' + vElement.attr("href") + '";', 250); return false; });
				}
				vElement.attr("href", vCookieValue);
				vElement.show();
			}
		});
	}
	return vElement;
};
/**
 * Badge images by product ID: adds an image (badge) over another image (target); target images are identified by product IDs.
 * 
 * @method badge_products
 *
 * @param {string|array} pProductIDs string of comma-separated product IDs, OR an array of product IDs (strings).
 * @param {url} pBadgeURL url of the badge image; the image should be a file with a transparent background.
 * @param {string} pPosition one of: jMUI.util.top_right (default), jMUI.util.top_center, jMUI.util.top_left, jMUI.util.bottom_right, jMUI.util.bottom_center or jMUI.util.bottom_left
 *
 * @static
 */
jMUI.yahoo.badge_products = jMUI.yahoo.badge_products || function(pProductIDs, pBadgeURL, pPosition) {
	if(!pPosition) pPosition = "tr";
	
	if(typeof(pProductIDs) == "string") pProductIDs = pProductIDs.split(",");
	pProductIDs = pProductIDs.join("|");
	jMUI.$(function() {
		var badge_it = function(link) {
			if((link.closest(".monitus-no-badge").length == 0) && link.is("a:regex(href,(^[^\\=]*?)(" + pProductIDs + ")\\.(html?|php)(\\?|\\#|$))")) {
				var image = link.find("img:first");
				if((image.length > 0) && image.parents("table.ys_basket").length == 0) jMUI.util.ui.badge_image(pBadgeURL, image, pPosition);
			}
		};
		jMUI.$(document).onInserted("body", function() {
			var link =  jMUI.$(this);
			if(!link.data("_monitus_badged")) {
				link.data("_monitus_badged", true);
				badge_it(link);
				link.find("a:regex(href,(^[^\\=]*?)(" + pProductIDs + ")\\.(html?|php)(\\?|\\#|$))").each(function() {
					badge_it(jMUI.$(this));
				});
			}
		}, "a");
	});
};
jMUI.ready = true;

Copyright © 2017 Yahoo! Inc. All rights reserved.