PageSourceSearch

https://tix.emergingwritersfestival.org.au/js/FTAPI.js?h=8c69a6eda…/&itemHash=&checkout=false&ftapi=true

js emergingwritersfestival.org.au collected 2026-10-02 04:32:16 UTC 191,136 bytes, 4,876 lines download raw bytes

1var ferve, ferve_h = "";
2
3var Ferve = function () {
4	var ferve = {};
5
6	var ferve_tu = "", ferve_tus = "", ferve_cache = true, ferve_api = false, ferve_de = false;
7	ferve.version = "1.7";
8	ferve.itemHash = "";
9	ferve.initTime = new Date();
10	ferve.currencyName = "en-AU";
11	ferve.currencyCode = "AUD";
12	ferve.currencySymbol = "$";
13
14	var src = document.getElementById("ft_ftapiJS").getAttribute("src").split("?")[1];
15	if (src.indexOf("clientHash") > -1 && document.querySelectorAll("[id='ft_ftapiJS']").length > 1) src = document.querySelectorAll("[id='ft_ftapiJS']")[1].getAttribute("src").split("?")[1];
16	src = src.replace(/\n|\r|\t/g, "").split("&");
17	for (var i = 0; i < src.length; i++) {
18		var pair = src[i].split("=");
19		if (pair[0] == "h") {
20			ferve_h = pair[1];
21			if (ferve_h == "clientHash") {
22				try {
23					console.error("Ferve Tickets widget is not linked correctly.");
24				}
25				catch (e) {
26					console.log("Ferve Tickets widget is not linked correctly");
27				}
28			}
29		}
30		if (pair[0] == "v") ferve.version = pair[1];
31		if (ferve_tu.length == 0 && pair[0] == "u") ferve_tu = pair[1];
32		if (ferve_tus.length == 0 && pair[0] == "s") ferve_tus = pair[1];
33		if (pair[0] == "ftapi") ferve_api = (pair[1] == "true");
34		if (pair[0] == String.fromCharCode(102, 116, 97)) ferve_cache = (!pair[1] == "1");
35		if (pair[0].toLowerCase() == "itemhash") {
36			ferve.itemHash = pair[1];
37			if (ferve.itemHash && ferve.itemHash.length > 0) ferve.itemHash = ferve.itemHash.trim();
38			ferve_api = true;
39		}
40	}
41
42	var delimiter = "**";
43	var ferveCookie = "";
44	var initComplete = false;
45	if (new RegExp(["qa.", "local", "staging", "wwwstage", "dev.", "foundry."].join("|")).test(document.URL)) ferve_de = true;
46	if (new RegExp(["qaNA", "localNA", "staging", "wwwstage", "devNA.", "foundry."].join("|")).test(document.URL)) ferve_cache = false;
47	var IE6 = (document.all && (navigator.userAgent.search("MSIE 6") >= 0) ? true : false);
48	if (ferve_tu.length == 0 && location.protocol == "https:" && window.location.pathname.toLowerCase().indexOf("/" + String.fromCharCode(112, 111, 115) + "/") > -1) {
49		ferve_tu = "https://" + window.location.host + "/";
50		ferve_cache = false;
51	}
52
53	ferve.overlays = ["ft_login", "ft_purchase", "ft_ferveCart", "ft_notification", "ftapi_modal"];
54	ferve.overlayOpacity = "40";
55
56	if (!window.btoa) {
57		var script = document.createElement("script");
58		script.type = "text/javascript";
59		script.onreadystatechange = function () {
60			if (this.readyState == "complete" || this.readyState == "loaded") {
61				window.btoa = base64.encode;
62				window.atob = base64.decode;
63			}
64		};
65		script.onload = function () {
66			window.btoa = base64.encode;
67			window.atob = base64.decode;
68		};
69		script.src = ferve.url + "js/base64.js?v=" + ferve.version;
70		document.getElementsByTagName("head")[0].appendChild(script);
71	}
72
73
74	// Cross domain messaging
75	ferve.receiveMessage = function (event) {
76		ferve.log("ferve.receiveMessage " + event, "info");
77
78		ferve.visitor.updatePropertiesFromCookie();
79
80		if (ferve_tu.indexOf(event.origin) == -1 && ferve_tus.indexOf(event.origin) == -1) ferve.log("bad origin\n\n" + event.origin, "error");
81		try {
82			eval(event.data);
83		}
84		catch (e) {
85			ferve.log("ferve.receiveMessage eval error:\n" + e.message, "error");
86		}
87		document.body.removeEventListener("message", ferve.receiveMessage, false);
88	}
89
90
91	// #mark ------ Visitor  ------
92	ferve.visitor = function () { };
93	ferve.visitor.hash = "";
94	ferve.visitor.type = 0;
95	ferve.visitor.loggedIn = "";
96	ferve.visitor.firstName = "";
97	ferve.visitor.memberType = "";
98	ferve.visitor.memberExpiryDate = "";
99	ferve.visitor.passtype = "";
100	ferve.visitor.subscriptions = "";
101	ferve.visitor.ferveData = null;
102	ferve.visitor.restricted = false;
103	ferve.visitor.geoPosition = null;
104	var geoRegion = null;
105	ferve.visitor.openLogin = function (method) {
106		ferve.log("ferve.visitor.openLogin(" + method + ")");
107		if (method == 0) {
108			document.location.href = ferve.utility.url("account");
109		} else if (method == 1 || method == 2) {
110			if (ferve_tu.length == 0) loadURLs(1);
111			if (window.addEventListener) {
112				window.addEventListener("message", ferve.receiveMessage, false);
113			} else if (window.attachEvent) {
114				window.attachEvent("onmessage", ferve.receiveMessage);
115			}
116			var ferveWin = window.open(ferve.utility.url("account") + "?ftam=" + method + "&ftapi=" + (ferve_api ? "1" : "0"), "FTL", "toolbar=no,menubar=no,scrollbars=yes,resizable=false,width=600,height=500");
117			ferveWin.focus();
118		} else if (method == 3) {
119			if (window.location.protocol != "https:") {
120				ferve.log("ferve.visitor.openLogin error: Only available when page is secure.");
121				return;
122			}
123			if (document.all && (IE6 || navigator.userAgent.search("MSIE 7") >= 0 || navigator.userAgent.search("MSIE 8") >= 0)) {
124				ferve.log("IE < 9 - in page login not available", "error");
125				ferve.visitor.openLogin(1);
126				return;
127			}
128			if (ferve_tu.length == 0) loadURLs(2);
129			var x = document.getElementById("ft_login");
130			if (!x) {
131				var div = document.createElement("div");
132				div.className = "ft_fade ft_itemHidden";
133				div.style.display = "none";
134				div.id = "ft_login";
135				div.innerHTML = "<form name=\"ft_loginForm\" id=\"ft_loginForm\" method=\"GET\" onsubmit=\"return ferve.visitor.openLogin.submit()\"><h2 id=\"ft_heading\">Login</h2><p><label for=\"email\">Email Address</label><input name=\"email\" type=\"email\" class=\"ft_email\" placeholder=\"Email Address\" maxlength=\"128\" autofocus=\"autofocus\" /></p><p><label for=\"password\">Password</label><input name=\"password\" type=\"password\" class=\"ft_password\" placeholder=\"Password\" maxlength=\"20\" /></p><p><button type=\"button\" onclick=\"ferve.visitor.openLogin.cancel()\">Cancel</button><button type=\"button\" onclick=\"ferve.visitor.openLogin.submit()\">Login</button></p><img src=\"" + ferve.url + "img/ferve/ferve.png\" style=\"position:absolute;bottom:5px;right:12px;width:50px;\" /></form>";
136				document.body.appendChild(div);
137				x = document.getElementById("ft_login");
138			}
139			if (x) {
140				var yLoc = 0;
141				if (typeof window.pageYOffset === "number") {
142					yLoc = window.pageYOffset;
143				} else if (document.body && (document.body.scrollLeft || document.body.scrollTop)) {
144					yLoc = document.body.scrollTop;
145				} else if (document.documentElement && (document.documentElement.scrollLeft || document.documentElement.scrollTop)) {
146					yLoc = document.documentElement.scrollTop;
147				}
148				if (312 - yLoc < 0) {
149					var h = screen.height;
150					x.style.top = (yLoc + (h / 2)) + "px";
151				}
152
153				showHoverElements(2);
154			}
155		}
156	};
157	ferve.visitor.openLogin.cancel = function () {
158		ferve.log("ferve.visitor.openLogin.cancel");
159		hideHoverElements(1);
160	};
161	ferve.visitor.openLogin.submit = function () {
162		ferve.log("ferve.visitor.openLogin.submit");
163
164		var e = document.ft_loginForm.email.value;
165		var p = document.ft_loginForm.password.value;
166
167		if (e.length == 0 || p.length == 0) {
168			ferve.notification.show("alert", "red", "Please enter your email address and password.", null, null, null);
169			return;
170		}
171
172		ferve.visitor.login("openLogin", e, p);
173
174		return false;
175	};
176	var ftd_openLogin = function (s) {
177		ferve.log("ftd_openLogin(" + s + ")");
178
179		var ftReturn = ferve.parseFTReturn(s);
180		if (!ftReturn) return;
181		if (ftReturn.Success) {
182			hideHoverElements(2);
183
184			ftd_accountStatusChange(s);
185
186			if (document.URL.toLowerCase().indexOf("/account/login") > -1) document.location.reload();
187
188		} else {
189			ferve.notification.show("alert", "red", "Your login was unsuccessful, please check your details and try again.", null, null, null);
190		}
191	};
192	ferve.visitor.login = function (source, email, password) {
193		// Non functional please contact Ferve
194		var login = { email: email, password: password };
195		var data = JSON.stringify(login);
196
197		ferve.xmlHttpRequest(ferve.utility.url("ssl") + "api/v1/Visitors/Login/?hash=" + ferve.visitor.hash, "POST", data, "", "", "ftd_visitorLogin('" + source + "',");
198	};
199	var ftd_visitorLogin = function (source, s) {
200		if (source == "openLogin") {
201			ftd_openLogin(s);
202		} else {
203			ftd_accountStatusChange(s);
204		}
205	};
206	ferve.visitor.logout = function (conf) {
207		ferve.log("ferve.visitor.logout(" + conf + ")");
208		if ((conf == 1 || conf == 3 || conf == 4)) {
209			var s = "";
210			ferve.notification.show("confirm", "blue", "Are you sure you wish to logout?" + (ferve.cart.count > 0 ? "\n\nAll items in your cart will be cleared." : ""), function (s) { ftd_visitorLogout(conf, s) }, null, null);
211			return;
212		};
213	}
214	var ftd_visitorLogout = function (conf, s) {
215		if (conf == -1) {
216			var ferveWin = window.open(ferve.utility.url("ssl") + "Account/Logout/", "FTAPILO", "toolbar=no,menubar=no,scrollbars=no,resizable=false,width=5,height=5");
217			ferveWin.focus();
218			return;
219		} else if (conf == 2 || conf == 3) {
220			ferve.utility.openLink("accountlogout", 0);
221		} else {
222			ferve.xmlHttpRequest(ferve.utility.url("ssl") + "api/v1/Visitors/Logout/?hash=" + ferve.visitor.hash, "GET", null, "", "", "ftd_accountStatusChange(");
223		}
224	};
225	var ftd_visitorLogout = function (conf, s) {
226		ferve.visitor.logout(-1);
227	};
228	var ftd_accountStatusChange = function (s) {
229		ferve.log("ftd_accountStatusChange(" + unescape(s) + ")");
230
231		var ftReturn = ferve.parseFTReturn(s);
232		if (!ftReturn) return;
233
234		if (!ftReturn.Success) {
235			ferve.log(ftReturn.Errors[0].CustomerMessage);
236
237		} else if (ftReturn.SuccessMessages[0] == "0") {
238			try {
239				ft_accountStatusUpdate(0);
240			}
241			catch (e) { }
242		} else if (ftReturn.SuccessMessages[0] == "1") {
243			ferve.visitor.updatePropertiesFromCookie();
244			outputProperties(true, false);
245			try {
246				ft_accountStatusUpdate(1);
247			}
248			catch (e) { }
249		} else if (ftReturn.SuccessMessages[0] == "2") {
250			ferve.visitor.loggedIn = "0";
251			ferve.visitor.memberType = 0;
252			ferve.visitor.memberExpiryDate = "";
253			ferve.visitor.firstName = "";
254			if (ftReturn.SuccessMessages[1].length == 0) {
255				ferve.wishlist.itemIds.length = 0;
256			} else {
257				ferve.wishlist.itemIds = ftReturn.SuccessMessages[1].split(",");
258			}
259			ferve.cart.count = 0;
260			ferve.cart.qty = 0;
261			ferve.cart.total = ferve.formatMoney(0, 2);
262			ferve.cart.updateTotals();
263			outputProperties(true, false);
264			try {
265				ft_accountStatusUpdate(2);
266			}
267			catch (e) { }
268			var x = document.getElementById("ft_logout");
269			if (x) x.style.display = "none";
270			ferve.notification.show("alert", "blue", "You have successfully logged out.", null, null, null);
271			var url = document.URL;
272			if (url.indexOf("/Account/") > -1) {
273				ferve.utility.openLink("account");
274			} else if (url.indexOf("/Cart") > -1) {
275				ferve.utility.openLink("cartView");
276			}
277		} else {
278			ferve.log("Unknown login result: " + unescape(s), "error");
279		}
280	};
281	ferve.visitor.location = function () {
282		if (ferve.ftwp() || ferve.isApp() || window.location.protocol != "https:" || window.sessionStorage.getItem("ftgeo_" + ferve_h) == "true") return;
283
284		var src = document.getElementById("ft_ftapiJS").getAttribute("src");
285		if (src.indexOf("location=true") == -1) return;
286
287		ferve.log("ferve.visitor.location()");
288
289		try {
290			var geo_options = { enableHighAccuracy: true, maximumAge: 60000, timeout: 60000 };
291			navigator.geolocation.getCurrentPosition(ftd_location, ftd_location, geo_options);
292		}
293		catch (e) {
294			ferve.log("geoLocation error: " + e);
295			window.sessionStorage.setItem("ftgeo_" + ferve_h, true);
296		}
297		function ftd_location(position) {
298			ferve.log("ftd_location()");
299			ferve.log(position);
300			if (position && position.coords) {
301				ferve.xmlHttpRequest(ferve.url + "api/v1/Visitors/Location?hash=" + ferve.visitor.hash + "&latitude=" + position.coords.latitude + "&longitude=" + position.coords.longitude + "&accuracy=" + position.coords.accuracy, "GET", null, "", "", "");
302				ferve.visitor.geoPosition = position;
303				try {
304					options.GeoPosition = { latitude: position.coords.latitude, longitude: position.coords.longitude, accuracy: position.coords.accuracy };
305				}
306				catch (e) {
307					// Nothing
308				}
309			}
310			window.sessionStorage.setItem("ftgeo_" + ferve_h, true);
311		}
312	};
313	var ft_visitorMediaCheck = function (s) {
314		if (!s) {
315			ferve.xmlHttpRequest(ferve.url + "api/v1/Visitors/MediaCheck?hash=" + ferve.visitor.hash, "GET", null, "", "", "ft_visitorMediaCheck(");
316		} else {
317			var ftReturn = ferve.parseFTReturn(s);
318			if (!ftReturn || !ftReturn.Success) return;
319
320			geoRegion = ftReturn.SuccessMessages[0];
321			var supported = (ftReturn.SuccessMessages[1] == "true");
322
323			if (!supported) {
324				eval("var f = document.ft_pricingForm_" + ferve.itemHash);
325				if (f) {
326					var geoblocks = document.querySelectorAll("select[data-geoblock]");
327					for (var i = 0; i < geoblocks.length; i++) {
328						var x = geoblocks[i].parentNode.parentNode.querySelector(".ft_ep_conditionsRow");
329						x.innerHTML += "<br /><span class=\"ft_ep_conditionsWarning\">It appears your device is unsupported. <a href=\"Javascript:ferve.pricing.mediaFAQs()\">Streaming FAQs.</a></span>";
330					}
331				}
332			}
333
334		}
335	};
336	ferve.visitor.updatePropertiesFromCookie = function () {
337		ferve.log("ferve.visitor.updatePropertiesFromCookie()");
338
339		if (!window.atob) {
340			ferve.log("window.atob not ready - exiting updatePropertiesFromCookie()", "info");
341			setTimeout(function () { ferve.visitor.updatePropertiesFromCookie(); }, 100);
342			return;
343		}
344
345		if (!ferve_h || ferve_h.length == 0) ferve.log("ferve.visitor.updatePropertiesFromCookie() ferve_h blank");
346		if (typeof (ftwp) == "object") {
347			FTWPIV();
348			return;
349		}
350
351		ferveCookie = getCookie("ftapi_" + ferve_h);
352		if (ferveCookie.length == 0 && !ferve_api && location.protocol != "https:") {
353			ferve.log("Exiting updatePropertiesFromCookie() cookie blank", "info");
354			return;
355		}
356		ferveCookie = ferveCookie.split(delimiter);
357
358		var vh = fcItem(0);
359		if (!vh || vh.length == 0) {
360			ferve.log("Exiting updatePropertiesFromCookie() vh blank", "info");
361			return;
362		}
363
364		ferve.log("Setting ferve.visitor.hash to " + fcItem(0), "info");
365		ferve.visitor.hash = fcItem(0);
366		ferve.visitor.loggedIn = fcItem(1);
367		var cData = window.atob(fcItem(2).replace(new RegExp("\r|\n", "g"), "")).split(";");
368		if (cData[0].length > 0) ferve.wishlist.itemIds = cData[0].split(",");
369		ferve.visitor.firstName = cData[1];
370		ferve.visitor.memberType = cData[2];
371		ferve.visitor.memberExpiryDate = cData[3];
372		ferve.visitor.passType = cData[4];
373		ferve.visitor.subscriptions = cData[5];
374		ferve.visitor.ferveData = (cData.length >= 6 && cData[6] && cData[6].length > 0 ? JSON.parse(cData[6]) : null);
375		ferve.visitor.restricted = (cData.length >= 7 ? (cData[7] == "true") : false);
376		ferve.visitor.type = (cData.length >= 10 ? parseInt(cData[9]) : 0);
377		ferve.cart.count = fcItem(3);
378		ferve.cart.qty = fcItem(4);
379		ferve.cart.total = fcItem(5);
380		if (ferve.version.split(".").length <= 2) ferve.version += "." + fcItem(9);
381		ferve.cart.hash = window.atob(fcItem(8));
382		if (ferve_cache && window.atob(fcItem(8)) == ferve.visitor.hash) ferve_cache = false;
383		if (ferve_cache && cData.length >= 8) ferve_cache = (ferve.cart.qty < cData[8]);
384
385		outputProperties(true, false);
386	};
387
388
389	ferve.visitor.cookieConsent = function (response) {
390		ferve.log("ferve.visitor.cookieConsent(" + response + ")");
391
392		if (!ferve.isNullOrEmpty(response)) {
393			if (response == "Accept") {
394				localStorage.setItem("ftcookie_" + ferve_h, "true");
395			} else if (response == "Reject") {
396				window.sessionStorage.setItem("ftcookie_" + ferve_h, "false");
397				window.sessionStorage.setItem("ftcookieurl_" + ferve_h, document.URL);
398				document.location.href = "/Error/NoCookies";
399			} else if (response == "Reset") {
400				localStorage.removeItem("ftcookie_" + ferve_h);
401				window.sessionStorage.removeItem("ftcookie_" + ferve_h);
402				window.sessionStorage.removeItem("ftcookieurl_" + ferve_h);
403				return;
404			}
405
406			ferve.notification.hide();
407			return;
408		}
409
410		if (localStorage.getItem("ftcookie_" + ferve_h) == "true") {
411			return;
412		} else if (window.sessionStorage.getItem("ftcookie_" + ferve_h) == "false") {
413			document.location.href = "/Error/NoCookies";
414			return;
415		}
416
417		var message = "<strong>This website uses cookies</strong><br /><div style=\"font-weight:normal;font-size:0.9em;\">We use cookies to track your visitor session and the items you add to your cart which is essential to provide secure cart services.<br />Please see <a href=\"https://ferve.tickets/privacy\" target=\"_blank\">ferve.tickets/privacy/</a> for more details.</div>"
418		ferve.notification.show("confirm", "blue", message, function () { ftd_cookieConsent(s) }, null, null);
419		setTimeout(function () {
420			var notification = document.querySelector("#ft_notification");
421			notification.classList.add("ft_notificationWide", "ft_notificationSpaced");
422			notification = document.querySelector("#ft_notificationMessage");
423
424			var buttons = document.querySelectorAll(".ft_notificationButton50");
425			buttons[0].innerHTML = "<a href=\"Javascript:ferve.visitor.cookieConsent('Reject')\">Reject</a>";
426			buttons[1].innerHTML = "<a href=\"Javascript:ferve.visitor.cookieConsent('Accept')\">Accept</a>";
427		}, 100);
428	};
429
430
431
432	// #mark ------ Wishlist  ------
433	ferve.wishlist = function () { };
434	ferve.wishlist.itemIds = new Array();
435	ferve.wishlist.imageOff = "";
436	ferve.wishlist.imageOn = "";
437	ferve.wishlist.returnStar = function (itemId, width, height) {
438		var inWishlist = false;
439		if (!initComplete) ferve.visitor.updatePropertiesFromCookie();
440		for (var i = 0; i < ferve.wishlist.itemIds.length; i++) {
441			if (itemId == ferve.wishlist.itemIds[i]) {
442				inWishlist = true;
443				break;
444			}
445		}
446		return "<a href=\"Javascript:ferve.wishlist.toggle('" + itemId + "');\"><div class=\"fticon-wishlist-" + (inWishlist ? "on" : "off") + "\" name=\"ft_edar\" id=\"ft_edarSD_" + itemId + "\"></div></a>";
447	};
448	ferve.wishlist.inWishlist = function (itemId) {
449		if (!initComplete) ferve.visitor.updatePropertiesFromCookie();
450		for (var i = 0; i < ferve.wishlist.itemIds.length; i++) {
451			if (itemId == ferve.wishlist.itemIds[i]) return true;
452		}
453		return false;
454	};
455	ferve.wishlist.toggle = function (itemId) {
456		var x = document.getElementById("ft_edar_" + itemId);
457		if (x) {
458			if (x.className.indexOf("fticon-wishlist-on") == -1) {
459				x.className = x.className.replace("fticon-wishlist-on", "fticon-wishlist-off");
460			} else {
461				x.className = x.className.replace("fticon-wishlist-off", "fticon-wishlist-on");
462			}
463		}
464		ferve.wishlist.addRemove(itemId, 0);
465	};
466	ferve.wishlist.addRemove = function (itemId, mode) {
467		var actions = ["Toggle", "Add", "Remove", "AddSeason", "RemoveSeason"];
468		ferve.xmlHttpRequest(ferve.url + "api/v1/Wishlist/" + actions[mode] + "?hash=" + ferve.visitor.hash + "&itemId=" + escape(itemId) + "&location=Web", "GET", null, "", "", "ftd_wishlistStatusChange('" + itemId + "',");
469	};
470	var ftd_wishlistStatusChange = function (itemId, s) {
471		ferve.log("ftd_wishlistStatusChange(" + itemId + "," + unescape(s) + ")");
472
473		var ftReturn = ferve.parseFTReturn(s);
474		if (!ftReturn) return;
475
476		if (ftReturn.Success) {
477			ferve.wishlist.itemIds = ftReturn.SuccessMessages[0].split(",");
478			ferve.renderWishlistStars();
479			var status = 0;
480			for (var i = 0; i < ferve.wishlist.itemIds.length; i++) {
481				if (ferve.wishlist.itemIds[i] == itemId) {
482					status = 1;
483					break;
484				}
485			}
486			if (typeof (items) != "undefined") {// Browse
487				for (var i = 0; i < items.length; i++) {
488					if (items[i].Hash == itemId) {
489						items[i].Wishlist = false;
490						break;
491					}
492				}
493			}
494			try {
495				ft_wishlistStatusUpdate(itemId, status);
496			}
497			catch (e) { }
498		} else {
499			ferve.log("ftd_wishlistStatusChange: Unknown result: " + unescape(s), "error");
500		}
501		outputProperties(true, false);
502	};
503	ferve.wishlist.toggleSeason = function (itemId) {
504		var s = "";
505
506		if (!ferve.wishlist.inWishlist(itemId)) {
507			ferve.notification.show("confirm", "blue", "Add all events to your wishlist?", function (s) { ftd_wishlistSeason(itemId, true, s) }, null, null);
508		} else {
509			ferve.notification.show("confirm", "blue", "Remove all events from your wishlist?", function (s) { ftd_wishlistSeason(itemId, false, s) }, null, null);
510		}
511	}
512	var ftd_wishlistSeason = function (itemId, add, s) {
513		if (add) {
514			ferve.wishlist.addRemove(itemId, 3);
515		} else {
516			ferve.wishlist.addRemove(itemId, 4);
517		}
518	};
519
520
521	// #mark ------ Cart  ------
522	ferve.cart = function () { };
523	ferve.cart.count = "";
524	ferve.cart.qty = "";
525	ferve.cart.total = "";
526	ferve.cart.show = function (mode) {
527		ferve.toggleWaiting(true);
528		if (mode == 0) {
529			ferve.utility.openLink("cartView");
530		} else if (mode == 1) {
531			toggleOverlay(1, false);
532			ferve.xmlHttpRequest(ferve.url + "api/v1/Cart/View?hash=" + ferve.visitor.hash + ferve.cart.checkoutParameters(), "GET", null, "", "", "ftd_cartAction('CS',");
533		}
534	};
535	ferve.cart.hide = function () {
536		ferve.log("ferve.cart.hide()");
537		hideHoverElements(3);
538	};
539	ferve.cart.remove = function (cartItemHash, source) {
540		var s = "";
541		ferve.notification.show("confirm", "blue", "Are you sure you wish to remove this item from your cart?", function (s) { ftd_cartRemove(cartItemHash, source, s) }, null, null);
542	};
543
544	ferve.cart.removeWithTrack = function (cartItemHash, source, target) {
545		var s = "";
546		var tracking = target.getAttribute("data-analytics");
547
548		ferve.notification.show("confirm", "blue", "Are you sure you wish to remove this item from your cart?", function (s) { try { eval(tracking) } catch { } ftd_cartRemove(cartItemHash, source, s) }, null, null);
549	};
550
551	var ftd_cartRemove = function (cartItemHash, source, s) {
552		ferve.xmlHttpRequest(ferve.url + "api/v1/Cart/Remove?hash=" + ferve.visitor.hash + "&cartItemHash=" + cartItemHash + "&source=" + source + ferve.cart.checkoutParameters(), "GET", null, "", "", "ftd_cartAction(-1,");
553	};
554	ferve.cart.removeSeat = function (itemHash, seatHash, allocated) {
555		if (allocated != 1) {
556			var s = "";
557			ferve.notification.show("confirm", "blue", "Are you sure you wish to remove this seat from your cart?", function (s) { ftd_cartRemoveSeat(itemHash, seatHash, allocated, s) }, null, null);
558			return;
559		}
560		ftd_cartRemoveSeat(itemHash, seatHash, allocated, null);
561	};
562	var ftd_cartRemoveSeat = function (itemHash, seatHash, allocated, s) {
563		ferve.xmlHttpRequest(ferve.url + "api/v1/Cart/RemoveSeat?hash=" + ferve.visitor.hash + "&itemHash=" + itemHash + "&seatHash=" + seatHash + ferve.cart.checkoutParameters(), "GET", null, "", "", "ftd_cartAction('" + seatHash + (allocated ? "*" : "") + "',");
564	};
565	ferve.cart.remove70101101 = function (f) {
566		ferve.xmlHttpRequest(ferve.url + "api/v1/Cart/Remove70101101?hash=" + ferve.visitor.hash + "&fh=" + f + ferve.cart.checkoutParameters(), "GET", null, "", "", "ftd_cartAction('R7',");
567	}
568	ferve.cart.removeVoucher = function (f) {
569		ferve.xmlHttpRequest(ferve.url + "api/v1/Cart/RemoveVoucher?hash=" + ferve.visitor.hash + "&vh=" + f + ferve.cart.checkoutParameters(), "GET", null, "", "", "ftd_cartAction('R8',");
570	};
571	var ftd_cartAction = function (itemHash, s) {
572		ferve.log("ftd_cartAction(" + itemHash + ")");
573		ferve.toggleWaiting(false);
574
575		addingToCart = false;
576
577		var ftReturn = ferve.parseFTReturn(s);
578		ferve.log(ftReturn);
579		if (!ftReturn) return;
580
581		if (ftReturn.Success) {
582			ferve.visitor.updatePropertiesFromCookie();
583			ft_timeoutMessage();
584			ferve.cart.count = ftReturn.SuccessMessages[0];
585			ferve.cart.qty = ftReturn.SuccessMessages[1];
586			ferve.cart.total = ftReturn.SuccessMessages[2];
587			ferve.cart.updateTotals();
588
589			if (itemHash != "CS") {
590				try {
591					ft_cartStatusUpdate((ftReturn.SuccessMessages.indexOf("RemoveSeat") == -1 ? itemHash : "RemoveSeat"));
592					if (itemHash == "R8") {
593						try {
594							ft_cardSource("FTAPI");
595						}
596						catch (e) { }
597						return;
598					}
599				}
600				catch (e) {
601					if (e.message.indexOf("ft_cartStatusUpdate is not a function") == -1 && e.message.indexOf("ft_cartStatusUpdate is not defined") && e.message.indexOf("Can't find variable: ft_cartStatusUpdate") == -1) ferve.log("ft_cartStatusUpdate error\n" + e.message, "error");
602				}
603			}
604
605			var url = document.URL;
606
607			if (itemHash == "-1") {
608				if (ferve.cart.count == 0 && !ferve_api && (url.indexOf("/Checkout") > -1 || url.indexOf("/Cart") > -1) && !ferve.ftwp()) {
609					document.location.href = ferve.url + "Cart/";
610					return;
611				} else if (ferve.isApp()) {
612					callApp("CartUpdated/" + ferve.cart.qty);
613				}
614			}
615
616			if (ftReturn.SuccessMessages.indexOf("RemoveSeat") != -1) {
617				if (!ferve.ftwp()) updateCart((itemHash != -1 && itemHash.substring(itemHash.length - 1) == "*" ? "RS" : itemHash), ftReturn);
618				if (typeof (ft_seating) != "undefined") {
619					var seatHashes = ftReturn.SuccessMessages[5].split(",");
620					for (var i = 0; i < seatHashes.length; i++) {
621						ft_seating.seatRemoved(seatHashes[i]);
622					}
623
624					if (ferve.cart.count == 0) ft_seating.seatsClear();
625				}
626			}
627
628			var x = document.getElementById("ft_ferveCart");
629			if (x && ferve.cart.qty == 0) {
630				ferve.cart.hide();
631				return;
632			}
633
634			if (itemHash == "R7X" || itemHash == "-1" || itemHash == "U" || itemHash == "CS") updateCart(itemHash, ftReturn);
635
636			if (ftReturn.SuccessMessages.indexOf("AddToCart") != -1) {// add
637				if (typeof (ft_seating) != "undefined" && typeof ft_seating.seatsBuyComplete == "function") {
638					ferve.log(ftReturn);
639					var seatHashes = (ftReturn.SuccessMessages.length >= 6 ? ftReturn.SuccessMessages[5] : "");
640					ft_seating.seatsBuyComplete(seatHashes);
641				}
642
643				eval("var f = document.ft_pricingForm_" + itemHash);
644
645				if (f) {
646					ferve.toggleDisplay(f.querySelector("#ft_pricingQuestionsContainer"), "none", true);
647					ferve.toggleDisplay(f.querySelector("#ft_pricingQuestionsHeading"), "none", true);
648					ferve.toggleDisplay(f.querySelector("#ft_pricingQuestionsIntroduction"), "none", true);
649					ferve.setContent(f.querySelector("#ft_pricingQuestions"), "");
650
651					for (var i = 0; i < f.elements.length; i++) {
652						if (f.elements[i].name.substring(0, 3) == "qty" || (f.elements[i].name.length > 8 && f.elements[i].name.substring(0, 8) == "Question")) {
653							if (f.elements[i].type == "select-one") {
654								f.elements[i].selectedIndex = 0;
655							} else if (f.elements[i].type == "checkbox") {
656								f.elements[i].checked = false;
657							} else if (f.elements[i].type == "radio") {
658								if (f.elements[i].name.length > 8 && f.elements[i].name.substring(0, 8) == "Question" && f.elements[i].id.substr(-1) == "1") {
659									f.elements[i].checked = true;
660								} else {
661									f.elements[i].checked = false;
662								}
663							} else if (f.elements[i].type == "text" || f.elements[i].type == "textarea") {
664								f.elements[i].value = "";
665								if (f.elements[i].name.substring(0, 8) == "qtyOther") f.elements[i].className = f.elements[i].className.replace("ft_itemVisible", "ft_itemHidden");
666							}
667						}
668					}
669					var counters = f.querySelectorAll(".ft_ep_qtyCounter_quantity");
670					for (var i = 0; i < counters.length; i++) {
671						counters[i].innerHTML = "0";
672					}
673				} else {
674					ferve.toggleDisplay("#ft_pricingQuestionsContainer", "none", true);
675					ferve.toggleDisplay("ft_pricingQuestionsHeading", "none", true);
676					ferve.toggleDisplay("ft_pricingQuestionsIntroduction", "none", true);
677					ferve.setContent("ft_pricingQuestions", "");
678				}
679
680				if (ferve.isApp()) {
681					callApp("CartAddSuccessful/" + ferve.cart.qty);
682				} else if (!ferve.ftwp()) {
683					try {
684						ft_addToCart(itemHash, ftReturn);
685					}
686					catch (e) {
687						var action = ftReturn.SuccessMessages.find(element => element.includes("REDIRECT:"));
688						if (action && action.indexOf("View Cart") > -1) {
689							ferve.utility.openLink("cartView");
690						} else if (action && action.indexOf("Checkout") > -1) {
691							ferve.utility.openLink("checkout");
692						} else {
693							updateCart(itemHash, ftReturn);// Show cart result
694						}
695						try {
696							ft_addToCart2(itemHash, ftReturn);
697						}
698						catch (e) { }
699					}
700				}
701			}
702		} else {
703
704			if (typeof (ftReturn.Errors[0]) != "undefined" && ftReturn.Errors[0].CustomerMessage.indexOf("SeatUnavailable") != -1) {
705				ft_seating.seatsBuyError(ftReturn.Errors[0].CustomerMessage);
706				return;
707			}
708
709			if (itemHash == "CS") {
710				ferve.utility.openLink('cartview', 0);
711				return;
712			}
713			if (typeof (ftReturn.Errors[0]) != "undefined") {
714				setTimeout(function () {
715					ferve.notification.show("alert", "red", ftReturn.Errors[0].CustomerMessage, null, null, null);
716				}, 500);
717			}
718			if (itemHash == "U") {
719				var selects = document.querySelectorAll("select[name='ft_ch']");
720				for (var i = 0; i < selects.length; i++) {
721					for (var j = 0; j < selects[i].options.length; j++) {
722						selects[i].options[j].selected = selects[i].options[j].defaultSelected;
723					}
724				}
725			}
726			if (ferve.isApp()) callApp("PricingError");
727
728			return;
729		}
730		try {
731			bookSeats_delegate(ftReturn);
732		}
733		catch (e) { }
734	};
735
736
737
738	function updateCart(itemHash, ftReturn) {
739		ferve.log("updateCart(" + itemHash + ")");
740		if (typeof (ftwp) != "undefined") return;
741		if (itemHash == "RS") return;// Seating plan remove seat
742		var x = document.getElementById("ft_ferveCartView");
743		if (itemHash == "CS" || !x) {
744			toggleOverlay(1, false);
745			x = document.getElementById("ft_ferveCart");
746			if (!x) {
747				var div = document.createElement("div");
748				div.className = "ft_fade ft_shadow ft_borderRadius6 ft_itemHidden";
749				div.id = "ft_ferveCart";
750				document.body.appendChild(div);
751				x = document.getElementById("ft_ferveCart");
752				if (!x) {
753					hideHoverElements(4);
754					ferve.notification.show("alert", "blue", "Item added to cart successfully.", null, null, null);
755					return;
756				}
757			}
758			x.innerHTML = ftReturn.SuccessMessages[3];
759			showHoverElements(1);
760		} else {
761			x.innerHTML = ftReturn.SuccessMessages[3].replace("<button type=\"button\" class=\"ft_button btn btn-default\" onclick=\"ferve.utility.openLink('cartview',0)\">View Cart</button>", "<button type=\"button\" class=\"ft_button btn btn-default\" onclick=\"ferve.cart.clear(1)\">Clear Cart</button>");
762			x = document.getElementById("ft_ferveCart");
763			if (x) x.innerHTML = ftReturn.SuccessMessages[3];
764		}
765
766		initTimer();
767	}
768
769	ferve.cart.clear = function (conf) {
770		ferve.log("ferve.cart.clear()");
771		if (conf) {
772			ferve.notification.show("confirm", "blue", "Are you sure you wish to clear your cart?", ftd_cartClear, null, null);
773			return;
774		}
775		ftd_cartClear(null);
776	};
777	var ftd_cartClear = function (s) {
778		ferve.log("ftd_cartClear()");
779		ferve.xmlHttpRequest(ferve.url + "api/v1/Cart/Clear?hash=" + ferve.visitor.hash, "GET", null, "", "", "ftd_cartClear2(");
780	};
781	var ftd_cartClear2 = function (s) {
782		ferve.log("ftd_cartClear2()");
783
784		var ftReturn = ferve.parseFTReturn(s);
785		if (!ftReturn) return;
786
787		if (ftReturn.Success) {
788			ferve.cart.count = ftReturn.SuccessMessages[0];
789			ferve.cart.qty = ftReturn.SuccessMessages[1];
790			ferve.cart.total = ftReturn.SuccessMessages[2];
791			ferve.cart.updateTotals();
792			var x = document.getElementById("ft_ferveCartContainer");
793			if (x) {
794				var h1 = x.getElementsByTagName("h1");
795				if (h1.length > 0) {
796					h1 = h1[0].outerHTML;
797				} else {
798					h1 = "";
799				}
800				ferve.setContent("ft_ferveCartContainer", h1 + "<p>You have no items in your cart.</p>");
801			}
802			try {
803				paymentClear_delegate2();
804				ft_cartStatusUpdate();
805			}
806			catch (e) {
807				if (ferve.ftwp()) {
808					ferve.log("ftd_cartClear2: Error: " + e.message, "error");
809					console.trace();
810					debugger;
811				}
812			}
813			if (ferve.isApp()) callApp("CartCleared");
814		} else {
815			ferve.log("ftd_cartClear2: Unknown result: " + unescape(s), "error");
816		}
817	};
818	ferve.cart.updateTotals = function () {
819		ferve.log("ferve.cart.updateTotals()");
820		// Update cart count/total html elements
821
822		var cartTotals = document.querySelectorAll("div[data-total], span[data-total]");
823		var cartTotal = ferve.cart.total;
824		if (cartTotal.length == 0) cartTotal = "0.00";
825		for (var i = 0; i < cartTotals.length; i++) {
826			if (cartTotal == "0.00" && cartTotals[i].getAttribute("data-ignorezero") == "1") {
827				cartTotals[i].innerHTML = "";
828			} else {
829				cartTotals[i].innerHTML = ferve.formatMoney(cartTotal, -2);
830			}
831		}
832		var cartCounts = document.querySelectorAll("div[data-count], span[data-count]");
833		for (var i = 0; i < cartCounts.length; i++) {
834			if (ferve.cart.count == 0 && cartCounts[i].getAttribute("data-ignorezero") == "1") {
835				cartCounts[i].innerHTML = ferve.cart.count;
836			} else {
837				cartCounts[i].innerHTML = ferve.cart.count;
838			}
839		}
840		var cartQtys = document.querySelectorAll("div[data-quantity], span[data-quantity]");
841		for (var i = 0; i < cartQtys.length; i++) {
842			if (ferve.cart.qty == 0 && cartQtys[i].getAttribute("data-ignorezero") == "1") {
843				cartQtys[i].innerHTML = "";
844			} else {
845				cartQtys[i].innerHTML = ferve.cart.qty;
846			}
847		}
848	};
849	ferve.cart.update = function (element) {
850		var cartitemhash = element.getAttribute("data-cartitemhash");
851
852		var source = "";
853		if (ferve.isApp()) {
854			source = "ft_ferveCartView";
855		} else {
856			var el = element;
857			while (el && el.parentNode) {
858				el = el.parentNode;
859				if (!el.id) continue;
860				if (el.id.length > 0 && el.id.toLowerCase().substring(0, 12) == "ft_fervecart") {
861					source = el.id;
862					break;
863				}
864			}
865		}
866
867		if (element && element.type == "select-one") ferve.xmlHttpRequest(ferve.url + "api/v1/Cart/Update?hash=" + ferve.visitor.hash + "&cartItemHash=" + cartitemhash + "&quantity=" + element.options[element.selectedIndex].value + "&source=" + source + ferve.cart.checkoutParameters(), "GET", null, "", "", "ftd_cartAction('U',");
868	};
869	ferve.CartItemToAdd = function (itemHash, dateHash, parenthash, quantity, priceTypeHash, discountHash, codeHash, seatingPlanHash, seatingPlanSection, seatHashes, seatSource, allocated, split, priceBandHash, generalAdmission, waitlistHash, payWhatYouWant, holds, memberCodeHash = null) {
870		this.ItemHash = itemHash;
871		this.DateHash = dateHash;
872		this.ParentHash = parenthash;
873		this.Quantity = quantity;
874		this.PriceTypeHash = priceTypeHash;
875		this.CodeHash = codeHash;
876		this.DiscountHash = discountHash;
877		this.SeatingPlanHash = seatingPlanHash;
878		this.SeatingPlanSection = seatingPlanSection;
879		this.SeatHashes = seatHashes;
880		this.SeatSource = seatSource;
881		this.Allocated = allocated;
882		this.Split = split;
883		this.PriceBandHash = priceBandHash;
884		this.GeneralAdmission = generalAdmission;
885		this.WaitlistHash = waitlistHash;
886		this.PayWhatYouWant = payWhatYouWant;
887		this.Holds = holds;
888		this.QuestionAnswersToAdd = null;
889		var cartsAbandoned = window.sessionStorage.getItem("ftca_" + ferve_h);
890		cartsAbandoned = (!cartsAbandoned ? [] : JSON.parse(cartsAbandoned));
891		this.CartsAbandoned = cartsAbandoned;
892		this.MemberCodeHash = memberCodeHash;
893	};
894	ferve.QuestionToAdd = function (questionHash, sequenceNumber, itemHash, priceTypeHash, answer) {
895		this.QuestionHash = questionHash;
896		this.SequenceNumber = sequenceNumber;
897		this.ItemHash = itemHash;
898		this.PriceTypeHash = priceTypeHash;
899		this.Answer = answer;
900	};
901	ferve.PricingQuestionDTO = function (priceTypeHash, quantity) {
902		this.PriceTypeHash = priceTypeHash;
903		this.Quantity = quantity;
904	};
905	ferve.cart.checkoutParameters = function () {
906		var url = document.URL.toLowerCase();
907		var s = "";
908		if (url.indexOf("/checkout") > -1) {
909			s += "&checkout=true";
910			if (typeof (FTStripe) != "undefined") s += "&id=" + FTStripe.id;
911		}
912		return s;
913	};
914
915	ferve.cart.contents = function (json, callback) {
916		var url = ferve.url + "api/v1/Cart/Contents?hash=" + ferve.visitor.hash + "&json=" + (json ? "true" : "false");
917		var result = "error:unknown";
918		let xhr = new XMLHttpRequest();
919		xhr.open("GET", url, (callback != null));
920		xhr.onload = function () {
921			if (this.status == 200) {
922				var ftReturn = ferve.parseFTReturn(this.response);
923				if (!ftReturn) return "error:invalid response";
924				if (json) {
925					result = JSON.parse(ftReturn.SuccessMessages[0])
926				} else {
927					result = ftReturn.SuccessMessages[0];
928				}
929			} else {
930				result = "error:" + this.status + "," + xhr.statusText;
931			}
932			if (callback) callback(result);
933		};
934		xhr.onerror = function () {
935			result = "error:" + this.status + "," + xhr.statusText;
936			if (callback) callback(result);
937		};
938		xhr.send();
939
940		if (!callback) return result;
941	};
942
943
944
945
946
947	// #mark ------ Pricing  ------
948	ferve.pricing = function () { };
949	ferve.pricing.selectEventOnRender = true;
950	ferve.pricing.eventDates = false;
951	ferve.pricing.purchase = function (itemHash, mode) {
952		ferve.log("ferve.pricing.purchase(" + itemHash + ", " + mode + ")");
953		var x = document.getElementById("ft_purchase");
954		if (!x) {
955			var div = document.createElement("div");
956			div.className = "ft_fade ft_itemHidden";
957			div.style.display = "none";
958			div.id = "ft_purchase";
959			document.body.appendChild(div);
960			x = document.getElementById("ft_purchase");
961		}
962		if (x) {
963			x.innerHTML = (mode == 0 ? "<div id=\"ft_eventDates_" + itemHash + "\"></div>" : "") + "<div id=\"ft_eventPricing_" + itemHash + "\"></div>";
964			var y = document.getElementById("ft_eventDates_" + itemHash);
965			if (y) y.innerHTML = "";
966			y = document.getElementById("ft_eventPricing_" + itemHash);
967			if (y) y.innerHTML = "<div style=\"margin-top:50px;left:50%;font-weight:bold;\">Loading...</div><div class=\"ft_ep_ferve\" style=\"bottom:0;\"><img src=\"/img/ferve/ferve.png\" /></div>";
968
969			var yLoc = 0;
970			if (typeof window.pageYOffset === "number") {
971				yLoc = window.pageYOffset;
972			} else if (document.body && (document.body.scrollLeft || document.body.scrollTop)) {
973				yLoc = document.body.scrollTop;
974			} else if (document.documentElement && (document.documentElement.scrollLeft || document.documentElement.scrollTop)) {
975				yLoc = document.documentElement.scrollTop;
976			}
977			if (312 - yLoc < 0) {
978				var h = screen.height;
979				x.style.top = (yLoc + (h / 2)) + "px";
980			}
981
982			showHoverElements(3);
983
984			if (mode == 0) {
985				ferve.pricing.returnEventDates(itemHash);
986			} else {
987				ferve.log("ferve.pricing.purchase() calling ferve.pricing.returnEventPricing");
988				ferve.pricing.returnEventPricing(itemHash);
989			}
990		}
991	};
992	ferve.pricing.returnEventDates = function (itemHash, selectedHash) {
993		ferve.log("returnEventDates(" + itemHash + ", " + selectedHash + ")");
994
995		ferve.itemHash = itemHash;
996		ferve.pricing.eventDates = true;
997		if (!initComplete) ferve.visitor.updatePropertiesFromCookie();
998
999		if (ferve.visitor.restricted) return ferve.pricing.restricted();
1000
1001		if (IE6) {
1002			var x = document.getElementById("ft_eventPricing");
1003			if (!x) x = document.getElementById("ft_eventPricing_" + itemHash);
1004			if (x) x.innerHTML = "";
1005			return;
1006		}
1007		if (ferve_cache) {
1008			ferve.xmlHttpRequest(ferve.url + "api/v1/Items/DatesCached?itemHash=" + itemHash + "&app=" + ferve.isApp(), "GET", null, "", "", "ftd_eventDates('" + itemHash + "',");
1009		} else {
1010			ferve.xmlHttpRequest(ferve.url + "api/v1/Items/Dates?hash=" + ferve.visitor.hash + "&itemHash=" + itemHash + (ferve.isNullOrEmpty(selectedHash) ? "" : "&selectedHash=" + selectedHash), "GET", null, "", "", "ftd_eventDates('" + itemHash + "',");
1011		}
1012	};
1013	var ftd_eventDates = function (itemHash, s) {
1014		ferve.log("ftd_eventDates(" + itemHash + ")");
1015
1016		var ftReturn = ferve.parseFTReturn(s);
1017		if (!ftReturn) return;
1018
1019		if (!ftReturn.Success) {
1020			if (ftReturn.Errors[0].CustomerMessage == "Invalid Hash.") {
1021				ferve.log("\n\n\n********** Invalid Hash. **********\n\n\n", "error");
1022				var url = document.URL;
1023				if (url.indexOf("rfc=") == -1) {
1024					url += (url.indexOf("?") == -1 ? "?" : "&");
1025					url += "rfc=1"
1026					document.location.href = url;
1027				}
1028			} else {
1029				var x = document.getElementById("ft_eventDates");
1030				if (!x) x = document.getElementById("ft_eventDates_" + itemHash);
1031				if (x) x.innerHTML = "";
1032				x = document.getElementById("ft_eventPricing");
1033				if (!x) x = document.getElementById("ft_eventPricing_" + itemHash);
1034				if (x) x.innerHTML = "Pricing is currently not available for this event.";
1035			}
1036
1037		} else {
1038
1039			if (ftReturn.SuccessMessages[0].indexOf("ft_pricingForm") != -1) {
1040				// Non event
1041				ferve.log("Non event pricing returned");
1042				ftd_eventPricing(itemHash, null, "", false, s);
1043				return;
1044			}
1045
1046			try {
1047				ft_eventDates(ftReturn.SuccessMessages[0]);
1048			}
1049			catch (e) {
1050				if (e.message.indexOf("ft_eventDates is not a function") == -1 && e.message.indexOf("ft_eventDates is not defined") == -1 && e.message.indexOf("Can't find variable: ft_eventDates") == -1) ferve.log("ft_eventDates error(1): " + e.message, "error");
1051
1052				var newHash = "", calendar = "", pricingLoading = false;
1053				for (var i = 0; i < ftReturn.SuccessMessages.length; i++) {
1054					if (ftReturn.SuccessMessages[i].indexOf("hash:") > -1) {
1055						newHash = ftReturn.SuccessMessages[i].replace("hash:", "");
1056					} else if (ftReturn.SuccessMessages[i].indexOf("ft_ed_cal") > -1) {
1057						calendar = ftReturn.SuccessMessages[i];
1058					}
1059				}
1060				if (!ferve.isNullOrEmpty(newHash)) {
1061					// New item hash
1062					x = document.getElementById("ft_eventDates_" + itemHash);
1063					if (x) x.id = "ft_eventDates_" + newHash;
1064					x = document.getElementById("ft_eventPricing_" + itemHash);
1065					if (x) x.id = "ft_eventPricing_" + newHash;
1066					itemHash = newHash;
1067				}
1068
1069				var eventDates = document.getElementById("ft_eventDates");
1070				if (!eventDates) eventDates = document.getElementById("ft_eventDates_" + itemHash);
1071
1072				var dates = unescape(ftReturn.SuccessMessages[0]);
1073				if (eventDates) eventDates.innerHTML = dates;
1074
1075				if (!ferve.isNullOrEmpty(calendar)) {
1076					// Calendar : show and clear dates selected
1077					if (!ft_calendar(itemHash) && (ferve_api || ferve.ftwp)) {
1078						var x = document.getElementById("ft_eventDates");
1079						if (!x) x = document.getElementById("ft_eventDates_" + itemHash);
1080						if (x) {
1081							var div = document.createElement("div");
1082							div.id = "ft_eventCalendar_" + itemHash;
1083							div.innerHTML = calendar;
1084							x.parentNode.insertBefore(div, x);
1085						}
1086					}
1087
1088					ferve.calendar.render(itemHash);
1089
1090					if (ferve.ftwp() && dates.indexOf("ft_ed_cal_times") > -1) {
1091						x = document.querySelector("div[id^='ft_eventCalendar_']");
1092						if (x) x.className = "ft_calendar_timeSlots";
1093					}
1094
1095					if (ftReturn.SuccessMessages[0].length == 0) {
1096						// No time slots, no date widget required
1097						ferve.log("ftd_eventDates(1) calling ferve.pricing.returnEventPricing()");
1098						ferve.pricing.returnEventPricing(itemHash, null, null, noCache);
1099						pricingLoading = true;
1100					}
1101				}
1102
1103				if (ferve.pricing.selectEventOnRender && document.querySelectorAll(".ft_ed_timeSlotRow#ft_e" + itemHash).length > 0 && !ferve.ftwp()) ferve.pricing.selectEventOnRender = false;
1104
1105				if (dates.indexOf("ft_ed_timeRowSelected") > -1) {
1106					// Event date pre-selected (not in past / cancelled)...
1107					x = eventDates.querySelector(".ft_ed_timeRowSelected");
1108					if (x) itemHash = x.id.replace("ft_e", "");
1109
1110				} else {
1111					x = document.getElementById("ft_e" + itemHash);
1112					if (x && x.classList.contains("ft_ed_timeRow")) {
1113						if (ferve.pricing.selectEventOnRender) {
1114							x.className = "ft_ed_timeRow ft_ed_timeRowSelected";
1115						} else {
1116							x.className = "ft_ed_timeRow";
1117						}
1118					}
1119				}
1120				var intro = eventDates.querySelector("[id='ft_ed_intro']");
1121				if (intro && x) x.style.display = "";
1122
1123				x = document.getElementsByName("ft_eventPricingRadio_" + itemHash);
1124				if (ferve.pricing.selectEventOnRender || x.length == 1) {
1125					ferve.pricing.selectEventOnRender = true;
1126					if (x.length == 1) ferve.eventHash = x[0].value;
1127					var noCache = Array.prototype.slice.call(x).filter(function (x) {
1128						return x.value == itemHash
1129					})[0]
1130					if (!noCache) noCache = eventDates.querySelector(".ft_ed_timeRowSelected");
1131					noCache = (noCache && noCache.dataset.nocache ? true : false);
1132
1133					var dateHash = null;
1134					if (ferve.ftwp()) {
1135						var t = document.querySelector(".ft_ed_timeSlotRow input[value='" + itemHash + "']");
1136						if (!t) t = document.querySelector(".ft_ed_timeSlotRow input");
1137						if (t) {
1138							dateHash = t.value;
1139							t.checked = true;
1140						} else {
1141							dateHash = itemHash;
1142						}
1143					}
1144
1145					if (!pricingLoading && ftReturn.SuccessMessages[0].indexOf("CANCELLED") == -1) {
1146						ferve.log("\n\nftd_eventDates(2) calling ferve.pricing.returnEventPricing\n\n");
1147						ferve.pricing.returnEventPricing(itemHash, dateHash, null, noCache);
1148						pricingLoading = true;
1149					}
1150
1151					if (x.length > 0 && x[0].parentNode.parentNode.dataset.media == "1" && eventDates.querySelector(".ft_ed_dateTime a").innerHTML.length == 0 && eventDates.querySelector(".ft_ed_venue a").innerHTML == "Online") {
1152						ferve.log("Only 1 date that is media");
1153						eventDates.style.display = "none";
1154					}
1155				}
1156
1157				// No event date
1158				if (x && x.length == 0 && intro) intro.style.display = "none";
1159
1160				for (var i = 0; i < x.length; i++) {
1161					if (x[i].value == itemHash) {
1162						x[i].checked = ferve.pricing.selectEventOnRender;
1163						if (ferve.pricing.selectEventOnRender) {
1164							if (intro) intro.style.display = "none";
1165						}
1166						break;
1167					}
1168				}
1169
1170				x = document.getElementById("ft_eventPricing");
1171				if (!x) x = document.getElementById("ft_eventPricing_" + itemHash);
1172				if (x) x.innerHTML = "";
1173
1174				ferve.pricing.selectEventOnRender = true;
1175
1176				ferve.renderWishlistStars();
1177
1178			}
1179			try {
1180				$("#ft_eventDates").trigger("create");
1181				$("#ft_eventDates_" + itemHash).trigger("create");
1182			}
1183			catch (e) { }
1184
1185			try {
1186				ft_eventDatesComplete();
1187				return;
1188			}
1189			catch (e) { }
1190		}
1191	};
1192
1193	ferve.pricing.returnEventTimes = function (itemHash, dateHash) {
1194		ferve.log("returnEventTimes(" + itemHash + ", " + dateHash + ")");
1195
1196		ferve.itemHash = itemHash;
1197		if (!initComplete) ferve.visitor.updatePropertiesFromCookie();
1198
1199		if (ferve.visitor.restricted) return ferve.pricing.restricted();
1200
1201		if (IE6) {
1202			var x = document.getElementById("ft_eventPricing");
1203			if (!x) x = document.getElementById("ft_eventPricing_" + itemHash);
1204			if (x) x.innerHTML = "";
1205			return;
1206		}
1207		if (ferve_cache) {
1208			ferve.xmlHttpRequest(ferve.url + "api/v1/Items/TimesCached?itemHash=" + dateHash + "&noCache=" + ferve_cache, "GET", null, "", "", "ftd_eventTimes('" + itemHash + "',");
1209		} else {
1210			ferve.xmlHttpRequest(ferve.url + "api/v1/Items/Times?hash=" + ferve.visitor.hash + "&itemHash=" + dateHash, "GET", null, "", "", "ftd_eventTimes('" + itemHash + "',");
1211		}
1212
1213
1214	};
1215	var ftd_eventTimes = function (itemHash, s) {
1216		ferve.log("ftd_eventTimes(" + itemHash + ")");
1217
1218		var ftReturn = ferve.parseFTReturn(s);
1219		if (!ftReturn) return;
1220
1221		if (!ftReturn.Success) {
1222			ferve.log("\n\n\n********** " + ftReturn.Errors[0].CustomerMessage + " **********\n\n\n", "error");
1223			var x = document.getElementById("ft_eventDates");
1224			if (!x) x = document.getElementById("ft_eventDates_" + itemHash);
1225			if (x) x.innerHTML = "Pricing is currently not available for this event";
1226			if (!x) {
1227				x = document.getElementById("ft_eventPricing");
1228				if (!x) x = document.getElementById("ft_eventPricing_" + itemHash);
1229				if (x) x.innerHTML = "Pricing is currently not available for this event.";
1230			}
1231
1232		} else {
1233
1234			var x = document.getElementById("ft_eventDates");
1235			if (!x) x = document.getElementById("ft_eventDates_" + itemHash);
1236			if (x) {
1237				x.innerHTML = ftReturn.SuccessMessages[0];
1238			} else {
1239				x = document.getElementById("ft_eventPricing");
1240				if (!x) x = document.getElementById("ft_eventPricing_" + itemHash);
1241				if (x) x.innerHTML = "Pricing is currently not available for this event.";
1242			}
1243
1244		}
1245	};
1246
1247	ferve.pricing.toggleEventTimes = function (itemHash) {
1248		ferve.log("toggleEventTimes(" + itemHash + ")");
1249
1250		if (typeof (ft_seating) != "undefined") {
1251			ft_seating.clear();
1252			ft_seating.statusReset(true, false);
1253		}
1254
1255		var eventTimeRows = document.getElementsByName("ft_ed_timeRow");
1256		for (var i = 0; i < eventTimeRows.length; i++) {
1257			if (eventTimeRows[i].id == "ft_e" + itemHash) {
1258				eventTimeRows[i].className = "ft_ed_timeRow ft_ed_timeRowSelected";
1259				eventTimeRows[i].style.height = "30px";
1260				eventTimeRows[i].style.marginTop = "0";
1261				var radio = eventTimeRows[i].querySelector("input");
1262				if (radio) radio.checked = true;
1263			} else {
1264				if (itemHash.length > 0) eventTimeRows[i].className = "ft_ed_timeRow";
1265			}
1266		}
1267
1268		var x = document.getElementById("ft_e" + itemHash);
1269		if (x) {
1270			x = x.parentNode;// ft_eventDates_
1271			var id = x.id;
1272			id = id.replace("ft_eventDates_", "");
1273			x = document.getElementById("ft_eventPricing_" + id);
1274		}
1275		var radios = document.getElementsByName("ft_eventPricingRadio_" + id);
1276		for (var i = 0, length = radios.length; i < length; i++) {
1277			if (radios[i].value == itemHash) {
1278				radios[i].checked = true;
1279			} else {
1280				radios[i].checked = false;
1281			}
1282		}
1283
1284		try {
1285			ft_eventTimes(itemHash);
1286		}
1287		catch (e) {
1288			if (e.message.indexOf("ft_eventTimes is not a function") == -1 && e.message.indexOf("ft_eventTimes is not defined") == -1 && e.message.indexOf("Can't find variable: ft_eventTimes") == -1) ferve.log("toggleEventTimes error(1): " + e.message, "error");
1289		}
1290	};
1291
1292	var ft_findPricingDiv = function (itemHash) {
1293		var x = (document.getElementById("ft_eventPricing") || document.getElementById("ft_eventPricing_" + itemHash));
1294		if (!x) {
1295			x = document.getElementById("ft_e" + itemHash);
1296			if (x) {
1297				x = x.parentNode;// ft_eventDates_
1298				var id = x.id;
1299				id = id.replace("ft_eventDates_", "");
1300				x = document.getElementById("ft_eventPricing_" + id);
1301			}
1302		}
1303		if (!x) x = document.getElementById("ft_eventPricing_" + ferve.itemHash);
1304		if (!x) x = document.querySelector("[id^='ft_eventPricing_']");//
1305		return x;
1306	};
1307
1308	ferve.pricing.returnEventPricing = function (itemHash, dateHash, seatHashes, noCache) {
1309		if (typeof noCache == "undefined") noCache = false;
1310		ferve.log("returnEventPricing(" + itemHash + ", " + dateHash + ", " + seatHashes + ", " + noCache + ")");
1311
1312		if (!initComplete || ferve.visitor.hash.length == 0) ferve.visitor.updatePropertiesFromCookie();
1313		if (ferve.visitor.restricted) return ferve.pricing.restricted();
1314		ferve.itemHash = itemHash;
1315		if (!seatHashes || ferve.isNullOrEmpty(seatHashes)) ferve.pricing.toggleEventTimes(itemHash);
1316		ft_validatedCodes.length = 0;
1317		if (!seatHashes || ferve.isNullOrEmpty(seatHashes)) seatHashes = "";
1318		var allocated = (!ferve.isNullOrEmpty(seatHashes));
1319
1320		if (!ferve_api && !ferve.ftwp() && ferve.pricing.eventDates) {
1321			try {
1322				ft_UpdateEventDetails(itemHash);
1323			}
1324			catch (e) {
1325				if (ferve_de && e.message.indexOf("ft_UpdateEventDetails is not a function") == -1 && e.message.indexOf("ft_UpdateEventDetails is not defined") == -1 && e.message.indexOf("Can't find variable: ft_UpdateEventDetails") == -1) {
1326					ferve.log("ferve.pricing.returnEventPricing error(]0): " + e.message, "error");
1327					debugger;
1328				}
1329			}
1330		}
1331
1332		if (dateHash) {
1333			var x = document.querySelector("input[name='ft_eventPricingRadio_times_" + itemHash + "'][value='" + dateHash + "']");
1334			if (!x) x = document.querySelector("input[name^='ft_eventPricingRadio_times_'][value='" + dateHash + "']");
1335			if (x) x.checked = true;
1336			noCache = true
1337
1338		} else {
1339			var timeSlots = document.querySelectorAll(".ft_ed_timeSlotRow");
1340			for (var i = 0; i < timeSlots.length; i++) {
1341				timeSlots[i].className = "ft_ed_timeSlotRow";
1342				timeSlots[i].querySelector("input[type=radio]").checked = false;
1343			}
1344
1345			timeSlots = document.querySelectorAll(".ft_ed_timeSlotRow#ft_e" + itemHash);
1346			if (timeSlots.length > 0) {
1347				for (var i = 0; i < timeSlots.length; i++) {
1348					timeSlots[i].className = "ft_ed_timeSlotRow ft_ed_timeSlotRowVisible";
1349				}
1350				var x = ft_findPricingDiv(itemHash);
1351				if (x) x.innerHTML = "";
1352				return;
1353			}
1354		}
1355
1356		if (!allocated) {
1357			var x = document.getElementById("ft_eventPricing");
1358			if (!x) x = document.getElementById("ft_eventPricing_" + itemHash);
1359			if (x) {
1360				if (ferve_cache) ferve_cache = (x.className.indexOf("ft_eventPricingNoCache") == -1);
1361				x.className = "ft_fade ft_itemHidden" + (x.className.indexOf("ft_eventPricingWithCheckout") > -1 ? " ft_eventPricingWithCheckout" : "");
1362			}
1363		}
1364
1365		if (ferve_cache && !noCache && !allocated) {
1366			ferve.xmlHttpRequest(ferve.url + "api/v1/Pricing/ListCached?itemHash=" + itemHash + "&dateHash=" + dateHash + "&app=" + ferve.isApp(), "GET", null, "", "", "ftd_eventPricing('" + itemHash + "','" + dateHash + "','" + seatHashes + "'," + noCache + ",");
1367		} else {
1368			if (seatHashes.length > 1000) {
1369				var data = JSON.stringify({ hash: ferve.visitor.hash, itemHash: itemHash, dateHash: dateHash, seatHashes: seatHashes });
1370				ferve.xmlHttpRequest(ferve.url + "api/v1/Pricing/ListSeats", "POST", data, "", "", "ftd_eventPricing('" + itemHash + "','" + dateHash + "','" + seatHashes + "'," + noCache + ",");
1371			} else {
1372				ferve.xmlHttpRequest(ferve.url + "api/v1/Pricing/List?hash=" + ferve.visitor.hash + "&itemHash=" + itemHash + "&dateHash=" + dateHash + (allocated ? "&seatHashes=" + seatHashes : ""), "GET", null, "", "", "ftd_eventPricing('" + itemHash + "','" + dateHash + "','" + seatHashes + "'," + noCache + ",");
1373			}
1374		}
1375	};
1376	var ftd_eventPricing = function (itemHash, dateHash, seatHashes, noCache, s) {
1377		ferve.log("ftd_eventPricing(" + itemHash + ", " + dateHash + ", " + seatHashes + ", " + noCache + ")");
1378		var ftReturn = ferve.parseFTReturn(s);
1379		var allocated = (!ferve.isNullOrEmpty(seatHashes));
1380
1381		if (!ftReturn) {
1382			var x = ft_findPricingDiv(itemHash);
1383			if (x) x.innerHTML = "There was an error loading the pricing, please reload the page.";
1384			x.className = "ft_fade ft_itemVisible";
1385			return;
1386		}
1387
1388		if (!ftReturn.Success) {
1389			if (ftReturn.Errors[0].CustomerMessage == "Invalid Hash.") {
1390				ferve.log("\n\n\n********** Invalid Hash. **********\n\n\n", "error");
1391				var url = document.URL;
1392				if (url.indexOf("rfc=") == -1) {
1393					url += (url.indexOf("?") == -1 ? "?" : "&");
1394					url += "rfc=1"
1395					document.location.href = url;
1396				}
1397			}
1398			try {
1399				ft_eventPricing((ferve.ftwp() ? ftReturn : ftReturn.Errors[0].CustomerMessage), allocated);
1400				return;
1401			}
1402			catch (e) {
1403				if (e.message.indexOf("ft_eventPricing is not a function") == -1 && e.message.indexOf("ft_eventPricing is not defined") == -1 && e.message.indexOf("Can't find variable: ft_eventPricing") == -1) ferve.log("ft_eventPricing error(1): " + e.message, "error");
1404
1405				if (allocated) {
1406					ft_seating.seatsBuyQtyChange();
1407					if (ftReturn.Errors[0].CustomerMessage.indexOf("SeatUnavailable") != -1) {
1408						ft_seating.seatsBuyError(ftReturn.Errors[0].CustomerMessage);
1409						return;
1410					}
1411				}
1412
1413				if (!noCache && ferve.visitor.loggedIn == "1" && ftReturn.Errors.some(er => er.CustomerMessage == "nocacheloggedin")) {
1414					ferve.log("ftd_eventPricing() Loading non-cached pricing (1)");
1415					ferve.pricing.returnEventPricing(itemHash, dateHash, seatHashes, true);
1416					return;
1417				}
1418				var x = ft_findPricingDiv(itemHash);
1419				if (x) x.innerHTML = ftReturn.Errors[0].CustomerMessage;
1420				if (x) x.className = "ft_fade ft_itemVisible" + (x.className.indexOf("ft_eventPricingWithCheckout") > -1 ? " ft_eventPricingWithCheckout" : "");
1421			}
1422		} else { // ftReturn.Success
1423			if (!noCache && ((ferve.visitor.loggedIn == "1" && ftReturn.SuccessMessages.indexOf("nocacheloggedin") != -1) || ftReturn.SuccessMessages.indexOf("nocache") != -1)) {
1424				ferve.log("ftd_eventPricing() Loading non-cached pricing (2)");
1425				ferve.pricing.returnEventPricing(itemHash, dateHash, seatHashes, true);
1426				return;
1427			}
1428
1429			if (!ferve_api && !ferve.ftwp() && ftReturn.SuccessMessages.indexOf("calendar") != -1) {
1430				ferve.log("ftd_eventPricing() Loading calendar");
1431				ferve.calendar.render(itemHash);
1432			}
1433
1434			if (s.indexOf("ft_ed_cal_times") > -1 || ftReturn.SuccessMessages[0] == "Tickets are no longer available to this time slot." || ftReturn.SuccessMessages[0].indexOf("CANCELLED") > -1) {
1435				var x = (document.getElementById("ft_eventDates") || document.getElementById("ft_eventDates_" + itemHash) || document.querySelector("[id^='ft_eventDates_']"));
1436				x = x.querySelector(".ft_ed_cal_times");
1437				if (!x) x = (document.getElementById("ft_eventDates") || document.getElementById("ft_eventDates_" + itemHash) || document.querySelector("[id^='ft_eventDates_']"));
1438				x = x.querySelectorAll(".ft_ed_timeSlotRow");
1439				if (x.length == 1) {
1440					ftReturn.SuccessMessages[0] = ftReturn.SuccessMessages[0].replace("Please note that this event has been cancelled.", "Please note that this day has been cancelled.")
1441				} else {
1442					ftReturn.SuccessMessages[0] = ftReturn.SuccessMessages[0].replace("Please note that this event has been cancelled.", "Please note that this time slot has been cancelled.")
1443				}
1444				// Time slots, update directly
1445				x = ft_findPricingDiv(itemHash);
1446				x.innerHTML = ftReturn.SuccessMessages[0];
1447				x.className = "ft_fade ft_itemVisible" + (x.className.indexOf("ft_eventPricingWithCheckout") > -1 ? " ft_eventPricingWithCheckout" : "");
1448
1449				try {
1450					ft_eventPricing((ferve.ftwp() ? ftReturn : ftReturn.SuccessMessages[0]), allocated);
1451				}
1452				catch (e) {
1453					// nothing
1454				}
1455				return;
1456			} else if (ftReturn.SuccessMessages[0].indexOf("ft_pricingForm") == -1 && !allocated) {
1457				var x = (document.getElementById("ft_eventDates") || document.getElementById("ft_eventDates_" + itemHash) || document.querySelector("[id^='ft_eventDates_']"));
1458				if (x) x = x.querySelector(".ft_ed_cal_times");
1459				//if (!x) x = (document.getElementById("ft_eventDates") || document.getElementById("ft_eventDates_" + itemHash) || document.querySelector("[id^='ft_eventDates_']"));
1460				if (x) x.innerHTML = "";
1461			}
1462
1463			if (!allocated && ferve_cache && ftReturn.SuccessMessages.length > 1) {
1464				var priceItems = ftReturn.SuccessMessages[ftReturn.SuccessMessages.length - 1];
1465				if (priceItems.indexOf("nocache") > -1) priceItems = ftReturn.SuccessMessages[ftReturn.SuccessMessages.length - 2];
1466				var pricesItem = JSON.parse(decodeURIComponent(escape(window.atob(priceItems))));
1467
1468				var pricing = document.createElement("div");
1469				pricing.innerHTML = ftReturn.SuccessMessages[0];
1470
1471				var element = pricing.querySelector(".ft_codesHeading");
1472				if (element && element.parentNode && ferve.visitor.loggedIn == "1" && ferve.visitor.ferveData) {
1473					for (var i = 0; i < ferve.visitor.ferveData.length; i++) {
1474						var html = ""
1475						var priceItems = pricesItem.filter(function (obj) { return obj.hash === ferve.visitor.ferveData[i].hash; });
1476						if (!priceItems || priceItems.length == 0) continue;
1477						for (var k = 0; k < priceItems.length; k++) {
1478							var priceItem = priceItems[k];
1479							html += "<div class=\"ft_ep_qty\"><select name=\"qty\" class=\"form-control\" data-itemhash=\"" + itemHash + "\" data-pricetypehash=\"" + priceItem.typeHash + "\" data-codehash=\"" + ferve.visitor.ferveData[i].codeHash + "\"><option value=\"0\">0</option>";
1480							for (var j = priceItem.min; j <= priceItem.max; j++) {
1481								html += "<option value=\"" + j + "\">" + j + "</option>";
1482							}
1483							html += "</select></div><div class=\"ft_ep_type\">" + priceItem.type + ": " + ferve.visitor.ferveData[i].code + "</div><div class=\"ft_ep_price\">" + priceItem.price + "<a href=\"Javascript:bookSeats('" + itemHash + "','" + priceItem.typeHash + "')\" class=\"ft_ep_alBuy\">( + )</a></div><div class=\"ft_clear\"></div>";
1484						}
1485
1486						var div = document.createElement("div");
1487						div.className = "ft_ep_priceRow";
1488						div.innerHTML = html;
1489						element.parentNode.insertBefore(div, element);
1490					}
1491				}
1492
1493				ftReturn.SuccessMessages[0] = pricing.innerHTML;
1494			}
1495
1496			if (ftReturn.Errors.length > 0) {
1497				// Event date widget contains same pricing error
1498				var x = (document.getElementById("ft_eventDates") || document.getElementById("ft_eventDates_" + itemHash) || document.querySelector("[id^='ft_eventDates_']"));
1499				if (x && ftReturn.Errors[0].CustomerMessage.length > 0 && ft_stripHtml(x.innerHTML, false).indexOf(ft_stripHtml(ftReturn.Errors[0].CustomerMessage, false)) > -1) {
1500					x.style.display = "none";
1501				}
1502			}
1503
1504
1505			// Upsells
1506			if (ftReturn.SuccessMessages[0].indexOf("ft_additions") > -1) {
1507				var pricing = document.createElement("div");
1508				pricing.innerHTML = ftReturn.SuccessMessages[0];
1509				var elements = pricing.querySelectorAll("select[data-membershiphash]:disabled");// upsell member items
1510				for (var i = 0; i < elements.length; i++) {
1511					if (ferve.visitor.loggedIn == "1" && ferve.visitor.ferveData && ferve.visitor.ferveData.filter(function (x) { return x.hash == elements[i].getAttribute("data-membershiphash"); }).length > 0) {
1512						elements[i].disabled = false;
1513					} else {
1514						elements[i].parentNode.parentNode.parentNode.removeChild(elements[i].parentNode.parentNode);
1515					}
1516				}
1517				ftReturn.SuccessMessages[0] = pricing.innerHTML;
1518			}
1519
1520			try {
1521				ft_eventPricing((ferve.ftwp() ? ftReturn : ftReturn.SuccessMessages[0]), allocated);
1522			}
1523			catch (e) {
1524				if (e.message.indexOf("ft_eventPricing is not a function") == -1 && e.message.indexOf("ft_eventPricing is not defined") == -1 && e.message.indexOf("Can't find variable: ft_eventPricing") == -1) ferve.log("ft_eventPricing error(2): " + e.message, "error");
1525
1526				if (allocated) {
1527					var x = document.getElementById("ft_pricingAllocated");
1528					x.innerHTML = ftReturn.SuccessMessages[0];
1529
1530					ft_seating.seatsBuyQtyChange();
1531
1532					var prices = x.querySelectorAll(".ft_ep_priceRow select[name=qty]");
1533					if (prices.length == 1) {
1534						// Pre-select desired quantity
1535						prices[0].lastElementChild.selected = true;
1536						var hashes = ft_seating.selectedSeats().map(s => s.hash).join(",");
1537						prices[0].setAttribute("data-seat-hashes", hashes);
1538						ferve.pricing.quantityChanged(prices[0]);
1539					}
1540
1541					if (ferve.isApp()) appInit();
1542
1543					var requiredPriceTypes = document.querySelectorAll("select[data-requiredpricetypehash]");
1544
1545					for (var i = 0; i < requiredPriceTypes.length; i++) {
1546						var hash = requiredPriceTypes[i].getAttribute("data-pricetypehash");
1547						var hashes = requiredPriceTypes[i].getAttribute("data-requiredpricetypehash").split("+");
1548
1549						for (var j = 0; j < hashes.length; j++) {
1550							var elements = document.querySelectorAll("select[data-pricetypehash='" + hashes[j] + "']");
1551							// The same price type hash on different price rows, pass redeem prices
1552
1553							for (var k = 0; k < elements.length; k++) {
1554								if (elements[k]) {
1555									elements[k].addEventListener("change", function (e) { ferve.pricing.priceTypeCheck(this, e); });
1556								}
1557							}
1558						}
1559					}
1560
1561					ft_loadCode(itemHash, true);
1562
1563					return;
1564				}
1565
1566				var x = ft_findPricingDiv(itemHash);
1567				if (x) x.innerHTML = ftReturn.SuccessMessages[0];
1568				if (x) x.className = "ft_fade ft_itemVisible" + (x.className.indexOf("ft_eventPricingWithCheckout") > -1 ? " ft_eventPricingWithCheckout" : "");
1569				x = document.getElementById("ft_ep_ft");
1570				if (x) { try { x.setAttribute("style", "display:block !important"); } catch (e) { } };
1571				eval("var f = document.ft_pricingForm_" + ferve.itemHash);
1572				if (!f && ftReturn.SuccessMessages[0].indexOf("<form") > -1) {
1573					// ft_eventPricing is within an already existing form, browser has stripped ft_pricingForm from content
1574					ferve.log("ft_eventPricing is within an already existing form", "warn");
1575					x = document.getElementById("ft_eventPricing");
1576					if (!x) x = document.getElementById("ft_eventPricing_" + ferve.itemHash);
1577					if (x) {
1578						var parent = x.parentNode;
1579						x.parentNode.removeChild(x);
1580						var div = document.createElement("div");
1581						div.id = "ft_eventPricing_" + ferve.itemHash;
1582						div.className = "ft_fade ft_itemVisible";
1583						div.innerHTML = ftReturn.SuccessMessages[0];
1584						var y = document.getElementById("ft_eventDates");
1585						if (!y) y = document.getElementById("ft_eventDates_" + ferve.itemHash);
1586						if (y) {
1587							if (y && y.parentNode) y.parentNode.insertBefore(div, y.nextSibling);
1588						} else {
1589							parent.appendChild(div);
1590						}
1591					}
1592				}
1593
1594				var dates = (document.getElementById("ft_eventDates") || document.getElementById("ft_eventDates_" + itemHash));
1595				if (dates && dates.querySelector(".ft_ed_cal_times")) {
1596					var offset = 35;
1597					var header = document.getElementById("ft_header");
1598					if (header) {
1599						offset += header.getBoundingClientRect().height;
1600					} else {
1601						try {
1602							header = document.querySelector("header");
1603							if (header && (header.style.position == "fixed" || header.style.position == "absolute")) offset += header.getBoundingClientRect().height;
1604						}
1605						catch (e) {
1606							debugger;
1607						}
1608					}
1609					x = ft_findPricingDiv(itemHash);
1610					var top = (x.getBoundingClientRect().top + window.pageYOffset - offset);
1611					window.scrollTo({ top: top, behavior: "smooth" });
1612				}
1613
1614				if (ftReturn.SuccessMessages[0].indexOf("[data-wishlist]" > -1)) ferve.renderWishlistStars();
1615			}
1616
1617			if (!allocated && document.getElementById("ft_rdo_seatingPlan")) {
1618				if (ferve.ftwp()) {
1619					setTimeout(function () {
1620						ferve.seating("ftd_eventPricing");
1621					}, 200);// Delay for text elements in raphael setting incorrect dy on tspan element as map not in DOM
1622				} else {
1623					ferve.seating("ftd_eventPricing");//11/9/20 !allocated
1624				}
1625			}
1626
1627			var geoblocks = document.querySelectorAll("select[data-geoblock]");
1628			if (geoblocks.length > 0 && !geoRegion) ft_visitorMediaCheck();
1629			for (var i = 0; i < geoblocks.length; i++) {
1630				geoblocks[i].addEventListener("change", function (e) { ferve.pricing.geoblock(this, e); });
1631			}
1632
1633			var requiredPriceTypes = document.querySelectorAll("select[data-requiredpricetypehash]");
1634
1635			for (var i = 0; i < requiredPriceTypes.length; i++) {
1636				var hash = requiredPriceTypes[i].getAttribute("data-pricetypehash");
1637				var hashes = requiredPriceTypes[i].getAttribute("data-requiredpricetypehash").split("+");
1638
1639				for (var j = 0; j < hashes.length; j++) {
1640					var elements = document.querySelectorAll("select[data-pricetypehash='" + hashes[j] + "']");
1641					// The same price type hash on different price rows, pass redeem prices
1642
1643					for (var k = 0; k < elements.length; k++) {
1644						if (elements[k]) {
1645							elements[k].addEventListener("change", function (e) { ferve.pricing.priceTypeCheck(this, e); });
1646						}
1647					}
1648				}
1649
1650				if (ferve.visitor.loggedIn == "1" || ferve.cart.count > 0) {
1651					ferve.xmlHttpRequest(ferve.url + "api/v1/Visitors/TicketQuantity?hash=" + ferve.visitor.hash + "&itemHash=" + escape(ferve.itemHash) + "&priceTypeHash=" + escape(hash), "GET", null, "", "", "ftd_priceTypeCheck('" + hash + "',");
1652				}
1653			}
1654
1655			ft_disableQuestionEnter();
1656
1657			if (document.getElementById("ft_recaptcha-container")) {
1658				var script = document.createElement("script");
1659				script.type = "text/javascript";
1660				script.src = "https://www.google.com/recaptcha/api.js?onload=recaptchaOnload&render=explicit";
1661				document.getElementsByTagName("head")[0].appendChild(script);
1662			}
1663
1664			ft_loadCode(itemHash, false);
1665
1666			var adobeAnalyticsCode = document.getElementById("ft_itemAdded");
1667			if (ferve.adobeAnalytics && adobeAnalyticsCode != null) adobeAnalytics();
1668		}
1669		try {
1670			ft_eventPricingComplete();
1671			return;
1672		}
1673		catch (e) { }
1674	};
1675
1676	var ft_loadCode = function (itemHash, allocated) {
1677		var code = ferve.utility.queryStringValue("code", "", true);
1678		if (code.length == 0) return;
1679
1680		var field = document.querySelector("form[name=ft_pricingForm_" + itemHash + "] input[name=code" + (allocated ? "_allocated" : "") + "]");
1681
1682		field.value = code;
1683		setTimeout(function () {
1684			ferve.pricing.validateCode(field, itemHash, allocated);
1685		}, 100);
1686	};
1687
1688	ferve.pricing.returnSeatPricing = function (itemHash, seatHash) {
1689		ferve.log("returnSeatPricing(" + itemHash + ", " + seatHash + ")");
1690
1691		if (!initComplete || ferve.visitor.hash.length == 0) ferve.visitor.updatePropertiesFromCookie();
1692		ferve.itemHash = itemHash;
1693		ft_validatedCodes.length = 0;
1694
1695		if (ferve_cache) {
1696			ferve.xmlHttpRequest(ferve.url + "api/v1/Pricing/ListCached?itemHash=" + itemHash + "&app=" + ferve.isApp() + "&seatHash=" + seatHash, "GET", null, "", "", "returnSeatPricing_delegate(");
1697		} else {
1698			ferve.xmlHttpRequest(ferve.url + "api/v1/Pricing/List?hash=" + ferve.visitor.hash + "&itemHash=" + itemHash + "&seatHash=" + seatHash, "GET", null, "", "", "returnSeatPricing_delegate(");
1699		}
1700	};
1701
1702	ferve.pricing.restricted = function () {
1703		if (ferve.visitor.restricted) {
1704			var x = document.getElementById("ft_eventDates");
1705			if (!x) x = document.getElementById("ft_eventDates_" + ferve.itemHash);
1706			if (x) x.innerHTML = "";
1707			x = document.getElementById("ft_eventPricing");
1708			if (!x) x = document.getElementById("ft_eventPricing_" + ferve.itemHash);
1709			if (x) x.innerHTML = "Purchasing from your region is restricted.";
1710			return;
1711		}
1712	};
1713
1714	ferve.pricing.pricingOk = function () {
1715		try {
1716			eval(String.fromCharCode(99, 97, 108, 108, 65, 112, 112) + "(\"PricingOk\")");
1717		}
1718		catch (e) { }
1719	};
1720
1721
1722	ferve.pricing.validateReset = function () {
1723		ft_validatedCodes.length = 0;
1724	};
1725
1726	ferve.pricing.qtyButton = function (label) {
1727		var id = label.htmlFor;
1728		var input = document.getElementById(id);
1729		if (!input) {
1730			ferve.log("ferve.pricing.qtyButton !input");
1731			return;
1732		}
1733
1734		var groupHash = input.getAttribute("data-grouphash");
1735		var other = (input.checked && input.value == "-1");
1736
1737		var checkboxes = document.querySelectorAll("input[data-grouphash]");
1738		for (var i = 0; i < checkboxes.length; i++) {
1739			if (checkboxes[i].getAttribute("data-grouphash") != groupHash) continue;
1740			if (checkboxes[i].value == input.value) {
1741				if (checkboxes[i].value == "-1" && !checkboxes[i].checked) other = true;
1742				if (checkboxes[i].value == "-1" && !checkboxes[i].checked) other = true;
1743			} else {
1744				checkboxes[i].checked = false;
1745			}
1746		}
1747
1748		var x = document.getElementById("ft_qtyOther_" + groupHash);
1749		if (!x) {
1750			return;
1751		}
1752		if (other) {
1753			x.className = x.className.replace("ft_itemHidden", "ft_itemVisible");
1754			x.focus();
1755		} else {
1756			x.className = x.className.replace("ft_itemVisible", "ft_itemHidden");
1757		}
1758	};
1759
1760
1761	ferve.pricing.codeKeyPress = function (field, e, itemHash) {
1762		if (ft_isEnterKey(field, e)) {
1763			if (field.name == "code") {
1764				ferve.pricing.validateCode(field, itemHash, false);
1765			} else if (field.name == "PaymentViewModel.CustomerVoucher.Code") {
1766				ft_codeValidate();
1767			}
1768			return false;
1769		} else {
1770			return true;
1771		}
1772	};
1773
1774	ferve.pricing.geoblock = function (field, e) {
1775		ferve.log("ferve.pricing.geoblock(" + field.selectedIndex + ")");
1776		if (field.selectedIndex == 0) return;
1777		var regions = field.getAttribute("data-geoblock");
1778		if (regions.length == 0) return;
1779		regions = window.atob(regions);
1780		regions = regions.split(", ");
1781		var region = window.atob(geoRegion).split(";");
1782		if (regions.indexOf(region[0]) == -1 && regions.indexOf(region[1]) == -1) ft_geoblocked(field, field.selectedIndex);
1783	};
1784	var ft_geoblocked = function (field, index) {
1785		field.selectedIndex = 0;
1786		ferve.notification.show("confirm", "red", "This stream is not available for play back in your current region. Are you sure you wish to continue?", function (s) { ftd_geoblocked(field, index, s) }, null, null);
1787	};
1788	var ftd_geoblocked = function (field, index, s) {
1789		field.selectedIndex = index;
1790	};
1791
1792	ferve.pricing.priceTypeCheck = function (field, e) {
1793		ferve.log("ferve.pricing.priceTypeCheck()");
1794		var hash = field.getAttribute("data-pricetypehash");
1795		var elements = document.querySelectorAll("select[data-requiredpricetypehash*='" + hash + "']");
1796
1797		for (var k = 0; k < elements.length; k++) {
1798			var quantity = 0;
1799			var element = elements[k];
1800			var hashes = element.getAttribute("data-requiredpricetypehash").split("+");
1801
1802			for (var i = 0; i < hashes.length; i++) {
1803				var x = document.querySelectorAll("select[data-pricetypehash='" + hashes[i] + "']");
1804				for (var j = 0; j < x.length; j++) {
1805					if (x[j]) quantity += parseInt(x[j].value);
1806				}
1807			}
1808
1809			if (quantity == 0) {
1810				element.value = 0;
1811				element.disabled = true;
1812				continue;
1813			}
1814
1815			var quantityAdd = element.getAttribute("data-requiredpricetypequantity");
1816			element.disabled = false;
1817			if (quantityAdd > 0) {
1818				quantityAdd = (quantity * quantityAdd);
1819				element.options.length = (quantityAdd + 1);
1820				for (var i = 0; i < element.options.length; i++) {
1821					element.options[i].value = i;
1822					element.options[i].text = i;
1823				}
1824			}
1825		}
1826	};
1827
1828	var ftd_priceTypeCheck = function (hash, s) {
1829		ferve.log("ftd_priceTypeCheck(" + hash + ", " + unescape(s) + ")");
1830		var ftReturn = ferve.parseFTReturn(s);
1831		if (!ftReturn || !ftReturn.Success) return;
1832
1833		var elements = document.querySelectorAll("select[data-pricetypehash='" + hash + "']");
1834
1835		elements.forEach(e => {
1836			var quantity = parseInt(ftReturn.SuccessMessages[0]);
1837			if (quantity > 0) {
1838				e.disabled = false;
1839				if (quantity > 20) quantity = 20;
1840				e.options.length = (quantity + 1);
1841				for (var i = 0; i < e.options.length; i++) {
1842					e.options[i].value = i;
1843					e.options[i].text = i;
1844				}
1845			}
1846		});
1847	};
1848
1849	ferve.pricing.membershipOption = function (hash, option) {
1850		ferve.log("ferve.pricing.membershipOption(" + hash + ", " + option + ")");
1851		if (option == "new") {
1852			var x = (document.querySelector("#ft_eventPricing_" + hash + " #ft_pricing") || document.querySelector("#ft_eventPricing #ft_pricing"));
1853			if (!x) {
1854				ferve.log("Can't find pricing div", "error");
1855				return;
1856			}
1857
1858			x.style.display = "block";
1859			ferve.pricing.pricingOk();
1860
1861		} else {
1862
1863			if (ferve.isApp()) {
1864				var x = (document.querySelector("#ft_eventPricing_" + hash + " #ft_pricing") || document.querySelector("#ft_eventPricing #ft_pricing"));
1865				if (x) x.style.display = "none";
1866
1867				// Not working
1868				alert("Please renew your membership on the ticketing site");
1869				document.location.href = "safari://https//" + document.location.host + "/Account/Login?returnurl=/Account/RenewMember";
1870			} else {
1871				ferve.utility.openLink("accountrenew", 0);
1872			}
1873		}
1874	}
1875
1876
1877	ferve.pricing.mediaConditions = function (hash) {
1878		if (ferve.isApp()) {
1879			document.location.href = ferve.url + "Page/Streaming-Restrictions/?hash=" + hash;
1880		} else {
1881			window.open(ferve.url + "Page/Streaming-Restrictions/?hash=" + hash, "_blank");
1882		} document.getElementById('ft_pricing').style.display = 'block'; ferve.pricing.pricingOk();
1883	};
1884
1885	ferve.pricing.mediaFAQs = function (hash) {
1886		window.open(ferve.url + "Page/Streaming-FAQ/", "_blank");
1887	}
1888
1889
1890	var ft_disableQuestionEnter = function () {
1891		// Prevent enter key from submitting the form on questions
1892		eval("var f = document.ft_pricingForm_" + ferve.itemHash);
1893		if (!f) return;
1894
1895		var parentSelector = f.querySelector("#ft_pricing"), allocated = (f.querySelector("input[name=ft_rdo_seatType]") != null && f.querySelector("input[name=ft_rdo_seatType]:checked"));
1896		if (allocated) parentSelector = f.querySelector("#ft_pricingAllocated");
1897		if (!parentSelector) return;
1898		var questions = parentSelector.querySelectorAll("[data-questionitemhash]");
1899		for (var i = 0; i < questions.length; i++) {
1900			if (questions[i].type == "text") {
1901				questions[i].onkeypress = function () {
1902					return ferve.pricing.codeKeyPress(this, event, ferve.itemHash);
1903				};
1904			}
1905		}
1906	};
1907
1908
1909	var ft_validatedCodes = new Array();
1910	var ft_validateCodeCount = 0;
1911	ferve.pricing.validateCode = function (field, itemHash, al) {
1912		ferve.log("ferve.pricing.validateCode(" + al + ")");
1913
1914		if (ft_validateCodeCount > 0) return;
1915		var type = "code";
1916		if (field.name == "membershipNo") {
1917			type = "membership number";
1918		} else if (field.name == "passNo") {
1919			type = "pass number";
1920		} else if (field.name == "discountCode") {
1921			type = "discount code";
1922		}
1923
1924		var fieldValue;
1925		if (field) {
1926			fieldValue = field.value.trim();
1927		} else {
1928			ferve.notification.show("local", "red", "Error validating your " + type + ".", null, field.getBoundingClientRect(), null);
1929			return;
1930		}
1931
1932		if (fieldValue.length == 0) {
1933			ferve.notification.show("local", "red", "Please enter a " + type + ".", null, field.getBoundingClientRect(), null);
1934			return;
1935		} else if (ft_validatedCodes.length > 0) {
1936			for (var i = 0; i < ft_validatedCodes.length; i++) {
1937				if (ft_validatedCodes[i] == fieldValue + "_" + itemHash) {
1938					ferve.notification.show("local", "red", "You have previously validated this " + type + ".", null, field.getBoundingClientRect(), null);
1939					return;
1940				}
1941			}
1942		}
1943
1944		// Allocated get selected seats (discount on price band)
1945		eval("var f = document.ft_pricingForm_" + itemHash);
1946		var allocated = f.querySelector("input[name=ft_rdo_seatType]:checked");
1947		var seatHashes = "";
1948		var parentHash = "";
1949		if (allocated) {
1950			if (typeof (ft_seating) != "undefined" && typeof ft_seating.selectedSeats == "function") {
1951				var seats = ft_seating.selectedSeats();
1952				for (var i = 0; i < seats.length; i++) {
1953					seatHashes += seats[i].hash + ",";
1954				}
1955				if (seatHashes.length > 1) seatHashes = seatHashes.substring(0, seatHashes.length - 1);
1956			}
1957		}
1958
1959		var btnCodeVal = f.querySelectorAll("[name=btnCodeVal]");
1960
1961		if (btnCodeVal.length > 0 && btnCodeVal[0].getAttribute("data-parentHash")) {
1962			parentHash = btnCodeVal[0].getAttribute("data-parentHash");
1963		}
1964
1965		// Prevent double click on validate code button
1966		if (btnCodeVal.length > 0) {
1967			ft_validateCodeCount++;
1968			btnCodeVal[0].disabled = true;
1969		}
1970
1971		var dateHash = ferve.pricing.dateHash(itemHash);
1972		var waitlistHash = (f.waitlistHash ? f.waitlistHash.value : "");
1973		ferve.xmlHttpRequest(ferve.url + "api/v1/Pricing/Code?hash=" + ferve.visitor.hash + "&itemHash=" + itemHash + "&dateHash=" + dateHash + "&code=" + escape(fieldValue) + (seatHashes != "" ? "&seatHashes=" + seatHashes : "") + (parentHash != "" ? "&parentHash=" + parentHash : "") + (waitlistHash != "" ? "&waitlistHash=" + waitlistHash : ""), "GET", null, "", "", "ftd_validateCode('" + field.name + "', '" + itemHash + "','" + type.substring(0, 2) + "','" + escape(fieldValue) + "',");
1974	};
1975
1976
1977
1978	var ftd_validateCode = function (fieldName, itemHash, t, code, s) {
1979		var ftReturn = ferve.parseFTReturn(s);
1980		if (!ftReturn) return;
1981
1982		if (!ftReturn.Success) {
1983			eval("var f = document.ft_pricingForm_" + itemHash);
1984			var x = f.querySelector("input[name=" + fieldName + "]");
1985			if (x) {
1986				x.focus();
1987				x.select();
1988			}
1989
1990			// Reset ft_validateCodeCount value
1991			var btnCodeVal = f.querySelectorAll("[name=btnCodeVal]");
1992			if (btnCodeVal.length > 0) {
1993				ft_validateCodeCount = 0;
1994				btnCodeVal[0].disabled = false;
1995			}
1996
1997			ferve.notification.show("notification", "red", ftReturn.Errors[0].CustomerMessage, null, null, null);
1998		} else {
1999
2000			ft_validatedCodes[ft_validatedCodes.length] = code + "_" + itemHash;
2001
2002			eval("var f = document.ft_pricingForm_" + itemHash);
2003
2004			// Reset ft_validateCodeCount value
2005			ft_validateCodeCount = 0;
2006			var btnCodeVal = f.querySelectorAll("[name=btnCodeVal]");
2007			if (btnCodeVal.length > 0) {
2008				btnCodeVal[0].disabled = false;
2009			}
2010
2011
2012			var allocated = (fieldName == "code_allocated");
2013			if (allocated) {
2014				var prices = document.querySelectorAll("#ft_pricingAllocated .ft_ep_priceRow select[name=qty]");
2015				if (prices.length == 1) {
2016					prices[0].selectedIndex = 0;
2017				}
2018			}
2019
2020			eval("var x = document.ft_pricingForm_" + itemHash + ".code" + (allocated ? "_allocated" : ""));
2021			if (x) x.value = "";
2022
2023
2024
2025			if (t == "me") {
2026				x = document.getElementById("ft_memRow_" + itemHash + (allocated ? "_allocated" : ""));
2027			} else if (t == "pa") {
2028				x = document.getElementById("ft_passRow_" + itemHash + (allocated ? "_allocated" : ""));
2029			} else if (t == "di") {
2030				x = document.getElementById("ft_dcRow_" + itemHash + (allocated ? "_allocated" : ""));
2031			} else {
2032				x = document.getElementById("ft_codeRow_" + itemHash + (allocated ? "_allocated" : ""));
2033			}
2034			if (x) {
2035				for (var i = 0; i < ftReturn.SuccessMessages.length; i++) {
2036					if (ftReturn.SuccessMessages[i].length == 0) continue;
2037					var div = document.createElement("div");
2038					div.innerHTML = ftReturn.SuccessMessages[i];
2039
2040					var elements = div.querySelectorAll("select[data-codehash]");
2041					for (var k = 0; k < elements.length; k++) {
2042						if (elements[k]) {
2043							elements[k].addEventListener("change", function (e) { ferve.pricing.priceTypeCheck(this, e); });
2044						}
2045					}
2046
2047					if (allocated && ftReturn.SuccessMessages.length == 1) {
2048						var q = div.querySelector(".ft_ep_priceRow select[name=qty]:enabled");
2049						if (document.querySelectorAll("#ft_pricingAllocated #ft_codesContainer .ft_ep_priceRow select[name=qty]").length == 0) {
2050							// Pre-select desired quantity
2051							var seats = ft_seating.selectedSeats().length;
2052							if (q && q.lastElementChild.value > seats) q.value = seats;
2053						} else {
2054							q.selectedIndex = 0;
2055						}
2056					}
2057
2058					if (typeof (ft_seating) != "undefined") div.onchange = ft_seating.seatsBuyQtyChange();
2059					x.parentNode.insertBefore(div, x.nextSibling);
2060
2061					// Fire onchange
2062					div.querySelector("select[data-codehash]").dispatchEvent(new Event("change"));
2063				}
2064			}
2065
2066			if (typeof (ft_seating) != "undefined") ft_seating.seatsBuyQtyChange();
2067
2068			if (ferve.ftwp()) {
2069				setTimeout(function () {
2070					eventButtonRow();
2071				}, 150);
2072			}
2073
2074			if (ferve.isApp()) {
2075				appInit();
2076			}
2077		}
2078	};
2079
2080	ferve.pricing.questionAnswers = null;
2081	ferve.pricing.quantityChanged = function (field) {
2082		var itemHash;
2083
2084		// If quanity field is disabled (i.e. Price start date set), don't show questions
2085		if (field.disabled) return;
2086
2087		if (typeof (field) == "string") {
2088			itemHash = field;
2089		} else {
2090			itemHash = field.getAttribute("data-itemhash");
2091		}
2092
2093		eval("var f = document.ft_pricingForm_" + itemHash);
2094
2095		var elements, parentSelector = f.querySelector("#ft_pricing");// parentSelector = document.getElementById("ft_pricing");
2096		var allocated = (f.querySelector("input[name=ft_rdo_seatType]") != null && f.querySelector("input[name=ft_rdo_seatType]:checked"));
2097		if (allocated) {
2098			if (allocated.value == "SeatingPlan") parentSelector = f.querySelector("#ft_pricingAllocated");
2099			elements = parentSelector.querySelectorAll("[name=qty]");
2100		} else {
2101			elements = f.elements;
2102		}
2103
2104		// Store previous answers
2105		ferve.pricing.questionAnswers = null;
2106		var questions = parentSelector.querySelectorAll("[data-questionitemhash]");
2107		if (questions.length > 0) {
2108			var questionAnswers = new Array();
2109			for (var i = 0; i < questions.length; i++) {
2110				var question = questions[i];
2111				var questionItemHash = question.getAttribute("data-questionitemhash");
2112
2113				var sequenceNumber = question.getAttribute("data-sequence");
2114				if (sequenceNumber == 0) continue;
2115
2116				var answer = "";
2117				var questionHash = question.id.split(".")[2];
2118				var priceTypeHash = question.getAttribute("data-questionpricetypehash");
2119
2120				if (question.type == "radio") {
2121					if (!question.checked) continue;
2122					answer = question.value;
2123
2124				} else if (question.type == "select-one") {
2125					answer = question[question.selectedIndex].value;
2126
2127				} else if (question.type == "checkbox") {
2128					if (question.checked) answer = question.value;
2129
2130				} else if (question.type != "radio") {
2131					answer = question.value;
2132				}
2133
2134				questionAnswers[questionAnswers.length] = new ferve.QuestionToAdd(questionHash, sequenceNumber, itemHash, priceTypeHash, answer);
2135			}
2136			if (questionAnswers.length > 0) ferve.pricing.questionAnswers = questionAnswers;
2137		}
2138
2139
2140		// Calculate quantity total (Ignore upsells && donation)
2141		var pricingQuestions = new Array();
2142
2143		for (var i = 0; i < elements.length; i++) {
2144
2145			// Exclude upsell items from retrieving questions from the parent event.
2146			if (elements[i].getAttribute("data-upsell") == "True") continue;
2147			if (elements[i].name != "qty" || elements[i].value == 0) continue;
2148			if (elements[i].type == "select-one") {
2149				if (String(elements[i].value).toLowerCase() === "other") continue;
2150				pricingQuestions[pricingQuestions.length] = new ferve.PricingQuestionDTO(elements[i].getAttribute("data-pricetypehash"), elements[i].value);
2151			} else if (elements[i].type == "number") {
2152				var v = parseInt(String(elements[i].value).trim(), 10);
2153				if (!isNaN(v) && v !== 0) {
2154					pricingQuestions[pricingQuestions.length] = new ferve.PricingQuestionDTO(elements[i].getAttribute("data-pricetypehash"), String(v));
2155				}
2156			}
2157		}
2158		// No ItemQuestions call until at least one line has a real qty (e.g. POS "Other" shows input at 0 — do not show questions yet).
2159		if (pricingQuestions.length === 0) {
2160			var allocatedFlag = (allocated && allocated.value == "SeatingPlan");
2161			var questionsHeader = parentSelector.querySelector("#ft_pricingQuestionsHeading" + (allocatedFlag ? "_allocated" : ""));
2162			var keepHeading = (questionsHeader != null && questionsHeader.getAttribute("keep-heading") === "True");
2163			if (!keepHeading) {
2164				ferve.toggleDisplay(parentSelector.querySelector("#ft_pricingQuestionsContainer" + (allocatedFlag ? "_allocated" : "")), "none", true);
2165				ferve.toggleDisplay(parentSelector.querySelector("#ft_pricingQuestionsHeading" + (allocatedFlag ? "_allocated" : "")), "none", true);
2166				ferve.toggleDisplay(parentSelector.querySelector("#ft_pricingQuestionsIntroduction" + (allocatedFlag ? "_allocated" : "")), "none", true);
2167			}
2168			ferve.setContent(parentSelector.querySelector("#ft_pricingQuestions" + (allocatedFlag ? "_allocated" : "")), "");
2169			try {
2170				ft_eventQuestionsComplete();
2171			}
2172			catch (e) { }
2173			return;
2174		}
2175
2176		var pricingQuestionsSerialized = JSON.stringify(pricingQuestions);
2177		ferve.log("\n\n\n\n\n\n" + pricingQuestionsSerialized + "\n\n\n\n\n\n");
2178
2179		ferve.toggleWaiting(true);
2180
2181		var dateHash = ferve.pricing.dateHash(itemHash);
2182
2183		ferve.xmlHttpRequest(ferve.url + "api/v1/Pricing/ItemQuestions?hash=" + ferve.visitor.hash + "&itemHash=" + itemHash + (ferve_api ? "&ftapi=1" : "") + "&waitlistHash=" + (f.waitlistHash ? f.waitlistHash.value : "-1") + "&dateHash=" + (dateHash ? dateHash : "-1"), "POST", pricingQuestionsSerialized, "", "", "ftd_quantityChanged('" + itemHash + "',");
2184	};
2185
2186	var ftd_quantityChanged = function (itemHash, s) {
2187		ferve.toggleWaiting(false);
2188
2189		var ftReturn = ferve.parseFTReturn(s);
2190		if (!ftReturn) return;
2191
2192		eval("var f = document.ft_pricingForm_" + itemHash);
2193
2194		var parentSelector = f.querySelector("#ft_pricing");// parentSelector = document.getElementById("ft_pricing");
2195
2196		if (!ftReturn.Success) {
2197			ferve.toggleWaiting(false);
2198			ferve.notification.show("notification", "red", ftReturn.Errors[0].CustomerMessage, null, null, null);
2199			var options = f.querySelectorAll("select");
2200			for (var i = 0; i < options.length; i++) {
2201				options[i].value = "0";
2202			}
2203			ferve.toggleDisplay(parentSelector.querySelector("#ft_pricingQuestionsContainer"), "none", true);
2204			ferve.toggleDisplay(parentSelector.querySelector("#ft_pricingQuestionsHeading"), "none", true);
2205			ferve.toggleDisplay(parentSelector.querySelector("#ft_pricingQuestionsIntroduction"), "none", true);
2206			ferve.setContent(parentSelector.querySelector("#ft_pricingQuestions"), "");
2207			return;
2208		}
2209
2210		var allocated = (f.querySelector("input[name=ft_rdo_seatType]") != null && f.querySelector("input[name=ft_rdo_seatType]:checked"));
2211
2212		if (allocated && allocated.value == "SeatingPlan") {
2213			allocated = true;
2214		} else {
2215			allocated = false;
2216		}
2217
2218		if (allocated) parentSelector = f.querySelector("#ft_pricingAllocated");
2219
2220		// check if keeping header is true
2221		var questionsHeader = parentSelector.querySelector("#ft_pricingQuestionsHeading" + (allocated ? "_allocated" : ""));
2222		var keepHeading = (questionsHeader != null && questionsHeader.getAttribute("keep-heading") === "True");
2223
2224		if (ftReturn.SuccessMessages.length == 0) {
2225			if (!keepHeading) {
2226				ferve.toggleDisplay(parentSelector.querySelector("#ft_pricingQuestionsContainer" + (allocated ? "_allocated" : "")), "n
2226one", true);
2227				ferve.toggleDisplay(parentSelector.querySelector("#ft_pricingQuestionsHeading" + (allocated ? "_allocated" : "")), "none", true);
2228				ferve.toggleDisplay(parentSelector.querySelector("#ft_pricingQuestionsIntroduction" + (allocated ? "_allocated" : "")), "none", true);
2229			}
2230		} else {
2231			ferve.toggleDisplay(parentSelector.querySelector("#ft_pricingQuestionsContainer" + (allocated ? "_allocated" : "")), "");
2232			ferve.toggleDisplay(parentSelector.querySelector("#ft_pricingQuestionsHeading" + (allocated ? "_allocated" : "")), "");
2233			ferve.toggleDisplay(parentSelector.querySelector("#ft_pricingQuestionsIntroduction" + (allocated ? "_allocated" : "")), "");
2234		}
2235		ferve.setContent(parentSelector.querySelector("#ft_pricingQuestions" + ((allocated) ? "_allocated" : "")), ftReturn.SuccessMessages.join(""));
2236
2237		ft_disableQuestionEnter();
2238
2239		// Restore previous answers, prevent enter key from submitting
2240		if (!ferve.pricing.questionAnswers) {
2241			try {
2242				ft_eventQuestionsComplete();
2243				return;
2244			}
2245			catch (e) { }
2246			return;
2247		}
2248		var questions = parentSelector.querySelectorAll("[data-questionitemhash]");
2249		if (questions.length == 0) return;
2250		for (var i = 0; i < questions.length; i++) {
2251			var question = questions[i];
2252			var questionItemHash = question.getAttribute("data-questionitemhash");
2253
2254			var sequenceNumber = question.getAttribute("data-sequence");
2255			if (sequenceNumber == 0) continue;
2256
2257			var questionHash = question.id.split(".")[2];
2258			var priceTypeHash = question.getAttribute("data-questionpricetypehash");
2259
2260			for (var j = 0; j < ferve.pricing.questionAnswers.length; j++) {
2261
2262				var answer = ferve.pricing.questionAnswers[j];
2263				if (questionHash != answer.QuestionHash || sequenceNumber != answer.SequenceNumber || questionItemHash != answer.ItemHash || priceTypeHash != answer.PriceTypeHash) continue;
2264
2265				if (question.type == "radio") {
2266					if (question.value != answer.Answer) continue;
2267					question.checked = true;
2268				} else if (question.type == "select-one") {
2269					for (var k = 0; k < question.length; k++) {
2270						if (question[k].value == answer.Answer) {
2271							question[k].selected = true;
2272							break;
2273						}
2274					}
2275				} else if (question.type == "checkbox") {
2276					if (question.value == answer.Answer) question.checked = true;
2277				}
2278				else if (question.type != "radio") {
2279					question.value = answer.Answer;
2280				}
2281			}
2282		}
2283
2284		try {
2285			ft_eventQuestionsComplete();
2286			return;
2287		}
2288		catch (e) { }
2289	};
2290
2291
2292	ferve.pricing.sectionChanged = function (itemHash, element) {
2293		ferve.log("ferve.pricing.sectionChanged(" + itemHash + ")");
2294		eval("var f = document.ft_pricingForm_" + itemHash);
2295		var allocated = f.querySelector("input[name=ft_rdo_seatType]:checked");
2296		if (allocated && (allocated.value == "BestAvailable" || allocated.value == "GeneralAdmission")) {
2297			ft_sectionChanged(itemHash, element);
2298		} else {//} else if (allocated && allocated.value != "GeneralAdmission") {
2299			// Choose your own adventure, no we mean seats
2300			ft_sectionChanged(itemHash, element);
2301			var seatingPlanHash = f.querySelector("input[name=ft_cs_section]:checked");
2302			seatingPlanHash = (seatingPlanHash ? seatingPlanHash.value : "NA");
2303			var dateHash = ferve.pricing.dateHash(itemHash);
2304			if (!dateHash || dateHash == "null" && document.getElementById("ft_modal-content")) {
2305				var url = Base64.decode($("#ft_modal-content").attr("data-url")).split("?")[1];
2306				dateHash = ferve.utility.queryStringValue("dateHash", url)
2307			}
2308
2309			if (seatingPlanHash != "NA") ft_seating.seatingPlanData(itemHash, dateHash, seatingPlanHash);
2310		}
2311
2312		for (var i = 0; i < f.elements.length; i++) {
2313			if (f.elements[i].name.substring(0, 3) == "qty" || (f.elements[i].name.length > 8 && f.elements[i].name.substring(0, 8) == "Question")) {
2314				if (f.elements[i].type == "select-one") {
2315					f.elements[i].selectedIndex = 0;
2316				} else if (f.elements[i].type == "checkbox") {
2317					f.elements[i].checked = false;
2318				} else if (f.elements[i].type == "radio") {
2319					if (f.elements[i].name.length > 8 && f.elements[i].name.substring(0, 8) == "Question" && f.elements[i].id.substr(-1) == "1") {
2320						f.elements[i].checked = true;
2321					} else {
2322						f.elements[i].checked = false;
2323					}
2324				} else if (f.elements[i].type == "text" || f.elements[i].type == "textarea") {
2325					f.elements[i].value = "";
2326					if (f.elements[i].name.substring(0, 8) == "qtyOther") f.elements[i].className = f.elements[i].className.replace("ft_itemVisible", "ft_itemHidden");
2327				}
2328			}
2329		}
2330	};
2331
2332	function ft_sectionChanged(itemHash, element) {
2333		ferve.log("ft_sectionChanged(" + itemHash + ")");
2334		eval("var f = document.ft_pricingForm_" + itemHash);
2335		if (!f) return;
2336
2337		var allocated = f.querySelector("input[name=ft_rdo_seatType]:checked").value;
2338		var pricingRows = f.querySelectorAll("[data-section], [data-seats]");
2339		var allocatedSections = f.querySelectorAll("#ft_allocated_generalAdmission [data-generaladmission]").length;
2340		if (!element) element = f.querySelector("input[name=ft_" + (allocated == "GeneralAdmission" ? "ga_" : "") + "section]:checked");
2341		var elementValue = (element ? element.value : "GA").replace(new RegExp(" ", "g"), "");
2342
2343		var sections = false;
2344		for (var i = 0; i < pricingRows.length; i++) {
2345			if (pricingRows[i].getAttribute("data-section") && pricingRows[i].getAttribute("data-section").length > 0) {
2346				sections = true;
2347				break;
2348			}
2349		}
2350
2351		for (var i = 0; i < pricingRows.length; i++) {
2352			var rowSection = pricingRows[i].getAttribute("data-section");
2353			var rowSeats = parseInt(pricingRows[i].getAttribute("data-seats"));
2354
2355			var show = 0;
2356			if (allocated == "BestAvailable" && (rowSeats == 0 || rowSeats == 2) && rowSection.length > 0 && elementValue == "ft-any") show = 1;
2357			if (allocated == "BestAvailable" && (rowSeats == 0 || rowSeats == 2) && elementValue.length > 0 && rowSection.indexOf(elementValue) > -1) show = 2;
2358			if (allocated == "BestAvailable" && (rowSeats == 0 || rowSeats == 2) && elementValue == "GA" && rowSection.length == 0) show = 3;
2359			if (allocated == "GeneralAdmission" && (rowSeats == 1 || rowSeats == 2) && allocatedSections > 0 && elementValue == "ft-any") show = 4;
2360			if (allocated == "GeneralAdmission" && allocatedSections > 1 && (rowSection.length == 0 || (elementValue.length > 0 && rowSection.indexOf(elementValue) > -1))) show = 5;
2361			if (allocated == "GeneralAdmission" && allocatedSections <= 1 && (rowSeats == 1 || rowSeats == 2)) show = 6;
2362			if (!sections) show = 7;
2363
2364			if (show > 0) {
2365				pricingRows[i].style.display = "";
2366			} else {
2367				pricingRows[i].style.display = "none";
2368			}
2369		}
2370
2371		if (ferve.ftwp() && allocated == "GeneralAdmission") eventButtonRow();
2372	};
2373
2374
2375	var addingToCart = false;
2376	ferve.pricing.addToCart = function (formHash) {
2377		ferve.log("ferve.pricing.addToCart(" + formHash + ")");
2378		if (addingToCart) return;
2379		addingToCart = true;
2380
2381		if (ferve.recaptcha() && grecaptcha.getResponse() == "") {
2382			ferve.notification.show("alert", "red", "Please complete the captcha.", null, null, null);
2383			addingToCart = false;
2384			return;
2385		}
2386
2387		var cartItemsToAdd = new Array();
2388		var SeatSources = { BestAvailable: 0, SeatingPlan: 1 };
2389
2390		var itemHash, dateHash, parentHash, quantity, priceTypeHash, discountHash, codeHash, seatingPlanHash, seatingPlanSection, seatHashes, seatSource = SeatSources[0], allocated, split, priceBandHash, generalAdmission, waitlistHash, payWhatYouWant = [], memberCodeHash;
2391
2392		eval("var f = document.ft_pricingForm_" + formHash);
2393		if (!f) eval("var f = document.ft_pricingForm_" + ferve.itemHash);
2394		if (!f) f = document.ft_pricingForm;
2395		var elements, parentSelector = f.querySelector("#ft_pricing");// parentSelector = document.getElementById("ft_pricing");
2396		var allocated = f.querySelector("input[name=ft_rdo_seatType]:checked");
2397		if (allocated) {
2398			if (allocated.value == "SeatingPlan") parentSelector = f.querySelector("#ft_pricingAllocated");
2399			elements = parentSelector.querySelectorAll("[name='qty']");
2400		} else {
2401			elements = f.elements;
2402		}
2403
2404		// Membership Renew
2405		var memRenew = "";
2406		var pt = document.getElementsByName("ft_rdo_memRenew");
2407		if (!ferve.isNullOrEmpty(pt)) {
2408			for (var i = 0; i < pt.length; i++) {
2409				if (pt[i].checked) {
2410					if (pt[i].id == "new") {
2411						pt = null;
2412						break;
2413					}
2414					memRenew = pt[i].value;
2415					break;
2416				}
2417			}
2418			if (pt && memRenew == "") {
2419				ferve.notification.show("alert", "red", "Please select a membership number to renew.", null, null, null);
2420				addingToCart = false;
2421				return;
2422			}
2423		}
2424
2425		for (var i = 0; i < elements.length; i++) {
2426			if (elements[i].name == "qty" && elements[i].value != 0) {
2427				if ((elements[i].type == "radio" || elements[i].type == "checkbox") && !elements[i].checked) continue;
2428
2429				itemHash = elements[i].getAttribute("data-itemhash");
2430				parentHash = elements[i].getAttribute("data-parenthash");
2431				quantity = elements[i].value;
2432				var groupHash = elements[i].getAttribute("data-grouphash");
2433				payWhatYouWant = [];
2434
2435				if (elements[i].type == "radio" || elements[i].type == "checkbox") {
2436					if (quantity == "-1") {
2437						var x = document.getElementById("ft_qtyOther_" + groupHash);
2438						quantity = ferve.getFloat(x.value);
2439						if (!ferve.isNumeric(quantity)) {
2440							ferve.notification.show("notification", "red", "Amount is invali
2440d.", null, null, null);
2441							addingToCart = false;
2442							if (ferve.isApp()) callApp("PricingError");
2443							return;
2444						}
2445					}
2446					quantity = parseInt(Math.round(quantity * 100));
2447				}
2448				priceTypeHash = elements[i].getAttribute("data-pricetypehash");
2449
2450				discountHash = elements[i].getAttribute("data-discountHash");
2451				codeHash = elements[i].getAttribute("data-codehash");
2452				if (memRenew && memRenew != "") {
2453					if (elements[i].getAttribute("data-upsell") == "False") {
2454						memberCodeHash = memRenew;
2455					}
2456
2457				}
2458				if (f.seatingPlanHash) seatingPlanHash = f.seatingPlanHash.value
2459				if (allocated && allocated.value == "BestAvailable") seatingPlanSection = f.querySelector("input[name=ft_section]:checked");
2460				if (seatingPlanSection && typeof (seatingPlanSection) == "object") seatingPlanSection = seatingPlanSection.value;
2461				seatHashes = elements[i].dataset.seatHashes;
2462				seatSource = 0;
2463				allocated = false;
2464				split = false;
2465				priceBandHash = elements[i].getAttribute("data-pricebandhash");
2466				generalAdmission = false;
2467				var radios = f.querySelectorAll("input[name='ft_rdo_seatType']");
2468				if (radios.length > 0) allocated = true;
2469				for (var j = 0; j < radios.length; j++) {
2470					if (radios[j].checked) {
2471						if (radios[j].value == "GeneralAdmission") {
2472							seatSource = 0;
2473							generalAdmission = true;
2474							// GA has priceband, so should not empty it
2475							//priceBandHash = "";
2476							seatingPlanSection = f.querySelector("input[name=ft_ga_section]:checked");
2477							if (seatingPlanSection && typeof (seatingPlanSection) == "object") seatingPlanSection = seatingPlanSection.value;
2478
2479						} else if (radios[j].value == "SeatingPlan") {
2480							seatSource = SeatSources.SeatingPlan;
2481						}
2482						break;
2483					}
2484				}
2485				if (allocated) {
2486					if (f.splitSeats) split = !f.splitSeats.checked;
2487				}
2488				waitlistHash = (f.waitlistHash ? f.waitlistHash.value : "");
2489				if (elements[i].getAttribute("data-pwyw")) {
2490					payWhatYouWant[payWhatYouWant.length] = elements[i].getAttribute("data-pwyw");
2491					var pwyw = elements[i].parentNode.parentNode.querySelector(".ft_ep_price input");
2492					if (!ferve.isNumeric(pwyw.value)) {
2493						ferve.notification.show("notification", "red", "Pay what you want amount is invalid.", null, null, null);
2494						addingToCart = false;
2495						pwyw.focus();
2496						if (ferve.isApp()) callApp("PricingError");
2497						return;
2498					} else if (elements[i].getAttribute("data-pwyw-min") && ferve.getFloat(pwyw.value) < ferve.getFloat(elements[i].getAttribute("data-pwyw-min"))) {
2499						ferve.notification.show("notification", "red", "Pay what you want minimum amount is " + ferve.formatMoney(elements[i].getAttribute("data-pwyw-min"), 2) + ".", null, null, null);
2500						addingToCart = false;
2501						pwyw.focus();
2502						if (ferve.isApp()) callApp("PricingError");
2503						return;
2504					}
2505					payWhatYouWant[payWhatYouWant.length] = pwyw.value;
2506				}
2507				holds = elements[i].getAttribute("data-holds");
2508
2509				var x = (document.getElementById("ft_eventDates") || document.getElementById("ft_eventDates_" + itemHash) || document.querySelector("[id^='ft_eventDates_']"));
2510				if (x) {
2511					var date = x.querySelector("input[name='ft_eventPricingRadio_times_" + itemHash + "']:checked");
2512					if (!date && !ferve.isNullOrEmpty(parentHash)) date = x.querySelector("input[name^='ft_eventPricingRadio_times_']:checked");
2513					if (date) dateHash = date.value;
2514					if (!date) date = elements[i].getAttribute("data-parentdatehash");
2515					if (!date && ferve.ftwp() && typeof (parentEvenDateHash) != "undefined") dateHash = parentEvenDateHash;
2516				}
2517
2518				cartItemToAdd = new ferve.CartItemToAdd(itemHash, dateHash, parentHash, quantity, priceTypeHash, discountHash, codeHash, seatingPlanHash, seatingPlanSection, seatHashes, seatSource, allocated, split, priceBandHash, generalAdmission, waitlistHash, payWhatYouWant, holds, memberCodeHash);
2519				ferve.log(cartItemToAdd);
2520
2521
2522				// Questions (Not if upsell item)
2523				var questionAnswersToAdd = new Array();
2524				if (formHash == itemHash && parentSelector && ((!groupHash || groupHash.length == 0) || (elements[i].type == "radio" || elements[i].type == "checkbox"))) {
2525					var questions = parentSelector.querySelectorAll("[data-questionitemhash]");
2526
2527					for (var j = 0; j < questions.length; j++) {
2528						var question = questions[j];
2529						if (question.type == "radio" && !question.required && !question.checked) continue;
2530
2531						var questionItemHash = question.getAttribute("data-questionitemhash");
2532						if (questionItemHash != formHash) continue;
2533						var questionPriceTypeHash = question.getAttribute("data-questionpricetypehash");
2534						if (questionPriceTypeHash && priceTypeHash != questionPriceTypeHash) continue;
2535
2536						var questionHash = question.id.split(".")[2];
2537						var sequenceNumber = question.getAttribute("data-sequence");
2538
2539						var answer = "";
2540						var checkboxOK = false;
2541						var radioBtnSelected = "";
2542
2543						if (question.type == "radio") {
2544							if (!question.required && !question.checked) continue;
2545							//Check if there is one answer selected
2546							var radioBtnChoices = parentSelector.querySelectorAll('input[name="' + question.name + '"]');
2547							for (var k = 0; k < radioBtnChoices.length; k++) {
2548								if (radioBtnChoices[k].checked) {
2549									radioBtnSelected = radioBtnChoices[k].value;
2550									break;
2551								}
2552							}
2553							if (question.checked) answer = question.value;
2554
2555						} else if (question.type == "select-one") {
2556							answer = question[question.selectedIndex].value;
2557
2558						} else if (question.type == "checkbox") {
2559							// Check if there at least one selected
2560							var checkboxes = parentSelector.querySelectorAll('input[name="' + question.name + '"]');
2561							for (var k = 0; k < checkboxes.length; k++) {
2562								if (checkboxes[k].checked) {
2563									checkboxOK = true;
2564									break;
2565								}
2566							}
2567
2568							if (question.checked) answer = question.value;
2569
2570						} else if (question.type != "radio") {
2571							answer = question.value;
2572						}
2573
2574						if ((question.type != "checkbox" && question.type != "radio" && question.required && answer && answer.replace(/\s/g, '').length == 0) || (question.type == "checkbox" && question.required && !checkboxOK) || (question.type == "radio" && question.required && radioBtnSelected == "")) {
2575							var label = document.getElementById(questionHash + "Label");
2576							// Regex to replace HTML tag with empty string "".
2577							var regex = /(<([^>]+)>)/ig
2578							ferve.notification.show("alert", "red", label.innerHTML.replace(regex, "") + " is a required field.", null, null, null);
2579							addingToCart = false;
2580							if (ferve.isApp()) callApp("PricingError");
2581							return;
2582
2583						}
2584
2585						if (answer.indexOf(">") >= 0) {
2586							var label = document.getElementById(questionHash + "Label");
2587							ferve.notification.show("alert", "red", "Invalid characters were found in field " + label.innerHTML, null, null, null);
2588							addingToCart = false;
2589							if (ferve.isApp()) callApp("PricingError");
2590							return;
2591						}
2592
2593						// return all if (answer.length > 0)
2594						questionAnswersToAdd[questionAnswersToAdd.length] = new ferve.QuestionToAdd(questionHash, sequenceNumber, itemHash, questionPriceTypeHash, answer);
2595					}
2596				}// grouphash
2597				cartItemToAdd.QuestionAnswersToAdd = questionAnswersToAdd;
2598
2599				cartItemsToAdd[cartItemsToAdd.length] = cartItemToAdd;
2600			}
2601		}
2602
2603		if (cartItemsToAdd.length == 0) {
2604			addingToCart = false;
2605			if (ferve.isApp()) {
2606				if (ferve.isApp("iOS")) {
2607					callApp("PricingError/Nothing to add to your cart, please select a ticket type.");
2608					return;
2609				} else {
2610					callApp("PricingError");
2611				}
2612			}
2613			ferve.notification.show("notification", "red", "Nothing to add to your cart, please select a quantity.", null, null, null);
2614			return;
2615		}
2616
2617		ferve.toggleWaiting(true);
2618
2619		var cartItemsToAddSerialized = JSON.stringify(cartItemsToAdd);
2620
2621		var x = document.getElementById("ft_purchase")
2622		if (x) {
2623			hideHoverElements(5);
2624		}
2625
2626		ferve.xmlHttpRequest(ferve.url + "api/v1/Cart/Add?hash=" + ferve.visitor.hash, "POST", cartItemsToAddSerialized, "", "", "ftd_cartAction('" + formHash + "',");
2627	};
2628
2629	ferve.pricing.addSeatsToCart = function (itemHash, priceTypeHash, codeHash, seatHashes) {
2630		debugger;// NOT USED?
2631		if (addingToCart) return;
2632		addingToCart = true;
2633
2634		var cartItemsToAdd = new Array();
2635		var seatingPlanHash = "";
2636		var seatingPlanSection = "";
2637		var seatSource = "SeatingPlan";
2638		var quantity = seatHashes.split(",").length;
2639		cartItemsToAdd[cartItemsToAdd.length] = new ferve.CartItemToAdd(itemHash, null, "", quantity, priceTypeHash, "", codeHash, seatingPlanHash, seatingPlanSection, seatHashes, seatSource, false, "", false, false, null, null);
2640		var cartItemsToAddSerialized = JSON.stringify(cartItemsToAdd);
2641
2642		ferve.xmlHttpRequest(ferve.url + "api/v1/Cart/Add?hash=" + ferve.visitor.hash, "POST", cartItemsToAddSerialized, "", "", "ftd_cartAction('" + itemHash + "',");
2643	};
2644
2645	ferve.pricing.addPackage = function (packageHash) {
2646		if (addingToCart) return;
2647		addingToCart = true;
2648
2649		ferve.xmlHttpRequest(ferve.url + "api/v1/Cart/AddPackage?hash=" + ferve.visitor.hash + "&packageHash=" + packageHash, "GET", null, "", "", "ftd_cartAction('AP',");
2650	};
2651
2652
2653	ferve.pricing.allocatedSeating = function (formHash, mode) {
2654		ferve.log("ferve.pricing.allocatedSeating(" + formHash + "," + mode + ")");
2655		if (ferve.isNullOrEmpty(formHash)) return;
2656
2657		ft_sectionChanged(formHash, null);
2658
2659		var container = document.getElementById("ft_eventPricing_" + formHash);
2660		if (!container) container = document.getElementById("ft_eventPricing");
2661		if (!container) container = document.querySelector("form[name='ft_pricingForm_" + formHash);
2662		if (!container) container = document.querySelector("div[id^='ft_eventPricing'");
2663
2664
2665		var allocated = container.querySelector("#ft_allocated");
2666		var ft_pricing = container.querySelector("#ft_pricing");
2667		var btnSubmit = container.querySelector("button[name='btnSubmit'");
2668
2669		var allocatedToggle = (ferve.ftwp() ? document.getElementById("ft_eventAllocatedToggle") : null);
2670		if (allocatedToggle) allocatedToggle.style.display = "none";
2671
2672		if (!ferve.isNullOrEmpty(mode) && mode != "split") {
2673			var radios = container.querySelectorAll("input[name='ft_rdo_seatType']");
2674			for (var i = 0; i < radios.length; i++) {
2675				radios[i].checked = (radios[i].value == mode);
2676			}
2677			radios = container.querySelectorAll("input[name='ft_rdo_seatTypeDisplay']");
2678			for (var i = 0; i < radios.length; i++) {
2679				radios[i].checked = (radios[i].value == mode);
2680			}
2681		}
2682
2683		if (mode == "BestAvailable") {
2684			allocated.className = "ft_bestAvailable";
2685			ft_pricing.style.display = "block";
2686			ft_seating.seatsBuyCancel();
2687
2688			eval("var f = document.ft_pricingForm_" + formHash);
2689			var radio = container.querySelector("input[name=section]:checked");
2690			ferve.pricing.sectionChanged(formHash, radio);
2691			if (ferve.isApp()) callApp("PricingAdd");
2692
2693
2694		} else if (mode == "SeatingPlan") {
2695			allocated.className = "ft_seatingPlan";
2696			ft_pricing.style.display = "none";
2697			if (allocatedToggle) allocatedToggle.style.display = "block";
2698
2699			ft_seatingReady = function (source) {
2700				ferve.log("++ ft_seatingReady(" + source + ") ++");
2701				ft_seating.touch(true);
2702				ft_seating.status();
2703				ft_seating.updateSelected();
2704				if (ft_seating.version() == 2) {
2705					toggleOverlay(1, true);
2706					document.body.setAttribute("data-ft_seating-2", "open");
2707				}
2708			};
2709			if (typeof ft_seating != "undefined" && ft_seating.ready()) {
2710				ft_seatingReady("ferve.pricing.allocatedSeating");
2711				ft_seatingReady = null;
2712			}
2713			if (ferve.isApp()) callApp("PricingNoAdd");
2714
2715
2716
2717
2718		} else if (mode == "GeneralAdmission") {
2719			allocated.className = "ft_generalAdmission";
2720			ft_pricing.style.display = "block";
2721			if (btnSubmit) btnSubmit.value = "Add to Cart";
2722			ferve.pricing.sectionChanged(formHash, null);
2723			ft_seating.seatsBuyCancel();
2724			if (ferve.isApp()) callApp("PricingAdd");
2725
2726		} else if (mode == "split") {
2727			var splitSeats = container.querySelector("#splitSeats");
2728			if (!splitSeats.checked && !confirm("Are you sure?\n\nSplitting seats may result in seats that are not next to each other.")) {
2729				return false;
2730			}
2731		} else if (allocatedToggle && container.querySelector("input#ft_rdo_seatingPlan:checked")) {
2732			allocatedToggle.style.display = "block";
2733		}
2734
2735		try {
2736			updateButtons(mode);
2737		}
2738		catch (e) { }
2739	};
2740
2741	ferve.pricing.destroy = function (itemHash) {
2742		ferve.log("ferve.pricing.destroy(" + itemHash + ")");
2743
2744		try {
2745			allocatedseatingSetup = false;
2746
2747			if (ft_seating) ft_seating.destroy();
2748
2749			var x = ft_findPricingDiv(itemHash);
2750			if (x) x.innerHTML = "<!-- Nothing to see here -->";
2751		}
2752		catch (e) {
2753			console.warn(e.message);
2754			debugger;
2755		}
2756	};
2757
2758
2759	ferve.pricing.addToWaitlist = function (formHash, dateHash) {
2760		ferve.log("ferve.pricing.addToWaitlist(" + formHash + ", " + dateHash + ")");
2761
2762		eval("var f = document.ft_pricingForm_" + formHash);
2763
2764		var questionAnswersToAdd = new Array();
2765		var questions = f.querySelectorAll("[data-questionitemhash]");
2766		var parentSelector = document.querySelector(".ft_pricing");
2767
2768		for (var j = 0; j < questions.length; j++) {
2769			var question = questions[j];
2770			if (question.type == "radio" && !question.checked) continue;
2771
2772			var questionItemHash = question.getAttribute("data-questionitemhash");
2773			if (questionItemHash != formHash) continue;
2774			var questionPriceTypeHash = question.getAttribute("data-questionpricetypehash");
2775			if (questionPriceTypeHash && priceTypeHash != questionPriceTypeHash) continue;
2776
2777			var questionHash = question.id.split(".")[2];
2778			var sequenceNumber = question.getAttribute("data-sequence");
2779			var checkboxOK = false;
2780
2781			var answer = "";
2782
2783			if (question.type == "radio") {
2784				if (!question.checked) continue;
2785				if (question.checked) answer = question.value;
2786
2787			} else if (question.type == "select-one") {
2788				answer = question[question.selectedIndex].value;
2789
2790			} else if (question.type == "checkbox") {
2791
2792				// Check if there at least one selected
2793				var checkboxes = parentSelector.querySelectorAll('input[name="' + question.name + '"]');
2794				for (var k = 0; k < checkboxes.length; k++) {
2795					ferve.log("checkboxes" + k + ": " + checkboxes[k].checked);
2796					if (checkboxes[k].checked) {
2797						checkboxOK = true;
2798						break;
2799					}
2800				}
2801				if (question.checked) answer = question.value;
2802
2803			}
2804			else if (question.type != "radio") {
2805				answer = question.value;
2806			}
2807
2808			if ((question.type != "checkbox" && question.required && answer.length == 0) || (question.type == "checkbox" && question.required && !checkboxOK)) {
2809				var label = document.getElementById(questionHash + "Label");
2810				ferve.notification.show("alert", "red", label.innerHTML + " is a required field.", null, null, null);
2811				addingToCart = false;
2812				if (ferve.isApp()) callApp("PricingError");
2813				return;
2814			}
2815
2816			if (question.type == "email" && answer.length > 0 && !ferve.isEmail(answer)) {
2817
2818				var label = document.getElementById(questionHash + "Label");
2819				ferve.notification.show("alert", "red", answer + " is not a valid e-mail address.", null, null, null);
2820				addingToCart = false;
2821				if (ferve.isApp()) callApp("PricingError");
2822				return;
2823			}
2824
2825			if (answer.indexOf(">") >= 0) {
2826				var label = document.getElementById(questionHash + "Label");
2827				ferve.notification.show("alert", "red", "Invalid characters were found in field " + label.innerHTML, null, null, null);
2828				addingToCart = false;
2829				if (ferve.isApp()) callApp("PricingError");
2830				return;
2831			}
2832
2833			// return all if (answer.length > 0)
2834			questionAnswersToAdd[questionAnswersToAdd.length] = new ferve.QuestionToAdd(questionHash, sequenceNumber, formHash, "", answer);
2835		}
2836
2837		if (questionAnswersToAdd.length == 0) return;
2838
2839		ferve.toggleWaiting(true);
2840
2841		var questionAnswersToAddSerialized = JSON.stringify(questionAnswersToAdd);
2842
2843		ferve.xmlHttpRequest(ferve.url + "api/v1/Items/Waitlist?hash=" + ferve.visitor.hash + (!ferve.isNullOrEmpty(dateHash) ? "&dateHash=" + dateHash : ""), "POST", questionAnswersToAddSerialized, "", "", "ftd_waitlist('" + formHash + "',");
2844	};
2845
2846	var ftd_waitlist = function (formhash, s) {
2847		ferve.toggleWaiting(false);
2848
2849		var ftReturn = ferve.parseFTReturn(s);
2850		if (!ftReturn) return;
2851
2852		if (!ftReturn.Success) {
2853			ferve.notification.show("notification", "red", ftReturn.Errors[0].CustomerMessage, null, null, null);
2854		} else {
2855			var x = document.getElementById("ft_waitlist");
2856			if (x) x.innerHTML = "<div class=\"ft_waitlistMessage\">" + ftReturn.SuccessMessages[0] + "</div>";
2857		}
2858	};
2859
2860	ferve.pricing.quantityTotal = function (formHash) {
2861		eval("var f = document.ft_pricingForm_" + formHash);
2862		if (!f) return 0;
2863		var total = 0;
2864		for (var i = 0; i < f.elements.length; i++) {
2865			var quantity = 0;
2866			if (f.elements[i].type == "radio" && f.elements[i].checked && f.elements[i].name.substring(0, 3) == "qty") {
2867				quantity = parseInt(f.elements[i].value.split("_")[0]);
2868			} else if ((f.elements[i].type == "checkbox" || f.elements[i].type == "radio") && f.elements[i].checked && f.elements[i].name != "ft_rdo_memRenew" && f.elements[i].name != "ft_section" && f.elements[i].name != "ft_cs_section" && f.elements[i].name.substring(0, 13) != "ft_ga_section") {
2869				quantity = parseInt(f.elements[i].value);
2870			} else if (f.elements[i].type != "radio") {
2871				if (f.elements[i].name.substring(0, 3) == "qty" && f.elements[i].type == "select-one") {
2872					quantity = (String(f.elements[i].value).toLowerCase() === "other") ? 0 : parseInt(f.elements[i].value, 10);
2873				} else if (f.elements[i].name == "qty" && f.elements[i].type == "number") {
2874					quantity = parseInt(String(f.elements[i].value).trim(), 10);
2875				} else if (f.elements[i].name == "serialNoQTY" && f.elements[i + 1].value.length > 0) {
2876					quantity = parseInt(f.elements[i].value);
2877				}
2878			}
2879
2880			if (ferve.isNumeric(quantity)) total += quantity;
2881		}
2882		return total;
2883	};
2884
2885	ferve.pricing.openSeatingPlan = function (itemHash, spi) {
2886		eval("var f = document.ft_pricingForm_" + itemHash);
2887		if (f && f.spi) {
2888			var f_spi = f.spi;
2889			if (f_spi.selectedIndex) {
2890				if (f_spi[f_spi.selectedIndex].value != "" && f_spi[f_spi.selectedIndex].value != 0) spi = f_spi[f_spi.selectedIndex].value;
2891			}
2892		}
2893
2894		window.open(ferve.url + "Events/SeatingPlans/" + itemHash + "/?seatingPlanHash=" + spi, "v", "toolbar=no,menubar=no,scrollbars=yes,resizable=false,width=1024,height=745");
2895	};
2896
2897	ferve.pricing.dateHash = function (itemHash) {
2898		var dateHash = "null";
2899		var x = (document.getElementById("ft_eventDates") || document.getElementById("ft_eventDates_" + itemHash) || document.querySelector("[id^='ft_eventDates_']"));
2900		if (x) {
2901			x = x.querySelector("input[name='ft_eventPricingRadio_times_" + itemHash + "']:checked");
2902			if (x) dateHash = x.value;
2903		}
2904		return dateHash;
2905	};
2906
2907
2908	ferve.pricing.relatedItems = function () {
2909		ferve.log("ferve.pricing.relatedItems()");
2910		ferve.xmlHttpRequest(ferve.url + "api/v1/Items/RelatedItems" + (ferve_cache ? "Cached" : "") + "?hash=" + ferve.visitor.hash + "&itemHash=" + ferve.itemHash, "GET", null, "", "", "ftd_relatedItems(");
2911	}
2912
2913	ferve.pricing.pwyw = function (e, input) {
2914		if (e.type == "change") {
2915			var qty = input.parentNode.parentNode.parentNode.querySelector(".ft_ep_qty select");
2916			if (qty.selectedIndex == 0) qty.selectedIndex = 1;
2917		} else {
2918			input.setSelectionRange(0, input.value.length);
2919		}
2920	}
2921
2922	function ftd_relatedItems(s) {
2923		var ftReturn = ferve.parseFTReturn(s);
2924		if (ftReturn) {
2925			var x = document.getElementById("ft_relatedItems");
2926			x.innerHTML = ftReturn.SuccessMessages[0];
2927		}
2928	};
2929
2930
2931	// #mark ------ Utility	(urls, links) ------
2932	ferve.utility = function () { };
2933	ferve.utility.url = function (page) {
2934		switch (page.toLowerCase()) {
2935			case "ticketing":
2936				return ferve_tu;
2937			case "ssl":
2938				return (ferve_tus.length > 0 ? ferve_tus : ferve_tu);
2939			case "account":
2940				var url = ferve.url + "Account";
2941				if (document.URL.indexOf(ferve.url) != -1) {
2942					var returnUrl = window.location.href.split("?")[0].replace(ferve.url, "/");
2943					var ignore = ["/", "/account", "/account/login", "/account/lost", "/events", "/sessions", "/passes", "/merchandise", "/vouchers", "/venues"];
2944					if (ignore.includes(returnUrl.toLowerCase())) returnUrl = "";
2945					if (returnUrl.toLowerCase().includes("script")) returnUrl = "";
2946					if (returnUrl.length > 0) url += (url.indexOf("?") == -1 ? "?" : "&") + "returnurl=" + escape(returnUrl);
2947					if (document.URL.indexOf("Vote") != -1) url += escape("?tickets=1#sessions");
2948				}
2949				return url;
2950			case "accountcreate":
2951				return ferve.url + "Account/Signup";
2952			case "accountlogout":
2953				return ferve.url + "Account/Logout";
2954			case "accountrenew":
2955				return ferve.url + "Account/Login?returnurl=" + escape("/Account/RenewMember");
2956			case "wishlist":
2957				return ferve.url + "Account/Wishlist";
2958			case "cartview":
2959				return ferve_tu + "Cart";
2960			case "checkout":
2961				return ferve.url + "Cart/Checkout";
2962			case "browse":
2963				return ferve.url + "Events";
2964			default:
2965				return ferve_tu + page;
2966		}
2967	};
2968
2969	ferve.url = (ferve_tus.length > 0 && window.location.protocol == "https:" ? ferve_tus : ferve_tu);
2970	ferve.urls = ferve_tu + ",," + ferve_tu + "Account," + ferve_tu + "Account/Wishlist," + ferve_tu + "Cart," + ferve_tu + "Cart/Checkout", ferve_tu + "Events";
2971	ferve.utility.openLink = function (page, method) {
2972		ferve.log("ferve.utility.openLink(" + page + "," + method + ")");
2973		var url = ferve.utility.url(page);
2974		if (page == "checkout" && document.URL.split("?")[0].slice(-4) == "Cart") url += "?fcv=1";
2975		if ((page == "account" || page == "accountcreate") && ferve_api && url.toLowerCase().indexOf("returnurl") == -1) url += (url.indexOf("?") == -1 ? "?" : "&") + "returnUrl=" + escape(window.location.href);
2976		if (url && url.length != 0) {
2977			if (method == 1 || method == 2) {
2978				ferve.openWindow(method, url, "", "");
2979			} else {
2980
2981				if (parent && parent.opener && parent.opener.length != 0) {
2982					try {
2983						if (parent.opener.ferve) {
2984							parent.opener.location.href = url;
2985							window.close();
2986						}
2987					}
2988					catch (e) {
2989						ferve.toggleWaiting(true);
2990						document.location.href = url;
2991					}
2992				} else {
2993					ferve.toggleWaiting(true);
2994					document.location.href = url;
2995				}
2996			}
2997		}
2998
2999	};
3000	ferve.utility.queryStringValue = function (variable, query, skipDecode) {
3001		if (!query) query = window.location.search.substring(1);
3002		var vars = query.split("&");
3003		for (var i = 0; i < vars.length; i++) {
3004			var pair = vars[i].split("=");
3005			if (pair[0].toLowerCase() == variable.toLowerCase()) {
3006				var value = pair[1];
3007				if (!skipDecode) value = decodeURIComponent(value);
3008				return value;
3009			}
3010		}
3011		return "";
3012	};
3013	ferve.utility.openEventPageInApp = function (itemHash) {
3014		document.location.href = ferve.utility.url("ticketing") + "app.asp?itemHash=" + itemHash + "&rf=" + escape(document.URL);
3015	};
3016
3017	// Logging
3018	ferve.log = function (s, c) {
3019		if (typeof ferve_de === "undefined" || !ferve_de) return;
3020		try {
3021			if (c == "error") {
3022				console.error(s);
3023			} else if (c == "info") {
3024				console.info(s);
3025			} else if (c == "warn") {
3026				console.warn(s);
3027			} else if (c && c.length > 0) {
3028				if (typeof s == "object") {
3029					console.log("%c%o", c, s);
3030				} else {
3031					console.log("%c%s", c, s);
3032				}
3033			} else {
3034				console.log(s);
3035			}
3036		}
3037		catch (e) {
3038			if (c != null && c.length > 0) ferve.log(s);
3039		}
3040	};
3041
3042
3043
3044	// #mark ------ Communication  ------
3045
3046	ferve.xmlHttpRequest = function (URL, method, data, fallbackURL, divName, callFunction, noRandom) {
3047		var regex = /\"(CardNumber|Password)\":"(.*?)":"(.*?)"/gmi, substitution = `:$1:<hidden>`;
3048		ferve.log("ferve.xmlHttpRequest(" + URL + ", " + method + ", " + (data ? data : "").replace(regex, substitution) + ', ' + fallbackURL + ", " + divName + ", " + callFunction + ")");
3049
3050		var xhr;
3051		try {
3052			xhr = new XMLHttpRequest();
3053		}
3054		catch (e) {
3055			try {
3056				xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
3057			}
3058			catch (e) {
3059				try {
3060					xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
3061				}
3062				catch (e) {
3063					if (fallbackURL != "") {
3064						document.location.href = fallbackURL;
3065					} else {
3066						alert(e.description);
3067					}
3068					return;
3069				}
3070			}
3071		}
3072		if (!ferve_api) {
3073			xhr.open(method, URL, true);
3074		} else {// CORS
3075			if ("withCredentials" in xhr) {
3076				xhr.open(method, URL, true);
3077				xhr.withCredentials = true;
3078			} else if (typeof XDomainRequest != "undefined") {
3079				xhr = new XDomainRequest();
3080				try {
3081					xhr.open(method, URL, true);
3082				}
3083				catch (e) {
3084					ferve.log("xhr.open error:\n" + e.message, "error");
3085					xhr = null;
3086					if (URL.indexOf("Visitors/Login") > -1) {
3087						ferve.visitor.openLogin(1);
3088					} else if (URL.indexOf("Visitors/Logout") > -1) {
3089						ferve.visitor.logout(-1);
3090					}
3091				}
3092			} else {
3093				xhr = null;
3094				if (URL.indexOf("m2=login") > -1) ferve.visitor.openLogin(1);
3095			}
3096		}
3097
3098		xhr.onload = function () {
3099			if (xhr.responseText != "") {
3100				var responseText = xhr.responseText;
3101				if (xhr.status != 200) {
3102					if (fallbackURL != "") document.location.href = fallbackURL;
3103
3104					try {
3105						ft_webError(xhr.status, responseText);
3106					}
3107					catch (e) { }
3108
3109					return;
3110				}
3111				if (divName != "") ferve.setContent(divName, responseText);
3112				if (callFunction != "" && callFunction != undefined) {
3113					if (callFunction.length > 1) {
3114						if (callFunction.charAt(callFunction.length - 1) == ")") callFunction = callFunction.substring(0, callFunction.indexOf(')'));
3115						if (callFunction.indexOf('(') == -1) callFunction += '(';
3116					}
3117					callFunction = callFunction + "'" + escape(xhr.responseText) + "')";
3118					eval(callFunction);
3119				}
3120			} else {
3121				if (fallbackURL != "") {
3122					document.location.href = fallbackURL;
3123				}
3124			}
3125		}
3126		if (method == "POST") {
3127			xhr.setRequestHeader("Content-type", "application/json");
3128			if (ferve.recaptcha() && grecaptcha.getResponse() != "") xhr.setRequestHeader("gcaptcharesponse", grecaptcha.getResponse());
3129			xhr.send(data);
3130		} else {
3131			if (!noRandom) {
3132				if (URL.indexOf("?") == -1) {
3133					URL += "?rand=" + ferve.returnUniqueID();
3134				} else {
3135					URL += "&rand=" + ferve.returnUniqueID();
3136				}
3137			}
3138			xhr.send(null);
3139		}
3140		return xhr;
3141	};
3142
3143	ferve.returnUniqueID = function () {
3144		var chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz";
3145		var myStr = "";
3146
3147		for (var i = 0; i < 16; i++) {
3148			var randNum = Math.floor(Math.random() * chars.length);
3149			myStr += chars.substring(randNum, randNum + 1);
3150		}
3151		return myStr;
3152	};
3153
3154
3155	// #mark ------ Overlay  ------
3156
3157	var createOverlay = function () {
3158		ferve.log("createOverlay()");
3159		if (document.getElementById("ft_fcBG")) return;
3160		var div = document.createElement("div");
3161		div.id = "ft_fcBG";
3162		div.className = "ft_fade ft_itemHidden";
3163		div.style.display = "none";
3164		if (document.body.firstChild) {
3165			document.body.insertBefore(div, document.body.firstChild);
3166		} else {
3167			document.body.appendChild(div);
3168		}
3169	};
3170
3171	ferve.toggleOverlay = function (mode, modal, callback) {
3172		toggleOverlay(mode, modal, callback);
3173	}
3174	var toggleOverlay = function (mode, modal, callback) {
3175		ferve.log("toggleOverlay(" + mode + ", " + modal + ")");
3176		var x = document.getElementById("ft_fcBG");
3177		if (!x) createOverlay();
3178		x = document.getElementById("ft_fcBG");
3179		if (x) {
3180			if (mode == 0) {
3181				if (typeof (overlayCallback) == "function") overlayCallback();
3182				overlayCallback = null;
3183
3184				x.className = "ft_fade ft_itemHidden";
3185				ferve.removeOverlayClick();
3186				setTimeout(function () { ferve.toggleDisplay("ft_fcBG", "none"); }, 500);
3187
3188			} else if (mode == 1) {
3189				if (x.className.indexOf("ft_itemVisible") != -1) return;
3190				x.className = "ft_fade ft_itemHidden";
3191				ferve.toggleDisplay("ft_fcBG", "");
3192				setTimeout(function () { ferve.toggleDisplay("ft_fcBG", ""); x.className = "ft_fade ft_itemVisible" + ferve.overlayOpacity; }, 175);
3193				if (!modal) setTimeout(function () {
3194					ferve.addOverlayClick();
3195				}, 750);
3196				if (typeof (callback) != "undefined") overlayCallback = callback;
3197			}
3198		}
3199		try {
3200			ft_overlayToggled(mode);
3201		}
3202		catch (e) { }
3203	};
3204
3205	var overlayClicked, overlayCallback;
3206	var overlayClick = function (e) {
3207		ferve.log("overlayClick(e) : " + overlayClicked);
3208		if (!overlayClicked) return;
3209
3210		if (!e) e = window.event;
3211
3212		var t = e.target || e.srcElement || e;
3213		if (t.id == "ft_notificationBG" || ((t.id == "ft_notificationMessage" || t.id == "ft_notificationIconElement") && ferve.ftwp())) {
3214			ferve.notification.hide(8);
3215			return;
3216		}
3217		if (t.id == "ft_notificationOK" || t.id == "ft_notificationCancel") {
3218			return;
3219		}
3220		var x;
3221		for (var i = 0; i < ferve.overlays.length; i++) {
3222			x = document.getElementById(ferve.overlays[i]);
3223			if (x && x.className.indexOf("ft_itemHidden") == -1 && x.style.display != "none") break;
3224		}
3225		while (t.parentNode) {
3226			if (t == x) {
3227				if (t.id == "ft_notification") {
3228					ferve.notification.hide(9);
3229				}
3230				return;
3231			}
3232			t = t.parentNode;
3233		}
3234		hideHoverElements(6);
3235		document.body.className = document.body.className.replace(" ftapi_modal", "").replace("ftapi_modal", "");
3236	};
3237
3238	var overlayMouseDown = function (e) {
3239		ferve.log("overlayMouseDown(e)");
3240		if (!e) e = window.event;
3241		var t = e.target || e.srcElement;
3242		overlayClicked = (t.id == "ft_fcBG" || ((t.id == "ft_notificationBG" || t.id == "ft_notificationMessage" || t.id == "ft_notificationIconElement") && ferve.ftwp() && ferve.notification.style != "alert"));
3243	};
3244
3245	ferve.addOverlayClick = function (element) {
3246		ferve.log("ferve.addOverlayClick()");
3247		if (!element) element = document;
3248		if (element.addEventListener) {
3249			element.addEventListener("click", overlayClick, false);
3250			element.addEventListener("mousedown", overlayMouseDown, false);
3251		} else {
3252			element.attachEvent("onclick", overlayClick);
3253			element.attachEvent("onmousedown", overlayMouseDown);
3254		}
3255	};
3256
3257	ferve.removeOverlayClick = function (element) {
3258		ferve.log("ferve.removeOverlayClick()");
3259		if (!element) element = document;
3260		if (element.addEventListener) {
3261			element.removeEventListener("click", overlayClick, false);
3262			element.removeEventListener("mousedown", overlayMouseDown, false);
3263		} else {
3264			element.detachEvent("onclick", overlayClick);
3265			element.detachEvent("onmousedown", overlayMouseDown);
3266		}
3267	};
3268
3269	ferve.modal = function (url) {
3270		ferve.log("ferve.modal(" + url + ")");
3271		var modal = document.getElementById("ftapi_modal");
3272
3273		if (url == "close" || url == "window") {
3274			if (url == "window") {
3275				url = modal.dataset.url;
3276				window.open(url, "FT-modal");
3277			}
3278
3279			overlayClicked = true;
3280			overlayClick(document.getElementById("ft_fcBG"));
3281			return;
3282		}
3283
3284		ferve.toggleWaiting(true);
3285
3286		if (location.protocol == "https:") url = url.replace("http://", "https://").replace("60054", "44300");
3287
3288		if (!modal) {
3289			modal = document.createElement("div");
3290			modal.className = "ft_fade ft_itemHidden";
3291			modal.id = "ftapi_modal";
3292			document.body.appendChild(modal);
3293		}
3294		modal.dataset.url = url;
3295
3296		var xhr = new XMLHttpRequest();
3297		xhr.onreadystatechange = function (e) {
3298			if (xhr.readyState == 4) {
3299				ferve.toggleWaiting(false);
3300				if (xhr.status == 200) {
3301					toggleOverlay(1, false);
3302					modal.innerHTML = xhr.responseText;
3303					var content = modal.querySelector(".ft_panelContent");
3304					if (content) modal.innerHTML = content.innerHTML;
3305					var div = document.createElement("div");
3306					div.id = "ftapi_modal-header";
3307					div.innerHTML = "<a href=\"javascript:ferve.modal('close');\">Close</a> | <a href=\"javascript:ferve.modal('window');\">New Window</a>";
3308					modal.insertBefore(div, modal.firstChild);
3309
3310					ferve.toggleDisplay("ftapi_modal", "");
3311
3312					setTimeout(function () {
3313						ferve.toggleDisplay("ft_fcBG", "");
3314						modal.className = "ft_fade ft_itemVisible";
3315						if (document.body.className.indexOf("ftapi_modal") == -1) document.body.className += " ftapi_modal";
3316					}, 175);
3317
3318				} else {
3319					window.open(url, "FT-modal");
3320				}
3321			}
3322		}
3323		xhr.open("GET", url, true);
3324		xhr.send();
3325	};
3326
3327
3328	var showHoverElements = function (mode) {
3329		ferve.log("showHoverElements(" + mode + ")");
3330		var x;
3331		toggleOverlay(1, false);
3332
3333		if (mode == 1) {
3334			x = document.getElementById("ft_ferveCart");
3335			if (x) {
3336				ferve.toggleDisplay("ft_ferveCart", "");
3337				setTimeout(function () { x.className = "ft_borderRadius6 ft_fade ft_itemVisible"; }, 150);
3338				googleAnalytics();
3339				facebookPixelAnalytics();
3340				if (ferve != null && document.body.id != "ft_checkout" && ferve.adobeAnalytics) adobeAnalytics();
3341			}
3342		}
3343		if (mode == 2) {
3344			x = document.getElementById("ft_login");
3345			if (x) {
3346				ferve.toggleDisplay("ft_login", "");
3347				setTimeout(function () { x.className = "ft_fade ft_itemVisible"; }, 150);
3348			}
3349		}
3350		if (mode == 3) {
3351			x = document.getElementById("ft_purchase");
3352			if (x) {
3353				ferve.toggleDisplay("ft_purchase", "");
3354				setTimeout(function () { x.className = "ft_fade ft_itemVisible"; }, 150);
3355			}
3356		}
3357	};
3358
3359	var facebookPixelAnalytics = function () {
3360
3361		// get the pixel script
3362		var pixelCode = document.getElementById("ft_pixelCode");
3363
3364		// get the pixel id
3365		var ft_facebookPixelAnalytics = document.getElementById("ft_facebookAnalytics");
3366		var scriptCode = "";
3367
3368		if (!ft_facebookPixelAnalytics || !ft_facebookPixelAnalytics.value.trim()) {
3369			console.warn("Facebook Pixel ID not found.");
3370			return;
3371		}
3372
3373		var pixelId = ft_facebookPixelAnalytics.value.trim();
3374
3375		if (pixelCode != null) {
3376			scriptCode = pixelCode.innerHTML;
3377			if (scriptCode.length == 0) return;
3378		} else {
3379			scriptCode = "!function(f,b,e,v,n,t,s)" +
3380				"{if(f.fbq)return;n=f.fbq=function(){n.callMethod?" +
3381				"n.callMethod.apply(n,arguments):n.queue.push(arguments)};" +
3382				"if(!f._fbq)f._fbq=n;n.push=n;n.loaded=!0;n.version='2.0';" +
3383				"n.queue=[];t=b.createElement(e);t.async=!0;" +
3384				"t.src=v;s=b.getElementsByTagName(e)[0];" +
3385				"s.parentNode.insertBefore(t,s)}(window, document,'script'," +
3386				"'https://connect.facebook.net/en_US/fbevents.js');" +
3387				"fbq('init', '" + pixelId + "');" +
3388				"fbq('track', 'PageView');";
3389		}
3390
3391		// Load Facebook Pixel script
3392		var fbScript = document.createElement("script");
3393		fbScript.innerHTML = scriptCode;
3394		document.head.appendChild(fbScript);
3395
3396		// noscript fallback for tracking
3397		var fbNoScript = document.createElement("noscript");
3398		fbNoScript.innerHTML =
3399			'<img height="1" width="1" style="display:none" ' +
3400			'src="https://www.facebook.com/tr?id=' + pixelId + '&ev=PageView&noscript=1" />';
3401		document.body.appendChild(fbNoScript);
3402
3403		// Cleanup
3404		if (pixelCode != null) {
3405			pixelCode.remove();
3406		}
3407		ft_facebookPixelAnalytics.remove();
3408
3409		console.log("Facebook Pixel initialized with ID:", pixelId);
3410	};
3411
3412
3413
3414	var googleAnalytics = function () {
3415
3416		var gtmCode = document.getElementById("ft_gtmCode");
3417		var ft_googleAnalytics = document.getElementById("ft_googleAnalytics");
3418		var ga4Code = document.getElementById("ft_ga4Code");
3419		var scriptCode = "";
3420		var googleAnalyticsScriptInsert = "";
3421		if (gtmCode != null) {
3422			scriptCode = gtmCode.innerHTML;
3423		} else if (ga4Code != null) {
3424			scriptCode = ga4Code.innerHTML;
3425		}
3426
3427		if (scriptCode.length == 0) return;
3428
3429		//MP : access the gtm code again to load dataLayer
3430		if (typeof GTMCode !== "undefined") {
3431			GAEvent(window, document, 'script', 'dataLayer', GTMCode);
3432		} else if (typeof GTMCode === "undefined" && gtmCode != null) {
3433			//For GTM
3434			//MP : In case of pricing widget, Ferve has no way to get the function from the layout so we need to re-insert the function again.
3435			googleAnalyticsScriptInsert = `(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start': new Date().getTime(),event:'gtm.js'});
3436							var f=d.getElementsByTagName(s)[0],j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';
3437							j.async=true;
3437j.src ='https://www.googletagmanager.com/gtm.js?id='+i+dl;
3438							f.parentNode.insertBefore(j, f);})
3439							(window, document, 'script', 'dataLayer','` + ft_googleAnalytics.value + `'); `;
3440			var gtmScript = document.createElement("script");
3441			gtmScript.innerHTML = googleAnalyticsScriptInsert;
3442			document.head.append(gtmScript);
3443
3444		} else {
3445			//For GA4
3446			//MP : In case of pricing widget, Ferve has no way to get the function from the layout so we need to re-insert the function again.
3447			var ga4script1 = document.createElement("script");
3448			ga4script1.src = "https://www.googletagmanager.com/gtag/js?id=" + ft_googleAnalytics.value + "";
3449			document.head.append(ga4script1);
3450			googleAnalyticsScriptInsert = `window.dataLayer = window.dataLayer || [];
3451											function gtag(){dataLayer.push(arguments);}
3452											gtag('js', new Date());
3453											gtag('config', '` + ft_googleAnalytics.value + `');`;
3454			var ga4script2 = document.createElement("script");
3455			ga4script2.innerHTML = googleAnalyticsScriptInsert;
3456			document.head.append(ga4script2);
3457		}
3458
3459		//Insert dataLayer on head
3460		var script = document.createElement("script");
3461		script.innerHTML = scriptCode;
3462		document.head.append(script);
3463		ferve.log("Google Analytics Script" + scriptCode);
3464
3465		//Remove the gtmCode/ga4Code in body
3466		if (gtmCode != null) {
3467			gtmCode.remove();
3468		} else {
3469			ga4Code.remove();
3470		}
3471		ft_googleAnalytics.remove();
3472	};
3473
3474	//MP : Adobe Analytics AddToCart and View Cart
3475	var adobeAnalytics = function () {
3476		if (ferve.ftwp()) return;
3477
3478		var adobeAnalyticsCode = document.getElementById("ft_itemAdded");
3479		var adobeAnalyticsScript = document.getElementById("ft_adobeScript");
3480
3481		if (adobeAnalyticsCode != null) {
3482			var value = adobeAnalyticsCode.getAttribute("value");
3483
3484			if (value == "viewCart") {
3485				removeExtraAnalyticsScript();
3486				addSatelliteTrackToHead("viewCart");
3487			}
3488			if (value == "addToCart") {
3489				var adobeAnalyticsScriptAppend = document.createElement("script");
3490				document.head.append(adobeAnalyticsScriptAppend);
3491				adobeAnalyticsScriptAppend.src = adobeAnalyticsScript.src
3492				adobeAnalyticsScriptAppend.id = adobeAnalyticsScript.id
3493				adobeAnalyticsScriptAppend.async = true;
3494				document.head.append(adobeAnalyticsScriptAppend);
3495				adobeAnalyticsScript.remove();
3496				// check every 100ms if cart is visible then track
3497				const interval = setInterval(() => {
3498					const el = document.getElementById("ft_ferveCart");
3499					if (el && el.classList.contains("ft_itemVisible")) {
3500						clearInterval(interval);
3501						addSatelliteTrackToHead("addToCart");
3502					}
3503				}, 300);
3504			}
3505			var adobeAnalyticsCodeAppend = document.createElement("script");
3506			document.head.append(adobeAnalyticsCodeAppend);
3507			adobeAnalyticsCodeAppend.innerHTML = adobeAnalyticsCode.innerHTML;
3508			document.head.append(adobeAnalyticsCodeAppend);
3509			adobeAnalyticsCode.remove();
3510
3511			ferve.log(adobeAnalyticsCodeAppend.innerHTML);
3512			ferve.log("Adobe Analytics " + value);
3513
3514		}
3515
3516
3517	};
3518
3519	addSatelliteTrackToHead = function (eventName) {
3520		if (ferve.ftwp()) return;
3521
3522		// Append _satellite.track script to head
3523		var satelliteTrackScript = document.createElement("script");
3524		satelliteTrackScript.innerHTML = `
3525						// Add _satellite.track
3526						if (typeof _satellite !== 'undefined') {
3527							_satellite.track('` + eventName + `', {
3528								event: 'addToCart',
3529								items: window.digitalData ? window.digitalData.product : []
3530							});
3531						}
3532					`;
3533		document.head.append(satelliteTrackScript);
3534	}
3535
3536	//MP : Adobe Analytics Remove from Cart
3537	ferve.adobeCartRemove = function (category, name, variant, price, quantity, sku) {
3538		if (ferve.ftwp()) return;
3539
3540		removeExtraAnalyticsScript();
3541
3542		var analyticsCartRemoveScript = document.createElement("script");
3543		document.head.append(analyticsCartRemoveScript);
3544		analyticsCartRemoveScript.innerHTML = `window.digitalData  = window.digitalData  || []; {
3545														digitalData = {
3546															product: [
3547																	{ category : '` + category + `',
3548																		name: '` + name + `',
3549																		variant: '` + variant + `',
3550																		price : '` + price + `',
3551																		quantity: ` + quantity + `,
3552																		sku: '` + sku + `'
3553																	}
3554																]
3555															}
3556
3557														_satellite.track('removeFromCart', digitalData);
3558
3559														};`;
3560
3561		document.head.append(analyticsCartRemoveScript);
3562
3563		ferve.log(analyticsCartRemoveScript.innerHTML);
3564		ferve.log("Adobe Analytics _removeFromCart");
3565
3566	};
3567
3568	var removeExtraAnalyticsScript = function () {
3569		if (ferve.ftwp()) return;
3570
3571		const headScripts = document.head.querySelectorAll('script');
3572
3573		// Loop through and find the target script
3574		headScripts.forEach((script) => {
3575			if (script.textContent.includes('window.digitalData') && script.id != 'ft_globalWindowDigital') {
3576				// Remove the matched script
3577				script.remove();
3578			}
3579		});
3580
3581	};
3582
3583	var hideHoverElements = function (n) {
3584		ferve.log("hideHoverElements(" + n + ")");
3585		var x;
3586		for (var i = 0; i < ferve.overlays.length; i++) {
3587			ferve.log(ferve.overlays[i]);
3588			x = document.getElementById(ferve.overlays[i]);
3589			if (x) {
3590				if (ferve.overlays[i] == "ft_ferveCart") {
3591					if (x.className.indexOf("ft_fcAdd") == -1) {
3592						x.className = "ft_shadow ft_borderRadius6 ft_fade ft_itemHidden";
3593					} else {
3594						x.className = "ft_fcAdd ft_shadow ft_borderRadius6 ft_fade ft_itemHidden";
3595					}
3596				} else {
3597					if (ferve.overlays[i].indexOf("ft_") != -1) {
3598						if (x.style.display == "none") continue;
3599						x.className = "ft_shadow ft_borderRadius6 ft_fade ft_itemHidden";
3600					} else if (x && x.className.indexOf("ft_itemHidden") == -1 && x.style.display != "none") {
3601						if (ferve.overlays[i].length > 6 && ferve.overlays[i].substr(ferve.overlays[i].length - 6) == "Screen") {
3602							eval(ferve.overlays[i].substring(0, ferve.overlays[i].length - 6) + "Close();");
3603						} else {
3604							x.className = x.className.replace("ft_itemVisible", "ft_itemHidden");
3605						}
3606					} else {
3607						continue;
3608					}
3609				}
3610				if (x) {
3611					setTimeout(function () { ferve.toggleDisplay(ferve.overlays[i], "none"); }, 500);
3612					if (ferve.overlays[i].indexOf("ft_") != -1) setTimeout(function () { var x = document.getElementById(ferve.overlays[i]); if (x) x.parentNode.removeChild(x); }, 750);
3613					break;
3614				}
3615			}
3616		}
3617
3618		setTimeout(function () { ferve.log("toggleOverlay(0)(2)"); toggleOverlay(0, false); }, 15);
3619	};
3620
3621
3622
3623	ferve.toggleDisplay = function (div, display, ignoreClass) {
3624		//ferve.log("toggleDisplay('" + div + "', '" + display + "', " + ignoreClass + ")");
3625		if (typeof (div) == "string") div = document.getElementById(div);
3626		if (div) {
3627			if (display == "none" && (!ignoreClass && div.className.indexOf("ft_itemHidden") == -1)) {
3628				ferve.log("exiting toggle (" + div.id + ")");
3629				return;
3630			}
3631			div.style.display = display;
3632		}
3633	};
3634
3635	ferve.toggleDivs = function (div1, div2) {
3636		var x = document.getElementById(div1);
3637		if (x) x.style.display = "none";
3638		x = document.getElementById(div2);
3639		if (x) x.style.display = "";
3640	};
3641
3642
3643	ferve.toggleWaiting = function (waiting) {
3644		if (waiting) {
3645			if (document.body.className.indexOf("ft_waiting") == -1) document.body.className += " ft_waiting";
3646		} else {
3647			document.body.className = document.body.className.replace(" ft_waiting", "");
3648		}
3649	};
3650
3651	ferve.setContent = function (div, html) {
3652		//ferve.log("setContent()");
3653		if (typeof (div) == "string") div = document.getElementById(div);
3654		if (div) div.innerHTML = html;
3655	};
3656
3657
3658	// #mark ------ Notifications  ------
3659
3660	ferve.notification = function () { };
3661	ferve.notification.style;
3662	ferve.notification.callback;
3663	ferve.notification.promptFields;
3664	ferve.notification.activeElement;
3665	ferve.notification.hideTimout;
3666	ferve.notification.show = function (style, colour, message, callBack, localLocation, promptFields) {
3667		// style			notification(default)/notification2(no fade, stays onscreen)notification3(as 2 but hides)/alert/confirm/prompt/local
3668		// colour			yellow/blue/red
3669		// message			(shown to customer)
3670		// callback			Function prompt calls back to
3671		// localLocation	Location local alert appears (pass in item.getBoundingClientRect())
3672		// promptFields		Default value (single input) OR List of fields to show (type:name:value;type:name:value)
3673		ferve.log("ferve.notification.show(" + style + ", " + colour + ", " + message + ", " + callBack + ", " + localLocation + ", " + promptFields + ")");
3674		if (!message) return;
3675		ferve.notification.style = style;
3676		ferve.notification.activeElement = document.activeElement;
3677		var isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
3678		if (!isSafari) document.activeElement.blur();
3679		var className = "ft_notification_" + style + " ft_notification_" + colour + " ft_fade ft_itemHidden";
3680		var x = document.getElementById("ft_notification");
3681		if (x) {
3682			x.className = className;
3683		} else {
3684			var div = document.createElement("div");
3685			div.className = className;
3686			div.id = "ft_notification";
3687			div.innerHTML = "<div id=\"ft_notificationIcon\"><div id=\"ft_notificationIconElement\" class=\"fticon-warning\"></div></div><div id=\"ft_notificationMessage\"></div><div id=\"ft_notificationButtons\"></div>";
3688			document.body.appendChild(div);
3689		}
3690		x = document.getElementById("ft_notificationMessage");
3691		x.innerHTML = message;
3692		if (style == "prompt") {
3693			var html = "<br /><form onsubmit=\"return false\">";
3694			if (promptFields.indexOf(":") == -1) {
3695				ferve.notification.promptFields = null;
3696				html += "<input type=\"text\" value=\"" + promptFields + "\" id=\"ft_notificationInput\" autocomplete=\"off\" />";
3697			} else {
3698				ferve.notification.promptFields = promptFields;
3699				var fields = promptFields.split(";");//type:name:value
3700				for (var i = 0; i < fields.length; i++) {
3701					var field = fields[i].split(":");
3702					var type = field[0];
3703					var required = (type.indexOf("*") > -1);
3704					type = type.replace("*", "");
3705					if (type == "text") {
3706						html += "<input type=\"text\" value=\"" + field[2] + "\" id=\"ft_notificationInput_" + field[1] + "\" class=\"form-control\" placeholder=\"" + field[1] + "\" autocomplete=\"off\"" + (required ? " required" : "") + " />"
3707					} else if (type == "textarea") {
3708						html += "<textarea id=\"ft_notificationInput_" + field[1] + "\" class=\"form-control\" placeholder=\"" + field[1] + "\" autocomplete=\"off\"" + (required ? " required" : "") + ">" + field[2] + "</textarea>";
3709					}
3710				}
3711			}
3712			x.innerHTML += "</form>";
3713			x.innerHTML += html;
3714		}
3715
3716		x = document.getElementById("ft_notificationButtons");
3717		if (style == "alert" || style == "confirm" || style == "prompt") {
3718			if (style == "alert") {
3719				x.innerHTML = "<div class=\"ft_notificationButton100\"><a href=\"Javascript:ferve.notification.hide(1)\" id=\"ft_notificationOK\">OK</a></div>";
3720				ferve.notification.callback = null;
3721			} else if (style == "confirm" || style == "prompt") {
3722				x.innerHTML = "<div class=\"ft_notificationButton50\"><a href=\"Javascript:ferve.notification.hide(2)\" id=\"ft_notificationCancel\">Cancel</a></div><div class=\"ft_notificationButton50\"><a href=\"Javascript:ferve.notification.OK()\" id=\"ft_notificationOK\">OK</a></div>";
3723				ferve.notification.callback = callBack;
3724			}
3725			setTimeout(function () {
3726				notificationSetupKeypress(true);
3727			}, 150);// Allow any current keystrokes to finish
3728		} else {
3729			x.innerHTML = "";
3730			ferve.notification.callback = null;
3731		}
3732
3733
3734		// Background
3735		x = document.getElementById("ft_notificationBG");
3736		if (!x) {
3737			var div = document.createElement("div");
3738			div.id = "ft_notificationBG";
3739			div.className = "ft_fade ft_itemHidden";
3740			div.style.display = "none";
3741			if (document.body.firstChild) {
3742				document.body.insertBefore(div, document.body.firstChild);
3743			} else {
3744				document.body.appendChild(div);
3745			}
3746			x = document.getElementById("ft_notificationBG");
3747		}
3748		x.className = "ft_fade ft_itemHidden";
3749		if (style == "notification") setTimeout(function () { ferve.addOverlayClick(x); }, 750);
3750
3751		if (style != "local" && style != "notification2" && style != "notification3") {
3752			ferve.toggleDisplay("ft_notificationBG", "");
3753			setTimeout(function () { var x = document.getElementById("ft_notificationBG"); x.className = "ft_fade ft_itemVisible80"; }, 175);
3754		}
3755
3756		x = document.getElementById("ft_notification");
3757		ferve.toggleDisplay("ft_notification", "");
3758
3759		if (localLocation) {
3760			var offsetX = 0, offsetY = 0;
3761			if (document.documentElement && (document.documentElement.scrollTop || document.documentElement.scrollLeft)) {
3762				offsetX = document.documentElement.scrollLeft;
3763				offsetY = document.documentElement.scrollTop;
3764			} else if (document.body && (document.body.scrollTop || document.body.scrollLeft)) {
3765				offsetX = document.body.scrollLeft;
3766				offsetY = document.body.scrollTop;
3767			} else if (window.pageXOffset || window.pageYOffset) {
3768				offsetX = window.pageXOffset;
3769				offsetY = window.pageYOffset;
3770			}
3771			x.style.top = (localLocation.top + offsetY - 65) + "px";
3772			x.style.left = (localLocation.left + offsetX + 120) + "px";
3773		} else if (style == "notification2" || (style == "notification3" && !ferve.ftwp())) {
3774			x.style.top = "95px";
3775			x.style.left = "auto";
3776			x.style.right = "25px";
3777		} else if (style == "notification3") {
3778			x.style.top = "60px";
3779			x.style.left = "auto";
3780			x.style.right = "5px";
3781		} else {
3782			x.style.top = "";
3783			x.style.left = "";
3784		}
3785
3786		setTimeout(function () {
3787			x.className = x.className.replace("ft_itemHidden", "ft_itemVisible");
3788			if (style == "prompt") {
3789				var input = document.querySelector("input[id^=ft_notificationInput]");
3790				if (input) {
3791					input.focus();
3792					input.selectionStart = input.selectionEnd = input.value.length;
3793				}
3794			}
3795		}, 450);
3796		if (style != "alert" && style != "confirm" && style != "prompt") {
3797			if (style == "local") {
3798				ferve.notification.hideTimout = setTimeout(function () { ferve.notification.hide(3); }, 2850);
3799			} else if (style != "notification2") {
3800				ferve.notification.hideTimout = setTimeout(function () { ferve.notification.hide(4); }, 3450);
3801			}
3802		}
3803	};
3804
3805	var notificationSetupKeypress = function (on) {
3806		ferve.log("notificationSetupKeypress(" + on + ")");
3807
3808		if (document.addEventListener) {
3809			if (on) {
3810				document.addEventListener("keyup", ftd_notificationKeyup, false);
3811			} else {
3812				document.removeEventListener("keyup", ftd_notificationKeyup, false);
3813			}
3814		} else if (window.attachEvent) {
3815			if (on) {
3816				document.attachEvent("onkeyup", ftd_notificationKeyup);
3817			} else {
3818				document.detachEvent("onkeyup", ftd_notificationKeyup);
3819			}
3820		}
3821	};
3822
3823	var ftd_notificationKeyup = function (e) {
3824		ferve.log("ftd_notificationKeyup()");
3825
3826		if (!e) var e = window.event; // Derp
3827		if (e.keyCode) {
3828			code = e.keyCode;
3829		} else if (e.which) {
3830			code = e.which;
3831		}
3832		//ferve.log("code: " + code);
3833		if (typeof (code) != "undefined" && code == 13) {
3834			if (document.activeElement.nodeName == "TEXTAREA") return;
3835
3836			if (ferve.notification.style == "alert") {
3837				ferve.notification.hide(5)
3838			} else {
3839				ferve.notification.OK();
3840			}
3841		} else if (typeof (code) != "undefined" && code == 27) {
3842			ferve.notification.hide(6)
3843		}
3844		e.preventDefault();
3845	};
3846
3847	ferve.notification.OK = function () {
3848		ferve.log("ferve.notification.OK()");
3849		var x = document.getElementById("ft_notificationInput");
3850		var s = "";
3851		var error = false;
3852		if (x) {
3853			s = x.value;
3854			var required = (ferve.notification.promptFields && ferve.notification.promptFields.indexOf("*") > -1);
3855			if (required && x.value.length == 0) {
3856				error = true;
3857				if (x.className.indexOf("has-error") == -1) x.className += " has-error";
3858			}
3859		} else if (ferve.notification.promptFields) {
3860			var fields = ferve.notification.promptFields.split(";");//type;name;value
3861			for (var i = 0; i < fields.length; i++) {
3862				var field = fields[i].split(":");
3863				var x = document.getElementById("ft_notificationInput_" + field[1]);
3864				var required = (field[0].indexOf("*") > -1);
3865				if (required && x.value.length == 0) {
3866					error = true;
3867					if (x.className.indexOf("has-error") == -1) x.className += " has-error";
3868				} else {
3869					x.className = x.className.replace(" has-error", "");
3870				}
3871				s += "<:>" + (x ? x.value : "");
3872			}
3873			s = s.substring(3);
3874		}
3875		if (error) return;
3876
3877		notificationSetupKeypress(false);
3878		ferve.notification.promptFields = null;
3879
3880		ferve.notification.hide(7);
3881
3882		ferve.notification.callback(s);
3883	};
3884
3885	ferve.notification.hide = function (n) {
3886		ferve.log("ferve.notification.hide(" + n + ")");
3887		if (typeof (ferve.notification.hideTimout) != "undefined") clearTimeout(ferve.notification.hideTimout);
3888		notificationSetupKeypress(false);
3889		var x = document.getElementById("ft_notification");
3890		if (!x) return;
3891		x.className = x.className.replace("ft_itemVisible", "ft_itemHidden");
3892		x = document.getElementById("ft_notificationBG");
3893		x.className = "ft_fade ft_itemHidden";
3894		setTimeout(function () { ferve.toggleDisplay("ft_notificationBG", "none"); }, 500);
3895		setTimeout(function () { ferve.toggleDisplay("ft_notification", "none"); }, 500);
3896
3897		ferve.removeOverlayClick(x);
3898		if (ferve.notification.activeElement && (ferve.notification.activeElement.type == "text" || ferve.notification.activeElement.type == "textarea")) {
3899			try {
3900				ferve.notification.activeElement.focus();
3901			}
3902			catch (e) { }
3903		}
3904	};
3905
3906
3907	// #mark ------ Misc  ------
3908
3909	ferve.openWindow = function (method, url, name, features) {
3910		var win;
3911		if (method == 1) {
3912			win = window.open(url, "_blank");
3913		} else {
3914			if (name.length == 0) name = "ftwin";
3915			if (features.length == 0) {
3916				var w = screen.width;
3917				var h = screen.height;
3918				if (w > 850) w = 850;
3919				if (h > 550) h = 550;
3920				if (w > 1200) w = 1200;
3921				if (h > 768) h = 768;
3922				features = "toolbar=no,menubar=no,scrollbars=yes,resizable=false,width=" 
3922+ w + ",height=" + h;
3923			}
3924			win = window.open(url, name, features);
3925		}
3926		try {
3927			win.focus();
3928		}
3929		catch (e) { }
3930	};
3931
3932	ferve.de = function (absolute) {
3933		if (absolute) return ferve_de;
3934		ferve_de = !![]; ft_errors();
3935	};
3936
3937	ferve.isNullOrEmpty = function (s) {
3938		return (!s || s.length == 0);
3939	};
3940
3941	ferve.isNumeric = function (n) {
3942		return (!isNaN(parseFloat(n)) && isFinite(n));
3943	};
3944
3945	ferve.isEmail = function (e) {
3946		var regEx = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
3947		return regEx.test(e);
3948	};
3949
3950	ferve.isMobile = function () {
3951		return (/Mobi/.test(navigator.userAgent) || (navigator.platform == "MacIntel" && navigator.maxTouchPoints > 1));
3952	};
3953
3954	ferve.isTablet = function () {
3955		return (/(ipad|tablet|(android(?!.*mobile))|(windows(?!.*phone)(.*touch))|kindle|playbook|silk|(puffin(?!.*(IP|AP|WP))))/.test(navigator.userAgent.toLowerCase()) || navigator.maxTouchPoints > 0 || navigator.msMaxTouchPoints > 0);
3956	};
3957
3958	ferve.isAndroid = function () {
3959		var userAgent = userAgent = window.navigator.userAgent.toLowerCase();
3960		var android = /android/.test(userAgent);
3961		return android;
3962	};
3963
3964	ferve.isIOS = function () {
3965		var userAgent = userAgent = window.navigator.userAgent.toLowerCase();
3966		var ios = /iphone|ipod|ipad/.test(userAgent) || (ferve.isTablet() && /macintosh/.test(userAgent));
3967		return ios;
3968	};
3969
3970	ferve.isPWA = function () {
3971		var pwa = window.matchMedia("(display-mode: standalone)").matches;
3972		return pwa;
3973	};
3974
3975	ferve.isApp = function (type) {
3976		var standalone = window.navigator.standalone, userAgent = window.navigator.userAgent.toLowerCase(), safari = /safari/.test(userAgent), ios = /iphone|ipod|ipad/.test(userAgent), iPad = (navigator.platform == "MacIntel" && navigator.maxTouchPoints > 1), android = /androidft/.test(userAgent), socialMedia = (/fbios|fban/.test(userAgent) || /instagram/.test(userAgent) || /twitter/.test(userAgent) || /linkedinapp/.test(userAgent));
3977		if (socialMedia) return false;
3978		if (type == "iOS") {
3979			return ([1 << 2, 5].includes(ferve.visitor.type));
3980		} else if (type == "Android") {
3981			return (ios && !standalone && !safari);
3982		} else {
3983			return ([1 << 2, 5].includes(ferve.visitor.type) || android);
3984		}
3985	};
3986
3987	ferve.ftwp = function () {
3988		return !(typeof (ftwp) == "undefined");
3989	};
3990
3991	ferve.recaptcha = function () {
3992		return (document.getElementById("ft_recaptcha") != null && typeof grecaptcha == "object" && document.getElementById("ft_recaptcha-container").innerHTML.length > 0);
3993	}
3994
3995	ferve.getFloat = function (number) {
3996		var a = number.indexOf("."), b = number.indexOf(",");
3997		if (a > -1 && b > -1 && a < b) {
3998			number = number.replace(/\./g, "").replace(",", ".");
3999		} else {
4000			if (ferve.currencyCode && ferve.currencyCode == "EUR" && a == -1 && b != -1) {
4001				number = number.replace(/,/g, ".");
4002			} else {
4003				number = number.replace(/,/g, "");
4004			}
4005		}
4006		number = number.replace(/[^\d.-]/g, '');
4007		number = parseFloat(number);
4008		if (isNaN(number)) number = 0;
4009		return number;
4010	};
4011
4012	ferve.formatMoney = function (number, decimals) {
4013		// Pass negative decimals to only format decimals if has a cent value
4014		if (decimals < 0) {
4015			if (number.toString().indexOf(".") == -1) {
4016				decimals = 0;
4017			} else {
4018				decimals = Math.abs(decimals);
4019			}
4020		}
4021		try {
4022			var formatter = new Intl.NumberFormat(ferve.currencyName, {
4023				style: "currency",
4024				currency: ferve.currencyCode,
4025				minimumFractionDigits: decimals,
4026			});
4027			number = formatter.format(number);
4028			return number;
4029		}
4030		catch (e) {
4031			ferve.log("ferve.formatMoney(" + number + ", " + decimals + ") error");
4032			number = Number(number).toFixed(decimals);
4033			return ferve.currencySymbol + number.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
4034		}
4035	};
4036
4037	ferve.parseFTReturn = function (s) {
4038		s = unescape(s);
4039		try {
4040			var ftReturn = JSON.parse(s);
4041			if (!ftReturn || typeof ftReturn.Success === "undefined" || ftReturn.Success.length == 0) {
4042				ferve.log(s);
4043				ferve.log(ftReturn);
4044				throw "\n\nftReturn is invalid.\n\n" + s + "\n\n";
4045			}
4046		}
4047		catch (e) {
4048			alert("An error occurred:\n\n" + e);
4049			return null;
4050		}
4051		return ftReturn;
4052	};
4053
4054	ferve.voting = function () { };
4055	ferve.voting.itemHash = "";
4056	ferve.voting.returnStars = function (itemId) { };
4057
4058
4059	ferve.renderWishlistStars = function () {
4060		ferve.log("ferve.renderWishlistStars()");
4061		var inWL;
4062		var stars = document.querySelectorAll("[data-wishlist]");
4063		ferve.log("Wishlist stars found " + stars.length);
4064		for (var i = 0; i < stars.length; i++) {
4065			inWL = false;
4066			var itemId = stars[i].getAttribute("data-wishlist");
4067			for (var j = 0; j < ferve.wishlist.itemIds.length; j++) {
4068				if (itemId == ferve.wishlist.itemIds[j]) {
4069					inWL = true;
4070					break;
4071				}
4072			}
4073			if (!inWL) {
4074				stars[i].className = stars[i].className.replace("fticon-wishlist-on", "fticon-wishlist-off");
4075			} else {
4076				stars[i].className = stars[i].className.replace("fticon-wishlist-off", "fticon-wishlist-on");
4077			}
4078		}
4079	};
4080
4081	ferve.calendar = function () { };
4082	var calendarStatus, calendarRequest, calendarReferred = false;
4083	var calendarDayNames = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], calendarMonthNames = ["January", "February", "March", "April", "May", "June",
4084		"July", "August", "September", "October", "November", "December"];
4085
4086	ferve.calendar.render = function (itemHash, increment, newDate) {
4087		if (calendarRequest) calendarRequest.abort();
4088
4089		var calendar = ft_calendar(itemHash);
4090		if (!calendar) return;
4091		ferve.log("ferve.calendar.render(" + itemHash + ")");
4092
4093		var date = new Date(calendar.getAttribute("data-date"));
4094		if (typeof increment == "number") {
4095			date = new Date(date.getFullYear(), (date.getMonth() + increment), 1);
4096			calendar.setAttribute("data-date", new Date(date.getTime() - (date.getTimezoneOffset() * 60000)).toISOString().split("T")[0]);
4097			calendar.setAttribute("data-dateevent", new Date(date.getTime() - (date.getTimezoneOffset() * 60000)).toISOString().split("T")[0]);
4098		}
4099
4100		var dateEvent = new Date(calendar.getAttribute("data-dateevent"));
4101		if (typeof increment == "number") dateEvent = null;
4102
4103		if (newDate) {
4104			date = newDate;
4105			dateEvent = newDate;
4106			calendar.setAttribute("data-date", new Date(date.getTime() - (date.getTimezoneOffset() * 60000)).toISOString().split("T")[0]);
4107		}
4108
4109		calendar.querySelectorAll(".ft_ed_cal_monthSwitch:first-child, .ft_ed_cal_monthSwitch_disabled")[0].innerHTML = "<a href=\"Javascript:ferve.calendar.render('" + itemHash + "',-1)\">&lt;</a>";
4110		calendar.querySelector(".ft_ed_cal_monthSwitch:last-child").innerHTML = "<a href=\"Javascript:ferve.calendar.render('" + itemHash + "',1)\">&gt;</a>"
4111		calendar.querySelectorAll(".ft_ed_cal_monthSwitch:first-child, .ft_ed_cal_monthSwitch_disabled")[0].className = (new Date(date.getFullYear(), date.getMonth(), 0) < new Date ? "ft_ed_cal_monthSwitch ft_ed_cal_monthSwitch_disabled" : "ft_ed_cal_monthSwitch");
4112
4113		calendar.querySelector(".ft_ed_cal_month").innerHTML = calendarMonthNames[date.getMonth()] + " " + date.getFullYear();
4114
4115		// Clean up previous calendar rows
4116		var rows = calendar.querySelectorAll(".ft_ed_cal_row");
4117		for (var i = 0; i < rows.length; i++) {
4118			rows[i].parentNode.removeChild(rows[i]);
4119		}
4120
4121		var firstDay = date.getDay();
4122		if (firstDay == 0) firstDay = 7;
4123		firstDay--;
4124
4125		rows = Math.ceil((new Date(date.getFullYear(), (date.getMonth() + 1), 0).getDate() + firstDay) / 7);
4126
4127		// Previous months
4128		var divRow = document.createElement("div");
4129		divRow.className = "ft_ed_cal_row";
4130		if (firstDay > 0) {
4131			for (var column = (new Date(date.getFullYear(), (date.getMonth()), 0).getDate() - firstDay + 1); column <= new Date(date.getFullYear(), (date.getMonth()), 0).getDate(); column++) {
4132				var divColumn = document.createElement("div");
4133				divColumn.className = "ft_ed_cal_column ft_ed_cal_columnInactive";
4134				divColumn.innerHTML = "<a href=\"Javascript:ferve.calendar.render('" + itemHash + "',-1)\">" + column + "</a>";
4135				divRow.appendChild(divColumn);
4136			}
4137		}
4138
4139		var day = 1, columnClass = "ft_ed_cal_column";
4140		for (var row = 1; row <= rows; row++) {
4141			if (row > 1) {
4142				divRow = document.createElement("div");
4143				divRow.className = "ft_ed_cal_row";
4144			}
4145
4146			var month = date.getMonth()
4147			for (var column = (row == 1 ? (firstDay + 1) : 1); column <= 7; column++) {
4148				var divColumn = document.createElement("div");
4149				if (columnClass.indexOf("ft_ed_cal_columnInactive") == -1) divColumn.setAttribute("data-day", day);
4150				var columnDate = new Date(date.getFullYear(), month, day);
4151				divColumn.setAttribute("data-date", new Date(columnDate.getTime() - (columnDate.getTimezoneOffset() * 60000)).toISOString().split("T")[0]);
4152				divColumn.className = columnClass;
4153				if (date.getYear() == new Date().getYear() && month == new Date().getMonth() && day == new Date().getDate()) divColumn.className += " ft_ed_cal_column_today";
4154				if (dateEvent && new Date(date.getFullYear(), month, day).toDateString() == dateEvent.toDateString()) divColumn.className += " ft_ed_cal_column_selected";
4155				divColumn.innerHTML = (columnClass.indexOf("ft_ed_cal_columnInactive") > -1 ? "<a href=\"Javascript:ferve.calendar.render('" + itemHash + "',1)\">" + day + "</a>" : day);
4156				divRow.appendChild(divColumn);
4157
4158				day++;
4159				if (day > new Date(date.getFullYear(), (date.getMonth() + 1), 0).getDate()) {
4160					day = 1;
4161					month++;
4162					columnClass = "ft_ed_cal_column ft_ed_cal_columnInactive";
4163				}
4164			}
4165
4166			calendar.appendChild(divRow);
4167		}
4168
4169		var divSpacer = document.createElement("div");
4170		divSpacer.className = "ft_ed_cal_footer";
4171		calendar.appendChild(divSpacer);
4172
4173		if (increment) {
4174			var dates = (document.getElementById("ft_eventDates") || document.getElementById("ft_eventDates_" + itemHash));
4175			if (dates) dates.innerHTML = "";
4176			var pricing = ft_findPricingDiv(itemHash);
4177			if (pricing) pricing.innerHTML = "";
4178		}
4179
4180		ft_calendarStatus(itemHash, date);
4181	};
4182
4183	ferve.calendar.dateSelected = function (itemHash, dateHash, date) {
4184		ferve.log("dateSelected(" + itemHash + ", " + dateHash + ", " + date + ")");
4185		if (ferve_api) {
4186			var pricing = (document.getElementById("ft_eventPricing") || document.getElementById("ft_eventPricing_" + itemHash));
4187			var times = (document.getElementById("ft_eventDates") || document.getElementById("ft_eventDates_" + itemHash));
4188			var calendar = ft_calendar(itemHash);
4189			var selected = calendar.querySelector(".ft_ed_cal_column_selected");
4190			if (selected) selected.className = "ft_ed_cal_column";
4191			//selected = calendar.querySelector("div[data-day='" + day + "']");
4192			// Find exact date instead of just day
4193			selected = calendar.querySelector("div[data-date='" + date + "']");
4194			
4195			if (selected) selected.className = "ft_ed_cal_column ft_ed_cal_column_selected";
4196
4197			pricing.innerHTML = "";
4198
4199			//var status = calendarStatus.find(x => x.Date.getDate() == day);
4200			// Find status using exact date
4201			var status = calendarStatus.find(x => new Date(x.Date.getTime() - (x.Date.getTimezoneOffset() * 60000)).toISOString().split("T")[0] == date);
4202			
4203			if (times && (status.Count > 1 || status.TimeSlots > 0)) {
4204				ferve.pricing.returnEventTimes(itemHash, dateHash);
4205			} else {
4206				times.innerHTML = "";
4207				ferve.pricing.returnEventPricing(dateHash, null, null, true);
4208			}
4209
4210		} else if (ferve.ftwp()) {
4211			sessionShow(event, dateHash);
4212
4213		} else {
4214			var url = document.location.pathname.split("/").slice(0, 3).join("/") + "/";
4215			//var cal = document.getElementById("ft_ed_cal");
4216			//var date;
4217
4218			//if (cal) {
4219			//	date = new Date(cal.getAttribute("data-date"));
4220			//	date = new Date(date.getFullYear(), date.getMonth(), day);
4221			//}
4222
4223			//var date = new Date(document.getElementById("ft_ed_cal").getAttribute("data-date"));
4224			//date = new Date(date.getFullYear(), date.getMonth(), day);
4225
4226			// date is passed in as "2026-10-01"
4227			var selectedDate = new Date(date + "T00:00:00");
4228
4229			for (var i = 0; i < calendarStatus.length; i++) {
4230			
4231				var statusDate = new Date(
4232					calendarStatus[i].Date.getTime() -
4233					(calendarStatus[i].Date.getTimezoneOffset() * 60000)
4234				).toISOString().split("T")[0];
4235
4236				if (statusDate == date) {
4237					selectedDate = calendarStatus[i].Date;
4238					break;
4239				}
4240			}
4241
4242			url += calendarDayNames[selectedDate.getDay()].substring(0, 3) + "-" + calendarMonthNames[selectedDate.getMonth()].substring(0, 3) + "-" + selectedDate.getDate() + "-" + selectedDate.getFullYear() + "-" + (selectedDate.getHours() < 10 ? "0" : "") + selectedDate.getHours() + "-" + (selectedDate.getMinutes() < 10 ? "0" : "") + selectedDate.getMinutes();
4243			if (ferve.isMobile()) url += "#ft_calendar";
4244
4245			ferve.toggleWaiting(true);
4246			document.location.href = url;
4247		}
4248	};
4249
4250	function ft_calendar(itemHash) {
4251		var parent = (document.getElementById("ft_ed_cal") ? document : document.getElementById("ft_eventCalendar_" + itemHash));
4252		if (!parent) return null;
4253
4254		return parent.querySelector(".ft_ed_cal");
4255	}
4256
4257	function ft_calendarStatus(itemHash, date) {
4258		calendarRequest = ferve.xmlHttpRequest(ferve.url + "api/v1/Pricing/Status?hash=" + ferve.visitor.hash + "&itemHash=" + itemHash + "&date=" + new Date(date.getTime() - (date.getTimezoneOffset() * 60000)).toISOString().split("T")[0], "GET", null, "", "", "ftd_calendarStatus('" + itemHash + "',");
4259	}
4260
4261	function ftd_calendarStatus(itemHash, s) {
4262		ferve.log("ftd_calendarStatus()");
4263		var ftReturn = ferve.parseFTReturn(s);
4264		if (!ftReturn || !ftReturn.Success) return;
4265		var calendar = ft_calendar(itemHash);
4266		if (!calendar) return;
4267
4268		// Look at the referrer for a date (BF)
4269		var date = null;
4270		if (!calendarReferred) {
4271			var referrer = document.referrer;
4272			//referrer = "https://ferve.tickets/event-date/sun-1-jun/";
4273			var regExp = /event-date\/[a-z]*-(\d*)-([a-z]*)/;
4274			var match = regExp.exec(referrer);
4275			if (match && match.length == 3) {
4276				var month = ["january", "february", "march", "april", "may", "june", "july", "august", "september", "october", "november", "december"].indexOf(match[2])
4277				if (month == -1) month = ["jan", "feb", "mar", "apr", "may", "jun", "jul", "aug", "sep", "oct", "nov", "dec"].indexOf(match[2])
4278				if (ferve.isNumeric(match[1]) && month != -1) {
4279					date = new Date();
4280					date.setDate(match[1]);
4281					date.setMonth(month);
4282					var calDate = new Date(calendar.getAttribute("data-date"));
4283					if (month != calDate.getMonth()) {
4284						ferve.calendar.render(itemHash, null, date);
4285						return;
4286					}
4287				}
4288			}
4289		}
4290		calendarReferred = true;
4291
4292		calendarStatus = JSON.parse(window.atob(ftReturn.SuccessMessages[0]));
4293		ferve.log(calendarStatus);
4294		for (var i = 0; i < calendarStatus.length; i++) {
4295			calendarStatus[i].Date = new Date(calendarStatus[i].Date);
4296
4297			if (date && date.toDateString() == calendarStatus[i].Date.toDateString()) {
4298				// Date set by referrer - select pricing
4299				ferve.log("ftd_calendarStatus() Selecting pricing for " + date.toDateString());
4300				ferve.calendar.dateSelected(itemHash, calendarStatus[i].Hash, new Date(
4301					calendarStatus[i].Date.getTime() -
4302					(calendarStatus[i].Date.getTimezoneOffset() * 60000)
4303				).toISOString().split("T")[0]);
4304			}
4305
4306			//var x = calendar.querySelector("div[data-day='" + calendarStatus[i].Date.getDate() + "']");
4307		
4308			var statusDate = new Date( calendarStatus[i].Date.getTime() - (calendarStatus[i].Date.getTimezoneOffset() * 60000)).toISOString().split("T")[0];
4309
4310			var x = calendar.querySelector("div[data-date='" + statusDate + "']");
4311
4312			if (!x) continue;
4313			//x.innerHTML = (x.classList.contains("ft_ed_cal_columnInactive") ? "<a href=\"Javascript:ferve.calendar.render('" + itemHash + "',1)\">" + calendarStatus[i].Date.getDate() + "</a>" : "<a href=\"Javascript:ferve.calendar.dateSelected('" + itemHash + "','" + calendarStatus[i].Hash + "'," + calendarStatus[i].Date.getDate() + ")\">" + calendarStatus[i].Date.getDate() + "</a>");
4314
4315			x.innerHTML = "<a href=\"Javascript:ferve.calendar.dateSelected('" + itemHash + "','" + calendarStatus[i].Hash + "','" + statusDate + "')\">" + calendarStatus[i].Date.getDate() + "</a>"
4316
4317			if (calendarStatus[i].Value < 20) calendarStatus[i].Value = 20;
4318			var className = "ft_ed_cal_normal";
4319			if (calendarStatus[i].Value >= 100) {
4320				className = "ft_ed_cal_soldOut";
4321			} else if (calendarStatus[i].Value >= 75) {
4322				className = "ft_ed_cal_sellingFast";
4323			}
4324			x.innerHTML += "<div class=\"ft_ed_cal_status " + className + "\" data-width=\"" + calendarStatus[i].Value + "\">&nbsp;</div>";
4325		}
4326
4327		setTimeout(function () {
4328			var statuses = calendar.querySelectorAll(".ft_ed_cal_status");
4329			for (var i = 0; i < statuses.length; i++) {
4330				statuses[i].style.width = statuses[i].getAttribute("data-width") + "%";
4331			}
4332		}, 50);
4333	}
4334
4335	function ft_calendarReferrerDate() {
4336		calendarRequest = ferve.xmlHttpRequest(ferve.url + "api/v1/Pricing/Status?hash=" + ferve.visitor.hash + "&itemHash=" + itemHash + "&date=" + new Date(date.getTime() - (date.getTimezoneOffset() * 60000)).toISOString().split("T")[0], "GET", null, "", "", "ftd_calendarStatus('" + itemHash + "',");
4337	}
4338
4339
4340	ferve.media = function () { };
4341	var mediaPlay = false;
4342	ferve.media.play = function (hash) {
4343		if (mediaPlay) return;
4344		ferve.toggleWaiting(true);
4345		mediaPlay = true;
4346
4347		var width = (screen.width > 1200 ? 1200 : 800), height = 600;
4348
4349		if (hash.indexOf("Account/") > -1 || hash.indexOf("Subscription/") > -1) {
4350			var windowPlay = window.open(ferve.url + hash, "Watch", "directories=no,titlebar=no,toolbar=no,location=no,status=no,menubar=no,scrollbars=no,resizable=yes,width=" 
4350+ width + ",height=" + height);
4351			windowPlay[windowPlay.addEventListener ? "addEventListener" : "attachEvent"](
4352				(windowPlay.attachEvent ? "on" : "") + "load", function () { ferve.toggleWaiting(false); }, false
4353			);
4354			mediaPlay = false;
4355			return;
4356		}
4357
4358		var xhr = new XMLHttpRequest();
4359		xhr.open("POST", ferve.url + "api/v1/Visitors/Play?hash=" + ferve.visitor.hash + "&media=" + hash, false);
4360		xhr.send(null);
4361		if (xhr.readyState == XMLHttpRequest.DONE) {
4362			ferve.toggleWaiting(false);
4363			mediaPlay = false;
4364			var ftReturn = ferve.parseFTReturn(xhr.responseText);
4365			if (ftReturn) {
4366				if (ftReturn.Success) {
4367					window.open(ftReturn.SuccessMessages[0], "Watch", "directories=no,titlebar=no,toolbar=no,location=no,status=no,menubar=no,scrollbars=no,resizable=yes,width=" + width + ",height=" + height);
4368				} else {
4369					ferve.notification.show("alert", "red", "An error occurred.<br /><i>" + ftReturn.Errors[0].CustomerMessage + "</i>", null, null, null);
4370				}
4371			}
4372		} else {
4373			ferve.toggleWaiting(false);
4374			mediaPlay = false;
4375			ferve.notification.show("alert", "red", "An error occurred.<br /><i>" + xhr.statusText + "</i>", null, null, null);
4376		}
4377	};
4378
4379
4380
4381	// #mark ------ Private Methods  ------
4382
4383	var fcItem = function (item) {
4384		var itemValue = "";
4385
4386		try {
4387			itemValue = window.atob(ferveCookie[item]);
4388		}
4389		catch (e) {
4390			ferve.log("fcItem error retrieving item " + item + ": " + e.message);
4391		}
4392		return itemValue;
4393	};
4394
4395	var getCookie = function (name) {
4396		name += "=";
4397		var ca = document.cookie.split(';');
4398		for (var i = 0; i < ca.length; i++) {
4399			var c = ca[i].replace(/^\s+|\s+$/g, "");
4400			if (c.indexOf(name) == 0) return unescape(c.substring(name.length, c.length));
4401		}
4402		return "";
4403	};
4404
4405	function ft_timeoutMessage() {
4406		ferve.log("ft_timeoutMessage()");
4407		if (ferve.cart.count == 0 || typeof (ftwp) == "undefined" || ferve.ftwp() || ferve.isApp()) return;
4408		setTimeout(function () {
4409			ferve.notification.show("alert", "blue", "Your session is about to expire, please checkout now to complete your purchase.", null, null, null);
4410		}, 20 * 60 * 1000);
4411	}
4412
4413	function ft_stripHtml(html, lineBreaks) {
4414		if (lineBreaks) {
4415			html = html.replaceAll("<br />", "\n");
4416			html = html.replaceAll("<p>", "\n\n");
4417			html = html.replaceAll("<td/>", "\n");
4418			html = html.replaceAll("</p>", "");
4419		}
4420
4421		var tmp = document.createElement("DIV");
4422		tmp.innerHTML = html;
4423		return tmp.textContent || tmp.innerText || "";
4424	}
4425
4426
4427	function initTimer() {
4428		ferve.log("initTimer()");
4429		var timer = document.getElementById("ft_timer");
4430		if (timer) {
4431			if (ferve.cart.qty == 0) {
4432				timer.style.opacity = 0;
4433			} else {
4434				var timeoutMinutes = 20;
4435				var delimiter = ":";
4436				var span = timer.getElementsByTagName("span");
4437				if (span.length == 1) {
4438					span = span[0];
4439					if (span.innerHTML.length > 0) {
4440						if (span.innerHTML.indexOf(".") > -1) delimiter = ".";
4441						var time = span.innerHTML.split(delimiter);
4442						if (time.length == 2 && ferve.isNumeric(time[0])) timeoutMinutes = parseInt(time[0]);
4443					}
4444
4445					window.ft_timerDate = new Date();
4446					window.ft_timerDate.setMinutes(window.ft_timerDate.getMinutes() + timeoutMinutes);
4447
4448					window.ft_timer = setInterval(function () {
4449						if (window.ft_timerDate < new Date()) {
4450							clearInterval(window.ft_timer);
4451							timer.style.opacity = 0;
4452						}
4453						var secs = Math.floor((window.ft_timerDate.getTime() - new Date().getTime()) / 1000);
4454						var mins = Math.floor(secs / 60).toString();
4455						secs = Math.floor(secs - (mins * 60)).toString();
4456						secs = Array(2 - secs.length + 1).join("0") + secs
4457						span.innerHTML = mins + delimiter + secs;
4458					}, 1000);
4459				}
4460				timer.style.opacity = 1;
4461			}
4462		}
4463		//MP : Append the updated digital data for cart after deleting an item
4464		if (document.body.id == "ft_cart" && ferve != null && ferve.adobeAnalytics) adobeAnalytics();
4465
4466	}
4467
4468	var outputProperties = function (console, html) {
4469		if (!ferve_de) return;
4470		var properties = "";
4471		properties += "hash:\t\t\t\t" + ferve.visitor.hash + "\n";
4472		properties += "loggedIn:\t\t\t" + ferve.visitor.loggedIn + "\n";
4473		properties += "firstName:\t\t\t" + ferve.visitor.firstName + "\n";
4474		properties += "memberType:\t\t\t" + ferve.visitor.memberType + "\n";
4475		properties += "memberExpiryDate:\t" + ferve.visitor.memberExpiryDate + "\n";
4476		properties += "passType:\t\t\t" + ferve.visitor.passType + "\n";
4477		properties += "subscriptions:\t\t" + ferve.visitor.subscriptions + "\n";
4478		properties += "ferveData:\t\t\t" + ferve.visitor.ferveData + "\n";
4479		properties += "count:\t\t\t\t" + ferve.cart.count + "\n";
4480		properties += "qty:\t\t\t\t" + ferve.cart.qty + "\n";
4481		properties += "total:\t\t\t\t" + ferve.cart.total + "\n";
4482		properties += "itemIds:\t\t\t" + ferve.wishlist.itemIds + "\n";
4483		properties += "ferve_tu:\t\t\t" + ferve_tu + "\n";
4484		properties += "ferve_tus:\t\t\t" + ferve_tus + "\n";
4485		properties += "ferve_cache:\t\t" + ferve_cache + "\n";
4486		if (console) ferve.log(properties);
4487		if (html) {
4488			var x = document.getElementById("ft_properties");
4489			if (!x) {
4490				var div = document.createElement("div");
4491				div.style.width = "	250px";
4492				div.style.position = "fixed";
4493				div.style.bottom = "0";
4494				div.style.right = "0";
4495				div.style.padding = "5px";
4496				div.style.background = "#000";
4497				div.style.color = "#28fe13";
4498				div.style.opacity = "0.7";
4499				div.style.fontSize = "9px";
4500				div.id = "ft_properties";
4501				document.body.appendChild(div);
4502				x = document.getElementById("ft_properties");
4503			}
4504			x.innerHTML = properties.replace(new RegExp("\n", "g"), "<br />");
4505		}
4506	};
4507
4508
4509	function ft_isEnterKey(field, e) {
4510		if (!e) e = window.event; // derp IE browser
4511		if (e.keyCode) {
4512			code = e.keyCode;
4513		} else if (e.which) {
4514			code = e.which;
4515		}
4516		return (code == 13);
4517	}
4518
4519
4520	function ft_errors() {
4521		let origin, sending = false;
4522		try {
4523			if (ferve.isNullOrEmpty(ferve_tus)) return;
4524			origin = new URL(ferve_tus).origin;
4525			if (origin !== window.location.origin) return;
4526		} catch {
4527			return;
4528		}
4529
4530		window.addEventListener("error", function (event) {
4531			if (sending || (event && event.target && event.target !== window)) return;
4532			if (ferve_de) console.log("Captured error: ", event);
4533
4534			const { message = "", filename: file = "", lineno: line = 0, colno: column = 0, error = null } = event || {};
4535			const payload = {
4536				discriminator: "JSError",
4537				message: String(message),
4538				page: location.href,
4539				file: file,
4540				line: line,
4541				column: column,
4542				stack: String(error?.stack || ""),
4543				userAgent: navigator.userAgent
4544			};
4545			ft_errors_send(payload);
4546		});
4547
4548		function ft_errors_send(payload) {
4549			const message = (payload.message || ""), stack = (payload.stack || ""), file = (payload.file || "");
4550			if (!message.toLowerCase().includes(origin.toLowerCase()) && !stack.toLowerCase().includes(origin.toLowerCase())) return;
4551			const ignore = ["/Template/", "/elementor/", "/chunks/", "tooltip is not a function", "mecCustomView", "window.webkit.messageHandlers", "at timestamp", "enableDidUserTypeOnKeyboardLogging", "javaEnabled", "Java object is gone"];
4552			if (ignore.some(i => message.toLowerCase().includes(i.toLowerCase()) || stack.toLowerCase().includes(i.toLowerCase()) || file.toLowerCase().includes(i.toLowerCase()))) return;
4553
4554			try {
4555				sending = true;
4556				fetch(ferve.url + "api/v1/Notification/FTAPI", {
4557					method: "POST",
4558					headers: {
4559						"Content-Type": "application/json"
4560					},
4561					body: JSON.stringify(payload),
4562					keepalive: true
4563				}).catch(() => { }).finally(() => {
4564					sending = false;
4565				});
4566
4567			}
4568			catch (e) {
4569				sending = false;
4570			}
4571		}
4572	}
4573
4574
4575	var allocatedseatingSetup = false;
4576	ferve.seating = function (source) {
4577		ferve.log("ferve.seating(" + source + ")");
4578
4579		if (allocatedseatingSetup || typeof ft_seatingInit == "function") {
4580			if (typeof ft_seatingInit != "function") {
4581				ferve.log("Allocated seating already loaded - seating.js not ready");
4582				setTimeout(function () {
4583					ferve.seating(source);
4584				}, 200);
4585				return;
4586			}
4587
4588			ferve.log("Allocated seating already loaded - initting directly");
4589			allocatedseatingSetup = true;
4590			ft_seatingInit(source);
4591			return;
4592		}
4593		allocatedseatingSetup = true;
4594		var script = document.createElement("script");
4595		script.index = i;
4596		script.type = "text/javascript";
4597		script.src = ferve.url + "js/seating.js?v=" + ferve.version;
4598		document.getElementsByTagName("head")[0].appendChild(script);
4599	}
4600
4601	ferve.render = function () {
4602		ferve.log("ferve.render " + ferve.itemHash + ", " + ferve.voting.itemHash);
4603		ferve.cart.updateTotals();
4604		// Automatically populate event dates, pricing and wishlist stars
4605		if (ferve.itemHash != "") {
4606			ferve.setContent("ft_wishlist", ferve.wishlist.returnStar(ferve.itemHash, 0, 0));
4607			var x = document.getElementById("ft_eventDates");
4608			if (!x) x = document.getElementById("ft_eventDates_" + ferve.itemHash);
4609			if (x) {
4610				ferve.pricing.returnEventDates(ferve.itemHash);
4611			} else {
4612				x = document.getElementById("ft_eventPricing")
4613				if (!x) x = document.getElementById("ft_eventPricing_" + ferve.itemHash);
4614				ferve.log("ferve.render() calling ferve.pricing.returnEventPricing");
4615				if (x) x = ferve.pricing.returnEventPricing(ferve.itemHash);
4616			}
4617			x = document.getElementById("ft_eventVoting");
4618			if (x) ferve.voting.returnStars((!ferve.isNullOrEmpty(ferve.voting.itemHash) ? ferve.voting.itemHash : ferve.itemHash));
4619
4620
4621		} else {
4622			ferve.log("ferve.render ferve.itemHash blank");
4623			if (ferve.voting.itemHash.length > 0) {
4624				var x = document.getElementById("ft_eventVoting");
4625				if (x) ferve.voting.returnStars(ferve.voting.itemHash);
4626			} else {
4627				ferve.log("ferve.render ferve.voting.itemHash blank");
4628			}
4629		}
4630
4631		if (document.getElementById("ft_rdo_seatingPlan")) ferve.seating("render");
4632
4633		ferve.renderWishlistStars();
4634
4635		var customers = document.querySelectorAll("[data-customer]");
4636		if (customers.length > 0) {
4637			for (var i = 0; i < customers.length; i++) {
4638				var s = customers[i].getAttribute("data-customer");
4639				if (s == "1") s = "";
4640				customers[i].innerHTML = (ferve.visitor.firstName.length > 0 ? ferve.visitor.firstName : s);
4641			}
4642		}
4643
4644		if (ferve.itemHash.length > 0) {
4645			var x = document.getElementById("ft_relatedItems");
4646			if (x && !x.getAttribute("data-loading")) {
4647				x.setAttribute("data-loading", "true");
4648				ferve.pricing.relatedItems();
4649			}
4650		}
4651
4652		initTimer();
4653
4654
4655		if (typeof ft_notification != "undefined" && ft_notification) ferve.notification.show(ft_notification.style, ft_notification.colour, ft_notification.message, null, null, null);
4656	};
4657
4658	// Load ferve API CSS
4659	try {
4660		if (document.getElementById("ft_ftapiJS") && document.getElementById("ft_ftapiJS").getAttribute("data-version") == "ft_v2") throw ("Not loading FTAPI css");
4661		if (ferve.version == "1.7") ferve.visitor.updatePropertiesFromCookie();
4662		var link = document.createElement("link");
4663		link.type = "text/css";
4664		link.rel = "stylesheet";
4665		link.href = ferve.url + "css/FTAPI.css?v=" + ferve.version;
4666		document.getElementsByTagName("head")[0].appendChild(link);
4667	}
4668	catch (e) {
4669		ferve.log("Error loading FTAPI css: " + e.message, "error");
4670	}
4671
4672	try {
4673		if (window.location.pathname.toLowerCase().indexOf("/" + String.fromCharCode(112, 111, 115) + "/") == -1 && !ferve.isApp()) {
4674			if (ferve.version == "1.7") ferve.visitor.updatePropertiesFromCookie();
4675			link = document.createElement("link");
4676			link.type = "text/css";
4677			link.rel = "stylesheet";
4678			link.href = ferve.url + "css/organiser/" + ferve_h + "_widget.css?v=" + ferve.version;
4679			document.getElementsByTagName("head")[0].appendChild(link);
4680		}
4681	}
4682	catch (e) {
4683		ferve.log("Error loading FTAPI organiser css: " + e.message, "error");
4684	}
4685
4686
4687	ferve.init = function (e) {
4688		ferve.log("ferve.init", "info");
4689		if (!ferve_api && e && !e.isTrusted) {
4690			ferve.log("exiting !e.isTrusted", "info");
4691			return;
4692		}
4693		ft_errors();
4694		if (initComplete) {
4695			ferve.log("exiting initComplete", "info");
4696			return;
4697		}
4698
4699
4700		if (document.head.querySelector("meta[name=ft-culture]")) {
4701			var culture = window.atob(document.head.querySelector("meta[name=ft-culture]").content).split("|");
4702			ferve.currencyName = culture[0];
4703			ferve.currencyCode = culture[1];
4704			ferve.currencySymbol = culture[2];
4705		}
4706
4707		ferve.visitor.updatePropertiesFromCookie();
4708		ferve.log("ferve.visitor.hash: " + ferve.visitor.hash, "info");
4709
4710		if (ferve.visitor.hash.length == 0) {
4711			if (ferve.ftwp()) {
4712				ferve.log("ferve.init() ftwp() - exiting init.");
4713				return;
4714			}
4715
4716			ferve.visitor.hash = "new";
4717
4718			var queryString = "";
4719			if (window.location.href.indexOf("?") > -1 && window.location.href.indexOf("utm_") > -1) {
4720				var qsElements = window.location.href.slice(window.location.href.indexOf("?") + 1).split("&");
4721				for (var i = 0; i < qsElements.length; i++) {
4722					if (qsElements[i].substring(0, 4) == "utm_") queryString += "&" + qsElements[i];
4723				}
4724			}
4725
4726			ferve.xmlHttpRequest(ferve.url + "api/v1/Visitors/Activity?hash=" + ferve.visitor.hash + queryString, "GET", null, "", "", "ferve.init_delegate(");
4727			ferve.log("ferve.init() with no visitor - exiting init.");
4728			return;
4729		}
4730
4731		if (document.getElementById("ft_ftapiJS").getAttribute("src").split("?")[1].toLowerCase().indexOf("gdpr=true") > -1) ferve.visitor.cookieConsent();
4732
4733		var ca = ferve.utility.queryStringValue("ft_ca");
4734		if (!ferve.isNullOrEmpty(ca)) {
4735			var cas = window.sessionStorage.getItem("ftca_" + ferve_h);
4736			try {
4737				cas = (!cas ? [] : JSON.parse(cas));
4738			}
4739			catch {
4740				cas = [];
4741			}
4742			if (!cas.find(c => c = ca)) {
4743				cas[cas.length] = ca;
4744				window.sessionStorage.setItem("ftca_" + ferve_h, JSON.stringify(cas));
4745
4746			}
4747		}
4748
4749		ferve.init2(false);
4750	};
4751
4752	ferve.init_delegate = function (s) {
4753		ferve.log("ferve.init_delegate", "info");
4754		var ftReturn = ferve.parseFTReturn(s);
4755		if (ftReturn) {
4756			if (ftReturn.SuccessMessages[0]) {
4757				document.cookie = "ftapi_" + ferve_h + "=" + ftReturn.SuccessMessages[0] + ";domain=" + ftReturn.SuccessMessages[1] + ";path=/";
4758				ferve.visitor.updatePropertiesFromCookie();
4759			}
4760		}
4761		ferve.init2(true);
4762	};
4763
4764	ferve.init2 = function (newVisitor) {
4765		ferve.log("ferve.init2", "info");
4766
4767		if (ferve_api) {
4768			if (typeof (ferveItemHash) != "undefined") {
4769				ferve.log("Setting ferve.itemHash to ferveItemHash (" + ferveItemHash + ")");
4770				ferve.itemHash = ferveItemHash;
4771				ferve.render();
4772
4773			} else {
4774
4775				var scripts = document.querySelectorAll("[id='ft_ftapiJS']");
4776				if (scripts.length == 0) {
4777					ferve.log("ft_ftapiJS not found - exiting!", "error");
4778					return;
4779				}
4780
4781				for (var i = 0; i < scripts.length; i++) {
4782					ferve.log(scripts[i]);
4783
4784					var src = scripts[i].getAttribute("src");
4785					ferve.itemHash = ferve.utility.queryStringValue("itemHash", src);
4786					if (ferve.itemHash == "") {
4787						continue;
4788					} else {
4789						ferve.itemHash = ferve.itemHash.trim();
4790					}
4791
4792					var x = document.getElementById("ft_eventPricing");
4793					if (i > 0 && x) {
4794						ferve.log("Multiple widgets found - resetting x", "error");
4795						x = null;
4796					}
4797					if (!x) x = document.getElementById("ft_eventPricing_" + ferve.itemHash);
4798					if (!x) {
4799						var div = document.createElement("div");
4800						div.id = "ft_eventPricing_" + ferve.itemHash;
4801						div.className = "[checkout]";
4802						scripts[i].parentNode.insertBefore(div, scripts[i].nextSibling);
4803					}
4804					x = document.getElementById("ft_eventDates");
4805					if (i > 0 && x) {
4806						ferve.log("Multiple widgets found - resetting x", "error");
4807						x = null;
4808					}
4809					if (!x) x = document.getElementById("ft_eventDates_" + ferve.itemHash);
4810					if (!x) {
4811						div = document.createElement("div");
4812						div.id = "ft_eventDates_" + ferve.itemHash;
4813						scripts[i].parentNode.insertBefore(div, scripts[i].nextSibling);
4814					}
4815
4816					ferve.render();
4817				}
4818			}
4819		} else {
4820			ferve.render();
4821		}
4822
4823		if (ferve_cache || ferve_api) {
4824			var csrc = ferve.utility.queryStringValue("csrc");
4825			if ((!newVisitor || ferve.itemHash.length > 0 || csrc.length > 0) && !ferve.isApp()) {
4826				ferve.xmlHttpRequest(ferve.url + "api/v1/Visitors/Activity?hash=" + ferve.visitor.hash + (ferve.itemHash.length > 0 ? "&itemHash=" + ferve.itemHash : "") + (csrc.length > 0 ? "&csrc=" + csrc : ""), "GET", null, "", "", "");
4827			}
4828		}
4829
4830		ferve.visitor.location();
4831
4832		ft_timeoutMessage();
4833
4834		var x = document.getElementById("ft_visitorHash");
4835		if (x) x.innerHTML = ferve.visitor.hash;
4836
4837		initComplete = true;
4838
4839		try {
4840			ferveInitComplete();
4841		}
4842		catch (e) { }
4843	};
4844
4845
4846	try {
4847		console.log("%c" + "          " + String.fromCharCode(84, 105, 99, 107, 101, 116, 105, 110, 103, 32, 98, 121, 32, 70, 101, 114, 118, 101, 32, 84, 105, 99, 107, 101, 116, 115, 32, 45, 32, 104, 116, 116, 112, 115, 58, 47, 47, 102, 101, 114, 118, 101, 46, 116, 105, 99, 107, 101, 116, 115) + "          ", "line-height: 25px;padding: 4px 22px;color:#ff5555;border-top:3px solid;border-image:linear-gradient(to right, #62cbe1 12%, #1db7a5 12%, #1db7a5 24%, #f1d210 24%, #f1d210 36%, #f68b1f 36%, #f68b1f 48%, #ef4023 48%, #ef4023 60%, #ce6128 60%, #ce6128 72%, #338cb9 72%, #338cb9 84%, #338cb9 84%, #62cbe1 84%, #62cbe1 100%) 5;border-bottom:3px solid;border-image:linear-gradient(to right, #62cbe1 12%, #1db7a5 12%, #1db7a5 24%, #f1d210 24%, #f1d210 36%, #f68b1f 36%, #f68b1f 48%, #ef4023 48%, #ef4023 60%, #ce6128 60%, #ce6128 72%, #338cb9 72%, #338cb9 84%, #338cb9 84%, #62cbe1 84%, #62cbe1 100%) 5;");
4848		if (ferve_api && (ferve_h == "" || ferve_tu == "" || ferve_tus == "")) {
4849			console.warn("%c Appears the FTAPI js is linked incorrectly", "font-size:20px;background:red;color:white;padding:5px 10px;");
4850		}
4851	}
4852	catch (e) { }
4853
4854	if (window.addEventListener) {
4855		ferve.log("adding ferve.init load event");
4856		window.addEventListener("load", ferve.init, false);
4857	} else if (window.attachEvent) {
4858		window.attachEvent("onload", ferve.init);
4859	}
4860	if (document.readyState === "complete") setTimeout(function () { ferve.init(); }, 100);
4861
4862	return ferve;
4863};
4864
4865var recaptchaOnload = function () {
4866	// Pricing widget
4867	grecaptcha.render("ft_recaptcha-container");
4868}
4869
4870try {
4871	if (!ferve || (ferve && (typeof ferve.nodeName == "undefined" || typeof ferve.visitor != "function"))) ferve = Ferve();
4872}
4873catch (e) {
4874	console.log("Error creating ferve object: " + e.message);
4875	debugger;
4876}

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.