PageSourceSearch

https://iepnw.com/rentals/foam-party/

html iepnw.com collected 2026-09-26 12:24:41 UTC 334,405 bytes, 6,179 lines download raw bytes

1<!doctype html><html dir="ltr" lang="en-US" prefix="og: https://ogp.me/ns#" prefix="og: https://ogp.me/ns#"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1"><link rel="profile" href="https://gmpg.org/xfn/11"><meta name="robots" content="max-image-preview:large" /><link rel="canonical" href="https://iepnw.com/rentals/foam-party/" /><meta name="generator" content="All in One SEO (AIOSEO) 5.0.2" /><meta property="og:locale" content="en_US" /><meta property="og:site_name" content="Inflatable Event Professionals LLC Spanaway WA - Party Rental and Bounce House Rental" /><meta property="og:type" content="article" /><meta property="og:title" content="Foam Party - Inflatable Event Professionals LLC Spanaway WA" /><meta property="og:url" content="https://iepnw.com/rentals/foam-party/" /><meta property="og:image" content="https://iepnw.com/wp-content/uploads/2024/04/logo-IEP-png-small_794854.png" /><meta property="og:image:secure_url" content="https://iepnw.com/wp-content/uploads/2024/04/logo-IEP-png-small_794854.png" /><meta property="article:published_time" content="2024-04-22T13:55:20+00:00" /><meta property="article:modified_time" content="2026-05-09T17:53:05+00:00" /><meta property="article:publisher" content="https://www.facebook.com/InflatableEventProfessionals/" /><meta name="twitter:card" content="summary_large_image" /><meta name="twitter:site" content="@FunWithIEP" /><meta name="twitter:title" content="Foam Party - Inflatable Event Professionals LLC Spanaway WA" /><meta name="twitter:creator" content="@FunWithIEP" /><meta name="twitter:image" content="https://iepnw.com/wp-content/uploads/2024/04/logo-IEP-png-small_794854.png" /> 
1<script type="application/ld+json" class="aioseo-schema">{"@context":"https:\/\/schema.org","@graph":[{"@type":"BreadcrumbList","@id":"https:\/\/iepnw.com\/rentals\/foam-party\/#breadcrumblist","itemListElement":[{"@type":"ListItem","@id":"https:\/\/iepnw.com\/#listItem","position":1,"name":"Home","item":"https:\/\/iepnw.com\/","nextItem":{"@type":"ListItem","@id":"https:\/\/iepnw.com\/rentals\/#listItem","name":"Inventory"}},{"@type":"ListItem","@id":"https:\/\/iepnw.com\/rentals\/#listItem","position":2,"name":"Inventory","item":"https:\/\/iepnw.com\/rentals\/","nextItem":{"@type":"ListItem","@id":"https:\/\/iepnw.com\/rentals\/foam-party\/#listItem","name":"Foam Party"},"previousItem":{"@type":"ListItem","@id":"https:\/\/iepnw.com\/#listItem","name":"Home"}},{"@type":"ListItem","@id":"https:\/\/iepnw.com\/rentals\/foam-party\/#listItem","position":3,"name":"Foam Party","previousItem":{"@type":"ListItem","@id":"https:\/\/iepnw.com\/rentals\/#listItem","name":"Inventory"}}]},{"@type":"Organization","@id":"https:\/\/iepnw.com\/#organization","name":"Inflatable Event Professionals LLC Spanaway WA Inflatable Event Professionals","description":"Party Rental and Bounce House Rental Bounce House and Party Equipment Rentals","url":"https:\/\/iepnw.com\/","email":"[email protected]","telephone":"+12533539797","logo":{"@type":"ImageObject","url":"https:\/\/iepnw.com\/wp-content\/uploads\/2024\/04\/logo-IEP-png-small_794854.png","@id":"https:\/\/iepnw.com\/rentals\/foam-party\/#organizationLogo","width":160,"height":113,"caption":"Inflatable Event Professionals LLC Spanaway WA"},"image":{"@id":"https:\/\/iepnw.com\/rentals\/foam-party\/#organizationLogo"},"sameAs":["https:\/\/www.facebook.com\/InflatableEventProfessionals\/","https:\/\/twitter.com\/FunWithIEP","https:\/\/www.instagram.com\/funwithiep","https:\/\/www.pinterest.com\/funwithiepnw\/_saved\/","https:\/\/www.youtube.com\/UCXu3R7G_Ms8Z99fx6zKOSPw","https:\/\/www.linkedin.com\/company\/inflatable-event-professionals\/","https:\/\/www.yelp.com\/biz\/inflatable-event-professionals-spanaway"]},{"@type":"WebPage","@id":"https:\/\/iepnw.com\/rentals\/foam-party\/#webpage","url":"https:\/\/iepnw.com\/rentals\/foam-party\/","name":"Foam Party - Inflatable Event Professionals LLC Spanaway WA","inLanguage":"en-US","isPartOf":{"@id":"https:\/\/iepnw.com\/#website"},"breadcrumb":{"@id":"https:\/\/iepnw.com\/rentals\/foam-party\/#breadcrumblist"},"image":{"@type":"ImageObject","url":"https:\/\/iepnw.com\/wp-content\/uploads\/2025\/06\/Spanaway20Foam20Party_1746154102_big.jpg","@id":"https:\/\/iepnw.com\/rentals\/foam-party\/#mainImage","width":750,"height":421},"primaryImageOfPage":{"@id":"https:\/\/iepnw.com\/rentals\/foam-party\/#mainImage"},"datePublished":"2024-04-22T13:55:20+00:00","dateModified":"2026-05-09T17:53:05+00:00"},{"@type":"WebSite","@id":"https:\/\/iepnw.com\/#website","url":"https:\/\/iepnw.com\/","name":"Inflatable Event Professionals LLC Spanaway WA","description":"Party Rental and Bounce House Rental","inLanguage":"en-US","publisher":{"@id":"https:\/\/iepnw.com\/#organization"}}]}</script>
1 <link media="all" href="https://iepnw.com/wp-content/cache/autoptimize/css/autoptimize_7802498c8040267670933d8d739e76d9.css" rel="stylesheet"><title>Foam Party - Inflatable Event Professionals LLC Spanaway WA</title><meta name="robots" content="follow, index, max-snippet:-1, max-video-preview:-1, max-image-preview:large"/><link rel="canonical" href="https://iepnw.com/rentals/foam-party/" /><meta property="og:locale" content="en_US" /><meta property="og:type" content="article" /><meta property="og:title" content="Foam Party - Inflatable Event Professionals LLC Spanaway WA" /><meta property="og:url" content="https://iepnw.com/rentals/foam-party/" /><meta property="og:site_name" content="Inflatable Event Professionals LLC Spanaway WA" /><meta property="og:updated_time" content="2026-05-09T17:53:05+00:00" /><meta property="og:image" content="https://iepnw.com/wp-content/uploads/2025/06/Spanaway20Foam20Party_1746154102_big.jpg" /><meta property="og:image:secure_url" content="https://iepnw.com/wp-content/uploads/2025/06/Spanaway20Foam20Party_1746154102_big.jpg" /><meta property="og:image:width" content="750" /><meta property="og:image:height" content="421" /><meta property="og:image:alt" content="Foam Party" /><meta property="og:image:type" content="image/jpeg" /><meta name="twitter:card" content="summary_large_image" /><meta name="twitter:title" content="Foam Party - Inflatable Event Professionals LLC Spanaway WA" /><meta name="twitter:image" content="https://iepnw.com/wp-content/uploads/2025/06/Spanaway20Foam20Party_1746154102_big.jpg" /><meta name="twitter:label1" content="Time to read" /><meta name="twitter:data1" content="9 minutes" /> 
1<script type="application/ld+json" class="rank-math-schema">{"@context":"https://schema.org","@graph":[{"@type":"BreadcrumbList","@id":"https://iepnw.com/rentals/foam-party/#breadcrumb","itemListElement":[{"@type":"ListItem","position":"1","item":{"@id":"https://iepnw.com","name":"Home"}},{"@type":"ListItem","position":"2","item":{"@id":"https://iepnw.com/rentals/","name":"Inventory"}},{"@type":"ListItem","position":"3","item":{"@id":"https://iepnw.com/rentals/foam-party/","name":"Foam Party"}}]}]}</script>
1 <link rel='dns-prefetch' href='//cdnjs.cloudflare.com' /><link rel="alternate" type="application/rss+xml" title="Inflatable Event Professionals LLC Spanaway WA &raquo; Feed" href="https://iepnw.com/feed/" /><link rel="alternate" type="application/rss+xml" title="Inflatable Event Professionals LLC Spanaway WA &raquo; Comments Feed" href="https://iepnw.com/comments/feed/" /><link rel="alternate" title="oEmbed (JSON)" type="application/json+oembed" href="https://iepnw.com/wp-json/oembed/1.0/embed?url=https%3A%2F%2Fiepnw.com%2Frentals%2Ffoam-party%2F" /><link rel="alternate" title="oEmbed (XML)" type="text/xml+oembed" href="https://iepnw.com/wp-json/oembed/1.0/embed?url=https%3A%2F%2Fiepnw.com%2Frentals%2Ffoam-party%2F&#038;format=xml" />
vendor: 53 bytes, line 1
1  <script src="//www.googletagmanager.com/gtag/js?id=
1G-TCDEV928T3
vendor: 88 bytes, line 1
1"  data-cfasync="false" data-wpfc-render="false" type="text/javascript" async></script> 
1<script data-cfasync="false" data-wpfc-render="false" type="text/javascript">var mi_version = '11.3.0';
2				var mi_track_user = true;
3				var mi_no_track_reason = '';
4								var MonsterInsightsDefaultLocations = {"page_location":"https:\/\/iepnw.com\/rentals\/foam-party\/"};
5								if ( typeof MonsterInsightsPrivacyGuardFilter === 'function' ) {
6					var MonsterInsightsLocations = (typeof MonsterInsightsExcludeQuery === 'object') ? MonsterInsightsPrivacyGuardFilter( MonsterInsightsExcludeQuery ) : MonsterInsightsPrivacyGuardFilter( MonsterInsightsDefaultLocations );
7				} else {
8					var MonsterInsightsLocations = (typeof MonsterInsightsExcludeQuery === 'object') ? MonsterInsightsExcludeQuery : MonsterInsightsDefaultLocations;
9				}
10
11								var disableStrs = [
12										'ga-disable-G-TCDEV928T3',
13									];
14
15				/* Function to detect opted out users */
16				function __gtagTrackerIsOptedOut() {
17					for (var index = 0; index < disableStrs.length; index++) {
18						if (document.cookie.indexOf(disableStrs[index] + '=true') > -1) {
19							return true;
20						}
21					}
22
23					return false;
24				}
25
26				/* Disable tracking if the opt-out cookie exists. */
27				if (__gtagTrackerIsOptedOut()) {
28					for (var index = 0; index < disableStrs.length; index++) {
29						window[disableStrs[index]] = true;
30					}
31				}
32
33				/* Opt-out function */
34				function __gtagTrackerOptout() {
35					for (var index = 0; index < disableStrs.length; index++) {
36						document.cookie = disableStrs[index] + '=true; expires=Thu, 31 Dec 2099 23:59:59 UTC; path=/';
37						window[disableStrs[index]] = true;
38					}
39				}
40
41				if ('undefined' === typeof gaOptout) {
42					function gaOptout() {
43						__gtagTrackerOptout();
44					}
45				}
46								window.dataLayer = window.dataLayer || [];
47
48				window.MonsterInsightsDualTracker = {
49					helpers: {},
50					trackers: {},
51				};
52				if (mi_track_user) {
53					function __gtagDataLayer() {
54						dataLayer.push(arguments);
55					}
56
57					function __gtagTracker(type, name, parameters) {
58						if (!parameters) {
59							parameters = {};
60						}
61
62						if (parameters.send_to) {
63							__gtagDataLayer.apply(null, arguments);
64							return;
65						}
66
67						if (type === 'event') {
68														parameters.send_to = monsterinsights_frontend.v4_id;
69							var hookName = name;
70							if (typeof parameters['event_category'] !== 'undefined') {
71								hookName = parameters['event_category'] + ':' + name;
72							}
73
74							if (typeof MonsterInsightsDualTracker.trackers[hookName] !== 'undefined') {
75								MonsterInsightsDualTracker.trackers[hookName](parameters);
76							} else {
77								__gtagDataLayer('event', name, parameters);
78							}
79							
80						} else {
81							__gtagDataLayer.apply(null, arguments);
82						}
83					}
84
85					__gtagTracker('js', new Date());
86					__gtagTracker('set', {
87						'developer_id.dZGIzZG': true,
88											});
89					if ( MonsterInsightsLocations.page_location ) {
90						__gtagTracker('set', MonsterInsightsLocations);
91					}
92										__gtagTracker('config', 'G-TCDEV928T3', {"forceSSL":"true","link_attribution":"true"} );
93										window.gtag = __gtagTracker;										(function () {
94						/* https://developers.google.com/analytics/devguides/collection/analyticsjs/ */
95						/* ga and __gaTracker compatibility shim. */
96						var noopfn = function () {
97							return null;
98						};
99						var newtracker = function () {
100							return new Tracker();
101						};
102						var Tracker = function () {
103							return null;
104						};
105						var p = Tracker.prototype;
106						p.get = noopfn;
107						p.set = noopfn;
108						p.send = function () {
109							var args = Array.prototype.slice.call(arguments);
110							args.unshift('send');
111							__gaTracker.apply(null, args);
112						};
113						var __gaTracker = function () {
114							var len = arguments.length;
115							if (len === 0) {
116								return;
117							}
118							var f = arguments[len - 1];
119							if (typeof f !== 'object' || f === null || typeof f.hitCallback !== 'function') {
120								if ('send' === arguments[0]) {
121									var hitConverted, hitObject = false, action;
122									if ('event' === arguments[1]) {
123										if ('undefined' !== typeof arguments[3]) {
124											hitObject = {
125												'eventAction': arguments[3],
126												'eventCategory': arguments[2],
127												'eventLabel': arguments[4],
128												'value': arguments[5] ? arguments[5] : 1,
129											}
130										}
131									}
132									if ('pageview' === arguments[1]) {
133										if ('undefined' !== typeof arguments[2]) {
134											hitObject = {
135												'eventAction': 'page_view',
136												'page_path': arguments[2],
137											}
138										}
139									}
140									if (typeof arguments[2] === 'object') {
141										hitObject = arguments[2];
142									}
143									if (typeof arguments[5] === 'object') {
144										Object.assign(hitObject, arguments[5]);
145									}
146									if ('undefined' !== typeof arguments[1].hitType) {
147										hitObject = arguments[1];
148										if ('pageview' === hitObject.hitType) {
149											hitObject.eventAction = 'page_view';
150										}
151									}
152									if (hitObject) {
153										action = 'timing' === arguments[1].hitType ? 'timing_complete' : hitObject.eventAction;
154										hitConverted = mapArgs(hitObject);
155										__gtagTracker('event', action, hitConverted);
156									}
157								}
158								return;
159							}
160
161							function mapArgs(args) {
162								var arg, hit = {};
163								var gaMap = {
164									'eventCategory': 'event_category',
165									'eventAction': 'event_action',
166									'eventLabel': 'event_label',
167									'eventValue': 'event_value',
168									'nonInteraction': 'non_interaction',
169									'timingCategory': 'event_category',
170									'timingVar': 'name',
171									'timingValue': 'value',
172									'timingLabel': 'event_label',
173									'page': 'page_path',
174									'location': 'page_location',
175									'title': 'page_title',
176									'referrer' : 'page_referrer',
177								};
178								for (arg in args) {
179																		if (!(!args.hasOwnProperty(arg) || !gaMap.hasOwnProperty(arg))) {
180										hit[gaMap[arg]] = args[arg];
181									} else {
182										hit[arg] = args[arg];
183									}
184								}
185								return hit;
186							}
187
188							try {
189								f.hitCallback();
190							} catch (ex) {
191							}
192						};
193						__gaTracker.create = newtracker;
194						__gaTracker.getByName = newtracker;
195						__gaTracker.getAll = function () {
196							return [];
197						};
198						__gaTracker.remove = noopfn;
199						__gaTracker.loaded = true;
200						window['__gaTracker'] = __gaTracker;
201					})();
202									} else {
203										console.log("");
204					(function () {
205						function __gtagTracker() {
206							return null;
207						}
208
209						window['__gtagTracker'] = __gtagTracker;
210						window['gtag'] = __gtagTracker;
211					})();
212									}</script>
212 <style id="wp-img-auto-sizes-contain-inline-css">img:is([sizes=auto i],[sizes^="auto," i]){contain-intrinsic-size:3000px 1500px}
213/*# sourceURL=wp-img-auto-sizes-contain-inline-css */</style><style id="classic-theme-styles-inline-css">/*! This file is auto-generated */
214.wp-block-button__link{color:#fff;background-color:#32373c;border-radius:9999px;box-shadow:none;text-decoration:none;padding:calc(.667em + 2px) calc(1.333em + 2px);font-size:1.125em}.wp-block-file__button{background:#32373c;color:#fff;text-decoration:none}
215/*# sourceURL=/wp-includes/css/classic-themes.min.css */</style><style id="global-styles-inline-css">:root{--wp--preset--aspect-ratio--square: 1;--wp--preset--aspect-ratio--4-3: 4/3;--wp--preset--aspect-ratio--3-4: 3/4;--wp--preset--aspect-ratio--3-2: 3/2;--wp--preset--aspect-ratio--2-3: 2/3;--wp--preset--aspect-ratio--16-9: 16/9;--wp--preset--aspect-ratio--9-16: 9/16;--wp--preset--color--black: #000000;--wp--preset--color--cyan-bluish-gray: #abb8c3;--wp--preset--color--white: #ffffff;--wp--preset--color--pale-pink: #f78da7;--wp--preset--color--vivid-red: #cf2e2e;--wp--preset--color--luminous-vivid-orange: #ff6900;--wp--preset--color--luminous-vivid-amber: #fcb900;--wp--preset--color--light-green-cyan: #7bdcb5;--wp--preset--color--vivid-green-cyan: #00d084;--wp--preset--color--pale-cyan-blue: #8ed1fc;--wp--preset--color--vivid-cyan-blue: #0693e3;--wp--preset--color--vivid-purple: #9b51e0;--wp--preset--gradient--vivid-cyan-blue-to-vivid-purple: linear-gradient(135deg,rgb(6,147,227) 0%,rgb(155,81,224) 100%);--wp--preset--gradient--light-green-cyan-to-vivid-green-cyan: linear-gradient(135deg,rgb(122,220,180) 0%,rgb(0,208,130) 100%);--wp--preset--gradient--luminous-vivid-amber-to-luminous-vivid-orange: linear-gradient(135deg,rgb(252,185,0) 0%,rgb(255,105,0) 100%);--wp--preset--gradient--luminous-vivid-orange-to-vivid-red: linear-gradient(135deg,rgb(255,105,0) 0%,rgb(207,46,46) 100%);--wp--preset--gradient--very-light-gray-to-cyan-bluish-gray: linear-gradient(135deg,rgb(238,238,238) 0%,rgb(169,184,195) 100%);
215--wp--preset--gradient--cool-to-warm-spectrum: linear-gradient(135deg,rgb(74,234,220) 0%,rgb(151,120,209) 20%,rgb(207,42,186) 40%,rgb(238,44,130) 60%,rgb(251,105,98) 80%,rgb(254,248,76) 100%);--wp--preset--gradient--blush-light-purple: linear-gradient(135deg,rgb(255,206,236) 0%,rgb(152,150,240) 100%);--wp--preset--gradient--blush-bordeaux: linear-gradient(135deg,rgb(254,205,165) 0%,rgb(254,45,45) 50%,rgb(107,0,62) 100%);--wp--preset--gradient--luminous-dusk: linear-gradient(135deg,rgb(255,203,112) 0%,rgb(199,81,192) 50%,rgb(65,88,208) 100%);--wp--preset--gradient--pale-ocean: linear-gradient(135deg,rgb(255,245,203) 0%,rgb(182,227,212) 50%,rgb(51,167,181) 100%);--wp--preset--gradient--electric-grass: linear-gradient(135deg,rgb(202,248,128) 0%,rgb(113,206,126) 100%);--wp--preset--gradient--midnight: linear-gradient(135deg,rgb(2,3,129) 0%,rgb(40,116,252) 100%);--wp--preset--font-size--small: 13px;--wp--preset--font-size--medium: 20px;--wp--preset--font-size--large: 36px;--wp--preset--font-size--x-large: 42px;--wp--preset--spacing--20: 0.44rem;--wp--preset--spacing--30: 0.67rem;--wp--preset--spacing--40: 1rem;--wp--preset--spacing--50: 1.5rem;--wp--preset--spacing--60: 2.25rem;--wp--preset--spacing--70: 3.38rem;--wp--preset--spacing--80: 5.06rem;--wp--preset--shadow--natural: 6px 6px 9px rgba(0, 0, 0, 0.2);--wp--preset--shadow--deep: 12px 12px 50px rgba(0, 0, 0, 0.4);--wp--preset--shadow--sharp: 6px 6px 0px rgba(0, 0, 0, 0.2);--wp--preset--shadow--outlined: 6px 6px 0px -3px rgb(255, 255, 255), 6px 6px rgb(0, 0, 0);--wp--preset--shadow--crisp: 6px 6px 0px rgb(0, 0, 0);}.wp-block-button{--wp--preset--dimension--25: 25%;--wp--preset--dimension--50: 50%;--wp--preset--dimension--75: 75%;--wp--preset--dimension--100: 100%;}:where(body) { margin: 0; }:where(.is-layout-flex){gap: 0.5em;}:where(.is-layout-grid){gap: 0.5em;}body .is-layout-flex{display: flex;}.is-layout-flex{flex-wrap: wrap;align-items: center;}.is-layout-flex > :is(*, div){margin: 0;}body .is-layout-grid{display: grid;}.is-layout-grid > :is(*, div){margin: 0;}body{padding-top: 0px;padding-right: 0px;padding-bottom: 0px;padding-left: 0px;}:root :where(.wp-element-button, .wp-block-button__link){background-color: #32373c;border-width: 0;color: #fff;font-family: inherit;font-size: inherit;font-style: inherit;font-weight: inherit;letter-spacing: inherit;line-height: inherit;padding-top: calc(0.667em + 2px);padding-right: calc(1.333em + 2px);padding-bottom: calc(0.667em + 2px);padding-left: calc(1.333em + 2px);text-decoration: none;text-transform: inherit;}.has-black-color{color: var(--wp--preset--color--black) !important;}.has-cyan-bluish-gray-color{color: var(--wp--preset--color--cyan-bluish-gray) !important;}.has-white-color{color: var(--wp--preset--color--white) !important;}.has-pale-pink-color{color: var(--wp--preset--color--pale-pink) !important;}.has-vivid-red-color{color: var(--wp--preset--color--vivid-red) !important;}.has-luminous-vivid-orange-color{color: var(--wp--preset--color--luminous-vivid-orange) !important;}.has-luminous-vivid-amber-color{color: var(--wp--preset--color--luminous-vivid-amber) !important;}.has-light-green-cyan-color{color: var(--wp--preset--color--light-green-cyan) !important;}.has-vivid-green-cyan-color{color: var(--wp--preset--color--vivid-green-cyan) !important;}.has-pale-cyan-blue-color{color: var(--wp--preset--color--pale-cyan-blue) !important;}.has-vivid-cyan-blue-color{color: var(--wp--preset--color--vivid-cyan-blue) !important;}.has-vivid-purple-color{color: var(--wp--preset--color--vivid-purple) !important;}.has-black-background-color{background-color: var(--wp--preset--color--black) !important;}.has-cyan-bluish-gray-background-color{background-color: var(--wp--preset--color--cyan-bluish-gray) !important;}.has-white-background-color{background-color: var(--wp--preset--color--white) !important;}.has-pale-pink-background-color{background-color: var(--wp--preset--color--pale-pink) !important;}.has-vivid-red-background-color{background-color: var(--wp--preset--color--vivid-red) !important;}.has-luminous-vivid-orange-background-color{background-color: var(--wp--preset--color--luminous-vivid-orange) !important;}.has-luminous-vivid-amber-background-color{background-color: var(--wp--preset--color--luminous-vivid-amber) !important;}.has-light-green-cyan-background-color{background-color: var(--wp--preset--color--light-green-cyan) !important;}.has-vivid-green-cyan-background-color{background-color: var(--wp--preset--color--vivid-green-cyan) !important;}.has-pale-cyan-blue-background-color{background-color: var(--wp--preset--color--pale-cyan-blue) !important;}.has-vivid-cyan-blue-background-color{background-color: var(--wp--preset--color--vivid-cyan-blue) !important;}.has-vivid-purple-background-color{background-color: var(--wp--preset--color--vivid-purple) !important;}.has-black-border-color{border-color: var(--wp--preset--color--black) !important;}.has-cyan-bluish-gray-border-color{border-color: var(--wp--preset--color--cyan-bluish-gray) !important;}.has-white-border-color{border-color: var(--wp--preset--color--white) !important;}.has-pale-pink-border-color{border-color: var(--wp--preset--color--pale-pink) !important;}.has-vivid-red-border-color{border-color: var(--wp--preset--color--vivid-red) !important;}.has-luminous-vivid-orange-border-color{border-color: var(--wp--preset--color--luminous-vivid-orange) !important;}.has-luminous-vivid-amber-border-color{border-color: var(--wp--preset--color--luminous-vivid-amber) !important;}.has-light-green-cyan-border-color{border-color: var(--wp--preset--color--light-green-cyan) !important;}.has-vivid-green-cyan-border-color{border-color: var(--wp--preset--color--vivid-green-cyan) !important;}.has-pale-cyan-blue-border-color{border-color: var(--wp--preset--color--pale-cyan-blue) !important;}.has-vivid-cyan-blue-border-color{border-color: var(--wp--preset--color--vivid-cyan-blue) !important;}.has-vivid-purple-border-color{border-color: var(--wp--preset--color--vivid-purple) !important;}.has-vivid-cyan-blue-to-vivid-purple-gradient-background{background: var(--wp--preset--gradient--vivid-cyan-blue-to-vivid-purple) !important;}.has-light-green-cyan-to-vivid-green-cyan-gradient-background{background: var(--wp--preset--gradient--light-green-cyan-to-vivid-green-cyan) !important;}.has-luminous-vivid-amber-to-luminous-vivid-orange-gradient-background{background: var(--wp--preset--gradient--luminous-vivid-amber-to-luminous-vivid-orange) !important;}.has-luminous-vivid-orange-to-vivid-red-gradient-background{background: var(--wp--preset--gradient--luminous-vivid-orange-to-vivid-red) !important;}
215.has-very-light-gray-to-cyan-bluish-gray-gradient-background{background: var(--wp--preset--gradient--very-light-gray-to-cyan-bluish-gray) !important;}.has-cool-to-warm-spectrum-gradient-background{background: var(--wp--preset--gradient--cool-to-warm-spectrum) !important;}.has-blush-light-purple-gradient-background{background: var(--wp--preset--gradient--blush-light-purple) !important;}.has-blush-bordeaux-gradient-background{background: var(--wp--preset--gradient--blush-bordeaux) !important;}.has-luminous-dusk-gradient-background{background: var(--wp--preset--gradient--luminous-dusk) !important;}.has-pale-ocean-gradient-background{background: var(--wp--preset--gradient--pale-ocean) !important;}.has-electric-grass-gradient-background{background: var(--wp--preset--gradient--electric-grass) !important;}.has-midnight-gradient-background{background: var(--wp--preset--gradient--midnight) !important;}.has-small-font-size{font-size: var(--wp--preset--font-size--small) !important;}.has-medium-font-size{font-size: var(--wp--preset--font-size--medium) !important;}.has-large-font-size{font-size: var(--wp--preset--font-size--large) !important;}.has-x-large-font-size{font-size: var(--wp--preset--font-size--x-large) !important;}
216:root :where(.wp-block-icon svg){width: 24px;}
217:where(.wp-block-gallery.is-layout-flex){gap: var( --wp--style--gallery-gap-default, var( --gallery-block--gutter-size, var( --wp--style--block-gap, 0.5em ) ) );}:where(.wp-block-gallery.is-layout-grid){gap: var( --wp--style--gallery-gap-default, var( --gallery-block--gutter-size, var( --wp--style--block-gap, 0.5em ) ) );}
218:where(.wp-block-latest-posts.is-layout-flex){gap: 1.25em;}:where(.wp-block-latest-posts.is-layout-grid){gap: 1.25em;}
219:where(.wp-block-post-template.is-layout-flex){gap: 1.25em;}:where(.wp-block-post-template.is-layout-grid){gap: 1.25em;}
220:where(.wp-block-term-template.is-layout-flex){gap: 1.25em;}:where(.wp-block-term-template.is-layout-grid){gap: 1.25em;}
221:where(.wp-block-columns.is-layout-flex){gap: 2em;}:where(.wp-block-columns.is-layout-grid){gap: 2em;}
222:root :where(.wp-block-pullquote){font-size: 1.5em;line-height: 1.6;}
223/*# sourceURL=global-styles-inline-css */</style><link rel='stylesheet' id='slick-carousel-css-css' href='https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.8.1/slick.min.css?ver=7.1.2' media='all' /><link rel='stylesheet' id='slick-carousel-theme-css-css' href='https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.8.1/slick-theme.min.css?ver=7.1.2' media='all' /> 
223<script id="jquery-core-js" src="https://iepnw.com/wp-includes/js/jquery/jquery.min.js?ver=3.7.1"></script>
223 
223<script data-cfasync="false" data-wpfc-render="false" type="text/javascript" id='monsterinsights-frontend-script-js-extra'>var monsterinsights_frontend = {"js_events_tracking":"true","download_extensions":"doc,pdf,ppt,zip,xls,docx,pptx,xlsx","inbound_paths":"[{\"path\":\"\\\/go\\\/\",\"label\":\"affiliate\"},{\"path\":\"\\\/recommend\\\/\",\"label\":\"affiliate\"}]","home_url":"https:\/\/iepnw.com","hash_tracking":"false","v4_id":"G-TCDEV928T3"};</script>
223 
223<script id="io-scripts-js-extra">var io_scripts_vars = {"io_username":"FunwithIEP","io_locationid":"41379","io_phonenumber":"(253) 353-9797","io_emailaddress":"[email protected]","io_businesshours":"","io_facebooklink":"https://www.facebook.com/","io_twitterlink":"https://twitter.com/","io_instagramlink":"https://www.instagram.com/","io_youtubelink":"","io_fpnumber":"","io_companyname":"Inflatable Event Professionals LLC Spanaway WA"};
224//# sourceURL=io-scripts-js-extra</script>
224 <link rel="https://api.w.org/" href="https://iepnw.com/wp-json/" /><link rel="alternate" title="JSON" type="application/json" href="https://iepnw.com/wp-json/wp/v2/pages/6230" /><link rel="EditURI" type="application/rsd+xml" title="RSD" href="https://iepnw.com/xmlrpc.php?rsd" /><link rel='shortlink' href='https://iepnw.com/?p=6230' /><meta name="generator" content="Elementor 4.3.2; features: additional_custom_breakpoints; settings: css_print_method-external, google_font-enabled, font_display-auto"><style>.e-con.e-parent:nth-of-type(n+4):not(.e-lazyloaded):not(.e-no-lazyload),
225				.e-con.e-parent:nth-of-type(n+4):not(.e-lazyloaded):not(.e-no-lazyload) * {
226					background-image: none !important;
227				}
228				@media screen and (max-height: 1024px) {
229					.e-con.e-parent:nth-of-type(n+3):not(.e-lazyloaded):not(.e-no-lazyload),
230					.e-con.e-parent:nth-of-type(n+3):not(.e-lazyloaded):not(.e-no-lazyload) * {
231						background-image: none !important;
232					}
233				}
234				@media screen and (max-height: 640px) {
235					.e-con.e-parent:nth-of-type(n+2):not(.e-lazyloaded):not(.e-no-lazyload),
236					.e-con.e-parent:nth-of-type(n+2):not(.e-lazyloaded):not(.e-no-lazyload) * {
237						background-image: none !important;
238					}
239				}</style><link rel="icon" href="https://iepnw.com/wp-content/uploads/2024/04/logo-IEP-png-small_794854-150x113.png" sizes="32x32" /><link rel="icon" href="https://iepnw.com/wp-content/uploads/2024/04/logo-IEP-png-small_794854.png" sizes="192x192" /><link rel="apple-touch-icon" href="https://iepnw.com/wp-content/uploads/2024/04/logo-IEP-png-small_794854.png" /><meta name="msapplication-TileImage" content="https://iepnw.com/wp-content/uploads/2024/04/logo-IEP-png-small_794854.png" /><style id="wp-custom-css">.grecaptcha-badge { visibility: hidden; }
240
241.search-submit{display:none;}
242
243.cartInfo{
244	display:none !important;
245}
246.io-footer-link a {
247color: var(--e-global-color-accent, orange);
248}
249
250.catDescriptionIO.catDescriptionIO_small.elementor-widget-text-editor {
251    padding: 10px;
252    font-size: small;
253    text-align: left;
254}
255
256.io_brand {
257    margin-bottom: 20px;
258}</style></head><body class="wp-singular page-template-default page page-id-6230 page-parent page-child parent-pageid-1311 wp-custom-logo wp-theme-io-kenos eio-default mega-menu-max-mega-menu-4 mega-menu-max-mega-menu-5 mega-menu-max-mega-menu-6 mega-menu-max-mega-menu-7 mega-menu-max-mega-menu-8 mega-menu-max-mega-menu-9 elementor-default elementor-kit-812"><header data-elementor-type="header" data-elementor-id="240" class="elementor elementor-240 elementor-location-header" data-elementor-post-type="elementor_library"><section class="elementor-section elementor-top-section elementor-element elementor-element-2729381f elementor-section-full_width io_header elementor-section-height-default elementor-section-height-default" data-id="2729381f" data-element_type="section" data-e-type="section" id="top" data-settings="{&quot;background_background&quot;:&quot;classic&quot;}"><div class="elementor-container elementor-column-gap-default"><div class="elementor-column elementor-col-100 elementor-top-column elementor-element elementor-element-5df2b2fb" data-id="5df2b2fb" data-element_type="column" data-e-type="column"><div class="elementor-widget-wrap elementor-element-populated"><section class="elementor-section elementor-inner-section elementor-element elementor-element-73f1967d elementor-section-height-min-height elementor-section-boxed elementor-section-height-default" data-id="73f1967d" data-element_type="section" data-e-type="section" data-settings="{&quot;background_background&quot;:&quot;classic&quot;,&quot;sticky&quot;:&quot;top&quot;,&quot;sticky_on&quot;:[&quot;desktop&quot;,&quot;tablet&quot;,&quot;mobile&quot;],&quot;sticky_offset&quot;:0,&quot;sticky_effects_offset&quot;:0,&quot;sticky_anchor_link_offset&quot;:0}"><div class="elementor-container elementor-column-gap-default"><div class="elementor-column elementor-col-33 elementor-inner-column elementor-element elementor-element-1c47ce05" data-id="1c47ce05" data-element_type="column" data-e-type="column"><div class="elementor-widget-wrap elementor-element-populated"><div class="elementor-element elementor-element-f06f2a5 elementor-widget elementor-widget-theme-site-logo elementor-widget-image" data-id="f06f2a5" data-element_type="widget" data-e-type="widget" data-widget_type="theme-site-logo.default"><div class="elementor-widget-container"> <a href="https://iepnw.com"> <img width="160" height="113" src="https://iepnw.com/wp-content/uploads/2024/04/logo-IEP-png-small_794854.png" class="elementor-animation-grow attachment-medium size-medium wp-image-4694" alt="Inflatable Event Professionals LLC Spanaway WA" /> </a></div></div></div></div><div class="elementor-column elementor-col-33 elementor-inner-column elementor-element elementor-element-69f18564" data-id="69f18564" data-element_type="column" data-e-type="column"><div class="elementor-widget-wrap elementor-element-populated"><div class="elementor-element elementor-element-4c8eb716 elementor-widget elementor-widget-wp-widget-maxmegamenu" data-id="4c8eb716" data-element_type="widget" data-e-type="widget" data-widget_type="wp-widget-maxmegamenu.default"><div class="elementor-widget-container"><div id="mega-menu-wrap-max_mega_menu_4" class="mega-menu-wrap"><div class="mega-menu-toggle"><div class="mega-toggle-blocks-left"></div><div class="mega-toggle-blocks-center"><div class='mega-toggle-block mega-menu-toggle-block mega-toggle-block-1' id='mega-toggle-block-1'><span aria-expanded="false" aria-haspopup="true" role="button" class='mega-toggle-label'><span class='mega-toggle-label-closed'></span><span class='mega-toggle-label-open'></span></span></div></div><div class="mega-toggle-blocks-right"></div></div><ul id="mega-menu-max_mega_menu_4" class="mega-menu max-mega-menu mega-menu-horizontal mega-no-js" data-event="hover_intent" data-effect="fade_up" data-effect-speed="200" data-effect-mobile="disabled" data-effect-speed-mobile="0" data-mobile-force-width="body" data-second-click="go" data-document-click="collapse" data-vertical-behaviour="standard" data-breakpoint="600" data-unbind="true" data-mobile-state="collapse_all" data-mobile-direction="vertical"><li class="mega-menu-item mega-menu-item-type-custom mega-menu-item-object-custom mega-menu-megamenu mega-menu-item-has-children mega-align-bottom-left mega-menu-item-806" id="mega-menu-item-806"><a class="mega-menu-link" href="https://iepnw.com/rentals/" aria-expanded="false" aria-controls="mega-sub-menu-806">Inventory<span class="mega-indicator" aria-hidden="true"></span></a><ul class="mega-sub-menu" id='mega-sub-menu-806'><li class="mega-menu-item mega-menu-item-type-widget widget_widget_featured mega-menu-column-standard mega-menu-columns-6-of-6 mega-menu-item-widget_featured-2" style="--columns:6; --span:6" id="mega-menu-item-widget_featured-2"><div class="widget-text wp_widget_plugin_box panel-grid panel-has-style" style="margin-top:0px;">
258<script>jQuery(document).ready(function(){
259                  jQuery('.io_mm_item .io_item2_list').css('box-shadow', 'none')
260                  jQuery('.io_mm_item .io_item2_list').addClass('nohover')
261
262                  jQuery('.io_mm_item .io_item2_listcat').css('box-shadow', 'none')
263                  jQuery('.io_mm_item .io_item2_listcat').addClass('nohover')
264              })</script>
264<div class="io_mm_outer io_widget_ " style="grid-template-columns:repeat(4, calc((100% - 45px)/4)); display:grid;"><style>.io_widget_ .io_item2_list_inner .rentNameIO_button {display:none !important;} .io_widget_ .io_item2_list_inner .rentNameIO_price {display:none !important;} .io_widget_ .io_item2_list .view-product-button {display:none !important;} .io_widget_ .io_item2_listcat .view-product-button {display:none !important;} .io_widget_ .io_item2_listcat .catDescriptionIO {display:none;}</style><div class="io_mm_item elementor-widget-heading simpleCart_ioShelfItem" name="maindiv_oam-party" style="text-align:center"><div class="io_item2_listcat elementor-widget-heading"> <a href="https://iepnw.com/rentals/foam-party/"><div class="cat_div"><div class="btn btn-primary view-product-button">View Products</div> <img class="cat_img" src="https://iepnw.com/wp-content/uploads/2025/06/Spanaway20Foam20Party_1746154102_big.jpg" alt="Foam Party" title="Foam Party" /></div> </a><div class="cat_div_inner"> <a href="https://iepnw.com/rentals/foam-party/"><p class="rentNameIO elementor-heading-title">Foam Party</p><div class="catDescriptionIO catDescriptionIO_small elementor-widget-text-editor"><p><span style="font-size:16px;"><span style="font-family:tahoma,geneva,sans-serif;"><span style="font-size:14px;">When it comes to party options one of the best ideas is a <strong><em>foam party rental for your event&nbsp;</em></strong>in the Tacoma, Spanaway and the surrounding areas. &nbsp;Inflatable Event Professionals offers several great foam party options. &nbsp;Having foam and bubbles at your event is a new and unique idea that will have everyone discussing the amount of fun they had at your event and wondering what you will come up with for your next blowout party!</span></span></span></p></div> </a></div></div></div><div class="io_mm_item elementor-widget-heading simpleCart_ioShelfItem" name="maindiv_oam-party" style="text-align:center"><div class="io_item2_listcat elementor-widget-heading"> <a href="https://iepnw.com/rentals/photo-booth/"><div class="cat_div"><div class="btn btn-primary view-product-button">View Products</div> <img class="cat_img" src="https://iepnw.com/wp-content/uploads/2025/06/Fun20photo20booth20rental_1712520760_big.jpg" alt="Photo Booth" title="Photo Booth" /></div> </a><div class="cat_div_inner"> <a href="https://iepnw.com/rentals/photo-booth/"><p class="rentNameIO elementor-heading-title">Photo Booth</p><div class="catDescriptionIO catDescriptionIO_small elementor-widget-text-editor"><p><span style="color: rgb(0, 0, 0); font-family: tahoma, geneva, sans-serif; font-size: 14px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; white-space: normal; text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial; display: inline !important; float: none;">Inflatable Event Professionals offers the best Photo Booth party rentals in Tacoma and the surrounding areas. When it comes to ensuring that your guests enjoy hours of countless fun and lifelong memories please consider Inflatable Event Professionals for your next event. &nbsp;With a photo booth party rental your guests can capture a photo memory at your event and then share it on social media.</span></p></div> </a></div></div></div><div class="io_mm_item elementor-widget-heading simpleCart_ioShelfItem" name="maindiv_oam-party" style="text-align:center"><div class="io_item2_listcat elementor-widget-heading"> <a href="https://iepnw.com/rentals/led-furniture/"><div class="cat_div"><div class="btn btn-primary view-product-button">View Products</div> <img class="cat_img" src="https://iepnw.com/wp-content/uploads/2025/06/temp_img_622030411_925263159_big.jpg" alt="LED Furniture" title="LED Furniture" /></div> </a><div class="cat_div_inner"> <a href="https://iepnw.com/rentals/led-furniture/"><p class="rentNameIO elementor-heading-title">LED Furniture</p><div class="catDescriptionIO catDescriptionIO_small elementor-widget-text-editor"><p><span style="font-family:tahoma,geneva,sans-serif;"><span style="font-size:14px;">We want to help you create awesome and magical outdoor celebration spaces with our LED Party Furniture Rental options.
264</span></span></p></div> </a></div></div></div><div class="io_mm_item elementor-widget-heading simpleCart_ioShelfItem" name="maindiv_oam-party" style="text-align:center"><div class="io_item2_listcat elementor-widget-heading"> <a href="https://iepnw.com/rentals/obstacle-courses/"><div class="cat_div"><div class="btn btn-primary view-product-button">View Products</div> <img class="cat_img" src="https://iepnw.com/wp-content/uploads/2025/06/18720Radical20Run_1712099917_big.jpg" alt="Obstacle Courses" title="Obstacle Courses" /></div> </a><div class="cat_div_inner"> <a href="https://iepnw.com/rentals/obstacle-courses/"><p class="rentNameIO elementor-heading-title">Obstacle Courses</p><div class="catDescriptionIO catDescriptionIO_small elementor-widget-text-editor"><p><span style="font-family:tahoma,geneva,sans-serif;"></span></p>Obstacle courses are thrilling, inflatable playgrounds designed to challenge participants with a series of fun hurdles, tunnels, and climbing walls. Perfect for parties or team-building events, they offer exhilarating competition and entertainment for kids and adults alike.</div> </a></div></div></div><div class="io_mm_item elementor-widget-heading simpleCart_ioShelfItem" name="maindiv_oam-party" style="text-align:center"><div class="io_item2_listcat elementor-widget-heading"> <a href="https://iepnw.com/rentals/water-rentals/"><div class="cat_div"><div class="btn btn-primary view-product-button">View Products</div> <img class="cat_img" src="https://iepnw.com/wp-content/uploads/2025/06/Water20rental_1733429999_big.jpg" alt="Water Rentals" title="Water Rentals" /></div> </a><div class="cat_div_inner"> <a href="https://iepnw.com/rentals/water-rentals/"><p class="rentNameIO elementor-heading-title">Water Rentals</p><div class="catDescriptionIO catDescriptionIO_small elementor-widget-text-editor">Dive into endless pools of joy and splash-filled excitement with water rentals! Whether it&#39;s water games, a dunk tank or inflatable water slides, these rentals promise a refreshing adventure for any fun-seeking enthusiast.</div> </a></div></div></div><div class="io_mm_item elementor-widget-heading simpleCart_ioShelfItem" name="maindiv_oam-party" style="text-align:center"><div class="io_item2_listcat elementor-widget-heading"> <a href="https://iepnw.com/rentals/bounce-house-and-slides-combos/"><div class="cat_div"><div class="btn btn-primary view-product-button">View Products</div> <img class="cat_img" src="https://iepnw.com/wp-content/uploads/2025/06/1820Foot20high20Xtreme20Dance20Dome20Inflatable_1733428313_b.jpg" alt="Bounce House  and Slides Combos" title="Bounce House  and Slides Combos" /></div> </a><div class="cat_div_inner"> <a href="https://iepnw.com/rentals/bounce-house-and-slides-combos/"><p class="rentNameIO elementor-heading-title">Bounce House  and Slides Combos</p><div class="catDescriptionIO catDescriptionIO_small elementor-widget-text-editor">Inflatable bounce houses are fantastic for letting some energy flow out. There are also combo bouncers that include the basketball hoop or slide built inside and a bounce zone. We specialize in bounce house rental and are willing to meet your needs for events.</div> </a></div></div></div><div class="io_mm_item elementor-widget-heading simpleCart_ioShelfItem" name="maindiv_oam-party" style="text-align:center"><div class="io_item2_listcat elementor-widget-heading"> <a href="https://iepnw.com/rentals/games/"><div class="cat_div"><div class="btn btn-primary view-product-button">View Products</div> <img class="cat_img" src="https://iepnw.com/wp-content/uploads/2025/06/Backyard20Party20Giant20Game20Rentals_1712097921_big.jpg" alt="Games" title="Games" /></div> </a><div class="cat_div_inner"> <a href="https://iepnw.com/rentals/games/"><p class="rentNameIO elementor-heading-title">Games</p><div class="catDescriptionIO catDescriptionIO_small elementor-widget-text-editor">Games rentals bring the excitement of interactive entertainment to any event, offering a variety of options like arcade classics, virtual reality adventures, or giant games. They&#39;re perfect for creating memorable experiences and engaging fun where everyone is a winner.</div> </a></div></div></div><div class="io_mm_item elementor-widget-heading simpleCart_ioShelfItem" name="maindiv_oam-party" style="text-align:center"><div class="io_item2_listcat elementor-widget-heading"> <a href="https://iepnw.com/rentals/concessions/"><div class="cat_div"><div class="btn btn-primary view-product-button">View Products</div> <img class="cat_img" src="https://iepnw.com/wp-content/uploads/2025/06/Sno20Cone20Cups_1712098264_big.png" alt="Concessions" title="Concessions" /></div> </a><div class="cat_div_inner"> <a href="https://iepnw.com/rentals/concessions/"><p class="rentNameIO elementor-heading-title">Concessions</p><div class="catDescriptionIO catDescriptionIO_small elementor-widget-text-editor">Concession machines are essential for any event to provide snacks for guests or a means to cool off by having a snow cone following all the excitement. These machines are operated you, adults at your event or by our staff.</div> </a></div></div></div><div class="io_mm_item elementor-widget-heading simpleCart_ioShelfItem" name="maindiv_oam-party" style="text-align:center"><div class="io_item2_listcat elementor-widget-heading"> <a href="https://iepnw.com/rentals/party-extras/"><div class="cat_div"><div class="btn btn-primary view-product-button">View Products</div> <img class="cat_img" src="https://iepnw.com/wp-content/uploads/2025/06/honda20650020generator20rental_1712098698_big.jpg" alt="Party Extras" title="Party Extras" /></div> </a><div class="cat_div_inner"> <a href="https://iepnw.com/rentals/party-extras/"><p class="rentNameIO elementor-heading-title">Party Extras</p><div class="catDescriptionIO catDescriptionIO_small elementor-widget-text-editor"><p>Party  equipment rentals and supplies are available for your event.&nbsp;</p></div> </a></div></div></div><div class="io_mm_item elementor-widget-heading simpleCart_ioShelfItem" name="maindiv_oam-party" style="text-align:center"><div class="io_item2_listcat elementor-widget-heading"> <a href="https://iepnw.com/rentals/tents-tables-and-chairs/"><div class="cat_div"><div class="btn btn-primary view-product-button">View Products</div> <img class="cat_img" src="https://iepnw.com/wp-content/uploads/2025/06/1020x201520Carnival20Canopy_1712099102_big.jpg" alt="Tents, Tables and Chairs" title="Tents, Tables and Chairs" /></div> </a><div class="cat_div_inner"> <a href="https://iepnw.com/rentals/tents-tables-and-chairs/"><p class="rentNameIO elementor-heading-title">Tents, Tables and Chairs</p><div class="catDescriptionIO catDescriptionIO_small elementor-widget-text-editor"><p><span style="font-size:14px;"><span style="font-family:Tahoma,Geneva,sans-serif;">We can help you create awesome outdoor celebration spaces with our tent, table and chair rentals.&nbsp;</span></span></p></div> </a></div></div></div><div class="io_mm_item elementor-widget-heading simpleCart_ioShelfItem" name="maindiv_oam-party" style="text-align:center"><div class="io_item2_listcat elementor-widget-heading"> <a href="https://iepnw.com/rentals/dry-slides/"><div class="cat_div"><div class="btn btn-primary view-product-button">View Products</div> <img class="cat_img" src="https://iepnw.com/wp-content/uploads/2025/06/Spirit20of20Seattle_1712099249_big.jpg" alt="Dry Slides" title="Dry 
264Slides" /></div> </a><div class="cat_div_inner"> <a href="https://iepnw.com/rentals/dry-slides/"><p class="rentNameIO elementor-heading-title">Dry Slides</p><div class="catDescriptionIO catDescriptionIO_small elementor-widget-text-editor"><p><span style="font-family:tahoma,geneva,sans-serif;"><span style="font-size:14px;">&nbsp;IEP offers the best blow up slides around. These inflatable slides are great for all ages, from children to adults.</span></span></p></div> </a></div></div></div><div class="io_mm_item elementor-widget-heading simpleCart_ioShelfItem" name="maindiv_oam-party" style="text-align:center"><div class="io_item2_listcat elementor-widget-heading"> <a href="https://iepnw.com/rentals/interactive-games/"><div class="cat_div"><div class="btn btn-primary view-product-button">View Products</div> <img class="cat_img" src="https://iepnw.com/wp-content/uploads/2025/06/Wrecking20Ball20Extreme_1712100220_big.jpg" alt="Interactive Games" title="Interactive Games" /></div> </a><div class="cat_div_inner"> <a href="https://iepnw.com/rentals/interactive-games/"><p class="rentNameIO elementor-heading-title">Interactive Games</p><div class="catDescriptionIO catDescriptionIO_small elementor-widget-text-editor">Our interactive game rentals can bring an element of variety to any celebration or occasion. These inflatables are perfect for celebrations like birthday parties or school events, as well as community events.</div> </a></div></div></div></div></div><style>.io_mm_item .io_item2_list, .io_mm_item .io_item2_listcat, .io_mm_item .io_item2_listrent { margin-bottom: 0px !important; }</style></li></ul></li><li class="mega-menu-item mega-menu-item-type-post_type mega-menu-item-object-page mega-menu-item-has-children mega-align-bottom-left mega-menu-flyout mega-menu-item-494" id="mega-menu-item-494"><a class="mega-menu-link" href="https://iepnw.com/about-us/" aria-expanded="false" aria-controls="mega-sub-menu-494">About Us<span class="mega-indicator" aria-hidden="true"></span></a><ul class="mega-sub-menu" id='mega-sub-menu-494'><li class="mega-menu-item mega-menu-item-type-post_type mega-menu-item-object-page mega-menu-item-493" id="mega-menu-item-493"><a class="mega-menu-link" href="https://iepnw.com/faqs/">FAQs</a></li><li class="mega-menu-item mega-menu-item-type-post_type mega-menu-item-object-page mega-menu-item-6217" id="mega-menu-item-6217"><a class="mega-menu-link" href="https://iepnw.com/faqs-2/">General Information</a></li><li class="mega-menu-item mega-menu-item-type-post_type mega-menu-item-object-page mega-menu-item-3296" id="mega-menu-item-3296"><a class="mega-menu-link" href="https://iepnw.com/contact-us/">Contact Us</a></li><li class="mega-menu-item mega-menu-item-type-post_type mega-menu-item-object-page mega-menu-item-3181" id="mega-menu-item-3181"><a class="mega-menu-link" href="https://iepnw.com/employment/">Employment</a></li></ul></li></ul></div></div></div></div></div><div class="elementor-column elementor-col-33 elementor-inner-column elementor-element elementor-element-6f43014b" data-id="6f43014b" data-element_type="column" data-e-type="column" data-settings="{&quot;background_background&quot;:&quot;classic&quot;}"><div class="elementor-widget-wrap elementor-element-populated"><div class="elementor-element elementor-element-299c0acd ioCart elementor-view-default elementor-widget elementor-widget-icon" data-id="299c0acd" data-element_type="widget" data-e-type="widget" data-widget_type="icon.default"><div class="elementor-widget-container"><div class="elementor-icon-wrapper"><div class="elementor-icon"> <i aria-hidden="true" class="fas fa-shopping-cart"></i></div></div></div></div></div></div></div></section><section class="elementor-section elementor-inner-section elementor-element elementor-element-6f566b06 elementor-section-content-middle elementor-section-boxed elementor-section-height-default elementor-section-height-default" data-id="6f566b06" data-element_type="section" data-e-type="section" data-settings="{&quot;background_background&quot;:&quot;classic&quot;}"><div class="elementor-container elementor-column-gap-no"><div class="elementor-column elementor-col-33 elementor-inner-column elementor-element elementor-element-44decdc4" data-id="44decdc4" data-element_type="column" data-e-type="column"><div class="elementor-widget-wrap elementor-element-populated"><div class="elementor-element elementor-element-3d10a966 elementor-icon-list--layout-inline elementor-mobile-align-start elementor-tablet-align-center elementor-hidden-mobile elementor-list-item-link-full_width elementor-widget elementor-widget-icon-list" data-id="3d10a966" data-element_type="widget" data-e-type="widget" data-widget_type="icon-list.default"><div class="elementor-widget-container"><ul class="elementor-icon-list-items elementor-inline-items"><li class="elementor-icon-list-item elementor-inline-item"> <a href="tel:(253)%20353-9797"> <span class="elementor-icon-list-icon"> <i aria-hidden="true" class="fas fa-phone-alt"></i> </span> <span class="elementor-icon-list-text">(253) 353-9797</span> </a></li><li class="elementor-icon-list-item elementor-inline-item"> <a href="mailto:[email protected]"> <span class="elementor-icon-list-icon"> <i aria-hidden="true" class="fas fa-envelope"></i> </span> <span class="elementor-icon-list-text">[email protected]</span> </a></li></ul></div></div><div class="elementor-element elementor-element-53375d00 elementor-icon-list--layout-inline elementor-mobile-align-center elementor-tablet-align-center elementor-hidden-desktop elementor-hidden-tablet elementor-list-item-link-full_width elementor-widget elementor-widget-icon-list" data-id="53375d00" data-element_type="widget" data-e-type="widget" data-widget_type="icon-list.default"><div class="elementor-widget-container"><ul class="elementor-icon-list-items elementor-inline-items"><li class="elementor-icon-list-item elementor-inline-item"> <a href="tel:(253)%20353-9797"> <span class="elementor-icon-list-icon"> <i aria-hidden="true" class="fas fa-phone-alt"></i> </span> <span class="elementor-icon-list-text"></span> </a></li><li class="elementor-icon-list-item elementor-inline-item"> <a href="mailto:[email protected]"> <span class="elementor-icon-list-icon"> <i aria-hidden="true" class="fas fa-envelope"></i> </span> <span class="elementor-icon-list-text"></span> </a></li></ul></div></div></div></div><div class="elementor-column elementor-col-33 elementor-inner-column elementor-element elementor-element-36453571" data-id="36453571" data-element_type="column" data-e-type="column"><div class="elementor-widget-wrap elementor-element-populated"><div class="elementor-element elementor-element-2bd4629d elementor-align-left elementor-mobile-align-center elementor-tablet-align-center elementor-widget elementor-widget-button" data-id="2bd4629d" data-element_type="widget" data-e-type="widget" data-widget_type="button.default"><div class="elementor-widget-container"><div class="elementor-button-wrapper"> <a class="elementor-button elementor-button-link elementor-size-xs elementor-animation-grow" href="https://iepnw.com/io_quoteform/"> <span class="elementor-button-content-wrapper"> <span class="elementor-button-text">Book Now</span> </span> </a></div></div></div></div></div><div class="elementor-column elementor-col-33 elementor-inner-column elementor-element elementor-element-3cb79163 elementor-hidden-mobile" data-id="3cb79163" data-element_type="column" data-e-type="column"><div class="elementor-widget-wrap elementor-element-populated"><div class="elementor-element elementor-element-7121d477 elementor-widget elementor-widget-wp-widget-searchio_live_search" data-id="7121d477" data-element_type="widget" data-e-type="widget" data-widget_type="wp-widget-searchio_live_search.default"><div class="elementor-widget-container"><form role="search" method="get" class="searchio-live-search-widget-search-form" action="https://iepnw.com"> <label> <span class="screen-reader-text">Search for:</span> <input type="search" class="search-field" style="width: 220px" placeholder="Search for..." value="" name="s" data-swplive="true" data-swpengine="default" data-swpconfig="default" autocomplete="off"> </label> <input type="submit" class="search-submit" style="display:none;" value="Search"></form></div></div></div></div></div></section></div></div></div></section></header><main id="main" class="site-main" role="main"><header class="page-header io_phshow"><div class ="elementor-widget-heading"><p id="breadcrumbs" class="io-entry-title elementor-heading-title"><a href="https://iepnw.com">Home</a><span class="separator"> &raquo; </span><a href="https://iepnw.com/rentals/">Inventory</a><span class="separator"> &raquo; </span><span class="last">Foam Party</span></p></div></header><div class="page-content"><div class="cartInfo" style="display:none"> <i class="cartIcon fas fa-shopping-cart"></i> <span class="simpleCart_quantity"></span> items</div><div class="pageDateRangeWrapper elementor-widget-button"><div class="elementor-button elementor-animation-grow" onclick="checkAvailDateClick()" style="display:block"><div class="ioDateRangeHeader">Set Event Date</div><div id="pageDateRange" class="ioDateRange"></div></div></div><div class="io_category_wrapper elementor-widget-heading"><h1 class="catNameIO elementor-heading-title elementor-size-default">Foam Party<span class="io_forrent io_forrent_304638"> for Rent</span></h1></div><div class="io_view_toggle_container" style="display:none;"><div class="io_view_toggle_buttons"> <button class="io_view_toggle_btn active" data-view="tile" title="Tile View"> <i class="fas fa-th-large"></i> </button> <button class="io_view_toggle_btn" data-view="list" title="List View"> <i class="fas fa-list"></i> </button></div></div><div class="category_id" style="display: none">304638</div><div class="cat_div_wrapper"><div class="io_cat_description io_cat_description_304638 elementor-widget-text-editor catDescriptionIO"></p><p><span style="font-size:16px;"><span style="font-family:tahoma,geneva,sans-serif;"><span style="font-size:14px;">When it comes to party options one of the best ideas is a <strong><em>foam party rental for your event&nbsp;</em></strong>in the Tacoma, Spanaway and the surrounding areas. &nbsp;Inflatable Event Professionals offers several great foam party options. &nbsp;Having foam and bubbles at your event is a new and unique idea that will have everyone discussing the amount of fun they had at your event and wondering what you will c
264ome up with for your next blowout party!</span></span></span></p><p></div></div><div class="io_catdiv2"></div><div class="io_landingpages io_landingpages_304638 elementor-widget-text-editor">Professional delivery to <span class=\"io_city_list\"><a href=https://iepnw.com/party-rentals-in-spanaway-wa/>Spanaway, WA</a>, <a href=https://iepnw.com/party-rentals-in-tacoma-wa/>Tacoma, WA</a></span> and surrounding areas. Please submit a quote or contact us to be sure we service your area.</div><div class="io_cat_longdescription io_cat_longdescription_304638 elementor-widget-text-editor"></p><p align="center"><strong><span style="font-size:18px;"><span style="font-family:tahoma,geneva,sans-serif;">Foam Parties</span></span></strong></p><div style="text-align: center;">&nbsp;&nbsp;<span class="fr-video fr-deletable fr-rv fr-draggable" contenteditable="false" draggable="true" style="display: block; clear: both; text-align: center;"><iframe width="640" height="360" src="https://player.vimeo.com/video/530537632?share=copy" class="fr-draggable"></iframe></span><span style="font-size:16px;"><span style="font-family:tahoma,geneva,sans-serif;"><span style="font-size:14px;"><br /></span></span></span></div><p>A foam party rental brings the ultimate playful and bubbly experience to your event. Imagine an area drenched in thick, frothy foam where everyone can jump in, dance, and laugh. It&#39;s like a cloud brought to earth just for having fun. Perfect for creating lasting memories, this rental transforms any space into a sudsy dreamland. With easy setup and all necessary equipment included, your gathering turns into a gleaming spectacle, enthralling guests of all ages as they slip and slide through a sea of foam.</p><p>Foam party rentals are great for birthdays, summer camps, schools, church socials, fundraisers, corporate events, college events, teen parties and block parties! Foam parties are perfect for EVERYBODY! It&#39;s the ultimate bubble party experience and will be enjoyed by all your party guest. You can fill your lawn or venue with foam or rent one of our foam pits that will fill with foam in minutes.&nbsp; It&#39;s a wonderful alternative to traditional summer pool parties. Another great option is to rent one of our water slide and add a foam package to add a whole new level of fun and excitement to your water slide party.</p><p></div> 
264<script>var isValid = function (u) {
265        if (!u) return false;
266        var s = String(u).trim();
267        if (!s) return false;
268        if (s.indexOf('%%') !== -1) return false;
269        if (s === '0' || s.toLowerCase() === 'null' || s.toLowerCase() === 'undefined') return false;
270        return true;
271    };
272
273    var isMp4 = function (u) {
274        if (!u) return false;
275        return /\.mp4(?:\?|#|$)/i.test(String(u).trim());
276    };
277
278    function CategoryGallery(rental_id, rental_name, images_arr){
279        var rid = rental_id;
280        var rentalName = rental_name;
281
282        try {
283            if (typeof images_arr === 'string' && images_arr.length) {
284                images_arr = JSON.parse(images_arr);
285            }
286        } catch (e) {
287            images_arr = {};
288        }
289        if (!images_arr) images_arr = {};
290
291        var $bigAfter = jQuery('#io_img_big2_' + rid);
292        var $thumbAfter = jQuery('#io_img_thumb1_' + rid);
293
294        if ($bigAfter.length && $thumbAfter.length) {
295            var relVal = $bigAfter.attr('rel') || 'img_group noopener';
296
297            var getBigUrl = function (imgObj) {
298                return imgObj["rentalimage_imagelocbig"] || imgObj["imagelocbig"] || imgObj["big"] || "";
299            };
300
301            var getThumbUrl = function (imgObj) {
302                return imgObj["rentalimage_imageloc"] || imgObj["imageloc"] || imgObj["thumb"] || "";
303            };
304
305            var addedThumbs = 0;
306            var $mainImg = jQuery('#io_img_big2_' + rid).closest('.io_item2_list').find('.io_image_big').first();
307
308            // Bind existing thumb1 to its existing big1 anchor using data-big-src
309            var $existingThumb1 = jQuery('#io_img_thumb1_' + rid);
310            var $existingBig1 = jQuery('#io_img_big1_' + rid);
311            if ($existingThumb1.length && $existingBig1.length) {
312                var existingBig1Href = $existingBig1.attr('href');
313                var existingThumb1Src = $existingThumb1.attr('src');
314
315                if (isMp4(existingBig1Href) && isValid(existingThumb1Src)) {
316                    existingBig1Href = existingThumb1Src;
317                    $existingBig1.attr('href', existingBig1Href);
318                }
319
320                if (isValid(existingBig1Href)) {
321                    $existingThumb1.attr('data-big-src', existingBig1Href);
322                    $existingThumb1.off('click.ioGallery').on('click.ioGallery', function () {
323                        if (typeof updateMainPic === 'function') {
324                            updateMainPic(this);
325                        }
326                    });
327                }
328            }
329
330            // Fix built-in big2 anchor if it points to mp4
331            if ($bigAfter.length) {
332                var builtInBig2Href = $bigAfter.attr('href');
333                var builtInThumb2Src = $thumbAfter.attr('src');
334
335                if (isMp4(builtInBig2Href) && isValid(builtInThumb2Src)) {
336                    $bigAfter.attr('href', builtInThumb2Src);
337                }
338            }
339
340            for (var key in images_arr) {
341                if (!images_arr.hasOwnProperty(key)) continue;
342
343                var imgObj = images_arr[key] || {};
344                var href = getBigUrl(imgObj);
345                var src  = getThumbUrl(imgObj);
346
347                if (isMp4(href) && isValid(src)) {
348                    href = src;
349                }
350
351                var n = parseInt(key, 10);
352                if (isNaN(n)) {
353                    n = addedThumbs + 1;
354                }
355
356                var bigIndex = n + 1;
357                var thumbIndex = n + 1;
358
359                if (isValid(href)) {
360                    var bigId = '#io_img_big' + bigIndex + '_' + rid;
361                    if (jQuery(bigId).length === 0) {
362                        var $a = jQuery('<a/>', {
363                            rel: relVal,
364                            href: href,
365                            id: 'io_img_big' + bigIndex + '_' + rid
366                        });
367                        $bigAfter.after($a);
368                        $bigAfter = $a;
369                    }
370                }
371
372                if (isValid(src)) {
373                    var thumbId = '#io_img_thumb' + thumbIndex + '_' + rid;
374                    if (jQuery(thumbId).length === 0) {
375                        var $img = jQuery('<img/>', {
376                            'class': 'io_image_thumb skip-lazy',
377                            title: rentalName,
378                            src: src,
379                            alt: rentalName,
380                            id: 'io_img_thumb' + thumbIndex + '_' + rid,
381                            'data-big-src': href
382                        }).on('click', function () {
383                            if (typeof updateMainPic === 'function') {
384                                updateMainPic(this);
385                            }
386                        });
387
388                        $thumbAfter.after($img);
389                        $thumbAfter = $img;
390                        addedThumbs++;
391                    }
392                }
393            }
394
395            if (addedThumbs > 0) {
396                jQuery('#io_img_thumb1_' + rid).closest('.io_image_thumbbox').show();
397            }
398        }
399    }
400
401    // Function to generate list view content on demand (global scope)
402    generateListViewContent = function() {
403        console.log('[IO List View] Generating list view content dynamically');
404
405        jQuery('.io_item2_list').each(function() {
406            var $item = jQuery(this);
407
408            if ($item.find('.io_list_view_content').length > 0) {
409                return;
410            }
411
412            var rentalId = $item.find('.item_rentalid').text().trim();
413            if (!rentalId) {
414                console.warn('[IO List View] No rental_id found for item, skipping');
415                return;
416            }
417
418            var indoorOutdoor = String(window.io_category_data[rentalId]["indoor_outdoor"] || "").replace(/[\r\n]+/g, "").trim();
419            var staff = String(window.io_category_data[rentalId]["staff"] || "").replace(/[\r\n]+/g, "").trim();
420            var electric = String(window.io_category_data[rentalId]["electric"] || "").replace(/[\r\n]+/g, "").trim();
421            var dimensions = String(window.io_category_data[rentalId]["dimensions"] || "").replace(/[\r\n]+/g, "").trim();
422
423            var stripHtml = function(html) {
424                var tmp = document.createElement("DIV");
425                tmp.innerHTML = html;
426                return (tmp.textContent || tmp.innerText || "").trim();
427            };
428
429            var escapeHtml = function(text) {
430                var map = {
431                    '&': '&amp;',
432                    '<': '&lt;',
433                    '>': '&gt;',
434                    '"': '&quot;',
435                    "'": '&#039;'
436                };
437                return text.replace(/[&<>"']/g, function(m) { return map[m]; });
438            };
439
440            var html = '<div class="io_list_view_content">';
441            html += '<div class="io_item_details_labeled">';
442
443            if (indoorOutdoor && indoorOutdoor !== '0' && indoorOutdoor.length > 0) {
444                html += '<div class="io_detail_item io_detail_setup">';
445                html += '<span class="io_detail_label">Setup:</span>';
446                html += '<span class="io_detail_value">' + escapeHtml(indoorOutdoor) + '</span>';
447                html += '</div>';
448            }
449
450            var operatorsText = staff ? staff + ' Adult Supervision Required' : "";
451            if (operatorsText &&
452                operatorsText !== '0 Adult Supervision Required' &&
453                operatorsText !== 'Adult Supervision Required' &&
454                operatorsText !== '0') {
455                html += '<div class="io_detail_item io_detail_operators">';
456                html += '<span class="io_detail_label">Operators:</span>';
457                html += '<span class="io_detail_value">' + escapeHtml(operatorsText) + '</span>';
458                html += '</div>';
459            }
460
461            var powerText = electric ? electric + ' Outlets' : "";
462            if (powerText &&
463                powerText !== '0 Outlets' &&
464                powerText !== '0.00 Outlets' &&
465                powerText !== 'Outlets' &&
466                powerText !== '0') {
467                html += '<div class="io_detail_item io_detail_power">';
468                html += '<span class="io_detail_label">Power:</span>';
469                html += '<span class="io_detail_value">' + escapeHtml(powerText) + '</span>';
470                html += '</div>';
471            }
472
473            if (dimensions && dimensions !== '0' && dimensions.length > 0) {
474                html += '<div class="io_detail_item io_detail_size">';
475                html += '<span class="io_detail_label">Size:</span>';
476                html += '<span class="io_detail_value">' + escapeHtml(dimensions) + '</span>';
477                html += '</div>';
478            }
479
480            html += '</div>';
481            html += '</div>';
482
483            $item.find('.io_buttons_container').before(html);
484        });
485    };
486
487    function bindExistingThumbTargets() {
488    jQuery('.io_item2_list').each(function() {
489        var $item = jQuery(this);
490        var rentalId = $item.find('.item_rentalid').text().trim();
491        if (!rentalId) return;
492
493        var arr = window.io_category_data?.[rentalId]?.images_arr;
494        try {
495            if (typeof arr === 'string' && arr.length) {
496                arr = JSON.parse(arr);
497            }
498        } catch (e) {
499            arr = {};
500        }
501        if (!arr) arr = {};
502
503        $item.find('.io_image_thumb[id]').each(function() {
504            var thumb = this;
505            var match = thumb.id.match(/io_img_thumb(\d+)_(\d+)/);
506            if (!match) return;
507
508            var index = parseInt(match[1], 10) - 1;
509            var imgObj = arr[index];
510            if (!imgObj) return;
511
512            var src = imgObj.rentalimage_imageloc || imgObj.imageloc || imgObj.thumb || "";
513            var href = imgObj.rentalimage_imagelocbig || imgObj.imagelocbig || imgObj.big || "";
514
515            if (isMp4(href) && isValid(src)) {
516                href = src;
517            }
518
519            if (isValid(href)) {
520                thumb.setAttribute('data-big-src', href);
521            }
522
523            jQuery(thumb).off('click.ioGallery').on('click.ioGallery', function () {
524                if (typeof updateMainPic === 'function') {
525                    updateMainPic(this);
526                }
527            });
528        });
529    });
530}
531
532
533    jQuery(document).ready(function($) {
534
535        jQuery(".io_item2_list").each(function(){
536            var rentalId = jQuery(this).find('.item_rentalid').text().trim();
537            if (io_categoryVariantImages == 'on'){
538                if (typeof window.io_category_data !== 'undefined' && window.io_category_data[rentalId]) {
539                    CategoryGallery(
540                        rentalId,
541                        window.io_category_data[rentalId]['rental_name'],
542                        window.io_category_data[rentalId]["images_arr"]
543                    );
544                }
545            }
546        });
547
548        bindExistingThumbTargets();
549
550        console.log('[IO View Toggle] Document ready, initializing view toggle functionality');
551
552        var categoryId = $('.category_id').text().trim();
553        var hasNumericCategoryId = categoryId && !isNaN(categoryId) && categoryId.length > 0;
554
555        if (!hasNumericCategoryId) {
556            console.log('[IO View Toggle] No valid numeric category ID found, this is not a category page - skipping initialization');
557            return;
558        }
559
560        console.log('[IO View Toggle] Category page detected with categoryId:', categoryId);
561        $('body').addClass('io-has-category-id');
562
563        $('.io_view_toggle_container').show();
564        console.log('[IO View Toggle] Toggle buttons displayed for category page');
565
566        var isInitialized = false;
567
568        function initViewToggle(force) {
569            if (isInitialized && !force) {
570                console.log('[IO View Toggle] Already initialized, skipping');
571                return;
572            }
573
574            console.log('[IO View Toggle] Initializing view toggle functionality');
575
576            if ($('.io_view_toggle_btn').length === 0) {
577                console.warn('[IO View Toggle] Toggle buttons not found in DOM');
578                return;
579            }
580            console.log('[IO View Toggle] Found', $('.io_view_toggle_btn').length, 'toggle buttons');
581
582            if ($('.io_catdiv2').length === 0) {
583                console.warn('[IO View Toggle] Category container (.io_catdiv2) not found');
584                return;
585            }
586            console.log('[IO View Toggle] Found', $('.io_catdiv2').length, 'category containers');
587
588            var savedView = localStorage.getItem('io_category_view') || 'tile';
589            console.log('[IO View Toggle] Retrieved saved view preference:', savedView);
590
591            $('.io_catdiv2').removeClass('tile-view list-view').addClass(savedView + '-view');
592            console.log('[IO View Toggle] Applied initial view class:', savedView + '-view');
593
594            $('.io_view_toggle_btn').removeClass('active');
595            $('.io_view_toggle_btn[data-view="' + savedView + '"]').addClass('active');
596            console.log('[IO View Toggle] Updated button states, active button:', savedView);
597
598            if (savedView === 'list') {
599                if (typeof generateListViewContent === 'function') {
600                    generateListViewContent();
601                } else {
602                    console.warn('[IO View Toggle] generateListViewContent function not available yet');
603                }
604            }
605
606            var itemCount = $('.io_item2_list').length;
607            console.log('[IO View Toggle] Found', itemCount, 'items in category');
608
609            $('.io_view_toggle_btn').off('click.viewToggle');
610
611            var buttons = document.querySelectorAll('.io_view_toggle_btn');
612            console.log('[IO View Toggle] Attaching event listeners to', buttons.length, 'buttons using native JS');
613
614            buttons.forEach(function(button) {
615                var newButton = button.cloneNode(true);
616                button.parentNode.replaceChild(newButton, button);
617
618                newButton.addEventListener('click', function(e) {
619                    e.preventDefault();
620                    e.stopPropagation();
621
622                    var view = this.getAttribute('data-view');
623                    console.log('[IO View Toggle] Button clicked (native listener), switching to view:', view);
624
625                    if (view === 'list') {
626                        if (typeof generateListViewContent === 'function') {
627                            generateListViewContent();
628                        } else {
629                            console.warn('[IO View Toggle] generateListViewContent function not available');
630                        }
631                    }
632
633                    document.querySelectorAll('.io_view_toggle_btn').forEach(function(btn
633) {
634                        btn.classList.remove('active');
635                    });
636                    this.classList.add('active');
637                    console.log('[IO View Toggle] Updated button active states');
638
639                    var catdiv = document.querySelector('.io_catdiv2');
640                    if (catdiv) {
641                        catdiv.classList.remove('tile-view', 'list-view');
642                        catdiv.classList.add(view + '-view');
643                        console.log('[IO View Toggle] Applied view class:', view + '-view');
644                    }
645
646                    localStorage.setItem('io_category_view', view);
647                    console.log('[IO View Toggle] Saved view preference to localStorage:', view);
648
649                    setTimeout(function() {
650                        if (catdiv) {
651                            var containerClasses = catdiv.className;
652                            var visibleItems = document.querySelectorAll('.io_item2_list:not([style*="display: none"])').length;
653                            console.log('[IO View Toggle] Layout updated - Container classes:', containerClasses);
654                            console.log('[IO View Toggle] Visible items after view change:', visibleItems);
655
656                            if (view === 'list') {
657                                var visibleListContent = document.querySelectorAll('.io_list_view_content:not([style*="display: none"])').length;
658                                console.log('[IO View Toggle] Visible list content elements:', visibleListContent);
659                            }
660                        }
661                    }, 100);
662                }, true);
663
664                console.log('[IO View Toggle] Event listener attached to button:', newButton.getAttribute('data-view'));
665            });
666
667            console.log('[IO View Toggle] Event handlers attached successfully');
668
669            isInitialized = true;
670        }
671
672        console.log('[IO View Toggle] Starting initial setup');
673        initViewToggle();
674
675        $(document).on('io_content_loaded', function() {
676            console.log('[IO View Toggle] Dynamic content loaded event detected, reinitializing');
677
678            jQuery(".io_item2_list").each(function(){
679                var rentalId = jQuery(this).find('.item_rentalid').text().trim();
680                if (io_categoryVariantImages == 'on'){
681                    if (typeof window.io_category_data !== 'undefined' && window.io_category_data[rentalId]) {
682                        CategoryGallery(
683                            rentalId,
684                            window.io_category_data[rentalId]['rental_name'],
685                            window.io_category_data[rentalId]["images_arr"]
686                        );
687                    }
688                }
689            });
690
691            bindExistingThumbTargets();
692            initViewToggle();
693        });
694
695        if (typeof MutationObserver !== 'undefined') {
696            var mutationTimeout;
697            var lastItemCount = $('.io_item2_list').length;
698
699            var observer = new MutationObserver(function(mutations) {
700                clearTimeout(mutationTimeout);
701
702                mutationTimeout = setTimeout(function() {
703                    var currentItemCount = $('.io_item2_list').length;
704
705                    if (currentItemCount > lastItemCount) {
706                        console.log('[IO View Toggle] New items detected in DOM (' + lastItemCount + ' -> ' + currentItemCount + ')');
707                        lastItemCount = currentItemCount;
708
709                        jQuery(".io_item2_list").each(function(){
710                            var rentalId = jQuery(this).find('.item_rentalid').text().trim();
711                            if (io_categoryVariantImages == 'on'){
712                                if (typeof window.io_category_data !== 'undefined' && window.io_category_data[rentalId]) {
713                                    CategoryGallery(
714                                        rentalId,
715                                        window.io_category_data[rentalId]['rental_name'],
716                                        window.io_category_data[rentalId]["images_arr"]
717                                    );
718                                }
719                            }
720                        });
721
722                        bindExistingThumbTargets();
723
724                        if (isInitialized) {
725                            var currentView = localStorage.getItem('io_category_view') || 'tile';
726                            if (currentView === 'list') {
727                                console.log('[IO View Toggle] Generating list view content for new items');
728                                if (typeof generateListViewContent === 'function') {
729                                    generateListViewContent();
730                                } else {
731                                    console.warn('[IO View Toggle] generateListViewContent function not available');
732                                }
733                            }
734                        } else {
735                            console.log('[IO View Toggle] Initializing due to new items');
736                            initViewToggle();
737                        }
738                    }
739                }, 250);
740            });
741
742            observer.observe(document.body, {
743                childList: true,
744                subtree: true
745            });
746            console.log('[IO View Toggle] DOM mutation observer started');
747        }
748
749        $(window).on('resize.viewToggle', function() {
750            var windowWidth = $(window).width();
751            var currentView = $('.io_catdiv2').hasClass('list-view') ? 'list' : 'tile';
752            console.log('[IO View Toggle] Window resized to:', windowWidth, 'px, current view:', currentView);
753        });
754
755        console.log('[IO View Toggle] Initialization complete');
756    });</script>
vendor: 1 bytes, line 756
756
757<script>window.io_category_data = window.io_category_data || {}; window.io_category_data['2279650'] = {"indoor_outdoor":"","staff":"","electric":"0.00","dimensions":"","rental_id":"2279650","rental_name":"Additional Foam Packages","images_arr":"{\u00220\u0022:{\u0022rentalimage_id\u0022:\u00221432876\u0022,\u0022rentalimage_createtime\u0022:\u00221712170886\u0022,\u0022rentalimage_modifiedtime\u0022:\u00221712170886\u0022,\u0022rentalimage_itemid\u0022:\u00222279650\u0022,\u0022rentalimage_order\u0022:\u00220\u0022,\u0022rentalimage_imageloc\u0022:\u0022https:\/\/rental.software\/users\/\/images\/temp_img_739619530_558510799.jpg\u0022,\u0022rentalimage_imagelocbig\u0022:\u0022https:\/\/rental.software\/users\/\/images\/temp_img_739619530_558510799_big.jpg\u0022,\u0022media_type\u0022:\u0022image\u0022}}"};</script>
757<div class="io_item2_list elementor-widget-heading simpleCart_ioShelfItem cat_div_2279650" name="maindiv_Additional Foam Packages"><div class="cat_div"> <a href="https://iepnw.com/rentals/foam-party/additional-foam-packages/"><div class="btn btn-primary view-product-button">View Product</div> <img decoding="async" class="category_big_img cat_img item_image io_image_big" title="Additional Foam Packages" src="https://rental.software/users//images/temp_img_739619530_558510799_big.jpg" alt="Additional Foam Packages" /> </a> <a rel="noopener" href="https://rental.software/users//images/temp_img_739619530_558510799_big.jpg" id="io_img_big1_2279650" target="_blank"></a> <a rel="img_group noopener" href="" id="io_img_big2_2279650"></a> <br><div class="io_image_thumbbox io_category_thumbox" style="display:none;"> <img decoding="async" class="io_image_thumb skip-lazy" title="Additional Foam Packages" src="https://rental.software/users//images/temp_img_739619530_558510799.jpg" alt="Additional Foam Packages"
758 id="io_img_thumb1_2279650" onclick="updateMainPic(this)" /></div></div><div class="io_item2_list_inner"><p class="elementor-heading-title rentNameIO item_name"><a href="https://iepnw.com/rentals/foam-party/additional-foam-packages/">Additional Foam Packages</a></p><p class="rentNameIO_price rentNameIO_price_2279650"><span class="cat_from" style="font-style:italic;font-size:smaller;">from</span> <span class="rentNameIO_pricespan">$35.00</span></p><p class="item_encoded" style="display:none;">Additional+Foam+Packages</p> <span class="item_href" style="display:none;">https://iepnw.com/rentals/foam-party/additional-foam-packages/</span><p class="item_rentalid" style="display:none;">2279650</p><p class="item_vendorid" style="display:none;"></p><p class="item_qtytype" style="display:none;">Supply</p><p class="item_inputtype" style="display:none;">Dropdown</p> <span class="item_qtyincrement" style="display:none;">1</span><div class="item_timeslots" style="display:none;"></div><p class="item_giftcardvalue" style="display:none;"></p><div class="item_hasRequiredAcc" style="display:none;"></div><div class="io_list_view_data"></div><div class="io_buttons_container"> <a href="https://iepnw.com/rentals/foam-party/additional-foam-packages/" class="io_more_info_button">MORE INFO</a><div class="elementor-widget-button add_cart_2279650"> <a class="item_add elementor-button elementor-size-sm elementor-animation-grow io_button rentNameIO_button"
759 href="javascript:;"><i class="fas fa-shopping-cart"></i> Add to Cart</a></div></div><div class="unavailable_message unavailable_message_2279650"  onclick="checkAvailDateClick()">item unavailable (change date)</div></div></div> 
759<script>jQuery(document).ready(function () {
760        // Hide price when zero
761        jQuery(".rentNameIO_pricespan").each(function () {
762            if( !Number( this.textContent.replace(/[^0-9.-]+/g,"") ) ){
763                jQuery(this.parentElement).hide();
764            }
765        });
766    });</script>
vendor: 1 bytes, line 766
766
767<script>window.io_category_data = window.io_category_data || {}; window.io_category_data['2279642'] = {"indoor_outdoor":"","staff":"","electric":"3.00","dimensions":"25L x 25W x 11H","rental_id":"2279642","rental_name":"Caution Pit Foam Extravaganza","images_arr":"{\u00220\u0022:{\u0022rentalimage_id\u0022:\u00221432868\u0022,\u0022rentalimage_createtime\u0022:\u00221712170876\u0022,\u0022rentalimage_modifiedtime\u0022:\u00221712170876\u0022,\u0022rentalimage_itemid\u0022:\u00222279642\u0022,\u0022rentalimage_order\u0022:\u00220\u0022,\u0022rentalimage_imageloc\u0022:\u0022https:\/\/rental.software\/users\/\/images\/temp_img_577217053_380891727.jpg\u0022,\u0022rentalimage_imagelocbig\u0022:\u0022https:\/\/rental.software\/users\/\/images\/temp_img_577217053_380891727_big.jpg\u0022,\u0022media_type\u0022:\u0022image\u0022}}"};</script>
767<div class="io_item2_list elementor-widget-heading simpleCart_ioShelfItem cat_div_2279642" name="maindiv_Caution Pit Foam Extravaganza"><div class="cat_div"> <a href="https://iepnw.com/rentals/foam-party/caution-pit-foam-extravaganza/"><div class="btn btn-primary view-product-button">View Product</div> <img decoding="async" class="category_big_img cat_img item_image io_image_big" title="Caution Pit Foam Extravaganza" src="https://rental.software/users//images/temp_img_577217053_380891727_big.jpg" alt="Caution Pit Foam Extravaganza" /> </a> <a rel="noopener" href="https://rental.software/users//images/temp_img_577217053_380891727_big.jpg" id="io_img_big1_2279642" target="_blank"></a> <a rel="img_group noopener" href="" id="io_img_big2_2279642"></a> <br><div class="io_image_thumbbox io_category_thumbox" style="display:none;"> <img decoding="async" class="io_image_thumb skip-lazy" title="Caution Pit Foam Extravaganza" src="https://rental.software/users//images/temp_img_577217053_380891727.jpg" alt="Caution Pit Foam Extravaganza"
768 id="io_img_thumb1_2279642" onclick="updateMainPic(this)" /></div></div><div class="io_item2_list_inner"><p class="elementor-heading-title rentNameIO item_name"><a href="https://iepnw.com/rentals/foam-party/caution-pit-foam-extravaganza/">Caution Pit Foam Extravaganza</a></p><p class="rentNameIO_price rentNameIO_price_2279642"><span class="cat_from" style="font-style:italic;font-size:smaller;">from</span> <span class="rentNameIO_pricespan">$999.00</span></p><p class="item_encoded" style="display:none;">Caution+Pit+Foam+Extravaganza</p> <span class="item_href" style="display:none;">https://iepnw.com/rentals/foam-party/caution-pit-foam-extravaganza/</span><p class="item_rentalid" style="display:none;">2279642</p><p class="item_vendorid" style="display:none;"></p><p class="item_qtytype" style="display:none;">Limited</p><p class="item_inputtype" style="display:none;">Dropdown</p> <span class="item_qtyincrement" style="display:none;">1</span><div class="item_timeslots" style="display:none;"></div><p class="item_giftcardvalue" style="display:none;"></p><div class="item_hasRequiredAcc" style="display:none;"></div><div class="io_list_view_data"></div><div class="io_buttons_container"> <a href="https://iepnw.com/rentals/foam-party/caution-pit-foam-extravaganza/" class="io_more_info_button">MORE INFO</a><div class="elementor-widget-button add_cart_2279642"> <a class="item_add elementor-button elementor-size-sm elementor-animation-grow io_button rentNameIO_button"
769 href="javascript:;"><i class="fas fa-shopping-cart"></i> Add to Cart</a></div></div><div class="unavailable_message unavailable_message_2279642"  onclick="checkAvailDateClick()">item unavailable (change date)</div></div></div> 
769<script>jQuery(document).ready(function () {
770        // Hide price when zero
771        jQuery(".rentNameIO_pricespan").each(function () {
772            if( !Number( this.textContent.replace(/[^0-9.-]+/g,"") ) ){
773                jQuery(this.parentElement).hide();
774            }
775        });
776    });</script>
vendor: 1 bytes, line 776
776
777<script>window.io_category_data = window.io_category_data || {}; window.io_category_data['2279644'] = {"indoor_outdoor":"","staff":"","electric":"2.00","dimensions":"15 L x 15 W x 11 H","rental_id":"2279644","rental_name":"Red, WHITE and Blue Foam Blast","images_arr":"{\u00220\u0022:{\u0022rentalimage_id\u0022:\u00221432870\u0022,\u0022rentalimage_createtime\u0022:\u00221712170878\u0022,\u0022rentalimage_modifiedtime\u0022:\u00221712170878\u0022,\u0022rentalimage_itemid\u0022:\u00222279644\u0022,\u0022rentalimage_order\u0022:\u00220\u0022,\u0022rentalimage_imageloc\u0022:\u0022https:\/\/rental.software\/users\/\/images\/temp_img_922038641_143198026.jpg\u0022,\u0022rentalimage_imagelocbig\u0022:\u0022https:\/\/rental.software\/users\/\/images\/temp_img_922038641_143198026_big.jpg\u0022,\u0022media_type\u0022:\u0022image\u0022}}"};</script>
777<div class="io_item2_list elementor-widget-heading simpleCart_ioShelfItem cat_div_2279644" name="maindiv_Red, WHITE and Blue Foam Blast"><div class="cat_div"> <a href="https://iepnw.com/rentals/foam-party/red-white-and-blue-foam-blast/"><div class="btn btn-primary view-product-button">View Product</div> <img decoding="async" class="category_big_img cat_img item_image io_image_big" title="Red, WHITE and Blue Foam Blast" src="https://rental.software/users//images/temp_img_922038641_143198026_big.jpg" alt="Red, WHITE and Blue Foam Blast" /> </a> <a rel="noopener" href="https://rental.software/users//images/temp_img_922038641_143198026_big.jpg" id="io_img_big1_2279644" target="_blank"></a> <a rel="img_group noopener" href="" id="io_img_big2_2279644"></a> <br><div class="io_image_thumbbox io_category_thumbox" style="display:none;"> <img decoding="async" class="io_image_thumb skip-lazy" title="Red, WHITE and Blue Foam Blast" src="https://rental.software/users//images/temp_img_922038641_143198026.jpg" alt="Red, WHITE and Blue Foam Blast"
778 id="io_img_thumb1_2279644" onclick="updateMainPic(this)" /></div></div><div class="io_item2_list_inner"><p class="elementor-heading-title rentNameIO item_name"><a href="https://iepnw.com/rentals/foam-party/red-white-and-blue-foam-blast/">Red, WHITE and Blue Foam Blast</a></p><p class="rentNameIO_price rentNameIO_price_2279644"><span class="cat_from" style="font-style:italic;font-size:smaller;">from</span> <span class="rentNameIO_pricespan">$499.00</span></p><p class="item_encoded" style="display:none;">Red%2C+WHITE+and+Blue+Foam+Blast</p> <span class="item_href" style="display:none;">https://iepnw.com/rentals/foam-party/red-white-and-blue-foam-blast/</span>
778<p class="item_rentalid" style="display:none;">2279644</p><p class="item_vendorid" style="display:none;"></p><p class="item_qtytype" style="display:none;">Limited</p><p class="item_inputtype" style="display:none;">Dropdown</p> <span class="item_qtyincrement" style="display:none;">1</span><div class="item_timeslots" style="display:none;"></div><p class="item_giftcardvalue" style="display:none;"></p><div class="item_hasRequiredAcc" style="display:none;"></div><div class="io_list_view_data"></div><div class="io_buttons_container"> <a href="https://iepnw.com/rentals/foam-party/red-white-and-blue-foam-blast/" class="io_more_info_button">MORE INFO</a><div class="elementor-widget-button add_cart_2279644"> <a class="item_add elementor-button elementor-size-sm elementor-animation-grow io_button rentNameIO_button"
779 href="javascript:;"><i class="fas fa-shopping-cart"></i> Add to Cart</a></div></div><div class="unavailable_message unavailable_message_2279644"  onclick="checkAvailDateClick()">item unavailable (change date)</div></div></div> 
779<script>jQuery(document).ready(function () {
780        // Hide price when zero
781        jQuery(".rentNameIO_pricespan").each(function () {
782            if( !Number( this.textContent.replace(/[^0-9.-]+/g,"") ) ){
783                jQuery(this.parentElement).hide();
784            }
785        });
786    });</script>
786</div></main><footer data-elementor-type="footer" data-elementor-id="243" class="elementor elementor-243 elementor-location-footer" data-elementor-post-type="elementor_library"><section class="elementor-section elementor-top-section elementor-element elementor-element-20194d60 elementor-section-boxed elementor-section-height-default elementor-section-height-default" data-id="20194d60" data-element_type="section" data-e-type="section" id="io_contactform" data-settings="{&quot;background_background&quot;:&quot;classic&quot;}"><div class="elementor-container elementor-column-gap-default"><div class="elementor-column elementor-col-50 elementor-top-column elementor-element elementor-element-23544145" data-id="23544145" data-element_type="column" data-e-type="column"><div class="elementor-widget-wrap elementor-element-populated"><div class="elementor-element elementor-element-1eaaf1ed elementor-widget elementor-widget-heading" data-id="1eaaf1ed" data-element_type="widget" data-e-type="widget" data-widget_type="heading.default"><div class="elementor-widget-container"><h2 class="elementor-heading-title elementor-size-xl">Contact Us</h2></div></div><div class="elementor-element elementor-element-255ad68b elementor-widget elementor-widget-text-editor" data-id="255ad68b" data-element_type="widget" data-e-type="widget" data-widget_type="text-editor.default"><div class="elementor-widget-container"><p>Have questions? We have answers! Can&#8217;t find what you&#8217;re looking for or curious about one of our products? Don&#8217;t hesitate to give us a call or use our <a href="#io_contactform">contact form</a> to reach out to us anytime!</p></div></div><div class="elementor-element elementor-element-a637949 elementor-icon-list--layout-inline elementor-mobile-align-start elementor-list-item-link-full_width elementor-widget elementor-widget-icon-list" data-id="a637949" data-element_type="widget" data-e-type="widget" data-widget_type="icon-list.default"><div class="elementor-widget-container"><ul class="elementor-icon-list-items elementor-inline-items"><li class="elementor-icon-list-item elementor-inline-item"> <a href="tel:(253)%20353-9797"> <span class="elementor-icon-list-icon"> <i aria-hidden="true" class="fas fa-phone-alt"></i> </span> <span class="elementor-icon-list-text">(253) 353-9797</span> </a></li><li class="elementor-icon-list-item elementor-inline-item"> <a href="mailto:[email protected]"> <span class="elementor-icon-list-icon"> <i aria-hidden="true" class="fas fa-envelope"></i> </span> <span class="elementor-icon-list-text">[email protected]</span> </a></li></ul></div></div><div class="elementor-element elementor-element-0f94ccd elementor-icon-list--layout-inline elementor-mobile-align-start elementor-list-item-link-full_width elementor-widget elementor-widget-icon-list" data-id="0f94ccd" data-element_type="widget" data-e-type="widget" data-widget_type="icon-list.default"><div class="elementor-widget-container"><ul class="elementor-icon-list-items elementor-inline-items"><li class="elementor-icon-list-item elementor-inline-item"> <span class="elementor-icon-list-icon"> <i aria-hidden="true" class="fas fa-map-marked-alt"></i> </span> <span class="elementor-icon-list-text">4206 200th St. E Spanaway, WA 98387</span></li></ul></div></div><div class="elementor-element elementor-element-58535fb elementor-widget elementor-widget-heading" data-id="58535fb" data-element_type="widget" data-e-type="widget" data-widget_type="heading.default"><div class="elementor-widget-container"><p class="elementor-heading-title elementor-size-default"><a href="https://iepnw.com/privacy/">Privacy Policy</a></p></div></div></div></div><div class="elementor-column elementor-col-50 elementor-top-column elementor-element elementor-element-3fb56be6" data-id="3fb56be6" data-element_type="column" data-e-type="column"><div class="elementor-widget-wrap elementor-element-populated"><div class="elementor-element elementor-element-54e5a10 elementor-button-align-stretch elementor-widget elementor-widget-form" data-id="54e5a10" data-element_type="widget" data-e-type="widget" data-settings="{&quot;step_next_label&quot;:&quot;Next&quot;,&quot;step_previous_label&quot;:&quot;Previous&quot;,&quot;button_width&quot;:&quot;100&quot;,&quot;step_type&quot;:&quot;number_text&quot;,&quot;step_icon_shape&quot;:&quot;circle&quot;}" data-widget_type="form.default"><div class="elementor-widget-container"><form class="elementor-form" method="post" id="io_contactusform" name="Request Call Back" aria-label="Request Call Back"> <input type="hidden" name="post_id" value="243"/> <input type="hidden" name="form_id" value="54e5a10"/> <input type="hidden" name="referer_title" value="Home - Inflatable Event Professionals LLC Spanaway WA" /> <input type="hidden" name="queried_id" value="109"/><div class="elementor-form-fields-wrapper elementor-labels-"><div class="elementor-field-type-text elementor-field-group elementor-column elementor-field-group-firstandlastname elementor-col-33"> <label for="form-field-firstandlastname" class="elementor-field-label elementor-screen-only"> Name </label> <input size="1" type="text" name="form_fields[firstandlastname]" id="form-field-firstandlastname" class="elementor-field elementor-size-sm  elementor-field-textual" placeholder="Name"></div><div class="elementor-field-type-email elementor-field-group elementor-column elementor-field-group-email elementor-col-33 elementor-field-required"> <label for="form-field-email" class="elementor-field-label elementor-screen-only"> Email </label> <input size="1" type="email" name="form_fields[email]" id="form-field-email" class="elementor-field elementor-size-sm  elementor-field-textual" placeholder="Email" required="required"></div><div class="elementor-field-type-tel elementor-field-group elementor-column elementor-field-group-cellphone elementor-col-33"> <label for="form-field-cellphone" class="elementor-field-label elementor-screen-only"> Phone </label> <input size="1" type="tel" name="form_fields[cellphone]" id="form-field-cellphone" class="elementor-field elementor-size-sm  elementor-field-textual" placeholder="Phone" pattern="[0-9()#&amp;+*-=.]+" title="Only numbers and phone characters (#, -, *, etc) are accepted."></div><div class="elementor-field-type-textarea elementor-field-group elementor-column elementor-field-group-notes elementor-col-100"> <label for="form-field-notes" class="elementor-field-label elementor-screen-only"> Message </label><textarea class="elementor-field-textual elementor-field  elementor-size-sm" name="form_fields[notes]" id="form-field-notes" rows="3" placeholder="&quot;I need help from a human sales rep.&quot;"></textarea></div><div class="elementor-field-type-acceptance elementor-field-group elementor-column elementor-field-group-oktotext elementor-col-100"> <label for="form-field-oktotext" class="elementor-field-label elementor-screen-only"> Text notifications okay? </label><div class="elementor-field-subgroup"> <span class="elementor-field-option"> <input type="checkbox" name="form_fields[oktotext]" id="form-field-oktotext" class="elementor-field elementor-size-sm  elementor-acceptance-field"> <label for="form-field-oktotext">Text notifications okay? (by completing this form you agree to re
786ceive text messages)</label> </span></div></div><div class="elementor-field-type-hidden elementor-field-group elementor-column elementor-field-group-oktotext elementor-col-100"> <input size="1" type="hidden" name="form_fields[oktotext]" id="form-field-oktotext" class="elementor-field elementor-size-sm  elementor-field-textual" value="1"></div><div class="elementor-field-type-recaptcha_v3 elementor-field-group elementor-column elementor-field-group-field_1a42aac elementor-col-100 recaptcha_v3-bottomright"><div class="elementor-field" id="form-field-field_1a42aac"><div class="elementor-g-recaptcha" data-sitekey="6LcSNw8eAAAAAN1cy4N20ZlzWX4YetiG7zmLXN_f" data-type="v3" data-action="Form" data-badge="bottomright" data-size="invisible"></div></div></div><div class="elementor-field-type-text"> <input size="1" type="text" name="form_fields[website_url]" id="form-field-website_url" class="elementor-field elementor-size-sm " style="display:none !important;"></div><div class="elementor-field-group elementor-column elementor-field-type-submit elementor-col-100 e-form__buttons"> <button class="elementor-button elementor-size-sm elementor-animation-grow" type="submit" id="io_cub"> <span class="elementor-button-content-wrapper"> <span class="elementor-button-icon"> <i aria-hidden="true" class="far fa-paper-plane"></i> </span> <span class="elementor-button-text">Send</span> </span> </button></div></div></form></div></div><div class="elementor-element elementor-element-bb8afcc elementor-widget elementor-widget-text-editor" data-id="bb8afcc" data-element_type="widget" data-e-type="widget" data-widget_type="text-editor.default"><div class="elementor-widget-container"> This site is protected by reCAPTCHA and the Google <a href="https://policies.google.com/privacy">Privacy Policy</a> and <a href="https://policies.google.com/terms">Terms of Service</a> apply.</div></div></div></div></div></section><section class="elementor-section elementor-top-section elementor-element elementor-element-5712f75c elementor-section-boxed elementor-section-height-default elementor-section-height-default" data-id="5712f75c" data-element_type="section" data-e-type="section" data-settings="{&quot;background_background&quot;:&quot;classic&quot;}"><div class="elementor-container elementor-column-gap-no"><div class="elementor-column elementor-col-100 elementor-top-column elementor-element elementor-element-145986c0" data-id="145986c0" data-element_type="column" data-e-type="column"><div class="elementor-widget-wrap elementor-element-populated"><div class="elementor-element elementor-element-b187d00 elementor-widget elementor-widget-global elementor-global-1920 elementor-widget-text-editor" data-id="b187d00" data-element_type="widget" data-e-type="widget" data-widget_type="text-editor.default"><div class="elementor-widget-container"><p>Copyright © <span id="io_fbs">Inflatable Event Professionals LLC Spanaway WA</span> All Rights Reserved | Rental Software Powered By <a href="https://www.inflatableoffice.com/" target="_blank" rel="noopener">InflatableOffice</a></p></div></div></div></div></div></section></footer> 
786<script type="speculationrules">{"prefetch":[{"source":"document","where":{"and":[{"href_matches":"/*"},{"not":{"href_matches":["/wp-*.php","/wp-admin/*","/wp-content/uploads/*","/wp-content/*","/wp-content/plugins/*","/wp-content/themes/io-kenos/*","/*\\?(.+)"]}},{"not":{"selector_matches":"a[rel~=\"nofollow\"]"}},{"not":{"selector_matches":".no-prefetch, .no-prefetch a"}}]},"eagerness":"conservative"}]}</script>
786 <img src="https://rental.software/include/iotracking.php" style="display:none;" importance="low" alt="dynamic io trk code" /><style>.io_product_price_4h,.io_product_price_8h,.io_product_price_24h,.io_product_price_additionalday{display:none}.io_product_price_6h{display: grid !important}
787        .io_product_cust_price
788        {
789            display: none !important;
790        }
791        #item_live_price_time_set_message
792        {
793            display: none !important;
794        }
795        
796    /* ALWAYS hide toggle buttons and list view on inventory/all-items pages (no category ID) */
797    body.io-no-category-id .io_view_toggle_container,
798    body.io-no-category-id .io_list_view_content
799    {
800        display: none !important;
801    }
802    
803    /* Force grid/tile layout on pages without category IDs */
804    body.io-no-category-id .io_catdiv2.list-view {
805        display: grid !important;
806        grid-template-columns: repeat(auto-fit, minmax(250px, 350px)) !important;
807        grid-gap: 10px !important;
808        margin: 50px !important;
809        max-width: none !important;
810        justify-content: space-evenly !important;
811    }
812    body.io-no-category-id .io_catdiv2.list-view .io_item2_list {
813        display: block !important;
814        flex-direction: column !important;
815        margin-bottom: 0 !important;
816        padding: 0 !important;
817        align-items: initial !important;
818        text-align: center !important;
819    }
820    body.io-no-category-id .io_catdiv2.list-view .cat_div {
821        flex: initial !important;
822        margin-right: 0 !important;
823        position: relative !important;
824    }
825    body.io-no-category-id .io_catdiv2.list-view .cat_img {
826        width: 100% !important;
827        height: auto !important;
828        object-fit: cover !important;
829    }
830    body.io-no-category-id .io_catdiv2.list-view .io_item2_list_inner {
831        flex: initial !important;
832        margin-top: initial !important;
833        display: block !important;
834        flex-direction: initial !important;
835        justify-content: initial !important;
836        min-height: auto !important;
837        height: auto !important;
838    }
839    
840    .io_all_item_cat{
841        display:none;
842        float:none;
843        width:100%;
844        margin-top:20px;
845    }</style> 
845<script>var io_wp_local_path = "";
846    var io_checkavail = "warn";
847    var io_hidetimes = "off";
848    var io_user_country = "US";
849    var io_user_currency = "USD";
850    var io_default_start_time = "11:00 am";
851    var io_default_end_time = "3:00 pm";
852    var io_default_duration = 4.00;
853    var io_force_blank_timepickers = "";
854    var io_hide_end_time = "";
855    var io_cart_date_format = "m/d/yy";
856    var io_cart_message = "";
857    var io_cart_time_format = "g:i a";
858    var io_multidayquote = "on";
859    var io_cartdayselect = "dropdown_options";
860    var io_cartAllowSameDay = "off";
861    var io_overnightPickupTime = "10:00 am";
862    var io_incartupsell = "on";
863    var io_distancecharge = "on";
864    var io_deliverymethod = "off";
865    var io_brand = "IO";
866    var io_restrict_times = "on";
867    var io_restrict_time_start = "8:00 am";
868    var io_restrict_time_end = "7:00 pm";
869    var io_default_state = "WA";
870    var io_hide_zero = "1";
871    var io_weekEndPrice = "off";
872    var io_weekDayText = "Weekday price.";
873    var io_weekEndText = "Weekend price.";
874    var io_weekendDefine = "friday-sunday";
875    var io_accessory_price = "off";
876    var io_accessory_select = "off";
877    var io_upsell_price = "off";
878    var io_cart_party_planner_email = "on";
879    var io_cart_party_planner_destination = "https://iepnw.com/plan-a-party/";
880    var io_hideQuantityAvail = "off";
881    var io_company_timeslots = [];
882    var io_info_required = "off";
883    var io_always_display_live_price = "off";
884    var io_default_delivery_method = "";
885    var io_hide_live_prices = 1;
886    var io_info_required_data = [];
887    var io_prices = {"0":"isset","override_groups":[],"1":"io_product_price_6h"};
888    var io_delivery_prices = {"default":[],"override":[]};
889    var io_custom_prices = {"default":[],"override":[]};
890    var io_delivery_methods = {"Delivery and Pickup":{"restricted":"[]","id":"88833"},"Email":{"restricted":[],"id":"89895"},"Fully Staffed":{"restricted":"[]","id":"88633"}};
891    var io_customer_geolocation = "";
892    var io_customer_ip = "34.225.87.80";
893    var io_delivery_methods_restrict = null;
894    var io_pagename = "Inflatable Event Professionals LLC";
895    var io_categoryVariantImages = "";
896    //var io_seocitylinktext = "Professional delivery to <span class=\"io_city_list\">%%landing_pages%%</span> and surrounding areas. Please submit a quote or contact us to be sure we service your area.";
897    jQuery( document ).ready(function() {
898
899        //force all quote form links to use cart data
900        //removing back to cart shortcode as this needs to only be done if cart is not empty IO-22561
901        /*
902        let headerBookButton = jQuery("a[href$='io_quoteform/']");
903        headerBookButton.addClass("ioCart_link");
904        headerBookButton.attr("href", "javascript:;");
905        */
906
907
908        let last_cat_name = "";
909        let ioTrigger = false;
910        jQuery(".io_all_item_cat").each(function() {
911            current_cat_name = jQuery(this).html();
912            if(last_cat_name !== current_cat_name) {
913                jQuery(this).show();
914                ioTrigger = true;
915            }
916            last_cat_name = current_cat_name;
917        });
918
919        // Setup gen page blocks
920		let io_divs = document.querySelectorAll(".io_item2_list, .io_item2_listcat, .io_item2_listrent, .io_all_item_cat");
921		let io_divscat = document.querySelectorAll(".io_item2_listcat");
922		let io_divsrent = document.querySelectorAll(".io_item2_listrent");
923		let io_divcat = document.querySelector(".io_catdiv2");
924		let io_pcc = document.querySelector(".page-content");
925		let io_html;
926
927		if (io_divs.length > 0) {
928	      for (let i of io_divs) {
929	        if(i.parentNode.className.indexOf("io_mm_") === -1){
930	          io_divcat.appendChild(i);
931	        }
932		  }
933		  if(io_divcat!==null) io_divcat.style.display = "grid";
934		}
935
936		if (ioTrigger) {
937            let pageBlock = document.querySelector(".io_catdiv2");
938            pageBlock.classList.add("elementor-widget-heading");
939            let scanRes = pageBlock.querySelectorAll(".io_item2_listrent");
940            pageBlock.style.display = "block";
941            pageBlock.style.margin = "auto";
942            pageBlock.style.textAlign = "center";
943            pageBlock.style.marginLeft = "5px";
944            pageBlock.style.marginRight = "5px";
945            for (let i of scanRes) {
946                i.style.display = "inline-block";
947                i.style.marginLeft = "5px";
948                i.style.marginRight = "5px";
949            }
950        }
951
952		/* fix font color on older sites */
953		if(jQuery("#cartData").css("background-color")=="rgb(35, 36, 37)"){
954		    jQuery("#cartData").css("color","white");
955		}
956    });</script>
956<style>.ui-datepicker-trigger{display:none}</style><div id="cartPopover"><div id="ioCartLoadingOverlay" aria-hidden="true"><div class="io-spinner" role="status" aria-live="polite" aria-label="Loading"></div></div><div id="triangle"></div><div id="cartCalendarTimePickerContainer"><div id="cartCalendar"></div><div id="cartTimePicker"><div id="div-overnight"> Days <select style="color:black;" name="whatday" id="whatday" onchange="endDisplay();"><option value="Same Day" selected="selected">Single Day</option><option value="Overnight">Overnight</option><option value="Multi-Day">Multi-Day</option> </select></div> <br><div id="ioCartTimeSelectContainer"><div> <span class="calTimeLabel calTimeLabelStart">Start</span> <i class="fas fa-calendar-check"></i> <input type="text" name="dateStart" class="ioCartDateInput" readonly="readonly" /> <i class="fas fa-clock"></i> <input type="text" name="timeStart" class="timepicker" style="width:75px;" /></div><div> <span class="calTimeLabel calTimeLabelEnd">End</span> <i class="fas fa-calendar-check"></i> <input type="text" name="dateEnd" class="ioCartDateInput" readonly="readonly" /> <i class="fas fa-clock"></i> <input type="text" name="timeEnd" class="timepicker" style="width:75px;" /></div></div> <br><div id="ioDeliveryMethodContainer" style="display:none; text-align: center;"></div> <br><div id="ioAdditonalInformationContainer" style="display:none; text-align: center;"><div class="io_info_modal_data_container" id="io_info_modal_address"> <label for="address" id="io_iml_address_label" style="width:105px"> Street Address </label> <input class="io_modal_input_address" style="margin-left:5px" id="io_im_address"  name="address" type="text"></input> <br></div><div class="io_info_modal_data_container" id="io_info_modal_city"> <label for="city" id="io_iml_city_label" style="width:105px"> City </label> <input class="io_modal_input_city" style="margin-left:5px" id="io_im_city" name="city" type="text"></input> <br></div><div class="io_info_modal_data_container" id="io_info_modal_zip"> <label for="zip" id="io_iml_zip_label" style="width:105px"> Zip Code </label> <input class="io_modal_input_zip" id="io_im_zip" style="margin-left:5px" name="zip" type="text"></input></div></div> <br><div class="elementor-widget-button" style="padding:10px;display:inline-block;"> <a onclick="calApply()" href="javascript:;"
957 class="elementor-button-link elementor-button elementor-size-sm elementor-animation-grow"
958 style="text-decoration: none;">Apply</a></div><div class="elementor-widget-button" style="padding:10px;display:inline-block;"> <a onclick="calCancel()" href="javascript:;"
959 class="elementor-button-link elementor-button elementor-size-sm elementor-animation-grow simpleCart_cancel"
960 style="text-decoration: none;">Cancel</a></div></div><div id="cartDateRange" class="ioDateRange" onclick="calSetDateRange(1)" style="display:none;"></div><div class="changeDateLinkWrapper elementor-widget-button"><div id="changeDateLink" onclick="calSetDateRange(1)" class="elementor-button elementor-animation-grow">Change Date</div></div></div><div id="cartPartyBuilderEmailContainer" style="display:none;text-align:center"><p>Provide an email address here to recieve our free party planner!</p> <input type="text" id="cartPartyBuilderEmailInput"><div class="elementor-widget-button" style="display:inline-block;"> <a onclick="io_party_planner_email_submit()" href="javascript:;" class="elementor-button-link elementor-button elementor-size-sm" style="padding: 6px 15px;text-decoration: none;">Go</a></div><div id="cartPartyBuilderEmailWarning" style="display:none">Pleave provide a valid email address.</div> <br><br></div><div id="cartCustomMessage" style="display:none;text-align:center"></div><div id="cartWarning" class="clearfix"></div><div id="deliveryMethodWarning" class="clearfix">Some items are not available for the selected delivery method.</div> <span class="io_locationRedirectLink">You may not be on the correct site. Click here to change location.</span><div id="cartData" class="clearfix"><div class="simpleCart_items"></div></div><div class="cartSubtotalBox"> Subtotal (estimate):<div id="cartSubtotal"></div></div><div class="checkDeliveryCartContainer"><div id="checkDeliveryMessage" class="cartDeliverytotalBox"><a class="cartLink" href="javascript:;" onClick="showAddressEntry(true)">Check Delivery</a></div><div id="deliverSubtotalContainer" class="cartDeliverytotalBox"> Delivery Fee (<span><a class="cartLink" href="javascript:;" onClick="showAddressEntry(true)">Change Address</a></span>):<div id="deliverySubtotal"></div></div></div><div id="cartCheckoutButton" class="clearfix"><div class="elementor-widget-button"> <a href="javascript:cartHide();
960" class="simpleCart_continue elementor-button elementor-size-sm elementor-animation-grow io_button">Continue Shopping</a> <a href="javascript:;" class="simpleCart_checkout elementor-button elementor-size-sm elementor-animation-grow io_button">Checkout</a></div><div id="cart-carousel-container" style="display:none"> <label> Some items you may be interested in: </label> <br><div class="cart-carousel"></div></div><div class="ioLink"><a href="https://www.inflatableoffice.com" target="_blank">powered by io</a></div></div></div>  
960<script>/* configurable globals */
961  var start_default = "11:00 am";
962  if(io_default_start_time != "") start_default = io_default_start_time;
963  var end_default = "3:00 pm";
964  if(io_default_end_time != "") end_default = io_default_end_time;
965
966  if(io_user_currency){
967    var currency = io_user_currency;
968  } else{
969    var currency = "USD";
970  }
971
972  if(io_user_country){
973    var country = io_user_country;
974  } else{
975    var country = "US";
976  }
977
978
979  var timeFormat = "g:i a";
980  if(io_cart_time_format != "") timeFormat = io_cart_time_format;
981  var dateFormat = "m/d/yy";
982  if(io_cart_date_format != "") dateFormat = io_cart_date_format;
983
984  var restrictTimes = false;
985  if(io_restrict_times === "on") restrictTimes = true;
986  var restrictTimeStart = start_default;
987  if(io_restrict_time_start != "") restrictTimeStart = io_restrict_time_start;
988  var restrictTimeEnd = end_default;
989  if(io_restrict_time_end != "") restrictTimeEnd = io_restrict_time_end;
990
991
992  var multi_day = true;
993  if(io_multidayquote === "off" || io_cartdayselect == "Single Day") multi_day = false;
994  var in_cart_upsell = false;
995  if(io_incartupsell === "on") in_cart_upsell = true;
996  var io_distance_charge = false;
997  if(io_distancecharge === "on") io_distance_charge = true;
998
999  /* other globals */
1000  var pallet_color1 = ""; /* set in onready */
1001  /* track the date start/end of calendar clicking */
1002  var click_count = 0;
1003
1004  /* for configuring upsell carosel in cart */
1005  var cart_carousel_set = false;
1006
1007  /* for checking when we remove an item from the cart */
1008  var last_remove = 0;
1009  var last_upsell_call = 0;
1010
1011  /* for buffering cart qty changes checkAvail calls for qty change only */
1012  var last_checkAvail_call = 0;
1013
1014  /* for cart loading animation */
1015  var io_cart_loading_active = false;
1016  var io_cart_loading_count = 0;
1017  var io_cart_loading_fallback_timer = null;
1018
1019  /*var start_default = "11:00";
1020    var end_default = "15:00";
1021    var currency = "EUR";
1022    var timeFormat = "G:i";
1023    var dateFormat = "d/m/yy";*/
1024
1025
1026  /* For weekday weekend pricing */
1027  var use_weekday_weekend = false;
1028  if(io_weekEndPrice == "on") use_weekday_weekend = true;
1029
1030  /* Accessory and Upsell Prices */
1031  var show_accessory_price = false;
1032  if(io_accessory_price == "on") show_accessory_price = true;
1033  var show_upsell_price = false;
1034  if(io_upsell_price == "on") show_upsell_price = true;
1035
1036  /* For customer geolocation shortcode */
1037  var storage_key = 'io_customer_location';
1038
1039  /*<editor-fold defaultstate="collapsed" desc="On Ready">*/
1040  jQuery(document).ready(function () {
1041    pallet_color1 = "var( --e-global-color-accent,green )";
1042    if(pallet_color1=="rgba(0, 0, 0, 0)" || pallet_color1=="rgb(255, 255, 255)") pallet_color1="rgb(25, 147, 35)";
1043
1044    /*<editor-fold defaultstate="collapsed" desc="SimpleCart Init">*/
1045    simpleCart({
1046      currency: currency,
1047      cartColumns: [{
1048        view: "image",
1049        attr: "image",
1050        label: "Image"
1051      },
1052        {
1053          attr: "name",
1054          label: "Name"
1055        },
1056        {
1057          attr: "encoded",
1058          label: false
1059        },
1060        {
1061          attr: "rentalid",
1062          label: false
1063        },
1064        {
1065          attr: "availability",
1066          label: false
1067        },
1068        {
1069          view: "decrement",
1070          label: false,
1071          text: "<i class='fas far fa-minus-square' style='color:" + pallet_color1 + "'></i>"
1072        },
1073        {
1074          view: "calculate_area",
1075          label: false
1076        },
1077        {
1078          view:"input",
1079          attr:"quantity"
1080
1081        },
1082        {
1083          attr: "qtyincrement",
1084          label: false
1085        },
1086        {
1087          attr: "inputtype",
1088          label: false
1089        },
1090        {
1091          attr: "qtytype",
1092          label: false
1093        },
1094        {
1095          attr: "vendorid",
1096          label: false
1097        },
1098        {
1099          view: "increment",
1100          label: false,
1101          text: "<i class='fas far fa-plus-square' style='color:" + pallet_color1 + "'></i>"
1102        },
1103        {
1104          attr: "price",
1105          label: "Price",
1106          view: 'currency'
1107        },
1108        {
1109          view: "remove",
1110          label: false,
1111          text: "<i class='fas fa-trash' style='color:" + pallet_color1 + "'></i>"
1112        },
1113        {
1114          attr: "total",
1115          label: "SubTotal",
1116          view: 'currency'
1117        },
1118        {
1119          attr: "timeslots",
1120          label: false
1121        },
1122        {
1123          attr: "timeslots-orig",
1124          label: false
1125        },
1126        {
1127          attr: "href",
1128          label: false
1129        },
1130        {
1131          attr: "linkqty",
1132          label: false
1133        },
1134        {
1135          attr: "acc_dd_parent_limit",
1136          label: false
1137        }
1138      ],
1139      checkout: {
1140        type: "SendForm",
1141        method: "GET",
1142        url: io_wp_local_path+"/io_quoteform/",
1143        extra_data: {
1144          /* name: decodeURIComponent("Inflatable Event Professionals LLC".replace(/[+]/gi, " ")), */
1145          clear_rentals: "1",
1146          selected_only: "1",
1147          wp_checkout: "1",
1148          startdate: "",
1149          enddate: "",
1150          starttime: "",
1151          endtime: "",
1152          io_custguid: ""
1153        }
1154      }
1155    });
1156
1157    simpleCart.bind('update', cart_onUpdate);
1158    simpleCart.bind('beforeSave', cart_hideTimepickerWrapper);
1159    simpleCart.bind('beforeRemove', cart_beforeRemove);
1160    simpleCart.bind('afterRemove', cart_afterRemove);
1161    simpleCart.bind('afterQtyChange', cart_afterQtyChange);
1162    simpleCart.bind('beforeCheckout', cart_beforeCheckout);
1163    simpleCart.bind('afterAdd', cart_afterAdd);
1164    simpleCart.bind('beforeAdd', cart_beforeAdd);
1165    simpleCart.bind('load', cart_afterLoad)
1166    /*</editor-fold>*/
1167
1168    /* showAvail(""); */
1169    let io_star_pic = document.querySelector("#io_star_pic");
1170    if (io_star_pic != null) {
1171      let io_star_src = io_star_pic.src;
1172      if (io_star_src.indexOf("0star") > -1 || io_star_src.indexOf("1star") > -1 || io_star_src.indexOf("2star") > -1 ||
1173              io_star_src.indexOf("3star") > -1) {
1174        io_star_pic.style.display = "none";
1175      }
1176    }
1177
1178    /*<editor-fold desc="Build Thumb Images">*/
1179    /* build multiple thumb images */
1180
1181    /*</editor-fold>*/
1182
1183    /*<editor-fold desc="Set up Accessories">*/
1184    /* Add Add To Cart Buttons */
1185    let button_add = document.querySelector("#bookNowBtn");
1186    var main_id = 0;
1187    if(jQuery(".io_product_container .item_rentalid")){
1188      main_id = jQuery(".io_product_container .item_rentalid").first().text();
1189    }
1190    /* if main item is dd but not pkg (linen code) */
1191    if(jQuery(".io_acc_accessorydd").text()==1 && jQuery(".io_acc_ispackage").text()!=1){
1192      /* if order is defined, then reorder here. */
1193      var acc_cls = jQuery('.io_product_accessories')
1194      acc_cls.hide();
1195      let pkg = document.querySelector(".io_product_acc_pkg");
1196      if(pkg==undefined){
1197        pkg = document.createElement("div");
1198        pkg.classList.add("io_product_acc_pkg");
1199        pkg.style.textAlign = "center";
1200        acc_cls.after(pkg);
1201      }
1202      for (let [key, value] of acc_obj_relate) {
1203        elem = getAccElem(key,main_id);
1204        if(elem){
1205          btn = makeAccBtn(elem,main_id);
1206          pkg.append(btn);
1207        }
1208
1209      }
1210      let line = document.createElement("div");
1211      line.innerHTML = "<br>";
1212      pkg.append(line.cloneNode(true));
1213      for (let [key, value] of acc_obj_relate) {
1214        for (key2 in acc_obj_relate.get(key)) {
1215          if(Object.keys(value[key2]).length > 0){
1216            /* 3rd level */
1217            pkg.append(line.cloneNode(true));
1218            for (key3 in acc_obj_relate.get(key)[key2]) {
1219              elem = getAccElem(key3,key2);
1220              if(elem){
1221                btn = makeAccBtn(elem,key2);
1222                btn.style.display = "none";
1223                pkg.append(btn);
1224              }
1225            }
1226          }else{
1227            elem = getAccElem(key2,key);
1228            if(elem){
1229              btn = makeAccBtn(elem,key);
1230              btn.style.display = "none";
1231              pkg.append(btn);
1232            }
1233
1234          }
1235        }
1236      }
1237    }else {
1238      let access_array = document.querySelectorAll(".io_acc_li");
1239      let count = 0;
1240      for (let i of access_array) {
1241        let path = i.id.replace("io_acc_","");
1242        count++;
1243        let newButton = button_add.cloneNode(true);
1244        newButton.id = button_add.id + count;
1245        newButton.classList.remove("elementor-animation-grow");
1246        newButton.classList.add("elementor-animation-shrink");
1247
1248        let path_arr = path.split("_");
1249        let pid = parseInt(path_arr[0]);
1250        let this_id = parseInt(path_arr[1]);
1251        if(path_arr.length==1) pid=0;
1252
1253        if(jQuery("#io_acc_accessorydd_"+path).first().text()==1){
1254          /* display different to provide choices in dd */
1255          //main_id = pid;
1256        }else{
1257          /* hide accessories inside a pkg when under an accessory choice item until clicked */
1258          if(jQuery("#io_acc_accessorydd_"+main_id+"_"+pid).first().text()==1){
1259          }else{
1260            /* jpa - not finished/tested yet */
1261            /*jQuery("#io_acc_"+path).hide();*/
1262          }
1263          /* Fix broken images for accessories. */
1264          let img_box = document.querySelectorAll(".io_acc_li_img_thumb");
1265          let firstImg = true;
1266          let lastAcc = "";
1267          for (let i of img_box) {
1268            if(lastAcc=="") lastAcc = i.id;
1269            if(lastAcc!=i.id){
1270              lastAcc = i.id;
1271              firstImg = true;
1272            }
1273            let io_img_src = i.src;
1274            if(io_img_src!==null) io_img_src = io_img_src.toLowerCase();
1275            let io_img_datasrc = i.getAttribute("data-src");
1276            if(io_img_datasrc===null){
1277              io_img_datasrc = "";
1278            }else{
1279              io_img_datasrc = io_img_datasrc.toLowerCase();
1280            }
1281            if ((io_img_src.indexOf("io_noimage.png") >= 0 || io_img_datasrc.indexOf("io_noimage.png") >= 0) || (io_img_src.indexOf(".jpg") == -1 && io_img_src.indexOf(".jpe") == -1 && io_img_src.indexOf(".png") == -1 && io_img_src.indexOf(".gif") == -1 && io_img_src.indexOf(".tif") == -1 && io_img_src.indexOf(".webp") == -1)){
1282              i.style.display = "none";
1283            }else if(!firstImg && jQuery("#io_acc_accessorydd_"+main_id+"_"+pid).first().text()!=1){
1284              i.style.display = "none";
1285            }
1286            firstImg = false;
1287          }
1288          if(jQuery("#io_acc_accessorydd_"+main_id+"_"+pid).first().text()==1){
1289            /* Make the accessory category look more mike a label. */
1290            jQuery("#iothumb_"+main_id+"_"+pid).hide();
1291            jQuery("#io_acc_"+main_id+"_"+pid).css("border", "none");
1292            jQuery("#io_acc_"+main_id+"_"+pid).css("width", "100%");
1293            jQuery("#io_acc_"+main_id+"_"+pid).css("margin-bottom", "5vh");
1294            jQuery("#io_acc_"+main_id+"_"+pid).css("box-shadow", "none");
1295            jQuery("#io_acc_shortname_"+pid).css("font-weight", "bold");
1296            jQuery("#io_acc_shortname_"+pid).css("position", "absolute");
1297            /* Make this auto selected to fix an issue where we can not add to cart if this item is
1298                           a child of another hidden accessory on screen */
1299            jQuery("#io_acc_"+main_id+"_"+pid).prop("selected", true);
1300            accessory_cat_text = jQuery("#io_acc_shortname_"+pid).first().text();
1301            /* This is necessary to make sure there are not multiple colons. */
1302            if(!accessory_cat_text.includes(":")){
1303              jQuery("#io_acc_shortname_"+pid).text(accessory_cat_text+":");
1304            }
1305            /* Remove Href so we do not open images on click for dd accessories. */
1306            jQuery("[id^=io_acc_imgbig_"+pid+"_]").removeAttr("href");
1307
1308            /* Get the accessory limit for this set of acessories, then set up click events. */
1309            /* Unbind is used to prevent cascading calls. */
1310            accLmt = parseInt(jQuery("#io_acc_accessorylimit_"+main_id+"_"+pid).prop("textContent"));
1311            jQuery("[id^=io_acc_"+pid+"_]").unbind("click").click({pid: pid, accLmt: accLmt}, accDDClicked);
1312            jQuery("[id^=io_acc_"+pid+"_]").css("cursor", "pointer");
1313            /* Set up the slected property of all children accessories. Default to false. */
1314            jQuery("[id^=io_acc_"+pid+"_]").prop("selected", false);
1315            /* We need to add a hidden button so we can simulate a click on add_item for the cart. */
1316            let newButton = button_add.cloneNode(true);
1317            newButton.id = button_add.id + count;
1318            newButton.classList.remove("elementor-animation-grow");
1319            newButton.setAttribute("style", "display: none !important");
1320            i.appendChild(newButton);
1321          }else{
1322            let button_wrap = document.createElement("div");
1323            button_wrap.classList.add("elementor-widget-button");
1324            button_wrap.classList.add("io_access_button");
1325            button_wrap.appendChild(newButton);
1326            let req = false;
1327            if(jQuery("#io_acc_required_"+path).first().text()>0) req = true;
1328            if(!req){
1329              i.appendChild(button_wrap);
1330            }else{
1331              var textnode = document.createTextNode("Included");
1332              i.appendChild(textnode);
1333            }
1334          }
1335        }
1336      }
1337    }
1338    /*</editor-fold>*/
1339
1340    let upsell_array = document.querySelectorAll(".io_upsell_li");
1341    count = 0;
1342    for (let i of upsell_array) {
1343      count++;
1344      let newButton = button_add.cloneNode(true);
1345      newButton.id = button_add.id + count;
1346      newButton.classList.remove("elementor-animation-grow");
1347      newButton.classList.add("elementor-animation-shrink");
1348
1349      let button_wrap = document.createElement("div");
1350      button_wrap.classList.add("elementor-widget-button");
1351      button_wrap.classList.add("io_upsell_button");
1352      button_wrap.appendChild(newButton);
1353      i.appendChild(button_wrap);
1354    }
1355
1356    if(io_deliverymethod == "on" && jQuery(".calDeliveryMethodLabel").length==0){
1357      let delivery_method_container = jQuery("#ioDeliveryMethodContainer").first();
1358      delivery_method_container.append('<span class="calDeliveryMethodLabel">Select Delivery Method</span>');
1359      let delivery_method_html = '<select class="ioDeliveryMethods" onchange="deliveryMethodSelected()">';
1360      let delivery_methods = Object.keys(io_delivery_methods)
1361      for(const index in delivery_methods){
1362        if(!io_delivery_methods_restrict){
1363          delivery_method_html += '<option value="'+delivery_methods[index]+'">'+delivery_methods[index]+'</option>';
1364          if(index == 0 && !getCookie("io_delivery_method")) setCookie("io_delivery_method", delivery_methods[index], 14);
1365        }else if( !io_delivery_methods_restrict.includes( io_delivery_methods[ delivery_methods[index] ]["id"] ) ){
1366          delivery_method_html += '<option value="'+delivery_methods[index]+'">'+delivery_methods[index]+'</option>';
1367          if(index == 0 && !getCookie("io_delivery_method")) setCookie("io_delivery_method", delivery_methods[index], 14);
1368        }
1369      }
1370      delivery_method_container.append(delivery_method_html);
1371      delivery_method_container.show();
1372      if(getCookie("io_delivery_method")){
1373        jQuery(".ioDeliveryMethods").val(getCookie("io_delivery_method"));
1374      }
1375    }else{
1376      setCookie("io_delivery_method", "", 14);
1377    }
1378
1379    let allow_same_day = 1;
1380    if(io_cartAllowSameDay == "on"){
1381      allow_same_day = 0;
1382    }
1383
1384    /*<editor-fold desc="Cart Calandar and Time Settings Setup">*/
1385    //var fullmonth_array = jQuery.datepicker.regional["en"].monthNames;
1386    jQuery("#cartCalendar").datepicker({
1387      changeMonth: true,
1388      changeYear: true,
1389      //monthNamesShort : fullmonth_array,
1390      dateFormat: dateFormat,
1391      rangeSelect: true,
1392      numberOfMonths: 1,
1393      stepMonths: 1,
1394      prevText: "<< Previous Months",
1395      nextText: "Next Months >>",
1396      speed: "fast",
1397      showOn: "both",
1398      onChangeMonthYear: cal_onChangeMonthYear,
1399      onSelect: cal_onSelect,
1400      buttonText: "Calendar",
1401      minDate: allow_same_day,
1402      firstDay: 0
1403    });
1404    jQuery(".ui-datepicker-trigger").hide();
1405    if(restrictTimes){
1406      jQuery(".timepicker").timepicker({
1407        startTime: new Date(0, 0, 10, 0, 0, 0),
1408        endTime: new Date(0, 0, 0, 20, 0, 0, 0),
1409        minTime:restrictTimeStart,
1410        maxTime:restrictTimeEnd,
1411        /*show24Hours: $show24Hours,*/
1412        timeFormat: timeFormat,
1413        separator: ":",
1414        className: "elementor-widget-text-editor",
1415        step: 15,
1416        disableTouchKeyboard: true
1417      }).keypress(function(e){
1418        e.preventDefault();
1419      });
1420    } else{
1421      jQuery(".timepicker").timepicker({
1422        startTime: new Date(0, 0, 10, 0, 0, 0),
1423        endTime: new Date(0, 0, 0, 20, 0, 0, 0),
1424        /*show24Hours: $show24Hours,*/
1425        timeFormat: timeFormat,
1426        separator: ":",
1427        className: "elementor-widget-text-editor",
1428        step: 15,
1429        disableTouchKeyboard: true
1430      });
1431    }
1432
1433    /* if we have company wide timeslots, alter time select in cart. Do this only if we are set to single day only */
1434    if(io_company_timeslots.length != 0 && io_cartdayselect == "single_day"){
1435      let time_select_container = jQuery("#ioCartTimeSelectContainer").first();
1436      time_select_container.empty();
1437      let selected_date_html = '<span style="margin-right: 5px !important" class="calTimeLabel">Date</span><i class="fas fa-calendar-check"></i><input style="margin-left: 5px !important" type="text" name="dateStart" class="ioCartDateInput" readonly="readonly" /><input style="display: none !important" type="text" name="dateEnd" class="ioCartDateInput" readonly="readonly" />'
1438      time_select_container.append(selected_date_html);
1439      time_select_container.append("<br>")
1440      time_select_container.append('<span class="calTimeLabel">Select Timeslot</span>');
1441      let timeslot_html = '<select class="ioCartCompanyTimeslots">';
1442      for(i=0; i<io_company_timeslots.length; ++i){
1443        timeslot_html += io_company_timeslots[i];
1444      }
1445      timeslot_html += "</select>"
1446      time_select_container.append(timeslot_html);
1447
1448    }
1449
1450    // Timeslot element on Quote Form
1451    const timeslotSelectElement = jQuery(".controls select[name=timeslot]");
1452
1453    /* jQuery( ".datepicker" ).datepicker({dateFormat: "m/d/yy",minDate:0}); */
1454    /* jQuery( ".datepicker" ).val(getCookie("checkDate")); */
1455    start_date = getCookie("io_dateStart");
1456    end_date = getCookie("io_dateEnd");
1457    start_time = getCookie("io_timeStart");
1458    end_time = getCookie("io_timeEnd");
1459    jQuery("input[name=dateStart]").val(start_date);
1460    jQuery("input[name=dateEnd]").val(end_date);
1461    if(io_company_timeslots.length != 0 && io_cartdayselect == "single_day" && getCookie("io_company_timeslot_selected")){
1462      jQuery(".ioCartCompanyTimeslots").val(getCookie("company_timeslot_selected"));
1463      // Set it on the quote page too.
1464      timeslotSelectElement.val(getCookie("io_company_timeslot_selected"));
1465    } else{
1466      jQuery("input[name=timeStart]").val(start_time);
1467      jQuery("input[name=timeEnd]").val(end_time);
1468    }
1469
1470    timeslotSelectElement.on('change', function() {
1471      // IO-31167: Upon timeslot change on Quote Form,
1472      // update timeslot cookie value for persistence
1473      if(this.value) {
1474        setCookie('io_company_timeslot_selected', this.value, 14);
1475      }
1476    });
1477
1478    if (jQuery("input[name=dateEnd]").val() != "") {
1479      setCalBackground();
1480      jQuery("#cartSubtotal").html(simpleCart.toCurrency(simpleCart.total()));
1481      if(getCookie("io_dateApplied") === "true") calCancel();
1482      else {
1483        jQuery("input[name=dateStart]").val(getCookie("io_dateStart"));
1484        jQuery("input[name=dateEnd]").val(getCookie("io_dateEnd"));
1485        if(io_company_timeslots.length != 0 && io_cartdayselect == "single_day" && getCookie("io_company_timeslot_selected")){
1486          jQuery(".ioCartCompanyTimeslots").val(getCookie("io_company_timeslot_selected"));
1487        }
1488        else if(io_force_blank_timepickers == "on")
1489        {
1490          setCookie("io_timeStart", "", 14);
1491          setCookie("io_timeEnd", "", 14);
1492          jQuery('[name=timeStart]').val("");
1493          jQuery('[name=timeEnd]').val("");
1494        }
1495        else{
1496          jQuery("input[name=timeStart]").val(getCookie("io_timeStart"));
1497          jQuery("input[name=timeEnd]").val(getCookie("io_timeEnd"));
1498        }
1499
1500        jQuery(".changeDateLinkWrapper").hide();
1501      }
1502    }
1503    /*</editor-fold>*/
1504
1505    jQuery("#io-dialog").dialog({
1506      autoOpen: false,
1507      resizable: false,
1508      modal: true,
1509      dialogClass: "noTitleStuff",
1510      width: 350,
1511      open: function () {
1512        jQuery(".ui-widget-overlay").bind("click", function () {
1513          jQuery("#io-dialog").dialog("close");
1514        })
1515      }
1516    });
1517
1518    /* change jquery calendar next/prev buttons to fa arrows w/matching site color */
1519    jQuery("#cartCalendar .ui-datepicker-prev").addClass("fas fa-arrow-left").css("color", pallet_color1);
1520    jQuery("#cartCalendar .ui-datepicker-next").addClass("fas fa-arrow-right").css("color", pallet_color1);
1521
1522    /* hide sections if not set */
1523    if(jQuery(".io_product_circuits_right").first().text()=="0"){jQuery(".io_product_circuits_right,.io_product_circuits_left").hide();}
1524    if(jQuery(".io_city_list").html()==""){jQuery(".io_landingpages").hide();}
1525    /* using this instead as it will handle custom ones added */
1526    let io_field_valbox = document.querySelector(".io_product_infobox");
1527    if (io_field_valbox != null || io_field_valbox != undefined) {
1528      let io_field_valarr = io_field_valbox.querySelectorAll(".io_product_detail_box");
1529      for (let i of io_field_valarr) {
1530        let check = i.querySelector("p:nth-child(2)");
1531        if (check != null && check.innerText == "") i.style.display = "none";
1532      }
1533    }
1534
1535    /* Hide description if there is no description */
1536    desc_box = document.querySelector(".io_product_desc")
1537    if(desc_box != null && desc_box.innerText.length == 0 && desc_box.innerHTML.length == 0){
1538      desc_detail_box = desc_box.parentElement;
1539      desc_detail_box.style.display = "none";
1540    }
1541
1542    if(document.querySelector(".io_product_reviewbox")!=null){
1543      if (document.querySelector(".io_product_reviewbox").innerText == "") {
1544        if(document.querySelector(".io_star_rating")!=null) document.querySelector(".io_star_rating a").style.display = "none";
1545      }
1546    }
1547
1548    let rid = jQuery(".io_product_container .item_rentalid").first().text();
1549    let regex = new RegExp("^io_product_price_.*_" + rid + "$");
1550    for (const price_index in io_prices){
1551      if(regex.test(io_prices[price_index])){
1552        use_weekday_weekend = false;
1553      }
1554    }
1555
1556    /* hide end date input. */
1557    if(!multi_day){
1558      /* TODO: Need to wait and see if this is necessary. If so needs to be more involved than this. */
1559      /* jQuery("input[name=dateEnd]").style("visibility", "hidden"); */
1560    }
1561    /* Call page avail now so we can display live price if its enabled */
1562    setTimeout(function(){
1563      if(jQuery(".io_acc_accessorydd").text()==1 && jQuery(".io_acc_ispackage").text()!=1){
1564        jQuery("#bookNowBtn").removeClass("item_add").addClass("item_add_off").trigger("classChange");
1565        checkAvailPageOnly();
1566      }else{
1567        checkAvailPageOnly();
1568      }
1569    },50);
1570
1571    /* Adjust picbox for header heights */
1572    setTimeout(adjustPicBoxForHeader,500);
1573
1574    /* Show buttons for distance charge check if the setting is on. Hide or show map button if applicable*/
1575    if(io_distance_charge){
1576      jQuery(".delivery_charge_check_container").show();
1577      jQuery(".calc_price_with_map_container").hide();
1578      jQuery(".checkDeliveryCartContainer").show();
1579    } else {
1580      jQuery(".delivery_charge_check_container").hide();
1581      jQuery(".calc_price_with_map_container").hide();
1582      jQuery(".checkDeliveryCartContainer").hide();
1583    }
1584    if(io_brand=="EH"){
1585      jQuery(".delivery_charge_check_container").hide();
1586      jQuery(".eh_additional_description").show();
1587    }
1588    if(jQuery(".io_product_infobox .item_inputtype").text() === "Map"){
1589      jQuery(".delivery_charge_check_container").hide();
1590      jQuery(".checkDeliveryCartContainer").hide();
1591      jQuery(".calc_price_with_map_container").show();
1592    }
1593
1594    /* If we have delivery set in cookie, be sure to show the charge in the cart. */
1595    if(getCookie("io_deliveryFee") && simpleCart.items().length > 0) {
1596      setDeliverySubtotal(getCookie("io_deliveryFee"));
1597      jQuery("#deliverSubtotalContainer").show();
1598      jQuery("#checkDeliveryMessage").hide();
1599    } else{
1600      jQuery("#deliverSubtotalContainer").hide();
1601    }
1602
1603    /* moved back here for IO-22561 */
1604    if(simpleCart.items().length > 0){
1605      let headerBookButton = jQuery("a[href$='io_quoteform/']");
1606      headerBookButton.addClass("ioCart_link");
1607      headerBookButton.attr("href", "javascript:;");
1608    }
1609    jQuery(".cartInfo").unbind("click").one("click", function(event){
1610      event.stopPropagation();
1611      event.stopImmediatePropagation();
1612      cartShow();
1613    });
1614    jQuery(".ioCart,.ioCart_link").unbind("click").one("click", function(event){
1615      event.stopPropagation();
1616      event.stopImmediatePropagation();
1617      cartShow();
1618    });
1619
1620    /* hide if click outside cart */
1621    jQuery(document).mouseup(function(e){
1622      var container = jQuery("#cartPopover");
1623      var cartButton = jQuery(".cartInfo, .ioCart, .ioCart_link");
1624      var addButton = jQuery(".item_add");
1625      var timePicker = jQuery(".ui-timepicker-wrapper");
1626
1627      if(jQuery(".cartInfo, .ioCart, .ioCart_link").hasClass("open")){
1628        if(!container.is(e.target) && container.has(e.target).length === 0 && !cartButton.is(e.target) && cartButton.has(e.target).length === 0 && !addButton.is(e.target) &&  addButton.has(e.target).length === 0 && !timePicker.is(e.target) &&  timePicker.has(e.target).length === 0 && !jQuery(".address_entry").is(e.target) &&  jQuery(".address_entry").has(e.target).length === 0){
1629          cartHide();
1630        }
1631      }
1632    });
1633
1634    if(!getCookie("io_state") && io_default_state){
1635      setCookie("io_state", io_default_state, 14);
1636    }
1637    if(country != "US") {
1638      jQuery("#io_cd_state").replaceWith('<input id="io_cd_state" style="display: table-cell" name="state" type="text"></input>');
1639      jQuery("#io_cdl_zip_label").text("Postal code");
1640      if(country == "CA"){
1641        jQuery("#io_cdl_state_label").text("Province");
1642      } else if(country == "AU"){
1643        jQuery("#io_cdl_city_label").text("Suburb");
1644      }
1645    } else{
1646      jQuery("#io_cd_zip").attr("type", "number");
1647    }
1648    /* Set up on change events to stop end timepickers from allowing users to pick times before start time */
1649    setTimeout(restrictEndTimepickers, 500);
1650    if(io_hide_end_time == "on" && io_default_duration > 0){
1651      jQuery('[name="timeEnd"]').parent().hide();
1652      // Hide end time stuff on checkout page and in the text.
1653      jQuery(".io_event_body_time .control-group:nth-child(2)").hide();
1654      jQuery(".io_event_body_time_display_text").text(jQuery(".io_event_body_time_display_text").text().replace(/\s*→.*/, ""))
1655      jQuery('[name="timeStart"]').change(function(){
1656        const regex = /^(\d{1,2}):(\d{2})(?:\s*([AP]M))?$/i;
1657        const match = this.value.match(regex);
1658
1659        let hours = parseInt(match[1], 10);
1660        const minutes = parseInt(match[2], 10);
1661        const period = match[3] ? match[3].toUpperCase() : null;
1662
1663        if (period) {
1664          if (period === "PM" && hours !== 12) hours += 12;
1665          if (period === "AM" && hours === 12) hours = 0;
1666        }
1667
1668        const baseDate = new Date(1970, 0, 1, hours, minutes);
1669        const newTime = new Date(baseDate.getTime() + io_default_duration * 3600000);
1670
1671        if (period) {
1672          // 12-hour
1673          let newHours = newTime.getHours();
1674          const newMinutes = newTime.getMinutes();
1675          const newPeriod = newHours >= 12 ? "PM" : "AM";
1676          newHours = newHours % 12;
1677          if (newHours === 0) newHours = 12;
1678          let end_time = `${newHours}:${newMinutes.toString().padStart(2, "0")} ${newPeriod}`;
1679          jQuery('[name="timeEnd"]').val(end_time);
1680        } else {
1681          // 24 hour
1682          let end_time = `${newTime.getHours().toString().padStart(2, "0")}:${newTime.getMinutes().toString().padStart(2, "0")}`;
1683          jQuery('[name="timeEnd"]').val(end_time);
1684        }
1685      });
1686    }
1687
1688    /* If we have a custom message in cart, display it. */
1689    if(io_cart_message){
1690      show_cart_message();
1691    }
1692
1693    /* code for day select in cart */
1694    if(io_cartdayselect == "dropdown_options" && io_multidayquote === "on"){
1695      saved_whatday = getCookie("io_whatday");
1696      if(saved_whatday) jQuery("#whatday").val(saved_whatday);
1697      endDisplay();
1698      setCalBackground();
1699    } else{
1700      jQuery("#div-overnight").hide();
1701      jQuery("#whatday").val("");
1702    }
1703
1704    checkRestrictedDeliveries()
1705    /* If we are using the information gathering tool, we do not want to show this message. */
1706    if( live_pricing_is_on() && io_info_required == "off" ){
1707      if(!event_time_set() && io_always_display_live_price != "on"){
1708        jQuery("#item_live_price_time_set_message").show();
1709      }else{
1710        jQuery("#item_live_price_time_set_message").hide();
1711      }
1712    }
1713
1714
1715    /* Check if information gathering header exists. If it does, Remove set even button and add some classes on onclicks */
1716    if(jQuery("#ioInfoHeader").length){
1717      remove_set_event_buttton();
1718      add_classes_and_onClicks();
1719      header_increment_step();
1720    }
1721
1722    jQuery(".io_acc_li").each(function() {
1723      if(jQuery(this).find(".item_required").first().text() > 0 && jQuery(this).find(".item_accessorydd").first().text() == 1){
1724        jQuery(jQuery(jQuery(this).parent()).prev()).appendTo(".io_product_requiredDD_accessories");
1725        jQuery(jQuery(this).parent()).appendTo(".io_product_requiredDD_accessories");
1726        jQuery(".io_product_requiredDD_accessories").show();
1727      }
1728    });
1729
1730    if(jQuery(".io_product_accessories .io_acc_li").length == 0) jQuery(".io_product_accessories").hide();
1731
1732    /* Hide the cart add button for items with required accessories on category page */
1733    jQuery(".item_hasRequiredAcc").each(function() {
1734      if (this.innerText == '1') {
1735        let rental_id_element = jQuery(this).parent().find(".item_rentalid")[0];
1736        let addCartButton = jQuery(".io_item2_list_inner .add_cart_" + rental_id_element.innerText).find('.io_button');
1737        addCartButton.removeClass("item_add");
1738        addCartButton.html('<i class="fas fa-arrow-right"></i>');
1739
1740        let itemHref = jQuery(this).parent().find(".item_href").text();
1741        addCartButton.attr('href', itemHref);
1742      }
1743    });
1744
1745
1746    /* If they have same day selection allowed, need to update checkout page datepicker on delay to make sure it works */
1747    if(io_cartAllowSameDay == "on"){
1748      setTimeout(allow_same_day_select_on_checkout, 500);
1749    }
1750
1751    if(io_info_required_data && io_info_required == "on"){
1752      let io_required_data = io_info_required_data;
1753      jQuery("#ioAdditonalInformationContainer").show();
1754      for (const [data, value] of Object.entries(io_required_data)) {
1755        if(value == 1){
1756          jQuery("#io_info_modal_"+data).css("display", "inline-flex")
1757          jQuery("#io_im_"+data).val(getCookie(data));
1758        }
1759      }
1760      show_or_hide_required_info_message()
1761    }
1762    if(jQuery(".bootstrap-timepicker").length == 0) {
1763      if (!/Mobi|Android/i.test(navigator.userAgent)) {
1764        jQuery("#cartPopover").scroll(function () {
1765          jQuery("[name=timeStart]").timepicker("hide");
1766          jQuery("[name=timeEnd]").timepicker("hide");
1767        });
1768        jQuery(window).scroll(function () {
1769          jQuery("#cartPopover [name=timeStart]").timepicker("hide");
1770          jQuery("#cartPopover [name=timeEnd]").timepicker("hide");
1771        });
1772      }
1773    }
1774
1775    if(jQuery(".io_product_infobox .item_inputtype").text() == "Map"){
1776      simpleCart.items().forEach(function (item, index){
1777        if(item.get("rentalid") === jQuery(".io_product_infobox .item_rentalid").text()){
1778          if(item.get("quantity") > 1){
1779            let units;
1780            if(jQuery(".io_product_infobox .item_qtytype").text() == "Area"){
1781              units = "sq meters"
1782              if(country === "US") units = "sq feet"
1783            }else if(jQuery(".io_product_infobox .item_qtytype").text() == "Perimeter"){
1784              units = "meters"
1785              if(country === "US") units = "feet"
1786            }
1787            set_price_on_item_page(units, item.get("quantity"));
1788          }
1789        }
1790      });
1791    }
1792    /* IO-21808 */
1793    jQuery(".io_product_price_box").each(function() {
1794      let classes = jQuery(this).attr("class");
1795      jQuery(this).attr("class", classes.replace(":", "_"));
1796    });
1797
1798    /* Set time instructions (IO-21496) */
1799    set_cart_time_instructions();
1800
1801    if(io_accessory_select === "on"){
1802      if(jQuery(".io_product_acc_pkg").children().length > 0){
1803        let main_rental_id = jQuery(".item_rentalid").text();
1804        let sel_div = jQuery("<div class=\"io_product_acc_pkg\" style=\"display:flex; margin-top:10px;\"></div>");
1805        let sel = jQuery("<select class=\"io_product_acc_pkg\" onchange=\"accOnClick(this)\" />");
1806        sel.append("<option value=\"\" selected=\"selected\" style=\"display:none\" disabled>Select one..</option>")
1807        jQuery("[id^=io_acc_shortname_"+main_rental_id+"]").each(function(){
1808          sel.append("<option value="+this.id+">"+this.innerHTML+"</option>")
1809          if(this.id.split("_").length > 4){
1810            let split_id = this.id.split("_");
1811            let option_rental_id = split_id[split_id.length - 1];
1812            let sel2 = jQuery("<select id=\"io_product_acc_pkg_sel_"+option_rental_id+"\" style=\"display:none; margin-left:5px;\" onchange=\"accOnClick(this)\" />");
1813            sel2.append("<option value=\"\" selected=\"selected\" style=\"display:none\" disabled>Select one..</option>")
1814            jQuery("[id^=io_acc_shortname_"+option_rental_id+"_]").each(function(){
1815              sel2.append("<option value="+this.id+">"+this.innerHTML+"</option>")
1816            });
1817            sel_div.append(sel2);
1818          }
1819        });
1820        sel_div.prepend(sel);
1821        jQuery(".io_product_acc_pkg").replaceWith(sel_div);
1822      }
1823    }
1824    if(io_cart_party_planner_email === "on" && io_cart_party_planner_destination){
1825      jQuery("#cartPartyBuilderEmailContainer").show()
1826      if(getCookie("io_email")){
1827        jQuery("#cartPartyBuilderEmailInput").val(getCookie("io_email"));
1828      }
1829    }
1830
1831    if(io_brand == "PW"){
1832      jQuery(".io_product_price_box").attr("style", "display: none !important;");
1833      jQuery(".io_product_price_sqfoot").attr("style", "display: grid !important;");
1834    }
1835
1836    setTimeout(simpleCart.init, 100);
1837    if(io_hide_zero == 1){
1838      jQuery(".io_product_price_top_left").each(function (){
1839        if(Number(this.innerText.replace(/[^0-9.-]+/g,"")) == 0){
1840          jQuery(this).parent().attr('style','display:none !important');
1841        }
1842      });
1843      jQuery(".io_product_price_left").each(function (){
1844        if(Number(this.innerText.replace(/[^0-9.-]+/g,"")) == 0){
1845          jQuery(this).parent().attr('style','display:none !important');
1846        }
1847      });
1848    }
1849      if (io_categoryVariantImages == 'on'){
1850          jQuery(".io_category_thumbox").show();
1851          jQuery('.view-product-button').addClass('view-product-button2')
1852      }
1853    let giftcard_value = jQuery(".item_giftcardvalue");
1854    if(giftcard_value && giftcard_value.text()){
1855      jQuery(".delivery_charge_check_container").hide();
1856    }
1857
1858    if (io_customer_geolocation == 'on') initializeGeolocation();
1859  }); /*end of on-ready*/
1860  /*</editor-fold>*/
1861
1862  /*<editor-fold defaultstate="collapsed" desc="Helper Functions">*/
1863  function phraseUpdateCount(inputElement)
1864  {
1865  //read the text and strip out spaces
1866    const fullText = inputElement.value;
1867    const lettersOnly  = fullText.replace(/\s+/g, "");
1868    const count = lettersOnly.length;
1869
1870    const cookieKey = inputElement.classList[0];
1871
1872    document.querySelector(".item_quantity").textContent = count;
1873
1874    setCookie(cookieKey, fullText, 45);
1875  }
1876  function io_party_planner_email_submit(){
1877    let valid_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,}))$/;
1878    let email = jQuery("#cartPartyBuilderEmailInput").val();
1879    if(email){
1880      if(email.match(valid_regex)){
1881        setCookie("io_email", email, 14);
1882        window.open(io_cart_party_planner_destination, '_blank').focus();
1883      }else{
1884        jQuery("#cartPartyBuilderEmailWarning").show();
1885      }
1886    }else{
1887      jQuery("#cartPartyBuilderEmailWarning").show();
1888    }
1889  }
1890
1891  function rid_in_batch(rid, batch_ids){
1892    let result = batch_ids.filter(function(batch){
1893      if(batch.includes(this)) return true;
1894    }, rid);
1895    return result
1896  }
1897
1898  function set_cart_time_instructions(){
1899    /* Making it clearer that customers need to set the time in order to see pricing and availability. */
1900    let instructions_container = jQuery("<p id=\"ioCartTimeInstructions\"></p>");
1901    let instructions = "";
1902
1903    if(multi_day){
1904      instructions += "Select the event date or date range using the calendar";
1905    }else{
1906      instructions += "Select the event date using the calendar";
1907    }
1908    instructions += ".";
1909    instructions_container.text(instructions);
1910    jQuery("#cartCalendar").append(instructions_container);
1911  }
1912
1913  function live_pricing_is_on(){
1914    /*
1915    Checks to see if live pricing is on. Assumes it is on unless one of the following conditions:
1916       The setting Hide Live Price is off.
1917       The setting Show Weekend/Weekday Pricing is off.
1918       Delivery method pricing is enabled by default.
1919       We are on an item page that uses delivery method pricing.
1920    */
1921    if(io_hide_live_prices != 1 || io_weekEndPrice != "on" ||
1922            io_delivery_prices["default"].length != 0 || jQuery(".io_product_infobox .item_rentalid").innerText in io_delivery_prices["override"] ||
1923            io_custom_prices["default"].length != 0 || jQuery(".io_product_infobox .item_rentalid").innerText in io_delivery_prices["override"]){
1924      return false;
1925    }
1926    return true;
1927  }
1928
1929  function allow_same_day_select_on_checkout(){
1930    jQuery(".jquery-datepicker").datepicker("option", "minDate", 0);
1931  }
1932
1933  function show_or_hide_required_info_message(){
1934    if(io_info_required == "on"){
1935      if(!all_info_provided()){
1936        jQuery("#io_all_prices").hide();
1937        jQuery("#item_additonal_info_open_message").show();
1938      }else{
1939        jQuery("#io_all_prices").show();
1940        jQuery("#item_additonal_info_open_message").hide();
1941      }
1942    }
1943  }
1944
1945  function all_info_provided(){
1946    /* This is used for when the "Hide all pricing on page until information is provided" setting is on price settings. */
1947    let all_data_provided = true;
1948    let io_required_data = io_info_required_data;
1949    for (const [data, value] of Object.entries(io_required_data)) {
1950      if(value == 1){
1951        if(!getCookie(data)){
1952          all_data_provided = false
1953        }
1954      }
1955    }
1956
1957    if(live_pricing_is_on() && !event_time_set()) {
1958      all_data_provided = false;
1959    }
1960
1961    return all_data_provided;
1962  }
1963
1964  function event_time_set(){
1965    if(getCookie("io_timeStart") &&
1966            getCookie("io_timeEnd") &&
1967            getCookie("io_dateStart") &&
1968            getCookie("io_dateEnd")){
1969      return true;
1970    } else{
1971      return false
1972    }
1973  }
1974
1975  function show_cart_message(){
1976    message_container = jQuery("#cartCustomMessage");
1977    message_container.html(io_cart_message);
1978    message_container.show();
1979  }
1980
1981  function deliveryMethodSelected(){
1982    setCookie("io_delivery_method", jQuery(".ioDeliveryMethods option:selected").text(), 14);
1983    checkRestrictedDeliveries();
1984  }
1985
1986  function adjustPicBoxForHeader(){
1987    /* For some reason its hard to get css with querySelector so we use jQuery to get the picbox. */
1988    pic_box = jQuery(".io_product_picbox");
1989    io_header = document.querySelector(".io_header");
1990    if(pic_box != null && pic_box.css("position") == "sticky"){
1991      if(io_header != null){
1992        header_height = io_header.offsetHeight;
1993        pic_box.css("top", (10+header_height).toString()+"px");
1994      }
1995      else{
1996        possible_headers = document.querySelectorAll("header,section")
1997        possible_headers.forEach((ele) =>{
1998          if(ele.style.top == "0px" && (ele.style.position == "fixed" || ele.style.position == "sticky")){
1999            header = ele;
2000            header_height = header.offsetHeight;
2001            pic_box.css("top", (10+header_height).toString()+"px");
2002
2003          }
2004        });
2005      }
2006    }
2007  }
2008  function cart_times_all_set(){
2009    if(jQuery("#ioCartTimeSelectContainer [name=dateStart]").val() == ""){
2010      return false;
2011    }
2012    if(io_hidetimes === "off" || io_hidetimes === ""){
2013      if(jQuery("#ioCartTimeSelectContainer [name=timeStart]").val() == ""){
2014        return false;
2015      }
2016      if(jQuery("#ioCartTimeSelectContainer [name=timeEnd]").val() == ""){
2017        return false;
2018      }
2019    }
2020
2021    return true;
2022  }
2023  function checkRestrictedDeliveries(){
2024    let items = simpleCart.items()
2025    let restrictions_found = false;
2026    for(i in items){
2027      let rid = items[i].get("rentalid");
2028      if(typeof jQuery(".ioDeliveryMethods").val() != "undefined"){
2029        if(io_delivery_methods[jQuery(".ioDeliveryMethods").val()]["restricted"].includes(rid)){
2030          jQuery("#deliveryMethodWarning").show();
2031          restrictions_found = true;
2032        }
2033      }
2034    }
2035    if(!restrictions_found){
2036      jQuery("#deliveryMethodWarning").hide();
2037    }
2038  }
2039
2040  function display_cart_warning(item){
2041    let cart_warning_container = jQuery("#cartWarning");
2042
2043    // Check if an event date if not we should tell them to set it.
2044    event_times = getAvailTimes();
2045    if(!event_times[0] || !event_times[1]){
2046      cart_warning_container.text("Please set the date and time for your event above.");
2047      cart_warning_container.show();
2048      return false;
2049    }
2050
2051    let item_name = item.get("name");
2052    let item_timeslots = item.get("timeslots");
2053    let timeslot_name = getTimeslotName(item_timeslots);
2054
2055    let stop_loop = false;
2056    if(item_timeslots){
2057      if(jQuery(item_timeslots).nodeName == "SELECT"){
2058        /* NOTE: It should not be possible for timeslots to be empty.
2059                   But in the event they somehow are, we should have this here. */
2060        /* timeslots */
2061        var timeslot_sel_range = jQuery(".item-timeslots [name=\""+timeslot_name+"\"] option:selected").val();
2062        if(typeof timeslot_sel_range != "undefined"){
2063          var [start_time, end_time] = break_timeslot_sel_range(timeslot_sel_range);
2064        }
2065      }else{
2066        /*  timepickers */
2067        let [start_timepicker, end_timepicker] = get_cart_timepickers(timeslot_name);
2068        var start_time = start_timepicker.value;
2069        var end_time = end_timepicker.value;
2070      }
2071      if(!start_time || !end_time){
2072        cart_warning_container.text("Please select a time range for the following item: " + item_name);
2073        cart_warning_container.show()
2074        stop_loop = true;
2075      }
2076    } else{
2077      cart_warning_container.text("Some items are not available on this date.");
2078      cart_warning_container.show()
2079    }
2080    return stop_loop
2081  }
2082
2083  const io_personal_cookie_keys = ["io_email", "io_phone", "io_address", "io_city", "io_state", "io_zip"];
2084
2085  function ioHasMarketingConsent(){
2086    if(typeof cmplz_has_consent !== 'function'){
2087      return true;
2088    }
2089    return cmplz_has_consent('marketing');
2090  }
2091
2092  function ioUnwrapStoredValue(raw) {
2093      // Fully peel any {v,e} wrapper layers that may have accumulated when an
2094      // older plugin version re-saved an already-wrapped value (IO-36799). Cart
2095      // values (dates, times, addresses) are never JSON objects, so any layer
2096      // that parses to a {v,...} object is a wrapper to unwrap. Returns
2097      // { value, expired, malformed } describing the innermost stored string.
2098      var value = (raw == null) ? "" : String(raw);
2099      for (var depth = 0; depth < 25; depth++) {
2100        var trimmed = value.trim();
2101        if (trimmed.charAt(0) !== '{') break;          // plain value -> done
2102        var obj;
2103        try {
2104          obj = JSON.parse(trimmed);
2105        } catch (e) {
2106          break;                                       // not parseable -> stop, keep value
2107        }
2108        if (!obj || typeof obj !== 'object' || !('v' in obj)) break;  // not our wrapper
2109        if (obj.e && Date.now() > obj.e) {
2110          return { value: "", expired: true, malformed: false };
2111        }
2112        value = (obj.v != null) ? String(obj.v) : "";
2113      }
2114      // Only flag as malformed if what remains still looks like our own broken
2115      // {"v":...} wrapper (e.g. truncated) -- never an ordinary value that just
2116      // happens to start with "{", which must be preserved untouched.
2117      var malformed = /^\s*\{\s*"v"\s*:/.test(value);
2118      return { value: value, expired: false, malformed: malformed };
2119  }
2120
2121  function setCookie(cname, cvalue, exdays) {
2122      if(io_personal_cookie_keys.indexOf(cname) !== -1 && !ioHasMarketingConsent()){
2123        return;
2124      }
2125      // Store values in localStorage with an io_ prefix for uniqueness and emulate expiration
2126      try {
2127        // Unwrap first so an already-wrapped value can never be re-wrapped and
2128        // compound into nested {v,e} layers (IO-36799).
2129        var clean = ioUnwrapStoredValue(cvalue).value;
2130        var expiresAt = (typeof exdays === 'number' && exdays > 0)
2131          ? Date.now() + (exdays * 24 * 60 * 60 * 1000)
2132          : null;
2133        var payload = JSON.stringify({ v: clean, e: expiresAt });
2134        window.localStorage.setItem(cname, payload);
2135      } catch (e) {
2136        // Swallow errors to keep behavior similar to cookie writes silently failing
2137        console.log(e);
2138      }
2139  }
2140
2141  function getCookie(cname) {
2142    // Read values from localStorage honoring expiration; return empty string if missing/expired
2143    try {
2144      var raw = window.localStorage.getItem(cname);
2145      if (!raw) return "";
2146      var result = ioUnwrapStoredValue(raw);
2147      if (result.expired || result.malformed) {
2148        // Drop expired or corrupted entries so they self-heal instead of being
2149        // rendered as raw JSON in the date/time fields (IO-36799).
2150        try { window.localStorage.removeItem(cname); } catch (e) {}
2151        return "";
2152      }
2153      return result.value;
2154    } catch (e) {
2155      return "";
2156    }
2157  }
2158  async function fetchAndSetCookie(name) {
2159    var requestInit = { credentials: "include" };
2160    fetch("https://rental.software/include/get_cookie.php?name=" + name, requestInit).then(function (response) {
2161      return response.json();
2162    }).then(function (response) {
2163      return handleResponse(name, response);
2164    });
2165  }
2166
2167  function handleResponse(name, response) {
2168    var currentCookieValue = getCookie(name);
2169    if (!!response.value && currentCookieValue !== response.value) {
2170      setCookie(name, response.value, 14);
2171    }
2172    return response.value;
2173  }
2174
2175  function clearIoPersonalDataForNoConsent(){
2176    io_personal_cookie_keys.forEach(function(key){
2177      try {
2178        window.localStorage.removeItem(key);
2179      } catch (e) {
2180        console.log(e);
2181      }
2182    });
2183
2184    var trackingUrl = (window.location.href.indexOf("localhost") > -1)
2185      ? "http://localhost/io/bugs/include/iotracking.php"
2186      : "https://rental.software/include/iotracking.php";
2187    var clearImg = new Image();
2188    clearImg.src = trackingUrl + "?action=remove&nocache=" + Math.random();
2189  }
2190
2191  document.addEventListener("cmplz_status_change", function (e) {
2192    if (e.detail.category === 'marketing' && e.detail.value === 'deny') {
2193      clearIoPersonalDataForNoConsent();
2194    }
2195  });
2196
2197  function break_timeslot_sel_range(timeslot_sel_range){
2198    /* Takes a time range given by selected timeslot and gets the start and end time removing meridiem.*/
2199    timeslot_sel_arr = timeslot_sel_range.split(" - ");
2200    var start_time = timeslot_sel_arr[0].replace("am"," am").replace("pm"," pm").replace("  "," ");
2201    var end_time = timeslot_sel_arr[1].replace("am"," am").replace("pm"," pm").replace("  "," ");
2202
2203    return Array(start_time, end_time);
2204  }
2205  function getAvailTimes(){
2206    /*
2207    Commonly used helper function. Accomplishes two things:
2208      Returns an array containing start_date, start_time, and event duration.
2209      Sets cookies for start and end date, and start and end time.
2210
2211    Uses the inputs available in the cart if they are filled out, so dateStart, dateEnd, timeStart, and timeEnd.
2212    If timeslots are being used in cart it chooses the selected timeslot and breaks it on - and gets the start ane end time from that.
2213    */
2214    let start_date = jQuery("input[name=dateStart]").val();
2215    let end_date = jQuery("input[name=dateEnd]").val();
2216    if(io_company_timeslots.length != 0 && io_cartdayselect == "single_day"){
2217      let cart_company_timeslot_selected = jQuery(".ioCartCompanyTimeslots option:selected").first().val();
2218      if(cart_company_timeslot_selected){
2219        setCookie("io_company_timeslot_selected", cart_company_timeslot_selected, 14);
2220        cart_company_timeslot_selected = cart_company_timeslot_selected.split("-");
2221        var start_time = cart_company_timeslot_selected[0].trim();
2222        var end_time = cart_company_timeslot_selected[1].trim();
2223      }
2224    } else {
2225      var start_time = jQuery("input[name=timeStart]").val();
2226      var end_time = jQuery("input[name=timeEnd]").val();
2227    }
2228
2229    if (start_date.length == 0) {
2230      start_date = getCookie("io_dateStart");
2231      end_date = getCookie("io_dateEnd");
2232      start_time = getCookie("io_timeStart");
2233      end_time = getCookie("io_timeEnd");
2234    }
2235
2236    const has_selected_company_timeslot = io_company_timeslots.length != 0
2237      && io_cartdayselect == "single_day"
2238      && jQuery(".ioCartCompanyTimeslots option:selected").first().val();
2239
2240    if(io_hidetimes === "on"
2241      && io_force_blank_timepickers != "on"
2242      && !has_selected_company_timeslot) {
2243      start_time = start_default;
2244      end_time = end_default;
2245      jQuery("input[name=timeStart]").val(start_time);
2246      jQuery("input[name=timeEnd]").val(end_time);
2247    }
2248
2249    if(io_force_blank_timepickers != "on")
2250    {
2251      if(start_time.length == 0)
2252      {
2253        start_time = start_default;
2254      }
2255      if(end_time.length == 0)
2256      {
2257        end_time = end_default;
2258      }
2259    }
2260
2261
2262    /* no past dates */
2263    if(start_date.length != 0 && convertDateStringtoDateObject(start_date, start_time) < new Date()){
2264      start_date="";
2265      end_date="";
2266    }
2267    /* setCookie("checkDate", start_date, 14); */
2268    setCookie("io_dateStart", start_date, 14);
2269    setCookie("io_dateEnd", end_date, 14);
2270    setCookie("io_timeStart", start_time, 14);
2271    setCookie("io_timeEnd", end_time, 14);
2272    /* If we are using the information gathering tool, we do not want to show this message.*/
2273    if( live_pricing_is_on() && io_info_required == "off" ){
2274      if(!event_time_set() && io_always_display_live_price != "on"){
2275        jQuery("#item_live_price_time_set_message").show();
2276      }else{
2277        jQuery("#item_live_price_time_set_message").hide();
2278      }
2279    }
2280
2281    var newDate1 = convertDateStringtoDateObject(start_date, start_time);
2282    var newDate2 = convertDateStringtoDateObject(end_date, end_time);
2283    let time_duration = ((newDate2 - newDate1) / 3600) / 1000;
2284    return [start_date,start_time,time_duration];
2285  }
2286
2287  function  getAllRentalIDsFromCart(){
2288    let rental_ids = "";
2289    jQuery("[id^='cartItem_']").each(function(){
2290      children = this.children
2291      for(let i = 0; i < children.length; ++i){
2292        if(children[i].className == "item-rentalid") {
2293          rental_ids += children[i].innerText + "|";
2294          break;
2295        }
2296      }
2297    });
2298    return rental_ids
2299  }
2300  /*</editor-fold>*/
2301
2302  /*<editor-fold defaultstate="collapsed" desc="Info Header Functions">*/
2303  function init_date_timepicker_for_info_header(){
2304    jQuery(".ioInfoDatepicker").datepicker({
2305      changeMonth: true,
2306      changeYear: true,
2307      dateFormat: dateFormat,
2308      rangeSelect: true,
2309      numberOfMonths: 1,
2310      stepMonths: 1,
2311      speed: "fast",
2312      showOn: "both",
2313      onChangeMonthYear: cal_onChangeMonthYear,
2314      buttonText: "Calendar",
2315      minDate: 1,
2316      firstDay: 0
2317    });
2318    jQuery("#ioHeaderDateStart").datepicker("option", { onSelect: function() {
2319        set_info_header_end_date();
2320        saveInfoHeader();
2321        // Add more functions if needed
2322      }
2323    });
2324
2325    if(restrictTimes){
2326      jQuery(".ioInfoTimepicker").timepicker({
2327        startTime: new Date(0, 0, 10, 0, 0, 0),
2328        endTime: new Date(0, 0, 0, 20, 0, 0, 0),
2329        minTime:restrictTimeStart,
2330        maxTime:restrictTimeEnd,
2331        /*show24Hours: $show24Hours,*/
2332        timeFormat: timeFormat,
2333        separator: ":",
2334        className: "elementor-widget-text-editor",
2335        step: 15,
2336        disableTouchKeyboard: true
2337      });
2338    } else{
2339      jQuery(".ioInfoTimepicker").timepicker({
2340        startTime: new Date(0, 0, 10, 0, 0, 0),
2341        endTime: new Date(0, 0, 0, 20, 0, 0, 0),
2342        /*show24Hours: $show24Hours,*/
2343        timeFormat: timeFormat,
2344        separator: ":",
2345        className: "elementor-widget-text-editor",
2346        step: 15,
2347        disableTouchKeyboard: true
2348      });
2349    }
2350    setTimeout(setUpTimeRestrictions_infoHeaderTimepickers, 500);
2351  }
2352
2353  function saveInfoHeader(){
2354    let info_header_start_date = jQuery("[id$=ioHeaderDateStart]");
2355    let info_header_end_date = jQuery("[id$=ioHeaderDateEnd]");
2356    let info_header_start_time = jQuery("[id$=ioHeaderTimeStart]");
2357    let info_header_end_time = jQuery("[id$=ioHeaderTimeEnd]");
2358    let info_header_address = jQuery("[id$=ioHeaderAddress]");
2359    let info_header_city = jQuery("[id$=ioHeaderCity]");
2360    let info_header_state = jQuery("[id$=ioHeaderState]");
2361    let info_header_zip = jQuery("[id$=ioHeaderZipCode]");
2362    let info_header_phone = jQuery("[id$=ioHeaderPhone]");
2363    let info_header_email = jQuery("[id$=ioHeaderEmail]");
2364
2365    if(info_header_start_time.val()) setCookie("io_timeStart", info_header_start_time.val(), 14);
2366    if(info_header_end_time.val()) setCookie("io_timeEnd", info_header_end_time.val(), 14);
2367    if(info_header_start_date.val()) setCookie("io_dateStart", info_header_start_date.val(), 14);
2368    if(info_header_end_date.val()) setCookie("io_dateEnd", info_header_end_date.val(), 14);
2369    if(info_header_address.val()) setCookie("io_address", info_header_address.val(), 14);
2370    if(info_header_city.val()) setCookie("io_city", info_header_city.val(), 14);
2371    if(info_header_state.val()) setCookie("io_state", info_header_state.val(), 14);
2372    if(info_header_zip.val()) setCookie("io_zip", info_header_zip.val(), 14);
2373    if(info_header_phone.val()) setCookie("io_phone", info_header_phone.val(), 14);
2374    if(info_header_email.val()) setCookie("io_email", info_header_email.val(), 14);
2375
2376    /* Set information in the cart. */
2377    calCancel();
2378
2379    header_increment_step();
2380
2381    /* Stop form from doing anything else for elementor */
2382    // jpa - still allow, turn off actions in form if wanted. to turn off io lead submission use the plugin settings
2383    //event.preventDefault();
2384    //event.stopPropagation();
2385    return true;
2386  }
2387
2388  function set_info_header_values(){
2389    let info_header_start_date = jQuery("[id$=ioHeaderDateStart]");
2390    let info_header_end_date = jQuery("[id$=ioHeaderDateEnd]");
2391    let info_header_start_time = jQuery("[id$=ioHeaderTimeStart]");
2392    let info_header_end_time = jQuery("[id$=ioHeaderTimeEnd]");
2393    let info_header_street = jQuery("[id$=ioHeaderAddress]");
2394    let info_header_city = jQuery("[id$=ioHeaderCity]");
2395    let info_header_state = jQuery("[id$=ioHeaderState]");
2396    let info_header_zip = jQuery("[id$=ioHeaderZipCode]");
2397    let info_header_phone = jQuery("[id$=ioHeaderPhone]");
2398    let info_header_email = jQuery("[id$=ioHeaderEmail]");
2399
2400    if(getCookie("io_timeStart")) info_header_start_time.val(getCookie("io_timeStart"));
2401    if(getCookie("io_timeEnd")) info_header_end_time.val(getCookie("io_timeEnd"));
2402    if(getCookie("io_dateStart")) info_header_start_date.val(getCookie("io_dateStart"));
2403    if(getCookie("io_dateEnd")) info_header_end_date.val(getCookie("io_dateEnd"));
2404    if(getCookie("io_address")) info_header_street.val(getCookie("io_address"));
2405    if(getCookie("io_city")) info_header_city.val(getCookie("io_city"));
2406    if(getCookie("io_state")) info_header_state.val(getCookie("io_state"));
2407    if(getCookie("io_zip")) info_header_zip.val(getCookie("io_zip"));
2408    if(getCookie("io_phone")) info_header_phone.val(getCookie("io_phone"));
2409    if(getCookie("io_email")) info_header_email.val(getCookie("io_email"));
2410  }
2411
2412  function add_classes_and_onClicks(){
2413
2414    /* First set up for dates */
2415    let info_header_start_date = jQuery("#ioHeaderDateStart");
2416    let info_header_end_date = jQuery("#ioHeaderDateEnd");
2417    info_header_start_date.addClass("ioInfoDatepicker");
2418    info_header_end_date.addClass("ioInfoDatepicker");
2419
2420    /* Now Timepickers */
2421    let info_header_start_time = jQuery("#ioHeaderTimeStart");
2422    let info_header_end_time = jQuery("#ioHeaderTimeEnd");
2423    info_header_start_time.addClass("ioInfoTimepicker");
2424    info_header_end_time.addClass("ioInfoTimepicker");
2425
2426    /* Add the onClick to the button */
2427    let button = jQuery("#ioInfoHeaderSubmit");
2428    button.click(saveInfoHeader);
2429    button.css("cursor", "pointer");
2430
2431    /* Init datepicker and timepickers */
2432    init_date_timepicker_for_info_header();
2433
2434    /* Lastly set the values if they are set already */
2435    set_info_header_values();
2436  }
2437
2438  function remove_set_event_buttton(){
2439    let set_event_button = jQuery(".pageDateRangeWrapper");
2440    if(set_event_button.length > 0) set_event_button.hide();
2441  }
2442
2443  function set_info_header_end_date(){
2444    if(!jQuery("#ioHeaderDateEnd").val()){
2445      jQuery("#ioHeaderDateEnd").val(jQuery("#ioHeaderDateStart").val())
2446    }
2447    jQuery("#ioHeaderDateEnd").datepicker("option", { minDate: new Date(jQuery("#ioHeaderDateStart").val()) });
2448  }
2449
2450  function header_increment_step(){
2451    let active = jQuery(".io-step-active");
2452
2453    switch(active.attr("id")){
2454      case "io-step-1":
2455        if (/Mobi|Android/i.test(navigator.userAgent)) {
2456          jQuery("#io-step-2,#io-step-3,#io-step-4").hide();
2457        }
2458        if(check_header_step_one(active)){
2459          active.removeClass("io-step-active");
2460          active.addClass("io-step-done")
2461          jQuery("#io-step-2").addClass("io-step-active")
2462          header_increment_step();
2463        }
2464        break;
2465      case "io-step-2":
2466        if (/Mobi|Android/i.test(navigator.userAgent)) {
2467          jQuery("#io-step-2,#io-step-3,#io-step-4").show();
2468        }
2469        if(simpleCart.items().length > 0){
2470          active.removeClass("io-step-active");
2471          active.addClass("io-step-done")
2472          jQuery("#io-step-3").addClass("io-step-active")
2473          header_increment_step();
2474        }
2475        break;
2476      case "io-step-3":
2477        if (/Mobi|Android/i.test(navigator.userAgent)) {
2478          jQuery("#io-step-2,#io-step-3,#io-step-4").show();
2479        }
2480        if(document.location.href.indexOf("io_quoteconfirm") >= 0){
2481          active.removeClass("io-step-active");
2482          active.addClass("io-step-done")
2483          jQuery("#io-step-4").addClass("io-step-active")
2484          header_increment_step();
2485        }
2486        break;
2487      case "io-step-4":
2488        if (/Mobi|Android/i.test(navigator.userAgent)) {
2489          jQuery("#io-step-2,#io-step-3,#io-step-4").show();
2490        }
2491        break;
2492    }
2493  }
2494
2495  function check_header_step_one(active) {
2496    var allInputs = active.find('input');
2497
2498    for (var i = 0; i < allInputs.length; i++) {
2499      if (jQuery(allInputs[i]).val() === "") {
2500        return false; // Return false if any input is empty
2501      }
2502    }
2503    return true; // Return true if all inputs have a value
2504  }
2505
2506  /*</editor-fold>*/
2507
2508  /*<editor-fold defaultstate="collapsed" desc="Accessory Click Functions">*/
2509  function accDDClicked(event){
2510    this_element = jQuery(this)
2511    if(!this_element.prop("selected")){
2512      pid = event.data.pid
2513      accLmt = event.data.accLmt
2514      all_elements = jQuery("[id^=io_acc_"+pid+"_]")
2515      let count = 0;
2516      /* Tried using .filter and .length to get the count of selected items but could not make it work. */
2517      for(i = 0; i < all_elements.length; ++i){
2518        if(all_elements[i].selected){
2519          ++count;
2520        }
2521      }
2522      if(accLmt == 0){
2523        this_element.css("border", "5px solid #bbb");
2524        this_element.prop("selected", true);
2525      } else if(count >= accLmt){
2526        let selected_value = jQuery("[id^=io_acc_"+pid+"_]").filter(function() {
2527          return this["selected"];
2528        });
2529        /* be sure to unselect other slected values if our acc limit has been reached. */
2530        selected_value.prop("selected", false);
2531        selected_value.css("border", "1px solid #bbb");
2532      }
2533      this_element.css("border", "5px solid #bbb");
2534      this_element.prop("selected", true);
2535    } else{
2536      this_element.prop("selected", false);
2537      this_element.css("border", "1px solid #bbb");
2538    }
2539  }
2540
2541  /* when accessory choice is clicked */
2542  function accOnClick(acc_select=null){
2543    /* set name/img back to original main in case they are just clicking on a 1st level size option */
2544    jQuery("#bookNowBtn").removeClass("item_add").addClass("item_add_off").trigger("classChange");
2545    jQuery(".io_product_title.item_name").html(main_name_orig);
2546    jQuery(".io_product_container .item_image").first().attr("src",main_img_src);
2547    jQuery(".io_product_container .item_image").first().attr("data-src",main_img_src);
2548    jQuery(".io_product_container .item_encoded").first().html(main_encoded);
2549    jQuery(".io_product_container .io_image_big").first().attr("src",main_img_src);
2550    jQuery(".io_product_container .io_image_big").first().attr("data-src",main_img_src);
2551    let main_id = jQuery(".io_product_container .item_rentalid").first().text();
2552    let main_id_arr = main_id.split(":")
2553    jQuery(".io_product_container .item_rentalid").html(main_id_arr[0]);
2554    let clk_id;
2555    if(jQuery(acc_select).find(":selected").val()){
2556      clk_id = jQuery(acc_select).find(":selected").val().replace("io_acc_shortname_","");
2557    }else{
2558      clk_id = this.id.replace("io_acc_shortname_","");
2559    }
2560    clk_id = clk_id.replace("iothumb_","");
2561    let click_id_arr = clk_id.split("_");
2562    /* let pid = main_id; */
2563    /* if(main_id.split("_").length>1) pid = parseInt(click_id_arr[0]); */
2564    let acc_obj_relate_is_map = acc_obj_relate instanceof Map;
2565    let acc_obj_relate_entries = acc_obj_relate_is_map ? acc_obj_relate.entries() : Object.entries(acc_obj_relate);
2566    for (let [key, value] of acc_obj_relate_entries) {
2567      let id = key;
2568      let children = acc_obj_relate_is_map ? acc_obj_relate.get(key) : value;
2569      if(Object.keys(children).length>0){
2570        for (key2 in children) {
2571          if(Object.keys(children[key2]).length > 0){
2572            /* 3rd level */
2573            for (key3 in children[key2]) {
2574              displayPackageChoices(clk_id,key2,key3,children[key2]);
2575            }
2576          }else{
2577            displayPackageChoices(clk_id,key,key2,children);
2578          }
2579        }
2580      }else{
2581        displayPackageChoices(clk_id,0,id,acc_obj_relate);
2582      }
2583    }
2584  }
2585
2586  /* show/hide accessory levels as needed */
2587  /* clk_id: one they clicked on, pid: parentid, id: iterator, arr: relationship array */
2588  function displayPackageChoices(clk_id,pid,id,arr){
2589    let main_id = jQuery(".io_product_container .item_rentalid").first().text();
2590    let main_arr = main_id.split("_");
2591    if(main_arr.length>1) main_id = parseInt(main_arr[0]);
2592    let click_id_arr = clk_id.split("_");
2593    elem = getAccElem(id,pid);
2594    if(click_id_arr[0]==pid || click_id_arr[1]==pid || pid==0){
2595      elem.style.display="inline-block";
2596    }else{
2597      elem.style.display="none";
2598    }
2599    if(click_id_arr[1]==id && (click_id_arr[0]==pid || (pid==0 && click_id_arr[0]==main_id) ) || (click_id_arr.length==1 && click_id_arr[0]==id)){
2600      jQuery("#bookNowBtn").removeClass("item_add_off").addClass("item_add").trigger("classChange");
2601      updateMainItem(id,pid);
2602    }
2603  }
2604
2605  /* update it with accessory data for choices */
2606  var main_img_src = jQuery("#single_image").first().attr("href");
2607  var main_name_orig = jQuery(".io_product_title.item_name").html();
2608  var main_encoded = jQuery(".io_product_container .item_encoded").html();
2609  var main_desc = jQuery(".io_product_detailbox .io_product_desc").html();
2610  function updateMainItem(id,pid){
2611    /* update add to cart btn, name, img, desc */
2612    let name = "";
2613    let name_enc = "";
2614    let main_id = jQuery(".io_product_container .item_rentalid").first().text();
2615    let main_arr = main_id.split(":");
2616    if(main_arr.length>1) main_id = main_arr[0];
2617    if(pid!=0){
2618      name += jQuery("#io_acc_itemname_"+pid).html()+":";
2619      name_enc += jQuery("#io_acc_itemname_"+pid).html()+":";
2620      name += jQuery("#io_acc_shortname_"+id).html();
2621      name_enc += jQuery("#io_acc_itemname_"+id).html();
2622    }else{
2623      pid = main_id;
2624      name += jQuery("#io_acc_itemname_"+id).html();
2625      name_enc += jQuery("#io_acc_itemname_"+id).html();
2626    }
2627    jQuery(".io_product_container .item_encoded").html(encodeURIComponent(name_enc.replace(/[\u2032\u2019]+/ig,"'")));
2628    jQuery(".io_product_container .item_rentalid").html(main_id+":"+pid+"_"+id);
2629    jQuery(".io_product_title.item_name").html(name);
2630    // Make sure the description actually displays text.
2631    let acc_desc = jQuery("#io_acc_desc_"+pid+"_"+id).first();
2632    if(acc_desc.length>0 && acc_desc.text()){
2633      jQuery(".io_product_container .io_product_desc").first().html(jQuery("#io_acc_desc_"+pid+"_"+id).first()[0].innerHTML);
2634    }
2635
2636    /* swap accessory image with main image pic for drop-down type items (linens) */
2637    let img = jQuery("#io_acc_imgbig_"+pid+"_"+id).first().attr("href");
2638    if(img==null) img = jQuery("#iothumb_"+pid+"_"+id).first().attr("src")
2639    if(img==null){
2640    }else{
2641      if(img.length==0 && pid==main_id){
2642        /* for 1 level dd items that have no img, use the main img */
2643        img = main_img_src;
2644      }
2645      jQuery(".io_product_container .io_image_big").first().attr("src",img);
2646      jQuery(".io_product_container .io_image_big").first().attr("data-src",
2646img);
2647      jQuery(".io_product_container .item_image").first().attr("src",jQuery("#iothumb_"+pid+"_"+id).first().attr("src"));
2648      jQuery(".io_product_container .item_image").first().attr("data-src",jQuery("#iothumb_"+pid+"_"+id).first().attr("src"));
2649
2650      jQuery("#single_image").first().attr("href",img).show();
2651    }
2652    checkAvailFilter();
2653  }
2654
2655  /* get either img or text for accessory choices */
2656  function getAccElem(id,pid){
2657    let path =pid+"_"+id;
2658    if(pid==0){
2659      path=id;
2660    }
2661    let elem = null;
2662    try{
2663      elem = document.querySelector("#ioAccButtonWrapper_"+path);
2664    }catch(e){}
2665    if(elem == null){
2666      try{
2667        elem = document.querySelector("#iothumb_"+path);
2668      }catch(e){}
2669    }
2670    if(elem==null){
2671      try{
2672        elem = document.querySelector("#io_product_acc_pkg_sel_"+pid);
2673      }catch(e){}
2674      if(elem!=null) return elem;
2675    }else{ return elem; }
2676    if(elem == null){
2677      try{
2678        elem = document.querySelector("#io_acc_shortname_"+path);
2679      }catch(e){}
2680    }else if(elem.src=="" | elem.getAttribute("data-src")==""){
2681      try{
2682        elem = document.querySelector("#io_acc_shortname_"+path);
2683      }catch(e){}
2684    }else if(elem.src.substr(-1)=="/"){
2685      try{
2686        elem = document.querySelector("#io_acc_shortname_"+path);
2687      }catch(e){}
2688    }
2689    if(elem==null){
2690      try{
2691        elem = document.querySelector("#io_acc_shortname_"+id);
2692      }catch(e){}
2693    }
2694    return elem;
2695  }
2696
2697  /* create the accessory choice btn (img/text) */
2698  function makeAccBtn(button_add,pid){
2699    let newButton;
2700    if(button_add.nodeName=="IMG"){
2701      newButton = button_add;
2702      let id =  newButton.id.replace("iothumb_"+pid,"");
2703      var wrapper = document.createElement("div");
2704      wrapper.setAttribute("id", "ioAccButtonWrapper_"+pid+id);
2705      wrapper.style.display = "inline-block";
2706      wrapper.appendChild(newButton);
2707      let acc_name = document.createElement("span");
2708      acc_name.style.overflow = "hidden";
2709      acc_name.style.textOverflow = "ellipsis";
2710      acc_name.style.maxWidth = "80px";
2711      acc_name.style.display = "block";
2712      acc_name.style.whiteSpace = "nowrap";
2713      acc_name.textContent = jQuery("#io_acc_shortname"+id).text();
2714      acc_name.classList.add("accTextName");
2715      acc_name.setAttribute("id", "io_acc_shortname_"+pid+id);
2716      wrapper.appendChild(document.createElement("br"));
2717      wrapper.appendChild(acc_name);
2718
2719    }else{
2720      newButton = button_add.cloneNode(true);
2721      let id = newButton.id.replace("io_acc_shortname_","");
2722      newButton.id = "io_acc_shortname_" + pid + "_" + id;
2723    }
2724    newButton.classList.add("elementor-animation-grow");
2725    newButton.classList.remove("item_image");
2726    newButton.style="cursor:pointer;border: solid 1px grey";
2727    newButton.classList.add("io_access_button");
2728    newButton.style.display = "inline-block";
2729    newButton.style.verticalAlign = "top";
2730    newButton.onclick=accOnClick;
2731    if(newButton.nodeName=="IMG"){
2732      newButton.style.minWidth = "80px";
2733      newButton.style.width = "80px";
2734      newButton.style.margin = "2px";
2735      newButton.style.height = "80px";
2736    }else{
2737      newButton.style.margin = "0px 2px 0px 2px";
2738    }
2739    if(button_add.nodeName=="IMG"){
2740      return wrapper
2741    }
2742
2743    return newButton;
2744  }
2745  /* when clicking the thumb swatches under main image (2nd image for an item) */
2746  function updateMainPic(img) {
2747    let container = img.parentElement;
2748    while (container && !container.querySelector(".io_image_big")) {
2749      container = container.parentElement;
2750    }
2751
2752    const main_img = container ? container.querySelector(".io_image_big") : null;
2753    if (!main_img) return;
2754
2755    const dataBigSrc = img.getAttribute("data-big-src");
2756    if (dataBigSrc) {
2757      main_img.src = dataBigSrc;
2758      return;
2759    }
2760
2761    let thumb_id = img.id;
2762    let big_id = thumb_id.replace("thumb", "big");
2763    const img_big = document.getElementById(big_id);
2764
2765    if (img_big && img_big.href) {
2766      main_img.src = img_big.href;
2767    }
2768  }
2769  /*</editor-fold>*/
2770
2771  /*<editor-fold defaultstate="collapsed" desc="Calendar Functions">*/
2772  function calApply() {
2773    /* reset timeslots if filtering is on */
2774    filterTimeslotsByDay_itemTimeslots();
2775    simpleCart.update();
2776
2777    /* Prevent zero-duration selection: disallow identical start and end date/time */
2778    try
2779    {
2780      var ds = jQuery("input[name=dateStart]").val();
2781      var de = jQuery("input[name=dateEnd]").val();
2782      var ts = jQuery("input[name=timeStart]").val();
2783      var te = jQuery("input[name=timeEnd]").val();
2784      if(ts && te && ds && de)
2785      {
2786        var s24 = convert12HourTo24Hour(ts);
2787        var e24 = convert12HourTo24Hour(te);
2788        var sObj = buildDateObj(ds.split("/"), s24);
2789        var eObj = buildDateObj(de.split("/"), e24);
2790        if(sObj && eObj && typeof sObj.getTime === 'function' && typeof eObj.getTime === 'function')
2791        {
2792          if(eObj.getTime() === sObj.getTime())
2793          {
2794            alert("Please choose an end time that's after the start time.");
2795            jQuery("input[name=timeEnd]").val("");
2796            return false;
2797          }
2798        }
2799      }
2800    }catch(e){}
2801
2802    if(cart_times_all_set()){
2803      ioCartLoaderActivate();
2804      setCookie("io_dateApplied", "true", 1)
2805      checkAvailAll();
2806      // If no availability calls were made, hide loader shortly after
2807      setTimeout(function()
2808      {
2809        if(io_cart_loading_active && io_cart_loading_count === 0)
2810        {
2811          io_cart_loading_active = false;
2812          ioCartShowOverlay(false);
2813        }
2814      }, 300);
2815      calCancel();
2816    }
2817
2818
2819    let io_required_data = io_info_required_data;
2820    for (const [data, value] of Object.entries(io_required_data)) {
2821      if(value == 1){
2822        setCookie(data, jQuery("#io_im_"+data).val(), 14);
2823      }
2824    }
2825
2826    /* Check if information gathering header exists. If it does, update the times on there. */
2827    if(jQuery("#ioInfoHeader").length){
2828      jQuery("#ioHeaderTimeStart").val(jQuery("[name=timeStart]").val());
2829      jQuery("#ioHeaderTimeEnd").val(jQuery("[name=timeEnd]").val());
2830      jQuery("#ioHeaderDateStart").val(jQuery("[name=dateStart]").val());
2831      jQuery("#ioHeaderDateEnd").val(jQuery("[name=dateEnd]").val());
2832      header_increment_step();
2833    }
2834
2835    show_or_hide_required_info_message()
2836    /* if(!cartStayOpen) cartHide(); */
2837  }
2838
2839  function calCancel() {
2840    click_count = 0;
2841    start_date = getCookie("io_dateStart");
2842    end_date = getCookie("io_dateEnd");
2843    start_time = getCookie("io_timeStart");
2844    end_time = getCookie("io_timeEnd");
2845    jQuery("input[name=dateStart]").val(start_date);
2846    jQuery("input[name=dateEnd]").val(end_date);
2847    if(io_company_timeslots.length != 0 && io_cartdayselect == "single_day" && getCookie("io_company_timeslot_selected")){
2848      jQuery(".ioCartCompanyTimeslots").val(getCookie("io_company_timeslot_selected"));
2849    } else{
2850      jQuery("input[name=timeStart]").val(start_time);
2851      jQuery("input[name=timeEnd]").val(end_time);
2852    }
2853    setCalBackground();
2854
2855    jQuery(".ioDateRange").html(smartFormatDateRange())
2856    jQuery("#cartCalendar, #cartTimePicker").hide();
2857    jQuery(".ioDateRange").show();
2858    jQuery(".changeDateLinkWrapper").show();
2859  }
2860
2861  /* var cartStayOpen = false; */
2862  function calSetDateRange(stayOpen) {
2863    /*
2864        if(stayOpen==1){
2865            cartStayOpen = true;
2866        }else{
2867            cartStayOpen = false;
2868        }
2869        */
2870    jQuery(".changeDateLinkWrapper").hide();
2871    jQuery("#cartCalendar, #cartTimePicker").show();
2872    jQuery("#cartDateRange").hide();
2873  }
2874
2875  function smartFormatDateRange() {
2876    let start_date = jQuery("input[name=dateStart]").val();
2877    let end_date = jQuery("input[name=dateEnd]").val();
2878    if(io_company_timeslots.length != 0 && io_cartdayselect == "single_day"){
2879      let cart_company_timeslot_selected = jQuery(".ioCartCompanyTimeslots option:selected").first().val();
2880      if(cart_company_timeslot_selected){
2881        setCookie("io_company_timeslot_selected", cart_company_timeslot_selected, 14);
2882        cart_company_timeslot_selected = cart_company_timeslot_selected.split("-");
2883        var start_time = cart_company_timeslot_selected[0].trim();
2884        var end_time = cart_company_timeslot_selected[1].trim();
2885      }
2886    } else {
2887      var start_time = jQuery("input[name=timeStart]").val();
2888      var end_time = jQuery("input[name=timeEnd]").val();
2889    }
2890
2891    let text = "";
2892    text = start_date;
2893    if(io_hidetimes!="on") text += " " + start_time;
2894
2895    if (start_date == end_date) {
2896      if(io_hidetimes!="on"){
2897        text += "  <i class='fas fa-arrow-right' style='padding:5px;'></i> ";
2898        text += end_time;
2899      }
2900    } else {
2901      text += "  <i class='fas fa-arrow-right' style='padding:5px;'></i> ";
2902      text += end_date;
2903      if(io_hidetimes!="on") text += " " + end_time;
2904    }
2905    /* text += "  <i class='fas fa-pencil-alt' style='margin-left:9px;color:"+pallet_color1+";'></i> "; */
2906
2907    return text;
2908  }
2909
2910
2911  function resetCalButtons() {
2912    jQuery("#cartCalendar .ui-datepicker-prev").addClass("fas fa-arrow-left").css("color", pallet_color1);
2913    jQuery("#cartCalendar .ui-datepicker-next").addClass("fas fa-arrow-right").
2913css("color", pallet_color1);
2914  }
2915
2916  function cal_onChangeMonthYear(year, month, obj) {
2917    setTimeout(resetCalButtons, 10);
2918    setTimeout(setCalBackground, 10);
2919  }
2920
2921  function cal_onSelect(dateText, obj) {
2922    setTimeout(resetCalButtons, 10);
2923    let whatday_choice = "";
2924    if(io_cartdayselect === "dropdown_options" && io_multidayquote === "on"){
2925      let choice_obj = jQuery("#whatday");
2926      if(choice_obj){
2927        whatday_choice = choice_obj.val();
2928      }
2929    }
2930
2931    click_count++;
2932    end_timepicker = jQuery("input[name=timeEnd]");
2933    let timeStart = jQuery("input[name=timeStart]").val();
2934    if(io_force_blank_timepickers != "on")
2935    {
2936      if (timeStart == "") {
2937        jQuery("input[name=timeStart]").val(start_default);
2938        jQuery("input[name=timeEnd]").val(end_default);
2939      }
2940    }
2941
2942    if (click_count == 1 || !multi_day || whatday_choice==="Same Day" || whatday_choice==="Overnight") {
2943      jQuery("input[name=dateStart]").val(dateText);
2944      jQuery("input[name=dateEnd]").val(dateText)
2945      end_timepicker.timepicker("option",{"minTime": jQuery("input[name=timeStart]").val()});
2946      if(EndTimeLessThanStartTime(
2947              jQuery("input[name=timeStart]").val(),
2948              end_timepicker.val(),
2949              jQuery("[name='dateStart']").val(),
2950              jQuery("[name='dateEnd']").val() ) ) {
2951        end_timepicker.val("");
2952      }
2953      if(io_cartAllowSameDay == "on"){
2954        restrictStartTimepickerOnSameDaySelect(dateText, jQuery("input[name=timeStart]"), end_timepicker);
2955      }
2956    } else if (click_count == 2) {
2957      jQuery("input[name=dateEnd]").val(dateText);
2958      let start_date_str = jQuery("input[name=dateStart]").val();
2959      let start_date_obj = convertDateStringtoDateObject(start_date_str);
2960      let end_date_obj = convertDateStringtoDateObject(dateText);
2961      if(end_date_obj < start_date_obj){
2962        jQuery("input[name=dateStart]").val(dateText);
2963        if(io_cartAllowSameDay == "on"){
2964          restrictStartTimepickerOnSameDaySelect(dateText, jQuery("input[name=timeStart]"), end_timepicker);
2965        }
2966      } else{
2967        end_timepicker.timepicker("option",{"minTime": io_restrict_time_start});
2968      }
2969      click_count = 0;
2970    } else {
2971      click_count = 0;
2972    }
2973    //custom code for suncoast_event
2974    if(io_cartdayselect === "dropdown_options" && io_multidayquote === "on"){
2975      endDisplay();
2976      //daysSelect();
2977    }
2978    filterTimeslotsByDay_companyTimeslots();
2979
2980    setTimeout(setCalBackground, 10);
2981  }
2982
2983  function endDisplay(){
2984    //todo: need to figure out if these work and set triggers
2985    // trigger enddisplay after date is selected or possibly when dateEnd changes?
2986    let choice = jQuery("#whatday").val();
2987
2988    setCookie("io_whatday", choice, 14);
2989    let dateStart = jQuery("[name=dateStart]");
2990    let timeStart = jQuery("[name=timeStart]");
2991    let dateEnd = jQuery("[name=dateEnd]");
2992    let timeEnd = jQuery("[name=timeEnd]");
2993    if(choice==='Overnight'){
2994      let startdate = dateStart.val();
2995      let starttime = io_overnightPickupTime;
2996      let endcalc_date_obj = new Date(buildDateobjectstring(startdate,dateFormat,starttime));
2997      let duration_hrs = 24;
2998      let end_date_obj = new Date(endcalc_date_obj.getTime()+duration_hrs*60*60*1000);
2999      if(!isNaN(end_date_obj)){
3000        dateEnd.val(getFormatteddate(end_date_obj));
3001        timeEnd.val(getFormattedtime(end_date_obj));
3002        timeEnd.attr('readonly','readonly');
3003      }
3004    }else if(choice==='Multi-Day'){
3005      let startdate = dateStart.val();
3006      let starttime = timeStart.val() || start_default;
3007      let start_date_obj = new Date(buildDateobjectstring(startdate, dateFormat, starttime));
3008      if(!isNaN(start_date_obj)){
3009        //dateEnd.val(getFormatteddate(start_date_obj));
3010        let cal = jQuery("#cartCalendar");
3011        let origOnSelect = cal.datepicker("option", "onSelect");
3012        cal.datepicker("option", "onSelect", null);
3013        cal.datepicker("setDate", start_date_obj);
3014        cal.datepicker("option", "onSelect", origOnSelect);
3015      }
3016      timeEnd.removeAttr('readonly');
3017      if(io_force_blank_timepickers == "on" && !timeEnd.val()){
3018        timeEnd.val("");
3019      } else if(!timeEnd.val()){
3020        timeEnd.val(end_default);
3021      }
3022    }else{
3023      let startdate = dateStart.val();
3024      let starttime = timeStart.val() || start_default;
3025      let start_date_obj = new Date(buildDateobjectstring(startdate, dateFormat, starttime));
3026      if(!isNaN(start_date_obj)){
3027        dateEnd.val(getFormatteddate(start_date_obj));
3028        let cal = jQuery("#cartCalendar");
3029        let origOnSelect = cal.datepicker("option", "onSelect");
3030        cal.datepicker("option", "onSelect", null);
3031        cal.datepicker("setDate", start_date_obj);
3032        cal.datepicker("option", "onSelect", origOnSelect);
3033      }
3034      timeEnd.removeAttr('readonly');
3035      if(io_force_blank_timepickers == "on"  && !timeEnd.val()){
3036        timeEnd.val("");
3037      } else if(!timeEnd.val()){
3038        timeEnd.val(end_default);
3039      }
3040      click_count = 0;
3041    }
3042    setTimeout(setCalBackground, 10);
3043  }
3044  function setCalBackground() {
3045    let dateStart_string = jQuery("input[name=dateStart]").val();
3046    let dateEnd_string = jQuery("input[name=dateEnd]").val();
3047
3048    if (dateFormat == "d/m/yy") {
3049      let dateStartArray = dateStart_string.split("/");
3050      let dateEndArray = dateEnd_string.split("/");
3051      var dateStart = new Date(dateStartArray[2], Number(dateStartArray[1])-1, dateStartArray[0]);
3052      var dateEnd = new Date(dateEndArray[2], Number(dateEndArray[1])-1, dateEndArray[0]);
3053    } else {
3054      var dateStart = new Date(dateStart_string);
3055      var dateEnd = new Date(dateEnd_string);
3056    }
3057
3058
3059    let sday = dateStart.getDate();
3060    let smonth = dateStart.getMonth();
3061    let syear = dateStart.getFullYear();
3062
3063    let eday = dateEnd.getDate();
3064    let emonth = dateEnd.getMonth();
3065    let eyear = dateEnd.getFullYear();
3066
3067    /* clear any (in case of cancel) */
3068    jQuery(".ui-datepicker-calendar [data-handler=selectDay]").css("background-color","initial");
3069
3070    /* set the selected ones */
3071    jQuery("#cartCalendar [data-month=" + smonth + "][data-year=" + syear + "], #cartCalendar [data-month=" +
3072            emonth + "][data-year=" + eyear + "]").each(function (i) {
3073      let cday = jQuery(this).find("a").first().text();
3074      let cmonth = jQuery(this).attr("data-month");
3075      let cyear = jQuery(this).attr("data-year");
3076      /* let dateCurrent = new Date(Date.UTC(cyear,cmonth,cday,12)); */
3077      let dateCurrent = new Date(cyear, cmonth, cday);
3078      if (click_count == 1 && dateEnd_string.length == 0) dateEnd = dateStart;
3079      if (dateCurrent.getTime() == dateStart.getTime() && dateCurrent.getTime() == dateEnd.getTime()) {
3080        jQuery(this).css("border-radius", "6px 6px 6px 6px");
3081      } else if (dateCurrent.getTime() == dateStart.getTime()) {
3082        jQuery(this).css("border-radius", "6px 0 0 6px");
3083      } else if (dateCurrent.getTime() == dateEnd.getTime()) {
3084        jQuery(this).css("border-radius", "0 6px 6px 0");
3085      }
3086
3087      if (dateCurrent >= dateStart && dateCurrent <= dateEnd) {
3088        jQuery(this).css("background-color", pallet_color1);
3089      }
3090
3091
3092    });
3093  }
3094  /*</editor-fold>*/
3095
3096  /*<editor-fold defaultstate="collapsed" desc="Timeslot/Timepicker Functions">*/
3097  /* called from simplecart */
3098  function timeslotChange(){
3099    checkAvailCartTimeslots();
3100  }
3101  function filterTimeslotsByDay_companyTimeslots(){
3102    var weekday = new Array();
3103    weekday[0] = "Sunday";
3104    weekday[1] = "Monday";
3105    weekday[2] = "Tuesday";
3106    weekday[3] = "Wednesday";
3107    weekday[4] = "Thursday";
3108    weekday[5] = "Friday";
3109    weekday[6] = "Saturday";
3110
3111    let times = getAvailTimes();
3112    let start_date = times[0];
3113    var newDate1 = convertDateStringtoDateObject(start_date);
3114    let day = weekday[new Date(newDate1).getDay()];
3115
3116    let selected_option_label = jQuery(".ioCartCompanyTimeslots option:selected").first().text().toLowerCase();
3117    if(optionHasDay(weekday, selected_option_label)){
3118      if(selected_option_label.indexOf(day.toLowerCase()) === -1){
3119        jQuery(".ioCartCompanyTimeslots").val("");
3120      }
3121    }
3122    if(io_company_timeslots.length != 0 && io_cartdayselect == "single_day"){
3123      jQuery(".ioCartCompanyTimeslots > option").each(function() {
3124        if(optionHasDay(weekday, this.text.toLowerCase())){
3125          for(i=0; i<weekday.length; ++i){
3126            if(day.toLowerCase() == weekday[i].toLowerCase() && this.text.toLowerCase().indexOf(day.toLowerCase()) !== -1){
3127              jQuery(this).show();
3128              day_missing = false;
3129            } else if(day.toLowerCase() != weekday[i].toLowerCase() && this.text.toLowerCase().indexOf(day.toLowerCase()) === -1){
3130              jQuery(this).hide();
3131            }
3132          }
3133        }
3134      });
3135    }
3136  }
3137
3138  function filterTimeslotsByDay_itemTimeslots(){
3139    var weekday = new Array();
3140    weekday[0] = "Sunday";
3141    weekday[1] = "Monday";
3142    weekday[2] = "Tuesday";
3143    weekday[3] = "Wednesday";
3144    weekday[4] = "Thursday";
3145    weekday[5] = "Friday";
3146    weekday[6] = "Saturday";
3147
3148    let times = getAvailTimes();
3149    let start_date = times[0];
3150    var newDate1 = convertDateStringtoDateObject(start_date);
3151    let day = weekday[new Date(newDate1).getDay()];
3152
3153    simpleCart.each(function (item, x) {
3154      var timeslots_html = item.get('timeslots');
3155      if(typeof timeslots_html != "undefined" && jQuery.parseHTML(timeslots_html)[0].nodeName == "SELECT"){
3156        if(timeslots_html.length > 0){
3157          var timeslot_name = getTimeslotName(timeslots_html);
3158          if(typeof item.get("timeslots-orig") == "undefined"){
3159            var timeslots_obj = jQuery.parseHTML(timeslots_html);
3160          } else{
3161            var timeslots_obj = jQuery.parseHTML(item.get('timeslots-orig'));
3162          }
3163          jQuery(timeslots_obj).find("option").each(function(){
3164            if(optionHasDay(weekday, this.text.toLowerCase())){
3165              for(i=0; i<weekday.length; ++i){
3166                if(day.toLowerCase() == weekday[i].toLowerCase() && this.text.toLowerCase().indexOf(day.toLowerCase()) !== -1){
3167                  /* jQuery(this).show(); */
3168                } else if(day.toLowerCase() != weekday[i].toLowerCase() && this.text.toLowerCase().indexOf(day.toLowerCase()) === -1){
3169                  jQuery(this).remove();
3170                }
3171              }
3172            }
3173          });
3174          if(typeof item.get("timeslots-orig") == "undefined") item.set("timeslots-orig",item.get("timeslots"));
3175          item.set("timeslots",'<select class="simpleCart_timeslots" name="'+timeslot_name+'">'+jQuery(timeslots_obj).html()+'</select>');
3176        }
3177      }
3178    });
3179  }
3180
3181  function optionHasDay(weekdays, option_label){
3182    for(i=0; i<weekdays.length; ++i){
3183      if(option_label.indexOf(weekdays[i].toLowerCase()) !== -1){
3184        return true;
3185      }
3186    }
3187    return false;
3188  }
3189
3190  function getTimeslotName(timeslots_html){
3191    if(typeof timeslots_html=="undefined") return "";
3192    var timeslot_name_s = timeslots_html.indexOf('name="');
3193    timeslot_name_s += 6;
3194    var timeslot_name_e = timeslots_html.indexOf('"',timeslot_name_s);
3195    var timeslot_name = timeslots_html.substr(timeslot_name_s,timeslot_name_e-timeslot_name_s);
3196    return timeslot_name;
3197  }
3198  function setTimeslotSelected(item, timeslot_name){
3199    jQuery(".item-timeslots [name=\""+timeslot_name+"\"] option").not(":selected").removeAttr("selected");
3200    jQuery(".item-timeslots [name=\""+timeslot_name+"\"] option:selected").attr("selected","selected");
3201    if(jQuery(".item-timeslots [name=\""+timeslot_name+"\"]").length>0){
3202      item.set("timeslots",jQuery(".item-timeslots [name=\""+timeslot_name+"\"]")[0].outerHTML);
3203    }
3204
3205    /* set on quote page */
3206    jQuery(".controls [name=\""+timeslot_name+"\"] option").not(":selected").removeAttr("selected");
3207    jQuery(".controls [name=\""+timeslot_name+"\"] option[value='"+jQuery(".item-timeslots [name=\""+timeslot_name+"\"] option:selected").val()+"']").attr("selected","selected");
3208  }
3209
3210  function setTimePicker(item, timepicker_name){
3211    let [start_timepicker, end_timepicker] = get_cart_timepickers(timepicker_name);
3212    let start_time = start_timepicker.value;
3213    let end_time = end_timepicker.value;
3214
3215    if(!start_time){
3216      start_timepicker.style.borderColor = "red";
3217    } else{
3218      start_timepicker.style.borderColor = "";
3219    }
3220    if(!end_time){
3221      end_timepicker.style.borderColor = "red";
3222    } else{
3223      end_timepicker.style.borderColor = "";
3224    }
3225
3226    let start_timepicker_html = start_timepicker.outerHTML;
3227    let end_timepicker_html = end_timepicker.outerHTML;
3228    if(document.querySelectorAll(".item-timeslots [name=\""+timepicker_name+"\"]").length>0){
3229      start_timepicker_html = addOrReplaceValueInTimepicker(start_timepicker_html, start_time);
3230      end_timepicker_html = addOrReplaceValueInTimepicker(end_timepicker_html, end_time);
3231      item.set("timeslots", '<div name="'+timepicker_name+'"> Start: '+start_timepicker_html+' End: '+end_timepicker_html+'</div>');
3232    }
3233    /* set on quote page */
3234    /* For linen type items with timepickers */
3235    let rental_id = item.get("rentalid");
3236    let split_on_colon = rental_id.split(":");
3237    if(split_on_colon.length > 1){
3238      fix_time_name_for_linen_rid(timepicker_name, split_on_colon, start_time, end_time, rental_id)
3239    }else{
3240      let quote_page_start_timepicker = document.querySelectorAll(".controls [name=\""+timepicker_name.replace("io_timepicker_", "starttime_")+"\"]")[0];
3241      let quote_page_end_timepicker = document.querySelectorAll(".controls [name=\""+timepicker_name.replace("io_timepicker_", "endtime_")+"\"]")[0];
3242      if(quote_page_start_timepicker != null && quote_page_end_timepicker != null){
3243        quote_page_start_timepicker.value = start_time;
3244        quote_page_end_timepicker.value = end_time;
3245      }
3246    }
3247  }
3248
3249  function fix_time_name_for_linen_rid(time_name, split_rid, start_time, end_time, rental_id){
3250    for(let x = 0; x < split_rid.length; x++){
3251      temp_timepicker_name = time_name.replace(rental_id, split_rid[x]);
3252      let quote_page_start_timepicker = document.querySelectorAll(".controls [name=\""+temp_timepicker_name.replace("io_timepicker_", "starttime_")+"\"]")[0];
3253      let quote_page_end_timepicker = document.querySelectorAll(".controls [name=\""+temp_timepicker_name.replace("io_timepicker_", "endtime_")+"\"]")[0];
3254      if(quote_page_start_timepicker != null && quote_page_end_timepicker != null){
3255        quote_page_start_timepicker.value = start_time;
3256        quote_page_end_timepicker.value = end_time;
3257      }
3258    }
3259  }
3260
3261  function addOrReplaceValueInTimepicker(timepicker_html, time_value){
3262    if(timepicker_html.includes("value=")){
3263      timepicker_html = [timepicker_html.slice(0, timepicker_html.indexOf("value=")), 'value="'+time_value+'"', timepicker_html.slice(timepicker_html.length-1)].join("");
3264    }else{
3265      /* No value defined. Add it at the end of the outer html. */
3266      let position = timepicker_html.lastIndexOf(">");
3267      timepicker_html = [timepicker_html.slice(0, position), ' value="'+time_value+'"', timepicker_html.slice(position)].join("");
3268    }
3269    return timepicker_html
3270  }
3271
3272  function restrictEndTimepickers(){
3273    setUpTimeRestrictions_cartTimepickers()
3274    setUpTimeRestrictions_timeBasedItems()
3275  }
3276
3277  function setUpTimeRestrictions_timeBasedItems(){
3278    jQuery("input[name^=start_timeslot_]").change(function()
3279    {
3280      end_timepicker = jQuery("input[name='"+this.name.replace("start", "end")+"']");
3281      end_timepicker = jQuery(end_timepicker[end_timepicker.length - 1]);
3282      end_timepicker.timepicker("option",{"minTime": jQuery(this).val()});
3283      if( EndTimeLessThanStartTime( jQuery(this).val(), end_timepicker.val(), "0/0/0", "0/0/0" ) ){
3284        end_timepicker.val("");
3285      }
3286    });
3287  }
3288
3289  function setUpTimeRestrictions_cartTimepickers(){
3290    jQuery("input[name=timeStart]").change(function()
3291    {
3292      end_timepicker = jQuery("[name='"+this.name.replace("Start", "End")+"']");
3293      if(jQuery("[name='dateStart']").val() === jQuery("input[name='dateEnd']").val()){
3294        end_timepicker.timepicker("option",{"minTime": jQuery(this).val()});
3295        if(EndTimeLessThanStartTime(
3296                jQuery(this).val(),
3297                end_timepicker.val(),
3298                jQuery("[name='dateStart']").val(),
3299                jQuery("[name='dateEnd']").val() ) ) {
3300          end_timepicker.val("");
3301        }
3302      }
3303    });
3304  }
3305
3306  function setUpTimeRestrictions_infoHeaderTimepickers(){
3307    jQuery("#ioHeaderTimeStart").change(function()
3308    {
3309      end_timepicker = jQuery("#ioHeaderTimeEnd");
3310      if(jQuery("#ioHeaderDateStart").val() === jQuery("#ioHeaderDateEnd").val()){
3311        end_timepicker.timepicker("option",{"minTime": jQuery(this).val()});
3312        if(EndTimeLessThanStartTime(
3313                jQuery(this).val(),
3314                end_timepicker.val(),
3315                jQuery("#ioHeaderDateStart").val(),
3316                jQuery("#ioHeaderDateEnd").val() ) ) {
3317          end_timepicker.val("");
3318        }
3319      }
3320    });
3321  }
3322
3323  /*
3324        helper function to see if the value from a start timepicker is less than the string value of an end timepicker.
3325
3326        param start_time: string representation of the start time picker. 12hr or 24hr.
3327        param end_time: string representation of the end time picker. 12hr or 24hr.
3328        param start_date: string representation of the start date, seperated by "/". Can be wither d/m/y or m/d/y. Pass "0/0/0" if dates do not matter.
3329        param end_date: string representation of the end date, seperated by "/". Can be wither d/m/y or m/d/y. Pass "0/0/0" if dates do not matter.
3330
3331  */
3332  function EndTimeLessThanStartTime(start_time, end_time, start_date, end_date){
3333    if(!start_time || !end_time) return false;
3334    start_time = convert12HourTo24Hour(start_time);
3335    end_time = convert12HourTo24Hour(end_time);
3336    var split_start_date = start_date.split("/");
3337    var split_end_date = end_date.split("/");
3338    var startDate = buildDateObj(split_start_date, start_time);
3339    var endDate = buildDateObj(split_end_date, end_time);
3340    if(endDate < startDate){
3341      return true;
3342    } else {
3343      return false;
3344    }
3345  }
3346  function get_cart_timepickers(timepicker_name){
3347    let start_timepicker = document.getElementsByName(timepicker_name.replace("io_timepicker_", "start_timeslot_"));
3348    let end_timepicker = document.getElementsByName(timepicker_name.replace("io_timepicker_", "end_timeslot_"));
3349    start_timepicker = start_timepicker[start_timepicker.length-1];
3350    end_timepicker = end_timepicker[end_timepicker.length-1];
3351    return Array(start_timepicker, end_timepicker);
3352  }
3353  function restrictStartTimepickerOnSameDaySelect(start_date_str, start_timepicker, end_timepicker){
3354    let selected_date_obj = convertDateStringtoDateObject(start_date_str);
3355    let current_date_obj = new Date();
3356    if(current_date_obj.getDate()  == selected_date_obj.getDate() &&
3357            current_date_obj.getMonth() == selected_date_obj.getMonth() &&
3358            current_date_obj.getYear()  == selected_date_obj.getYear()){
3359      let next_hour_time_stamp = current_date_obj.setMinutes(60);
3360      let next_hour_str = getFormattedtime(new Date(next_hour_time_stamp))
3361      start_timepicker.timepicker("option",{"minTime": next_hour_str});
3362
3363      /* If the time in the input box is less than the time we just restricted too, then clear time inputs */
3364      restricted_time_obj = convertDateStringtoDateObject(start_date_str, next_hour_str);
3365      currently_selected_time_obj = convertDateStringtoDateObject(start_date_str, start_timepicker.val());
3366      if(currently_selected_time_obj < restricted_time_obj){
3367        start_timepicker.val(next_hour_str);
3368        end_timepicker.val("");
3369        end_timepicker.timepicker("option",{"minTime": next_hour_str});
3370      }
3371    }else{
3372      start_timepicker.timepicker("option",{"minTime": restrictTimeStart});
3373    }
3374  }
3375  /*</editor-fold>*/
3376
3377  /*<editor-fold defaultstate="collapsed" desc="Simple Cart Bound Functions">*/
3378  function cart_onUpdate() {
3379    /* need slight delay so simplecart updates before this runs */
3380    setTimeout(cart_onUpdate2, 500);
3381    try{
3382      for(var i=0;i<document.getElementsByClassName("ioCart").length;i++){
3383        document.getElementsByClassName("ioCart")[i].setAttribute("cnt", simpleCart.items().length);
3384      }
3385    }catch(e){}
3386  }
3387
3388  function cart_onUpdate2() {
3389    jQuery("#cartSubtotal").html(simpleCart.toCurrency(simpleCart.total()));
3390    if(io_checkavail=="off") return;
3391    jQuery("#cartWarning").hide();
3392    let hasUnavail = false;
3393    gift_cards_only = false;
3394    simpleCart.each(function (item, x) {
3395      let item_id = item.get("id");
3396      var giftCardValue = item.get("giftcardvalue");
3397      if (giftCardValue && giftCardValue.trim()) {
3398        gift_cards_only = true;
3399      }
3400      let avail = 0;
3401      let stop_loop = false;
3402      if (item.get("availability") != null) avail = item.get("availability").replace(" available", "");
3403      let quantity = Number(item.get("quantity"));
3404      if(item.get("inputtype") == "Map"){
3405        quantity = 1
3406      }
3407      if(typeof item.get("availability") != 'undefined'){
3408        if (quantity > Number(avail) || avail == "not") {
3409          /* item.set("availability","<span style=color:red>"+item.get("availability")+"</span>"); */
3410          setTimeout(function () {
3411            jQuery("#cartItem_" + item_id + " .item-availability").css("color", "red")
3412          }, 10);
3413          //jQuery("#cartWarning").show();
3414          stop_loop = display_cart_warning(item);
3415          hasUnavail = true;
3416        } else {
3417          jQuery("#cartItem_" + item_id + " .item-availability").css("color", "inherit");
3418        }
3419      }else{
3420        event_times = getAvailTimes();
3421        if(!event_times[0] || !event_times[1]){
3422          jQuery("#cartWarning").text("Please set the date and time for your event above.");
3423          jQuery("#cartWarning").show()
3424        }
3425      }
3426
3427      var timeslots_html = item.get("timeslots");
3428      if(typeof timeslots_html != "undefined"){
3429        if(timeslots_html.length > 0){
3430          var timeslot_name = getTimeslotName(timeslots_html);
3431          if(timeslots_html.indexOf("<select") >= 0){
3432            setTimeslotSelected(item, timeslot_name);
3433          }else{
3434            setTimePicker(item, timeslot_name);
3435          }
3436        }
3437      }
3438      if(stop_loop){
3439        return false;
3440      }
3441    });
3442
3443    if(gift_cards_only){
3444      jQuery("#cartCalendarTimePickerContainer").hide();
3445    }else{
3446      jQuery("#cartCalendarTimePickerContainer").show();
3447    }
3448
3449    if(hasUnavail && io_checkavail!="off"){
3450      jQuery(".simpleCart_checkout").removeClass("simpleCart_checkout").addClass("simpleCart_checkout_off").trigger("classChange").click(cartShow);
3451    }else if(io_checkavail!="off"){
3452      jQuery(".simpleCart_checkout_off").removeClass("simpleCart_checkout_off").addClass("simpleCart_checkout").trigger("classChange");
3453    }
3454
3455    add_cart_buttons = document.querySelectorAll("[class*=add_cart_]");
3456    if(add_cart_buttons){
3457      for(let i = 0; i < add_cart_buttons.length; ++i){
3458        add_cart_buttons[i].innerHTML = add_cart_buttons[i].innerHTML.replace("fa-cart-arrow-down", "fa-shopping-cart");
3459        add_cart_buttons[i].innerHTML = add_cart_buttons[i].innerHTML.replace("Added to Cart", "Add to Cart");
3460        add_cart_buttons[i].style.filter = "brightness(100%)";
3461        simpleCart.each(function (item, x) {
3462          if( add_cart_buttons[i].className.includes( item.get("rentalid") ) ){
3463            add_cart_buttons[i].innerHTML = add_cart_buttons[i].innerHTML.replace("fa-shopping-cart", "fa-cart-arrow-down");
3464            add_cart_buttons[i].innerHTML = add_cart_buttons[i].innerHTML.replace("Add to Cart", "Added to Cart");
3465            add_cart_buttons[i].style.filter = "brightness(90%)";
3466          }
3467        });
3468      }
3469    }
3470
3471    /* init time-based items */
3472    if(document.location.href.indexOf("io_quoteform") == -1){
3473      let today = new Date();
3474      let io_dd = today.getDate();
3475      let io_mm = today.getMonth() + 1;
3476      let io_yyyy = today.getFullYear();
3477      if(restrictTimes){
3478        jQuery(".item-timeslots .timepicker").each( function() {
3479          if(this.name.includes("end")){
3480            start_timepicker = jQuery("input[name='"+this.name.replace("end", "start")+"']");
3481            start_timepicker = jQuery(start_timepicker[start_timepicker.length - 1]);
3482
3483            if (io_force_blank_timepickers == "on")
3484            {
3485              start_timepicker.val("");
3486              jQuery(this).timepicker({
3487                startTime: "",
3488                endTime:   "",
3489                minTime:   restrictTimeStart,
3490                maxTime:   restrictTimeEnd,
3491                timeFormat: timeFormat,
3492                separator:  ":",
3493                className:  "elementor-widget-text-editor",
3494                step: 15,
3495                disableTouchKeyboard: true
3496              });
3497            }
3498            else
3499            {
3500              // Existing logic if "force blank" is not active
3501              if (start_timepicker.val() != "") {
3502                jQuery(this).timepicker({
3503                  startTime: new Date(io_mm+"/"+io_dd+"/"+io_yyyy + " " + start_default),
3504                  endTime:   new Date(io_mm+"/"+io_dd+"/"+io_yyyy + " " + end_default),
3505                  minTime:   start_timepicker.val(),
3506                  maxTime:   restrictTimeEnd,
3507                  timeFormat: timeFormat,
3508                  separator:  ":",
3509                  className:  "elementor-widget-text-editor",
3510                  step: 15,
3511                  disableTouchKeyboard: true
3512                });
3513              } else {
3514                jQuery(this).timepicker({
3515                  startTime: new Date(io_mm+"/"+io_dd+"/"+io_yyyy + " " + start_default),
3516                  endTime:   new Date(io_mm+"/"+io_dd+"/"+io_yyyy + " " + end_default),
3517                  minTime:   restrictTimeStart,
3518                  maxTime:   restrictTimeEnd,
3519                  timeFormat: timeFormat,
3520                  separator:  ":",
3521                  className:  "elementor-widget-text-editor",
3522                  step: 15,
3523                  disableTouchKeyboard: true
3524                });
3525              }
3526            }
3527
3528          }
3529          else {
3530            if (io_force_blank_timepickers == "on")
3531            {
3532              start_timepicker.val("");
3533              jQuery(this).timepicker({
3534                startTime: "",
3535                endTime:   "",
3536                minTime:   restrictTimeStart,
3537                maxTime:   restrictTimeEnd,
3538                timeFormat: timeFormat,
3539                separator:  ":",
3540                className:  "elementor-widget-text-editor",
3541                step: 15,
3542                disableTouchKeyboard: true
3543              });
3544            }
3545            else
3546            {
3547              jQuery(this).timepicker({
3548                startTime: new Date(io_mm+"/"+io_dd+"/"+io_yyyy + " " + start_default),
3549                endTime: new Date(io_mm+"/"+io_dd+"/"+io_yyyy + " " + end_default),
3550                minTime:restrictTimeStart,
3551                maxTime:restrictTimeEnd,
3552                timeFormat: timeFormat,
3553                separator: ":",
3554                className: "elementor-widget-text-editor",
3555                step: 15,
3556                disableTouchKeyboard: true
3557              });
3558            }
3559          }
3560        });
3561      } else{
3562        jQuery(".item-timeslots .timepicker").each( function() {
3563          if(this.name.includes("end") != -1){
3564            start_timepicker = jQuery("input[name='"+this.name.replace("end", "start")+"']");
3565            start_timepicker = jQuery(start_timepicker[start_timepicker.length - 1]);
3566            if (io_force_blank_timepickers == "on")
3567            {
3568              start_timepicker.val("");
3569              jQuery(this).timepicker({
3570                startTime: "",
3571                endTime:   "",
3572                minTime:   restrictTimeStart,
3573                maxTime:   restrictTimeEnd,
3574                timeFormat: timeFormat,
3575                separator:  ":",
3576                className:  "elementor-widget-text-editor",
3577                step: 15,
3578                disableTouchKeyboard: true
3579              });
3580            }
3581            else
3582            {
3583              if (start_timepicker.val() != "") {
3584                jQuery(this).timepicker({
3585                  startTime: new Date(io_mm + "/" + io_dd + "/" + io_yyyy + " " + start_default),
3586                  endTime: new Date(io_mm + "/" + io_dd + "/" + io_yyyy + " " + end_default),
3587                  minTime: start_timepicker.val(),
3588                  timeFormat: timeFormat,
3589                  separator: ":",
3590                  className: "elementor-widget-text-editor",
3591                  step: 15,
3592                  disableTouchKeyboard: true
3593                });
3594              } else {
3595                jQuery(this).timepicker({
3596                  startTime: new Date(io_mm + "/" + io_dd + "/" + io_yyyy + " " + start_default),
3597                  endTime: new Date(io_mm + "/" + io_dd + "/" + io_yyyy + " " + end_default),
3598                  timeFormat: timeFormat,
3599                  separator: ":",
3600                  className: "elementor-widget-text-editor",
3601                  step: 15,
3602                  disableTouchKeyboard: true
3603                });
3604              }
3605            }
3606          }
3607          else
3608          {
3609            if (io_force_blank_timepickers == "on")
3610            {
3611              start_timepicker.val("");
3612              jQuery(this).timepicker({
3613                startTime: "",
3614                endTime:   "",
3615                minTime:   restrictTimeStart,
3616                maxTime:   restrictTimeEnd,
3617                timeFormat: timeFormat,
3618                separator:  ":",
3619                className:  "elementor-widget-text-editor",
3620                step: 15,
3621                disableTouchKeyboard: true
3622              });
3623            }
3624            else
3625            {
3626              jQuery(this).timepicker({
3627                startTime: new Date(io_mm + "/" + io_dd + "/" + io_yyyy + " " + start_default),
3628                endTime: new Date(io_mm + "/" + io_dd + "/" + io_yyyy + " " + end_default),
3629                timeFormat: timeFormat,
3630                separator: ":",
3631                className: "elementor-widget-text-editor",
3632                step: 15,
3633                disableTouchKeyboard: true
3634              });
3635            }
3636          }
3637        });
3638      }
3639      setUpTimeRestrictions_timeBasedItems();
3640      if(!event_time_set()){
3641        jQuery(".itemRow .item-total").hide();
3642      }else{
3643        jQuery(".itemRow .item-total").show();
3644      }
3645    }
3646  }
3647  function cart_beforeCheckout(data) {
3648    data.startdate = jQuery("input[name=dateStart]").val();
3649    data.enddate = jQuery("input[name=dateEnd]").val();
3650    if(getCookie("guid")){
3651      data.guid = getCookie("guid");
3652    }else{
3653      data.io_custguid = fetchAndSetCookie("guid");
3654    }
3655    if(io_company_timeslots.length != 0 && io_cartdayselect == "single_day"){
3656      let cart_company_timeslot_selected = jQuery(".ioCartCompanyTimeslots option:selected").first().val();
3657      if(cart_company_timeslot_selected){
3658        setCookie("io_company_timeslot_selected", cart_company_timeslot_selected, 14);
3659        cart_company_timeslot_selected = cart_company_timeslot_selected.split("-");
3660        data.starttime = cart_company_timeslot_selected[0];
3661        data.endtime = cart_company_timeslot_selected[1];
3662      }
3663    } else {
3664      data.starttime = jQuery("input[name=timeStart]").val();
3665      data.endtime = jQuery("input[name=timeEnd]").val();
3666    }
3667  }
3668  function cart_beforeAdd(item) {
3669    var main_id = jQuery(".io_product_container .item_rentalid").first().text();
3670    var item_id = item.get("rentalid");
3671
3672    timeslots = item.get("timeslots");
3673    if(timeslots){
3674      if(timeslots.indexOf("<select") !== -1){
3675        timeslot_name_id_start_pos = timeslots.lastIndexOf('name="timeslot_') + 'name="timeslot_'.length;
3676        timeslot_name_id_end_pos = timeslots.indexOf('"', timeslot_name_id_start_pos);
3677        new_timeslots = [timeslots.slice(0, timeslot_name_id_start_pos), item_id, timeslots.slice(timeslot_name_id_end_pos,timeslots.length)]
3678        new_timeslots = new_timeslots.join("")
3679        item.set("timeslots", new_timeslots);
3680      }else if(timeslots.indexOf("<div name=\"io_timepicker_") !== -1){
3681        timeslot_name_id_start_pos = timeslots.lastIndexOf('name="io_timepicker_') + 'name="io_timepicker_'.length;
3682        timeslot_name_id_end_pos = timeslots.indexOf('"', timeslot_name_id_start_pos);
3683        new_timeslots = [timeslots.slice(0, timeslot_name_id_start_pos), item_id, timeslots.slice(timeslot_name_id_end_pos,timeslots.length)]
3684        new_timeslots = new_timeslots.join("")
3685
3686        timeslot_name_id_start_pos = new_timeslots.lastIndexOf('name="start_timeslot_') + 'name="start_timeslot_'.length;
3687        timeslot_name_id_end_pos = new_timeslots.indexOf('"', timeslot_name_id_start_pos);
3688        new_timeslots = [new_timeslots.slice(0, timeslot_name_id_start_pos), item_id, new_timeslots.slice(timeslot_name_id_end_pos,new_timeslots.length)]
3689        new_timeslots = new_timeslots.join("")
3690
3691        timeslot_name_id_start_pos = new_timeslots.lastIndexOf('name="end_timeslot_') + 'name="end_timeslot_'.length;
3692        timeslot_name_id_end_pos = new_timeslots.indexOf('"', timeslot_name_id_start_pos);
3693        new_timeslots = [new_timeslots.slice(0, timeslot_name_id_start_pos), item_id, new_timeslots.slice(timeslot_name_id_end_pos,new_timeslots.length)]
3694        new_timeslots = new_timeslots.join("")
3695
3696        item.set("timeslots", new_timeslots);
3697      }
3698
3699    }
3700    /* Here we are checking if we are on an item page and if we are adding the main item.
3701           If this is not true, we do not want to continue. Bail here. */
3702    if((!main_id || !item_id)){
3703      return true;
3704    }else if (item_id != main_id){
3705      /* we are adding an accessory, We want to forcibly add the main item first. */
3706      /* IO-26864 */
3707      jQuery("#bookNowBtn").click();
3708    }
3709    let required_dropdown_values = jQuery(".io_acc_li").filter(function() {
3710      let required_ele = jQuery(this).find(".item_required");
3711      let required = 0;
3712      if(required_ele[0]){
3713        required = required_ele[0].outerText;
3714      }
3715      let dropdown_ele = jQuery(this).find(".item_accessorydd");
3716      let dropdown = 0;
3717      if(dropdown_ele[0]){
3718        dropdown = dropdown_ele[0].outerText;
3719      }
3720      return (required > 0 && dropdown == 1)
3721    });
3722    var required_selected = true;
3723    required_dropdown_values.each(function() {
3724      required_value_id = jQuery(this).find(".item_rentalid")[0].outerText;
3725      required_value_id = required_value_id.split("_");
3726      required_value_id = required_value_id[required_value_id.length-1];
3727
3728      let selected = jQuery("[id^='io_acc_"+required_value_id+"']").filter(function() {
3729        return this["selected"];
3730      });
3731
3732      //IO-22431 - This wasnt catching if [0] was undefined
3733      if(jQuery(this).find(".io_acc_li_name")[0] != undefined){
3734        required_value_name = jQuery(this).find(".io_acc_li_name")[0].outerText ? jQuery(this).find(".io_acc_li_name")[0].outerText : "";
3735      }
3736      if(selected.length < jQuery(this).find(".item_required")[0].outerText){
3737        if(item_id == main_id){
3738          alert(required_value_name+" is a required field.");
3739        }
3740        required_selected = false;
3741      }
3742
3743      if(!required_selected){
3744        return false;
3745      }
3746      return true;
3747    });
3748    if(!required_selected){
3749      return false;
3750    }
3751
3752    /* IO-14857 */
3753    if(jQuery(".io_product_measurement_price").length > 0){
3754      let units;
3755      if(jQuery(".io_product_infobox .item_qtytype").text() == "Area"){
3756        units = "sq meters"
3757        if(country === "US") units = "sq feet"
3758      }else if(jQuery(".io_product_infobox .item_qtytype").text() == "Perimeter"){
3759        units = "meters"
3760        if(country === "US") units = "feet"
3761      }
3762      item.set("units", units);
3763      item.set("quantity", jQuery(".io_measure_price_raw_measurement").text());
3764    }
3765  }
3766  function cart_afterAdd(item) {
3767    /*loading animation*/
3768    ioCartLoaderActivate();
3769    setTimeout(function(){ if(io_cart_loading_active && io_cart_loading_count === 0){ io_cart_loading_active=false; ioCartShowOverlay(false);} }, 300);
3770
3771    /* Add required Accessories */
3772    let required_accs = jQuery("[id^=io_acc_required_]").filter(function() {
3773      return parseInt(this["outerText"]) > 0 && this.parentElement.style['display'] != 'none';
3774    });
3775    required_accs.each(function(index) {
3776      simpleCart.parse_html_and_add(this, true);
3777    });
3778
3779
3780    let selected_values = jQuery("[id^=io_acc_]").filter(function() {
3781      return this["selected"];
3782    });
3783
3784    selected_values.each(function() {
3785      let info = {};
3786      let rid = jQuery(this).find(".item_rentalid")[0].outerText;
3787      let split_rid = rid.split("_");
3788      if(split_rid.length == 3){
3789        let parent_rid = split_rid[1];
3790        let main_item_rid = split_rid[0];
3791        info["acc_dd_parent_limit"] = jQuery("#io_acc_accessorylimit_"+main_item_rid+"_"+parent_rid)[0].outerText;
3792      }else{
3793        info["acc_dd_parent_limit"] = "0";
3794      }
3795      info["name"]         = jQuery(this).find(".io_acc_li_name")[0].outerText
3796      info["qtyincrement"] = jQuery(this).find(".item_qtyincrement")[0].outerText
3797      info["quantity"]     = jQuery(this).find(".item_required")[0].outerText > 0 ? jQuery(this).find(".item_required")[0].outerText : 1;
3798      info["rentalid"]     = jQuery(this).find(".item_rentalid")[0].outerText
3799      info["linkqty"]      = jQuery(this).find(".item_linkqty")[0].outerText
3800      info["pagename"]     = io_pagename;
3801      if(jQuery(this).find(".io_acc_li_img_thumb")[0]){
3802        info["image"] = jQuery(this).find(".io_acc_li_img_thumb")[0].src
3803      }
3804      let already_added = simpleCart.items().filter((item) => item.get("rentalid").startsWith(split_rid[0]+"_"+split_rid[1]));
3805      if(jQuery(this).find(".item_accessorydd")[0].outerText != 1 &&
3806         (info["acc_dd_parent_limit"] == "0" || already_added.length < info["acc_dd_parent_limit"]) ){
3807        simpleCart.add(info, true);
3808      }
3809    });
3810
3811    checkAvailCartOnly(true);
3812
3813    let last_upsell_call_time = Date.now() - last_upsell_call;
3814    if(in_cart_upsell && last_upsell_call_time > 2000){
3815      let rental_ids = "";
3816
3817      /* Get the last element in the cart. This is the last item added. */
3818      last_added = jQuery("[id^='cartItem_']").last();
3819      if(last_added.length){
3820        last_added_children = last_added.children();
3821        for(let i = 0; i < last_added_children.length; ++i){
3822          if(last_added_children[i].className == "item-rentalid") {
3823            rental_ids += last_added_children[i].innerText + "|";
3824          }
3825        }
3826      }
3827
3828      if(rental_ids.length>0 && jQuery("#cartPopover").attr("class") == "cartIn"){
3829        var times = getAvailTimes();
3830        last_upsell_call = Date.now();
3831        getUpsellsCall(times[0],times[1],times[2],rental_ids,updateCartUpsell);
3832      }
3833      else{
3834        jQuery("#cart-carousel-container").hide();
3835      }
3836    }
3837
3838    if(io_company_timeslots.length != 0 && io_cartdayselect == "single_day"){
3839      filterTimeslotsByDay_itemTimeslots();
3840      simpleCart.update();
3841    }
3842
3843    if (jQuery(".cartInfo.open,.ioCart.open, .ioCart_link.open").length == 0) {
3844      setTimeout(function () {
3845        cartShow();
3846      }, 100);
3847    }
3848
3849    if(simpleCart.items().length==0){
3850      jQuery(".simpleCart_checkout").hide()
3851    }else{
3852      jQuery(".simpleCart_checkout").show();
3853    }
3854
3855    if(simpleCart.items().length > 0){
3856      let headerBookButton = jQuery("a[href$='io_quoteform/']");
3857      headerBookButton.addClass("ioCart_link");
3858      headerBookButton.attr("href", "javascript:;");
3859    }
3860
3861    checkRestrictedDeliveries()
3862
3863    if(jQuery("#ioInfoHeader").length){
3864      header_increment_step();
3865    }
3866  }
3867  function cart_afterQtyChange(){
3868    let last_checkAvail_call_time = Date.now() - last_checkAvail_call;
3869    if(last_checkAvail_call_time > 2000){
3870      /*loading animation*/
3871      ioCartLoaderActivate();
3872      setTimeout(function(){ if(io_cart_loading_active && io_cart_loading_count === 0){ io_cart_loading_active=false; ioCartShowOverlay(false);} }, 300);
3873      last_checkAvail_call = Date.now();
3874      checkAvailCart();
3875      checkAvailCartTimeslots();
3876    }
3877  }
3878  function cart_hideTimepickerWrapper(){
3879    jQuery(".ui-timepicker-wrapper").hide();
3880  }
3881  function cart_beforeRemove() {
3882    last_remove = Date.now();
3883  }
3884  function cart_afterRemove(removed_item){
3885    checkAvailCart();
3886    last_upsell_call_time = Date.now() - last_upsell_call;
3887    if(in_cart_upsell && last_upsell_call_time > 2000){
3888      rental_ids = getAllRentalIDsFromCart();
3889      if(rental_ids.length>0 && jQuery("#cartPopover").attr("class") == "cartIn"){
3890        var times = getAvailTimes();
3891        last_upsell_call = Date.now();
3892        getUpsellsCall(times[0],times[1],times[2],rental_ids,updateCartUpsell);
3893      }
3894      else{
3895        jQuery("#cart-carousel-container").hide();
3896      }
3897    }
3898
3899    /* IO-24060 */
3900    simpleCart.items().forEach(function (item, index) {
3901      let expression = '^' + removed_item.get('rentalid') + '(?:[_:]\\d+)*';
3902      if(item.get("rentalid").match(expression)){
3903        item.remove();
3904      }
3905    });
3906
3907
3908    checkAvailCartTimeslots();
3909    checkRestrictedDeliveries();
3910    if(simpleCart.items().length==0){
3911      jQuery(".simpleCart_checkout").hide()
3912    }else{
3913      jQuery(".simpleCart_checkout").show();
3914    }
3915
3916    if(jQuery("#ioInfoHeader").length && simpleCart.items().length == 0){
3917      jQuery("#io-step-3").removeClass("io-step-active");
3918      jQuery("#io-step-2").addClass("io-step-active");
3919      jQuery("#io-step-2").removeClass("io-step-done")
3920    }
3921  }
3922  function cart_afterLoad(){
3923    var items_removed = false;
3924    simpleCart.items().forEach(function(item){
3925      if(item.get("pagename") != io_pagename){
3926        item.remove()
3927        items_removed = true;
3928      }
3929    })
3930    if(items_removed){
3931      alert("Some items in the cart are from a different location and have been removed.");
3932    }
3933  }
3934  /*</editor-fold>*/
3935
3936  /*<editor-fold defaultstate="collapsed" desc="Date/Time Object/String Conversion Functions">*/
3937  function getFormatteddate(date_obj){
3938    if(dateFormat.substring(0,1)=='d'){
3939      let month = date_obj.getMonth() + 1;
3940      formatteddate = date_obj.getDate()+'/'+month+'/'+date_obj.getFullYear();
3941    }else{
3942      let month = date_obj.getMonth() + 1;
3943      formatteddate = month+'/'+date_obj.getDate()+'/'+date_obj.getFullYear();
3944    }
3945    return formatteddate;
3946  }
3947
3948  function getFormattedtime(date_obj){
3949    var hour24 = false;
3950    var ampm = 'am';
3951    var starttime = jQuery('[name=timeStart]').val();
3952    if(starttime.length>0 && starttime.indexOf('m')==-1) hour24 = true;
3953    if(hour24){ //24 hour return
3954      return date_obj.getHours()+':'+pad(date_obj.getMinutes(),2);
3955    }else{ //12 hour return
3956      var hour = date_obj.getHours();
3957      if(hour==12) ampm='pm';
3958      if(hour==0) hour=12;
3959      if(hour>12){
3960        hour-=12;
3961        ampm='pm';
3962      }
3963      return hour+':'+pad(date_obj.getMinutes(),2)+' '+ampm;
3964    }
3965  }
3966
3967  function buildDateobjectstring(date,dateformat,time){
3968    var ampm = 'am';
3969    var hour24 = false;
3970    if(typeof date == "undefined") return;
3971    if(typeof dateformat == "undefined") return;
3972    var start_arr = date.split('/');
3973    if(dateformat.substring(0,1)=='d'){
3974      date = start_arr[2]+'/'+pad(start_arr[1],2)+'/'+pad(start_arr[0],2);
3975    }else{
3976      date = start_arr[2]+'/'+pad(start_arr[0],2)+'/'+pad(start_arr[1],2);
3977    }
3978    if(time.length>0 && time.indexOf('m')==-1) hour24 = true;
3979    if(hour24){
3980      try{
3981        var time_arr = time.split(':');
3982        var hour = parseInt(time_arr[0]);
3983        var min = pad(time_arr[1], 2);
3984        time = hour + ':' + min + ':00';
3985      }catch(err){
3986        time = "";
3987      }
3988    }else {
3989      try {
3990        time = time.replace('am', "").replace(' ', "");
3991        if (time.indexOf('pm') != -1) ampm = 'pm';
3992        time = time.replace('pm', "").replace(' ', "");
3993        var time_arr = time.split(':');
3994        var hour = parseInt(time_arr[0]);
3995        var min = pad(time_arr[1], 2);
3996        if (ampm == 'pm') {
3997          if (hour < 12) hour += 12;
3998        } else if (ampm == 'am' && hour == 12) {
3999          hour -= 12;
4000        }
4001        hour = pad(hour, 2);
4002        time = hour + ':' + min + ':00';
4003      } catch (err) {
4004        time = "";
4005      }
4006    }
4007    return date+' '+time;
4008  }
4009
4010  function pad(num, size) {
4011    var s = num+"";
4012    while (s.length < size) s = "0" + s;
4013    return s;
4014  }
4015  function convertDateStringtoDateObject(date_str, time_str=null){
4016    if(date_str){
4017      split_date_str = date_str.split("/");
4018      /* Parse start and end time. */
4019      if(time_str){
4020        /* Check and see if we are in 12 hour format, if so convert it to 24 hour format. */
4021        split_time_str = convert12HourTo24Hour(time_str);
4022      }else{
4023        /* If we do not have a time, then default to zeros */
4024        split_time_str = [0, 0];
4025      }
4026      /* Create date object based off our set date format. */
4027      date_obj = buildDateObj(split_date_str, split_time_str);
4028      return date_obj;
4029    }else{
4030      return new Date();
4031    }
4032  }
4033
4034  function buildDateObj(split_date_str, split_time_str){
4035    if (dateFormat == "d/m/yy"){
4036      return new Date(split_date_str[2], (+split_date_str[1] - 1).toString(), split_date_str[0],
4037              split_time_str[0], split_time_str[1]);
4038    }else{
4039      return new Date(split_date_str[2], (+split_date_str[0] - 1).toString(), split_date_str[1],
4040              split_time_str[0], split_time_str[1]);
4041    }
4042  }
4043
4044  function convert12HourTo24Hour(time_str){
4045    /* This function returns an array containing hours and minutes of provided string in 24 hour format. */
4046    /* This is primarily used for creating JS Date objects */
4047    split_time = time_str.split(":");
4048
4049    /* We are in 12 hour format if there is an "m" attached to minutes portion. */
4050    if(split_time[1].toLowerCase().search("m") != -1) {
4051      let separated_minutes = split_time[1].split(" ");
4052      if(separated_minutes.length==1){
4053        split_time[1] = split_time[1].replace("am"," am");
4054        split_time[1] = split_time[1].replace("pm"," pm");
4055        separated_minutes = split_time[1].split(" ");
4056      }
4057      let minutes = separated_minutes[0];
4058      let modifier = separated_minutes[1];
4059      split_time[1] = minutes;
4060
4061      /* First assume that if the hours are 12, then its midnight. */
4062      if(split_time[0] == "12"){
4063        split_time[0] = "00";
4064      }
4065      /* Second if there is a "p" in the modifier, then add twelve to the hours. */
4066      if(typeof modifier != "undefined"){
4067        if(modifier.toLowerCase().search("p") != -1){
4068          split_time[0] = (parseInt(split_time[0], 10) + 12);
4069        }
4070      }
4071    }
4072    return split_time;
4073  }
4074  /*</editor-fold>*/
4075
4076  /*<editor-fold defaultstate="collapsed" desc="Cart Show and Hide">*/
4077  function cartShow() {
4078    jQuery("#cartPopover").show();
4079    jQuery("#cartPopover").removeClass("cartOut");
4080    jQuery("#cartPopover").addClass("cartIn");
4081    jQuery(".cartInfo,.ioCart,.ioCart_link").addClass("open");
4082    if (/Mobi|Android/i.test(navigator.userAgent)) {
4083      document.body.style.overflow = "hidden";
4084    }
4085    /* jQuery(this).one("click", cartHide); */
4086    jQuery(".cartInfo").unbind("click").one("click", function(event){
4087      event.stopPropagation();
4088      event.stopImmediatePropagation();
4089      cartHide();
4090    });
4091    jQuery(".ioCart, .ioCart_link").unbind("click").one("click", function(event){
4092      event.stopPropagation();
4093      event.stopImmediatePropagation();
4094      cartHide();
4095    });
4096    jQuery(".cartIcon").removeClass("fa-shopping-cart").addClass("fa-close");
4097    if(simpleCart.items().length==0){
4098      jQuery(".simpleCart_checkout").hide()
4099    }else{
4100      jQuery(".simpleCart_checkout").show();
4101    }
4102
4103    checkAvailCartOnly();
4104
4105    last_upsell_call_time = Date.now() - last_upsell_call;
4106    if(in_cart_upsell && last_upsell_call_time > 2000){
4107      rental_ids = getAllRentalIDsFromCart();
4108      if(rental_ids.length>0 && jQuery("#cartPopover").attr("class") == "cartIn"){
4109        var times = getAvailTimes();
4110        last_upsell_call = Date.now();
4111        getUpsellsCall(times[0],times[1],times[2],rental_ids,updateCartUpsell);
4112      }
4113      else{
4114        jQuery("#cart-carousel-container").hide();
4115      }
4116    }
4117  }
4118
4119  function cartHide() {
4120    jQuery("#cartPopover").removeClass("cartIn");
4121    jQuery("#cartPopover").addClass("cartOut");
4122    if (/Mobi|Android/i.test(navigator.userAgent)) {
4123      document.body.style.overflow = "auto";
4124    }
4125    /* jQuery("#cartPopover").hide(); */
4126    jQuery(".cartInfo,.ioCart, .ioCart_link").removeClass("open");
4127    /* jQuery(this).one("click", cartShow); */
4128    jQuery(".cartInfo").unbind("click").one("click", function(event){
4129      event.stopPropagation();
4130      event.stopImmediatePropagation();
4131      cartShow();
4132    });
4133    jQuery(".ioCart, .ioCart_link").unbind("click").one("click", function(event){
4134      event.stopPropagation();
4135      event.stopImmediatePropagation();
4136      cartShow();
4137    });
4138    jQuery(".cartIcon").removeClass("fa-close").addClass("fa-shopping-cart");
4139  }
4140  /*
4141    function set_date_cookie(){
4142        if(this.id.indexOf("start_") !== -1){
4143            setCookie("dateStart", this.value, 14);
4144        } else if(this.id.indexOf("end_") !== -1){
4145            setCookie("dateEnd", this.value, 14);
4146        }
4147    }
4148    */
4149  jQuery(document).ready(function () {setTimeout(simpleCart.init, 3);});
4150  /*</editor-fold>*/
4151
4152  /*<editor-fold defaultstate="collapsed" desc="Check Avail All Call">*/
4153  function checkAvailAll(){
4154    checkAvailCart();
4155    checkAvailCartTimeslots();
4156    checkAvailFilter();
4157  }
4158  /*</editor-fold>*/
4159
4160  /*<editor-fold defaultstate="collapsed" desc="Check Avail - Page">*/
4161  /* for items on page not in cart */
4162  function checkAvailFilter() {
4163    let rental_names = "";
4164    let rental_ids = "";
4165    let batch_ids = [];
4166    let cart_rental_names = "";
4167    let cart_rental_ids = "";
4168    let item_id = "";
4169    let main_id = "";
4170    jQuery(".item_encoded").each(function(){
4171      rental_names += this.innerText + "|";
4172    });
4173    jQuery(".io_product_infobox .item_rentalid").each(function(){
4174      rental_ids += this.innerText + "|";
4175      item_id = this.innerText;
4176      main_id = this.innerText;
4177    });
4178    let batch_count = 0;
4179    let batch_index = 0;
4180    // If we have rental id string set, then we don't want to include availability checking for fpw items in header
4181    // IO-31498
4182    if(!rental_ids) {
4183      jQuery(".io_item2_list_inner .item_rentalid, .io_item2_listrent .item_rentalid").each(function () {
4184        /*
4185        if(rental_ids.indexOf(this.innerText+"|") == -1){
4186          rental_ids += this.innerText + "|";
4187        }
4188        */
4189        if (batch_count < 9) {
4190          if (!batch_ids.length) batch_ids.push("")
4191          if (!rid_in_batch(this.innerText + "|", batch_ids).length) {
4192            batch_ids[batch_index] += this.innerText + "|";
4193            batch_count++;
4194          }
4195        } else {
4196          if (!rid_in_batch(this.innerText + "|", batch_ids).length) {
4197            batch_ids[batch_index] += this.innerText + "|";
4198            batch_index++;
4199            batch_count = 0;
4200            batch_ids.push("");
4201          }
4202        }
4203      });
4204    }
4205    simpleCart.each(function (item, x) {
4206      var cart_name = item.get("encoded");
4207      if(cart_name==null){
4208        cart_name = encodeURIComponent(item.get("name"));
4209        cart_name = encodeURIComponent(decodeURIComponent(cart_name).replace(/[\u2032\u2019]+/ig,"'"));
4210      }
4211      let quantity = item.get("quantity");
4212      if(item.get("inputtype") == "Map"){
4213        quantity = 1
4214      }
4215      cart_rental_names += cart_name + "-" + quantity + "|";
4216      var cart_id = item.get("rentalid");
4217      cart_rental_ids += cart_id + "-" + quantity + "|";
4218    });
4219    /* #14494 IO-13779 */
4220    let delivery_methods_arr = [];
4221    var delivery_prices = [];
4222    if(io_delivery_prices){
4223      if(Object.keys(io_delivery_prices["override"]).includes(item_id)){
4224        delivery_prices = io_delivery_prices["override"][item_id]
4225      }else{
4226        if(!item_is_in_overrride_group(main_id)){
4227          delivery_prices = io_delivery_prices["default"]
4228        }
4229      }
4230      for(item in io_delivery_methods){
4231        if(delivery_prices.includes(io_delivery_methods[item]["id"])){
4232          delivery_methods_arr.push(item);
4233        }
4234      }
4235    }
4236
4237    let custom_prices_arr = [];
4238    if(io_custom_prices){
4239      if(Object.keys(io_custom_prices["override"]).includes(item_id.replace(":", '_'))){
4240        custom_prices_arr = io_custom_prices["override"][item_id.replace(":", '_')]
4241      }else{
4242        if(!item_is_in_overrride_group(main_id)){
4243          custom_prices_arr = io_custom_prices["default"]
4244        }
4245      }
4246    }
4247
4248    /* IO-13548 */
4249    if(io_accessory_price == "on"){
4250      let times = getAvailTimes();
4251      let acc_rental_id_str = getAccIDforPrice();
4252      let return_id = 0;
4253      if(acc_rental_id_str != ""){
4254        checkAvailCall(times[0],times[1],times[2],rental_names,acc_rental_id_str,displayAccessoryPrices,0,[],[],return_id,0,null,1,"",1);
4255      }
4256    }
4257
4258    let times = getAvailTimes();
4259    if(rental_names.length>0){
4260      if(use_weekday_weekend && rental_ids && !item_is_in_overrride_group(main_id)){
4261        let return_id = 0;
4262        let week_weekend = "";
4263        if(rental_ids != ""){
4264          return_id = 1;
4265          week_weekend = get_week_weekend_times(times, main_id);
4266          checkAvailCall(week_weekend["weekday"][0],week_weekend["weekday"][1],week_weekend["weekday"][2],rental_names,rental_ids,updatePageAvail_weekday,0,cart_rental_ids,cart_rental_names,return_id,1);
4267          checkAvailCall(week_weekend["weekend"][0],week_weekend["weekend"][1],week_weekend["weekend"][2],rental_names,rental_ids,updatePageAvail_weekend,0,cart_rental_ids,cart_rental_names,return_id,1);
4268        }
4269      }
4270      let return_id = 0;
4271      if(rental_ids != "" || batch_ids.length){
4272        return_id = 1;
4273      }
4274      if(delivery_methods_arr && rental_ids){
4275        delivery_methods_arr.forEach(function(delivery_method){
4276          checkAvailCall(times[0],times[1],times[2],rental_names,rental_ids,updatePageAvail_delivery_method,0,cart_rental_ids,cart_rental_names,return_id,1,delivery_method);
4277        });
4278      }
4279      if(custom_prices_arr && rental_ids){
4280        custom_prices_arr.forEach(function(custom_price){
4281          let start_date = times[0];
4282          let start_time = times[1];
4283          if(!start_date){
4284            start_date = getFormatteddate(new Date());
4285          }
4286          if(!start_time){
4287            start_time = io_default_start_time;
4288          }
4289          checkAvailCall(start_date,start_time,custom_price['duration'],rental_names,rental_ids,updatePageAvail_custom_price,0,cart_rental_ids,cart_rental_names,return_id,1,"",1,custom_price['name']);
4290        });
4291      }
4292
4293      if(batch_ids.length){
4294        batch_ids.forEach(function(rids){
4295          return checkAvailCall(times[0],times[1],times[2],"",rids,updatePageAvail,0,cart_rental_ids,cart_rental_names,return_id,1,null,1,"",1);
4296        });
4297      }else{
4298        return checkAvailCall(times[0],times[1],times[2],rental_names,rental_ids,updatePageAvail,0,cart_rental_ids,cart_rental_names,return_id,1,null,1);
4299      }
4300    }
4301  }
4302
4303  function item_is_in_overrride_group(item_id){
4304    for(const group_id in io_prices['override_groups']){
4305      for(const search_id in io_prices['override_groups'][group_id]){
4306        if(search_id == item_id){
4307          return true;
4308        }
4309      }
4310    }
4311    return false
4312  }
4313
4314  function get_week_weekend_times(times, rid){
4315    /* Create a copy instead of reference.*/
4316    let temp_times = JSON.parse(JSON.stringify(times));
4317    let start_date = temp_times[0];
4318    if(!start_date){
4319      start_date = getFormatteddate(new Date());
4320      temp_times[0] = start_date;
4321    }
4322    temp_times[1] = io_default_start_time
4323    var newDate1 = convertDateStringtoDateObject(start_date, io_default_start_time);
4324    var newDate2 = convertDateStringtoDateObject(start_date, io_default_end_time);
4325    let time_duration = ((newDate2 - newDate1) / 3600) / 1000;
4326    temp_times[2] = time_duration;
4327    let day = new Date(newDate1).getDay(); //IO-28150 - Other countries put the date dd/mm/yy so using the formatted newDate1 instead of start_date accounts for this
4328    let weekday_weekend = {};
4329    weekday_weekend["rid"] = rid;
4330    if(io_weekendDefine == "friday-sunday"){
4331      if(day == 5 || day == 6 || day == 0){
4332        weekday_weekend["weekend"] = JSON.parse(JSON.stringify(temp_times));
4333        temp_times[0] = getNextMonday(temp_times[0]);
4334        weekday_weekend["weekday"] = JSON.parse(JSON.stringify(temp_times));
4335      }else if(day == 1 || day == 2 || day == 3 || day == 4){
4336        weekday_weekend["weekday"] = JSON.parse(JSON.stringify(temp_times));
4337        temp_times[0] = getNextSaturday(temp_times[0]);
4338        weekday_weekend["weekend"] = JSON.parse(JSON.stringify(temp_times));
4339      }
4340    }else if(io_weekendDefine == "saturday-sunday") {
4341      if (day == 6 || day == 0) {
4342        weekday_weekend["weekend"] = JSON.parse(JSON.stringify(temp_times));
4343        temp_times[0] = getNextMonday(temp_times[0]);
4344        weekday_weekend["weekday"] = JSON.parse(JSON.stringify(temp_times));
4345      } else if (day == 1 || day == 2 || day == 3 || day == 4 || day == 5) {
4346        weekday_weekend["weekday"] = JSON.parse(JSON.stringify(temp_times));
4347        temp_times[0] = getNextSaturday(temp_times[0]);
4348        weekday_weekend["weekend"] = JSON.parse(JSON.stringify(temp_times));
4349      }
4350    }else if (io_weekendDefine == "friday-monday"){
4351      if(day == 5 || day == 6 || day == 0 || day == 1){
4352        weekday_weekend["weekend"] = JSON.parse(JSON.stringify(temp_times));
4353        temp_times[0] = getNextTuesday(temp_times[0]);
4354        weekday_weekend["weekday"] = JSON.parse(JSON.stringify(temp_times));
4355      }else if(day == 2 || day == 3 || day == 4){
4356        weekday_weekend["weekday"] = JSON.parse(JSON.stringify(temp_times));
4357        temp_times[0] = getNextSaturday(temp_times[0]);
4358        weekday_weekend["weekend"] = JSON.parse(JSON.stringify(temp_times));
4359      }
4360    }
4361    return weekday_weekend;
4362  }
4363
4364  /*
4365        helper function found here:
4366        https://bobbyhadz.com/blog/javascript-get-date-of-next-monday#:~:text=To%20get%20the%20next%20Monday%2C%20we%3A&text=If%20the%20remainder%20is%20equal,month%20for%20the%20next%20Monday.
4367    */
4368  function getNextMonday(date_str) {
4369    const date_obj = parseDate(date_str, dateFormat);
4370
4371    const nextMonday = new Date(
4372            date_obj.setDate(
4373                    date_obj.getDate() + ((7 - date_obj.getDay() + 1) % 7 || 7),
4374            ),
4375    );
4376
4377    return getFormatteddate(nextMonday);
4378  }
4379
4380    function getNextTuesday(date_str) {
4381      const date_obj = parseDate(date_str, dateFormat);
4382
4383      const nextMonday = new Date(
4384              date_obj.setDate(
4385                      date_obj.getDate() + ((7 - date_obj.getDay() + 2) % 7 || 7),
4386              ),
4387      );
4388
4389      return getFormatteddate(nextMonday);
4390    }
4391
4392  function parseDate(date_str, format) {
4393      var parts = date_str.split(/[/.-]/);
4394      var day, month, year;
4395
4396      if (format === "m/d/yy") {
4397          month = parseInt(parts[0]) - 1;
4398          day = parseInt(parts[1]);
4399          year = parseInt(parts[2]) + (parts[2].length === 2 ? 2000 : 0);
4400      } else if (format === "d/m/yy") {
4401          day = parseInt(parts[0]);
4402          month = parseInt(parts[1]) - 1;
4403          year = parseInt(parts[2]) + (parts[2].length === 2 ? 2000 : 0);
4404      } else if (format === "yy/m/d") {
4405          year = parseInt(parts[0]) + (parts[0].length === 2 ? 2000 : 0);
4406          month = parseInt(parts[1]) - 1;
4407          day = parseInt(parts[2]);
4408      } else {
4409          throw new Error("Unsupported date format");
4410      }
4411
4412      return new Date(year, month, day);
4413  }
4414
4415  /* modified from function above */
4416  function getNextSaturday(date_str) {
4417    const date_obj = parseDate(date_str, dateFormat);
4418
4419    const next_friday = new Date(
4420            date_obj.setDate(
4421                    date_obj.getDate() + ((7 - date_obj.getDay() + 6) % 7 || 7),
4422            ),
4423    );
4424
4425    return getFormatteddate(next_friday);
4426  }
4427
4428  function updatePageAvail(data){
4429    let use_id = data["return_id"]
4430    delete data["return_id"];
4431    if(use_id == 1){
4432      updatePageAvail_itemIDs(data)
4433    }else{
4434      updatePageAvail_itemNames(data);
4435    }
4436  }
4437  function updatePageAvail_weekday(data){
4438    jQuery.each(data, function (rental_id, qty){
4439      if (rental_id == "price") {
4440        var prices = qty;
4441        jQuery.each(prices, function (price_id, amt) {
4442          let cust_price = document.querySelector(".io_product_cust_price_weekday");
4443          if(cust_price==undefined){
4444            var first_price = document.querySelector(".io_product_price_box");
4445            if(first_price != null){
4446              cust_price = first_price.cloneNode(true);
4447              /* clear all classes */
4448              cust_price.className = "";
4449              cust_price.classList.add("io_product_price_box");
4450              cust_price.classList.add("io_product_cust_price_weekday");
4451              cust_price.style.display = "none";
4452              first_price.before(cust_price);
4453            }
4454          }
4455
4456          main_item_id = jQuery(".io_product_infobox .item_rentalid").first().text();
4457          if(main_item_id == price_id && cust_price!=undefined){
4458            if(typeof amt == "string") amt = Number(amt.replace(",",""));
4459            cust_price.querySelector("p:nth-child(1)").innerHTML=simpleCart.toCurrency(amt);
4460            let times = getAvailTimes();
4461            cust_price.querySelector("p:nth-child(2)").innerHTML = io_weekDayText;
4462            if(amt>0){
4463              cust_price.style.display = "grid";
4464            }else{
4465              cust_price.style.display = "none";
4466            }
4467          }
4468        });
4469      }
4470    });
4471  }
4472  function updatePageAvail_delivery_method(data){
4473    var delivery_method = data["delivery_method"]
4474    jQuery.each(data, function (rental_id, qty){
4475      if (rental_id == "price") {
4476        var prices = qty;
4477        jQuery.each(prices, function (price_id, amt) {
4478          let cust_price = document.querySelector(".io_product_cust_price_delivery_method"+io_delivery_methods[delivery_method]["id"]);
4479          let rid = jQuery(".io_product_container .item_rentalid").first().text();
4480          if(cust_price==undefined && !io_delivery_methods[delivery_method]["restricted"].includes(rid)){
4481            var first_price = document.querySelector(".io_product_price_box");
4482            if(first_price != null){
4483              cust_price = first_price.cloneNode(true);
4484              /* clear all classes */
4485              cust_price.className = "";
4486              cust_price.classList.add("io_product_price_box");
4487              cust_price.classList.add("io_product_cust_price_delivery_method"+io_delivery_methods[delivery_method]["id"]);
4488              cust_price.style.display = "none";
4489              first_price.before(cust_price);
4490            }
4491          }
4492
4493          main_item_id = jQuery(".io_product_infobox .item_rentalid").first().text();
4494          if(main_item_id == price_id && cust_price!=undefined){
4495            if(typeof amt == "string") amt = Number(amt.replace(",",""));
4496            cust_price.querySelector("p:nth-child(1)").innerHTML=simpleCart.toCurrency(amt);
4497            let times = getAvailTimes();
4498            cust_price.querySelector("p:nth-child(2)").innerHTML = make_live_price_editable_time(times, delivery_method);
4499            if(amt>0 && event_time_set()){
4500              cust_price.style.display = "grid";
4501            }else{
4502              cust_price.style.display = "none";
4503            }
4504          }
4505        });
4506      }
4507    });
4508  }
4509  function updatePageAvail_custom_price(data, custom_price_name){
4510    let custom_price_class_name = custom_price_name.replace(/[\s:./()!]/g, '_');
4511    jQuery.each(data, function (rental_id, qty){
4512      if (rental_id == "price") {
4513        var prices = qty;
4514        jQuery.each(prices, function (price_id, amt) {
4515          let cust_price = document.querySelector(".io_product_cust_price_"+custom_price_class_name);
4516          let rid = jQuery(".io_product_container .item_rentalid").first().text();
4517          if(cust_price==undefined){
4518            var first_price = document.querySelector(".io_product_price_box");
4519            if(first_price != null){
4520              cust_price = first_price.cloneNode(true);
4521              /* clear all classes */
4522              cust_price.className = "";
4523              cust_price.classList.add("io_product_price_box");
4524              cust_price.classList.add("io_product_cust_price_"+custom_price_class_name);
4525              cust_price.style.display = "none";
4526              first_price.before(cust_price);
4527            }
4528          }
4529
4530          main_item_id = jQuery(".io_product_infobox .item_rentalid").first().text();
4531          if(main_item_id == price_id && cust_price!=undefined){
4532            if(typeof amt == "string") amt = Number(amt.replace(",",""));
4533            cust_price.querySelector("p:nth-child(1)").innerHTML=simpleCart.toCurrency(amt);
4534            cust_price.querySelector("p:nth-child(2)").innerHTML = "for " + custom_price_name;
4535            if(amt>0){
4536              cust_price.style.display = "grid";
4537            }else{
4538              cust_price.style.display = "none";
4539            }
4540          }
4541        });
4542      }
4543    });
4544  }
4545  function updatePageAvail_weekend(data){
4546    jQuery.each(data, function (rental_id, qty){
4547      if (rental_id == "price") {
4548        var prices = qty;
4549        jQuery.each(prices, function (price_id, amt) {
4550          let cust_price = document.querySelector(".io_product_cust_price_weekend");
4551          if(cust_price==undefined){
4552            var first_price = document.querySelector(".io_product_price_box");
4553            if(first_price != null){
4554              cust_price = first_price.cloneNode(true);
4555              /* clear all classes */
4556              cust_price.className = "";
4557              cust_price.classList.add("io_product_price_box");
4558              cust_price.classList.add("io_product_cust_price_weekend");
4559              cust_price.style.display = "none";
4560              first_price.before(cust_price);
4561            }
4562          }
4563
4564          main_item_id = jQuery(".io_product_infobox .item_rentalid").first().text();
4565          if(main_item_id == price_id && cust_price!=undefined){
4566            if(typeof amt == "string") amt = Number(amt.replace(",",""));
4567            cust_price.querySelector("p:nth-child(1)").innerHTML=simpleCart.toCurrency(amt);
4568            let times = getAvailTimes();
4569            cust_price.querySelector("p:nth-child(2)").innerHTML = io_weekEndText;
4570            if(amt>0){
4571              cust_price.style.display = "grid";
4572            }else{
4573              cust_price.style.display = "none";
4574            }
4575          }
4576        });
4577      }
4578    });
4579  }
4580  function updatePageAvail_itemIDs(data){
4581    jQuery.each(data, function (rental_id, qty){
4582      if (rental_id == "price"  && jQuery(".io_product_infobox .item_inputtype").text() != "Map") {
4583        var prices = qty;
4584        jQuery.each(prices, function (price_id, amt) {
4585          let cust_price = document.querySelector(".io_product_cust_price");
4586          if(cust_price==undefined){
4587            var first_price = document.querySelector(".io_product_price_box");
4588            if(first_price != null){
4589              cust_price = first_price.cloneNode(true);
4590              /* clear all classes */
4591              cust_price.className = "";
4592              cust_price.classList.add("io_product_price_box");
4593              cust_price.classList.add("io_product_cust_price");
4594              cust_price.style.display = "none";
4595              first_price.before(cust_price);
4596            }
4597          }
4598          main_item_id = jQuery(".io_product_infobox .item_rentalid").first().text();
4599          if(main_item_id == price_id && cust_price!=undefined){
4600            if(typeof amt == "string") amt = Number(amt.replace(",",""));
4601            cust_price.querySelector("p:nth-child(1)").innerHTML=simpleCart.toCurrency(amt);
4602            let times = getAvailTimes();
4603            cust_price.querySelector("p:nth-child(2)").innerHTML = make_live_price_editable_time(times);
4604            if(amt>0 && (event_time_set() || io_always_display_live_price == "on")){
4605              cust_price.style.display = "grid";
4606            }else{
4607              cust_price.style.display = "none";
4608            }
4609          }
4610        });
4611      }
4612
4613      if(qty<=0 && rental_id != "delivery_method"){
4614        /* cat,all-item,widget */
4615        if(io_checkavail=="warn"){
4616          jQuery(".add_cart_"+rental_id.replace(":", "\\\:")+" .item_add").removeClass("item_add").addClass("item_add_off").trigger("classChange");
4617          jQuery(".unavailable_message_"+rental_id.replace(":", "\\\:")).show();
4618        }
4619        if(io_checkavail=="hide") jQuery(".add_cart_"+rental_id).parent().parent().parent().hide();
4620
4621        /* product page */
4622        if(jQuery(".io_product_container").length && io_checkavail!="off" && jQuery(".io_product_container .item_rentalid").first().text() === rental_id){
4623          jQuery(".add_cart_"+rental_id.replace(":", "\\\:")+" .item_add").first().removeClass("item_add").addClass("item_add_off").trigger("classChange");
4624          jQuery(".io_product_container .unavailable_message").show();
4625        }
4626      }else if(qty>0){
4627        if(io_checkavail=="warn"){
4628          jQuery(".add_cart_"+rental_id.replace(":", "\\\:")+" .item_add_off").removeClass("item_add_off").addClass("item_add").trigger("classChange");
4629          jQuery(".unavailable_message_"+rental_id.replace(":", "\\\:")).hide();
4630        }
4631        if(io_checkavail=="hide") jQuery(".add_cart_"+rental_id).parent().parent().parent().show();
4632
4633        /* product page */
4634        if(jQuery(".io_product_container").length && io_checkavail!="off" && jQuery(".io_product_container .item_rentalid").first().text() === rental_id){
4635          jQuery(".add_cart_"+rental_id.replace(":", "\\\:")+" .item_add_off").removeClass("item_add_off").addClass("item_add").trigger("classChange");
4636          jQuery(".io_product_container .unavailable_message").hide();
4637        }
4638      }
4639    });
4640  }
4641  function updatePageAvail_itemNames(data){
4642    jQuery.each(data, function (rental_name, qty) {
4643      rental_name = rental_name.replace(/[\u2032\u2019]+/ig,"'");
4644      var main_name_temp = "";
4645      if(typeof main_name_orig != "undefined"){
4646        main_name_temp = main_name_orig.replace(/[\u2032\u2019]+/ig,"'");
4647      }
4648      rental_name_esc = rental_name.replace(/'/g, "\\\\'");
4649      if (rental_name == "price") {
4650        var prices = qty;
4651        jQuery.each(prices, function (price_name, amt) {
4652          /* var prices = document.querySelector(".io_product_price_box:not(.io_product_cust_price)"); */
4653          /* if(prices != null) prices.remove(); */
4654          let cust_price = document.querySelector(".io_product_cust_price");
4655          if(cust_price==undefined){
4656            var first_price = document.querySelector(".io_product_price_box");
4657            if(first_price != null){
4658              cust_price = first_price.cloneNode(true);
4659              /* clear all classes */
4660              cust_price.className = "";
4661              cust_price.classList.add("io_product_price_box");
4662              cust_price.classList.add("io_product_cust_price");
4663              cust_price.style.display = "none";
4664              first_price.before(cust_price);
4665            }
4666          }
4667          try{
4668            var main_name = decodeURIComponent(jQuery(".io_product_container .item_encoded").first().html().replace(/[+]/gi, "%20"));
4669          }catch(e){main_name=""}
4670          var i = main_name.lastIndexOf(":");
4671          let acc_name = "";
4672          let rental_name = "";
4673          var i = main_name.lastIndexOf(":");
4674          if(i>0){
4675            rental_name = main_name.substring(0, i);
4676            acc_name = main_name.substring(i+1);
4677          }
4678          if (acc_name.toUpperCase() == price_name.toUpperCase() && cust_price!=undefined){
4679            var rental_id = document.querySelector(".item_rentalid").innerText;
4680            if(rental_id != null){
4681              rid_arr = rental_id.split(":");
4682              /* ignore the main id for this */
4683              rental_id = rid_arr[rid_arr.length-1];
4684              if(jQuery("#io_acc_overrideprice_"+rental_id).first().text()>0){
4685                amt = prices[acc_name];
4686              }else{
4687                let item_price = Number(prices[rental_name].replace(",",""));
4688                amt = Number(amt.replace(",","")) + item_price;
4689                amt = simpleCart.toCurrency(amt, {symbol:""})
4690              }
4691            }
4692            cust_price.querySelector("p:nth-child(1)").innerText="$"+amt;
4693            if(typeof amt == "string") amt = Number(amt.replace(",",""));
4694            let times = getAvailTimes();
4695            cust_price.querySelector("p:nth-child(2)").innerHTML = make_live_price_editable_time(times);
4696            if(amt>0 && (event_time_set() || io_always_display_live_price == "on")){
4697              cust_price.style.display = "grid";
4698            }else{
4699              cust_price.style.display = "none";
4700            }
4701
4702          }else if(!rental_name && !acc_name && cust_price!=undefined){
4703            amt = prices[main_name];
4704            cust_price.querySelector("p:nth-child(1)").innerText="$"+amt;
4705            if(typeof amt == "string") amt = Number(amt.replace(",",""));
4706            let times = getAvailTimes();
4707            cust_price.querySelector("p:nth-child(2)").innerHTML = make_live_price_editable_time(times);
4708            if(amt>0 && (event_time_set() || io_always_display_live_price == "on")){
4709              cust_price.style.display = "grid";
4710            }else{
4711              cust_price.style.display = "none";
4712            }
4713          }
4714
4715        });
4716      }
4717
4718      if(qty<=0){
4719        /* cat,all-item,widget */
4720        if(io_checkavail=="warn"){
4721          jQuery("div[name='maindiv_"+rental_name_esc+"'] .item_add").removeClass("item_add").addClass("item_add_off").trigger("classChange");
4722          jQuery("div[name='maindiv_"+rental_name_esc+"'] .unavailable_message").show();
4723        }
4724        if(io_checkavail=="hide") jQuery("div[name='maindiv_"+rental_name_esc+"']").hide();
4725
4726        /* product page */
4727        if(jQuery(".io_product_container").length && io_checkavail!="off"){
4728          if(main_name_temp==rental_name){
4729            jQuery(".io_product_container .item_add").first().removeClass("item_add").addClass("item_add_off").trigger("classChange");
4730            jQuery(".io_product_container .unavailable_message").show();
4731          }
4732        }
4733      }else if(qty>0){
4734        /* console.log("good"); */
4735        if(io_checkavail=="warn"){
4736          jQuery("div[name='maindiv_"+rental_name_esc+"'] .item_add_off").removeClass("item_add_off").addClass("item_add").trigger("classChange");
4737          jQuery("div[name='maindiv_"+rental_name_esc+"'] .unavailable_message").hide();
4738        }
4739        if(io_checkavail=="hide") jQuery("div[name='maindiv_"+rental_name_esc+"']").show();
4740
4741        /* product page */
4742        if(jQuery(".io_product_container").length && io_checkavail!="off"){
4743          if(main_name_temp==rental_name){
4744            jQuery(".io_product_container .item_add_off").removeClass("item_add_off").addClass("item_add").trigger("classChange");
4745            jQuery(".io_product_container .unavailable_message").hide();
4746          }
4747        }
4748      }
4749    });
4750  }
4751  function displayAccessoryPrices(data) {
4752      if (data.price) {
4753          let acc_prices = data.price;
4754          for (const [key, value] of Object.entries(acc_prices)) {
4755              let new_key = key;
4756              if ((key.match(/_/g) || []).length > 1) {
4757                  let split_key = key.split("_");
4758                  let second_to_last = split_key[split_key.length - 2];
4759                  let last = split_key[split_key.length - 1];
4760                  new_key = second_to_last + "_" + last;
4761              }
4762              if (io_hide_zero == 1 && value > 0) {
4763                  let id_string = "#io_acc_desc_" + new_key;
4764                  let formatted_price = simpleCart.toCurrency(value);
4765                  if (jQuery("#io_acc_" + new_key + " .io_acc_price").length > 0) {
4766                      jQuery("#io_acc_" + new_key + " .io_acc_price").html(formatted_price);
4767                  } else {
4768                      let price_display = '<span class="io_acc_price"> ' + formatted_price + ' </span>';
4769                      jQuery(id_string).after(price_display);
4770                  }
4771              } else if (io_hide_zero == 0) {
4772                  let id_string = "#io_acc_desc_" + new_key;
4773                  let formatted_price = simpleCart.toCurrency(value);
4774                  if (jQuery("#io_acc_" + new_key + " .io_acc_price").length > 0) {
4775                      jQuery("#io_acc_" + new_key + " .io_acc_price").html(formatted_price);
4776                  } else {
4777                      let price_display = '<span class="io_acc_price"> ' + formatted_price + ' </span>';
4778                      jQuery(id_string).after(price_display);
4779                  }
4780              }
4781          }
4782      }
4783  }
4784  function make_live_price_editable_time(times, delivery_method=null) {
4785    if(!delivery_method) delivery_method = getCookie("io_delivery_method");
4786    let ele_text = "";
4787    if(times[0]) ele_text = "on " + times[0] + " ";
4788    if(times[2] === 0) times[2] = 1;
4789    if(io_hidetimes!="on" && !isNaN(times[2])) ele_text += "for "+times[2]+" hours ";
4790    if(delivery_method) ele_text += "for " + delivery_method + ". ";
4791    ele_text += '<span style="cursor:pointer; color:blue; text-decoration:underline;" onclick=checkAvailDateClick()>edit</span>';
4792    return ele_text;
4793  }
4794  function checkAvailDateClick(){
4795    cartShow();
4796    /* expand the date picker */
4797    setTimeout(calSetDateRange,100);
4798  }
4799  function checkAvailPageOnly(){
4800    checkAvailFilter();
4801    if(addressCookiesSet() && io_distance_charge){
4802      runDeliveryCall(true);
4803    }
4804  }
4805  function getAccIDforPrice(){
4806    let accessory_arr = jQuery(".io_acc_li").toArray();
4807    let acc_rental_id_str = "";
4808    for(let current_accessory = 0; current_accessory < accessory_arr.length; current_accessory++){
4809      let required_tag = jQuery(accessory_arr[current_accessory]).find(".item_required");
4810      if(required_tag.length > 0){
4811        if(required_tag[0].innerText == 0){
4812          acc_rental_id_str += jQuery(accessory_arr[current_accessory]).find(".item_rentalid")[0].innerText +"|";
4813        }
4814      }
4815    }
4816    return acc_rental_id_str;
4817  }
4818  function getUpsellIDforPrice(){
4819    let upsell_arr = jQuery(".page-carousel-rid").toArray();
4820    let upsell_rental_id_str = "";
4821    for(let current_upsell = 0; current_upsell < upsell_arr.length; current_upsell++){
4822      upsell_rental_id_str +=upsell_arr[current_upsell].innerText+"|";
4823    }
4824    return upsell_rental_id_str;
4825  }
4826  function displayUpsellPrices(data){
4827    if(data.price){
4828      let upsell_prices = data.price;
4829      for (const [key, value] of Object.entries(upsell_prices)) {
4830        if(io_hide_zero == 1 && value > 0){
4831          let id_string = "#rid"+ key;
4832          let formatted_price = simpleCart.toCurrency(value);
4833          let price_display ='<span class="page-carousel-price"> '+formatted_price+' </span>';
4834          jQuery(id_string).after(price_display);
4835        }else if(io_hide_zero == 0){
4836          let id_string = "#rid"+ key;
4837          let formatted_price = simpleCart.toCurrency(value);
4838          let price_display ='<span class="page-carousel-price"> '+formatted_price+' </span>';
4839          jQuery(id_string).after(price_display);
4840        }
4841      }
4842      pageFlickityRefresh();
4843    }
4844  }
4845  /*</editor-fold>*/
4846
4847  /*<editor-fold defaultstate="collapsed" desc="Check Avail - Cart">*/
4848  function checkAvailCartOnly(skip_timer=false){
4849    checkAvailCart();
4850    checkAvailCartTimeslots();
4851  }
4852
4853  function checkAvailCartTimeslots(){
4854    let rental_names = "";
4855    let rental_ids = "";
4856    let cart_rental_names = "";
4857    let cart_rental_ids = "";
4858    let times = getAvailTimes();
4859    let start_date = times[0];
4860    let event_duration = times[2];
4861    let end_date = start_date;
4862    var event_start_time = getCookie("io_timeStart");
4863    simpleCart.each(function (item, x) {
4864      var timeslots_html = item.get('timeslots');
4865      if(typeof timeslots_html == "undefined") return;
4866      if(timeslots_html.length == 0) return;
4867      var cart_name = item.get("encoded");
4868      if(cart_name==null) {
4869        cart_name = encodeURIComponent(item.get("name"));
4870        cart_name = encodeURIComponent(decodeURIComponent(cart_name).replace(/[\u2032\u2019]+/ig,"'"));
4871      }
4872      rental_id = item.get("rentalid");
4873
4874      var timeslot_name = getTimeslotName(timeslots_html);
4875      var timeslot_sel_range = jQuery(".item-timeslots [name=\""+timeslot_name+"\"] option:selected").val();
4876      if(typeof timeslot_sel_range != "undefined"){
4877        /* timeslots */
4878        setTimeslotSelected(item, timeslot_name);
4879      }else{
4880        /*  timepickers */
4881        setTimePicker(item, timeslot_name);
4882        let start_timepicker = document.getElementsByName(timeslot_name.replace("io_timepicker_", "start_timeslot_"));
4883        let end_timepicker = document.getElementsByName(timeslot_name.replace("io_timepicker_", "end_timeslot_"));
4884        timeslot_sel_range = start_timepicker[start_timepicker.length-1].value;
4885        timeslot_sel_range += " - " + end_timepicker[end_timepicker.length-1].value;
4886      }
4887
4888      var timeslot_sel_arr = "";
4889      if(typeof timeslot_sel_range != "undefined"){
4890        var [start_time, end_time] = break_timeslot_sel_range(timeslot_sel_range);
4891        if(start_time && end_time){
4892          let newDate1 = convertDateStringtoDateObject(start_date, start_time);
4893          let newDate2 = convertDateStringtoDateObject(end_date, end_time);
4894          let time_duration = ((newDate2 - newDate1) / 3600) / 1000;
4895          let quantity = item.get("quantity");
4896          if(item.get("inputtype") == "Map"){
4897            quantity = 1
4898          }
4899          rental_names += cart_name + "-" + quantity+"|";
4900          rental_ids += rental_id+"-"+quantity+"-"+start_time+"-"+time_duration+"|";
4901          cart_rental_names = rental_names;
4902          cart_rental_ids = rental_ids;
4903        }
4904      }
4905    });
4906    if(rental_ids || rental_names){
4907      checkAvailCall(start_date,event_start_time,event_duration,rental_names,rental_ids,updateCartAvail,1,cart_rental_ids,cart_rental_names,1);
4908    }
4909    return true;
4910  }
4911
4912  function checkAvailCart(){
4913    let rental_names = "";
4914    let rental_ids = "";
4915    let cart_rental_names = "";
4916    let cart_rental_ids = "";
4917    simpleCart.each(function (item, x) {
4918      if(typeof item.get('timeslots') != "undefined"){
4919        if(item.get('timeslots').length > 0){
4920          return;
4921        }
4922      }
4923      var cart_name = item.get("encoded");
4924      if(cart_name==null){
4925        cart_name = encodeURIComponent(item.get("name"));
4926        cart_name = encodeURIComponent(decodeURIComponent(cart_name).replace(/[\u2032\u2019]+/ig,"'"));
4927      }
4928      let quantity = item.get("quantity");
4929      if(item.get("inputtype") == "Map"){
4930        quantity = 1
4931      }
4932      rental_names += cart_name + "-" + quantity + "|";
4933      cart_rental_names += cart_name + "-" + quantity + "|";
4934      var cart_id = item.get("rentalid");
4935      rental_ids += cart_id + "-" + quantity + "|";
4936      cart_rental_ids += cart_id + "-" + quantity + "|";
4937    });
4938    var times = getAvailTimes();
4939    let return_id = 0;
4940    if(rental_ids != ""){
4941      return_id = 1;
4942    }
4943    if(rental_ids != "" || rental_names != ""){
4944      return checkAvailCall(times[0],times[1],times[2],rental_names,rental_ids,updateCartAvail,1,cart_rental_ids,cart_rental_names,return_id);
4945    }
4946    return true;
4947  }
4948  function updateCartAvail(data){
4949    let use_id = data["return_id"]
4950    delete data["return_id"];
4951    if(use_id == 1){
4952      updateCartAvail_itemIDs(data)
4953    }else{
4954      updateCartAvail_itemNames(data);
4955    }
4956    console.log("cart update");
4957    if(addressCookiesSet() && io_distance_charge){
4958      runDeliveryCall(true);
4959    }
4960    /* simpleCart.trigger("update"); */
4961    simpleCart.update();
4962    /* jQuery("#avail").html(output); */
4963  }
4964
4965  function updateCartAvail_itemIDs(data){
4966    jQuery.each(data, function (rental_id, qty){
4967      simpleCart.each(function (item, x) {
4968        if(rental_id == item.get("rentalid")){
4969          if(io_hideQuantityAvail == "off"){
4970            if(qty>=9999 || item.get("inputtype") == "Map" || (item.get("giftcardvalue") && item.get("giftcardvalue").trim())){
4971              item.set("availability", "available");
4972            }else{
4973              item.set("availability", qty + " available");
4974            }
4975          }else if(io_hideQuantityAvail == "on"){
4976            if(qty<=0 || qty < item.get("quantity")){
4977              item.set("availability", "not available");
4978            }else{
4979              item.set("availability", "available");
4980            }
4981          }
4982          var vendorid = item.get("vendorid");
4983          if(vendorid && vendorid.trim()){
4984            item.set("availability", "availability must be verified");
4985          }
4986        }
4987        if (rental_id == "price") {
4988          var prices = qty;
4989          jQuery.each(prices, function (price_name, amt) {
4990            if(price_name == item.get("rentalid")){
4991              if (typeof amt == "string" || amt instanceof String){
4992                if(amt != "TBD"){
4993                  if(typeof amt == "string") amt = Number(amt.replace(",",""));
4994                }
4995              }
4996              item.set("price", amt);
4997            }
4998          });
4999        }
5000      });
5001    });
5002  }
5003
5004  function updateCartAvail_itemNames(data){
5005    jQuery.each(data, function (rental_name, qty) {
5006      rental_name = rental_name.replace(/[\u2032\u2019]+/ig,"'");
5007      simpleCart.each(function (item, x) {
5008        try{
5009          var cart_name = decodeURIComponent(item.get("encoded").replace(/[+]/gi, "%20"));
5010        }catch(e){cart_name=null}
5011        if(cart_name==null) cart_name = item.get("name")
5012        cart_name = cart_name.replace(/[\u2032\u2019]+/ig,"'");
5013        var i = cart_name.lastIndexOf(":");
5014        if(i>0 && cart_name.toUpperCase() != rental_name.toUpperCase() && rental_name!="price"){cart_name = cart_name.substring(i+1)}
5015        if (cart_name.toUpperCase() == rental_name.toUpperCase()) {
5016          if(qty>9999){
5017            item.set("availability", "available");
5018          }else{
5019            item.set("availability", qty + " available");
5020          }
5021        }
5022        if (rental_name == "price") {
5023          var prices = qty;
5024          jQuery.each(prices, function (price_name, amt) {
5025            price_name = price_name.replace(/[\u2032\u2019]+/ig,"'");
5026            let acc_name = "";
5027            let rental_name = "";
5028            var i = cart_name.lastIndexOf(":");
5029            if(i>0){
5030              rental_name = cart_name.substring(0, i);
5031              acc_name = cart_name.substring(i+1);
5032            }
5033            if (acc_name === price_name) {
5034              var rental_id = item.get("rentalid");
5035              if(rental_id != null){
5036                rid_arr = rental_id.split(":");
5037                /* ignore the main id for this */
5038                rental_id = rid_arr[rid_arr.length-1];
5039                if(jQuery("#io_acc_overrideprice_"+rental_id).first().text()>0){
5040                  amt = prices[acc_name];
5041                }else{
5042                  let item_price = Number(prices[rental_name].replace(",",""));
5043                  amt = Number(amt.replace(",","")) + item_price;
5044                  item.set("price", amt);
5045                  return;
5046                }
5047              }
5048              if(amt==null){
5049                amt = "0";
5050              }
5051              /* returned price is per unit */
5052              if(typeof amt == "string") amt = Number(amt.replace(",",""));
5053              item.set("price", amt);
5054            }else if(!rental_name && !acc_name){
5055              amt = Number(prices[cart_name].replace(",",""));
5056              item.set("price", amt);
5057            }
5058          });
5059        }
5060      });
5061    });
5062  }
5063  /*</editor-fold>*/
5064
5065  /*<editor-fold defaultstate="collapsed" desc="Upsell Carousels">*/
5066  function updateCartUpsell(data){
5067    let cart_carousel = jQuery(".cart-carousel");
5068    viewport = jQuery(".cart-carousel .flickity-viewport");
5069    if(viewport.length > 0){
5070      cart_carousel.flickity("destroy");
5071    }
5072    cart_carousel.empty();
5073    data.forEach(function(upsell){
5074      cell = createCartCarouselCell(upsell["image"], upsell["name"], upsell["page"]);
5075      cart_carousel.append(cell);
5076    });
5077    makeCarousel(cart_carousel);
5078    jQuery("#cart-carousel-container").show();
5079    setTimeout(cartFlickityRefresh, 500);
5080  }
5081
5082  function cartFlickityRefresh(){
5083    jQuery(".cart-carousel").flickity("resize");
5084  }
5085
5086  //IO-14031
5087  function isMobile()
5088  {
5089  // Modern detection
5090    if (navigator.userAgentData && navigator.userAgentData.mobile !== undefined) {
5091      return navigator.userAgentData.mobile;
5092    }
5093
5094  // Fallback for older browsers
5095    return /Mobi|Android|iPhone|iPad|iPod/i.test(navigator.userAgent) ||
5096           ('ontouchstart' in window && navigator.maxTouchPoints > 0);
5097  }
5098
5099  function makeCarousel(cart_carousel)
5100  {
5101    cart_carousel.flickity({
5102      wrapAround: true,
5103      draggable: isMobile(),
5104      cellAlign: 'left',
5105      //autoPlay: 3000,
5106      groupCells: true,
5107      resize: true
5108    });
5109    cart_carousel_set = true;
5110  }
5111
5112  function createCartCarouselCell(image, name, page){
5113    cell = '<div class="io_cart_carousel_cell"> <a href='+page+' class="cart-carousel-link"> <img class="cart-carousel-image" src='+image+'> <p class="cart-carousel-name"> '+name+' </p> </a> </div>';
5114    return cell;
5115  }
5116  /*</editor-fold>*/
5117
5118  /*<editor-fold defaultstate="collapsed" desc="Ajax Calls">*/
5119  function checkAvailCall(start_date,start_time,time_duration,rental_names,rental_ids,returnFunc,singleCart,cart_rental_ids,cart_rental_names,return_id,temp=0,delivery_method=null,price_only=0,custom_price_name="", skip_hidden_lead = 0) {
5120        /*
5121        IO-21459 If we have no duration set (event not set in cart), and we are doing the call for the page live
5122        price, and we have the setting on where we want to display this price even if the event date is not set:
5123
5124        We set the time_duration to 1 hour. This defaults the start date to January 1, 1970 with duration of
5125        1 hour in the lead meaning it will be available and we have the one hour price.
5126        */
5127    if((isNaN(time_duration) || time_duration===0) && price_only==1 && io_always_display_live_price == "on"){
5128      time_duration = 1;
5129      if(!start_date){
5130        start_date = getFormatteddate(new Date());
5131      }
5132      if(!start_time){
5133        start_time = getFormattedtime(new Date());
5134      }
5135    }else if((isNaN(time_duration) || time_duration===0) && price_only==0 && io_hidetimes === "on"){
5136      /* IO-22689 if they have times hidden, and happen to have the same default start and end time, we still want to do the call. */
5137      time_duration = 1;
5138    }else if(isNaN(time_duration) || time_duration===0){
5139      return;
5140    }
5141    url = "https://rental.software/quotes/check_availability_v2.php?callback=?";
5142    if(window.location.href.indexOf("localhost") > -1){
5143      //url = "http://localhost/bugs/quotes/check_availability_v2.php?callback=?";
5144      url = "http://localhost/io/bugs/quotes/check_availability_v2.php?callback=?";
5145      //url = "http://localhost/jbug/trunk/quotes/check_availability_v2.php?callback=?";
5146    }
5147    if(!delivery_method) delivery_method = getCookie("io_delivery_method");
5148    let address_data = {
5149      "address": getCookie("io_address"),
5150      "state": getCookie("io_state"),
5151      "city": getCookie("io_city"),
5152      "zip": getCookie("io_zip")
5153    };
5154    if(!ioHasMarketingConsent()){
5155      address_data = {"address":"", "state":"", "city":"", "zip":""};
5156    }
5157    url +=
5158            "&name=" + encodeURIComponent("Inflatable Event Professionals LLC") +
5159            "&startdate=" + start_date +
5160            "&starttime=" + start_time +
5161            "&duration=" + time_duration +
5162            "&street=" + encodeURIComponent(address_data["address"]) +
5163            "&city=" + encodeURIComponent(address_data["city"]) +
5164            "&state=" + encodeURIComponent(address_data["state"]) +
5165            "&zip=" + encodeURIComponent(address_data["zip"]) +
5166            "&single_cart=" + singleCart +
5167            "&usecushion=1" +
5168            "&include_price=1" +
5169            "&showlocations=0" +
5170            "&rental_names=" + rental_names +
5171            "&rental_ids=" + rental_ids +
5172            "&cart_rental_names=" + cart_rental_names +
5173            "&cart_rental_ids=" + cart_rental_ids +
5174            "&return_id=" + return_id +
5175            "&delivery_method=" + delivery_method +
5176            "&temp=" + temp +
5177            "&skip_hidden_lead="+ skip_hidden_lead;
5178      if (custom_price_name)
5179      {
5180          ioCartLoaderIncrement();
5181          jQuery.getJSON(url, function (data)
5182          {
5183              try
5184              {
5185                  returnFunc(data, custom_price_name);
5186              }
5187              finally
5188              {
5189                  ioCartLoaderDecrement();
5190              }
5191          });
5192      }
5193      else
5194      {
5195          ioCartLoaderIncrement();
5196          jQuery.getJSON(url, function (data)
5197          {
5198              try
5199              {
5200                  returnFunc(data);
5201              }
5202              finally
5203              {
5204                  ioCartLoaderDecrement();
5205              }
5206          });
5207      }
5208  }
5209
5210  function getUpsellsCall(start_date,start_time,time_duration,rental_ids,returnFunc) {
5211    if(rental_ids.replace(/[|]/g,"").length==0){return;}
5212    url = "https://rental.software/quotes/in_cart_upsell.php?callback=?";
5213    if(window.location.href.indexOf("localhost") > -1){
5214      //url = "http://localhost/bugs/quotes/in_cart_upsell.php?callback=?"
5215      url = "http://localhost/io/bugs/quotes/in_cart_upsell.php?callback=?"
5216    }
5217    url +=
5218            "&name=" + encodeURIComponent("Inflatable Event Professionals LLC") +
5219            "&startdate=" + start_date +
5220            "&starttime=" + start_time +
5221            "&duration=" + time_duration +
5222            "&usecushion=1" +
5223            "&include_price=1" +
5224            "&showlocations=0" +
5225            "&rental_ids=" + rental_ids;
5226    //IO-25557
5227    if(window.location.href.indexOf("dev.rental.software") > -1)//if it is a dev site, we need to send
5228    {
5229      let pattern = /(https:\/\/dev\.rental\.software\/[^\/]+\/)/;
5230      let matches = window.location.href.match(pattern);
5231      matches && matches.length > 0 ? url += "&site=" + matches[0]:0;
5232    }
5233    else
5234    {
5235      url += "&site=" + window.location.host;
5236    }
5237    jQuery.getJSON(url, returnFunc);
5238  }
5239  /*</editor-fold>*/
5240
5241  /*<editor-fold defaultstate="collapsed" desc="Customer Geolocation Functions">*/
5242  function setLocationInLocalStorage(city)
5243  {
5244      try
5245      {
5246          const location_data =
5247          {
5248              city: city,
5249              timestamp: Date.now()
5250          };
5251          localStorage.setItem(storage_key, JSON.stringify(location_data));
5252          return true;
5253      }
5254      catch (e)
5255      {
5256          console.warn('Failed to save location to localStorage:', e);
5257          return false;
5258      }
5259  }
5260
5261  function getLocationFromLocalStorage()
5262  {
5263      try
5264      {
5265          const location_data = localStorage.getItem(storage_key);
5266          if (location_data)
5267          {
5268              return JSON.parse(location_data);
5269          }
5270
5271      }
5272      catch (e)
5273      {
5274          console.warn('Failed to retrieve location from localStorage:', e);
5275      }
5276      return null;
5277  }
5278
5279  function displayLocation(city)
5280  {
5281      const location_element = jQuery('.io_geo_city');
5282      const container_element = jQuery('#io_customer_geolocation');
5283
5284      if (location_element.length && container_element.length)
5285      {
5286          location_element.text(`${city}`);
5287          container_element.show();
5288          return true;
5289      }
5290      return false;
5291  }
5292
5293  function getCityFromIO(returnFunc)
5294  {
5295    var url = "https://rental.software/include/geolocation_handler.php?callback=?";
5296    if(window.location.href.indexOf("localhost") > -1)
5297    {
5298      url = "http://localhost//features//include/geolocation_handler.php?callback=?";
5299    }
5300    url +=
5301        "&name=" + encodeURIComponent("Inflatable Event Professionals LLC") +
5302        "&ip=" + encodeURIComponent(io_customer_ip);
5303
5304    jQuery.getJSON(url, returnFunc);
5305  }
5306
5307  function initializeGeolocation()
5308  {
5309      try
5310      {
5311      // Check local storage first
5312          const cached_location = getLocationFromLocalStorage();
5313          if (cached_location && cached_location.city)
5314          {
5315              if (displayLocation(cached_location.city))
5316              {
5317                  return;
5318              }
5319          }
5320
5321          // If no cached location, call the handler to get location
5322          getCityFromIO(function(location_data)
5323          {
5324              if (location_data && location_data.city && !location_data.error)
5325              {
5326                  // Display and store the location
5327                  if (displayLocation(location_data.city))
5328                  {
5329                      setLocationInLocalStorage(location_data.city);
5330                  }
5331              }
5332              else
5333              {
5334                  console.warn('Failed to get location:', location_data ? location_data.error : 'Unknown error');
5335              }
5336          });
5337      } 
5338      catch (error)
5339      {
5340          console.error('Geolocation initialization failed:', error);
5341      }
5342  }
5343  /*</editor-fold>*/
5344
5345  /*<editor-fold defaultstate="collapsed" desc="Loading Animation Helpers">*/
5346
5347  /**
5348  * Toggles the visibility of the cart loading overlay.
5349  *
5350  * @param {boolean} show - A boolean value to determine whether to show or hide the overlay.
5351  *                         If true, the overlay becomes visible; if false, it is hidden.
5352  * @return {void} This function does not return a value.
5353  */
5354  function ioCartShowOverlay(show)
5355  {
5356      try
5357      {
5358          var overlay = document.getElementById('ioCartLoadingOverlay');
5359          if (!overlay) return;
5360          if (show)
5361          {
5362              overlay.style.display = 'flex';
5363              overlay.setAttribute('aria-hidden', 'false');
5364          }
5365          else
5366          {
5367              overlay.style.display = 'none';
5368              overlay.setAttribute('aria-hidden', 'true');
5369          }
5370      }
5371      catch (e)
5372      {}
5373  }
5374
5375  /**
5376   * Activates the cart loader by setting the loading state to active, initializing the loading count,
5377   * and displaying the overlay. Includes a fallback to deactivate the loader if no response is received
5378   * within a specified timeout period.
5379   *
5380   * @return {void} This method does not return a value.
5381   */
5382  function ioCartLoaderActivate()
5383  {
5384      io_cart_loading_active = true;
5385      io_cart_loading_count = 0;
5386      ioCartShowOverlay(true);
5387
5388      //fallback in case the availability call doesn't come back
5389      if (io_cart_loading_fallback_timer) clearTimeout(io_cart_loading_fallback_timer);
5390      io_cart_loading_fallback_timer = setTimeout(function () {
5391          if (io_cart_loading_active) {
5392              io_cart_loading_active = false;
5393              io_cart_loading_count = 0;
5394              ioCartShowOverlay(false);
5395          }
5396      }, 15000);
5397  }
5398
5399  /**
5400   * Increments the count of active cart loading operations and ensures the cart overlay is displayed.
5401   *
5402   * This method increases the `io_cart_loading_count` if the `io_cart_loading_active` flag is set to true.
5403   * It also calls the `ioCartShowOverlay` function with a true value to show the overlay.
5404   *
5405   * @return {void} This function does not return any value.
5406   */
5407  function ioCartLoaderIncrement()
5408  {
5409      if (io_cart_loading_active)
5410      {
5411          io_cart_loading_count++;
5412          ioCartShowOverlay(true);
5413      }
5414  }
5415
5416  /**
5417   * Decrements the `io_cart_loading_count` if `io_cart_loading_active` is true.
5418   * If the count reaches zero, it deactivates the loader, removes the overlay,
5419   * and clears the fallback timer
5420   */
5421  function ioCartLoaderDecrement()
5422  {
5423      if (io_cart_loading_active)
5424      {
5425          io_cart_loading_count = Math.max(0, io_cart_loading_count - 1);
5426
5427          if (io_cart_loading_count === 0)
5428          {
5429              io_cart_loading_active = false;
5430              ioCartShowOverlay(false);
5431
5432              if (io_cart_loading_fallback_timer)
5433              {
5434                  clearTimeout(io_cart_loading_fallback_timer);
5435                  io_cart_loading_fallback_timer = null;
5436              }
5437          }
5438      }
5439  }
5440
5441  /*</editor-fold>*/</script>
5441 <div class="address_entry elementor-widget-text-editor"><table><tr><td> <label for="address" id="io_cdl_address_label" style="display: table-cell"> Street Address </label></td><td> <input id="io_cd_address" style="display: table-cell" name="address" type="text"></input></td></tr><tr><td> <label for="city" id="io_cdl_city_label" style="display: table-cell"> City </label></td><td> <input id="io_cd_city" style="display: table-cell" name="city" type="text"></input></td></tr><tr id="us-state-select"><td> <label for="state" id="io_cdl_state_label" style="display: table-cell"> State </label></td><td> <select name="state" id="io_cd_state" style="display: table-cell" class="input-mini"><option value=""></option><option value="AK">AK</option><option value="AL">AL</option><option value="AR">AR</option><option value="AZ">AZ</option><option value="CA">CA</option><option value="CO">CO</option><option value="CT">CT</option><option value="DC">DC</option><option value="DE">DE</option><option value="FL">FL</option><option value="GA">GA</option><option value="HI">HI</option><option value="IA">IA</option><option value="ID">ID</option><option value="IL">IL</option><option value="IN">IN</option><option value="KS">KS</option><option value="KY">KY</option><option value="LA">LA</option><option value="MA">MA</option><option value="MD">MD</option><option value="ME">ME</option><option value="MI">MI</option><option value="MN">MN</option><option value="MO">MO</option><option value="MS">MS</option><option value="MT">MT</option><option value="NC">NC</option><option value="ND">ND</option><option value="NE">NE</option><option value="NH">NH</option><option value="NJ">NJ</option><option value="NM">NM</option><option value="NV">NV</option><option value="NY">NY</option><option value="OH">OH</option><option value="OK">OK</option><option value="OR">OR</option><option value="PA">PA</option><option value="RI">RI</option><option value="SC">SC</option><option value="SD">SD</option><option value="TN">TN</option><option value="TX">TX</option><option value="UT">UT</option><option value="VA">VA</option><option value="VT">VT</option><option value="WA">WA</option><option value="WI">WI</option><option value="WV">WV</option><option value="WY">WY</option> </select></td></tr><tr><td> <label for="zip" id="io_cdl_zip_label" style="display: table-cell"> Zip Code </label></td><td> <input id="io_cd_zip" style="display: table-cell" name="zip" type="text"></input></td></tr></table> <a class="elementor-button elementor-size-sm io_button"
5442 id="address_entry_submit"
5443 href="javascript:;"> Save Address </a><div id="delivery_charge_info_box"><hr><h3 id="info_box_header"></h3><p id="info_box_information"></p> <a href="javascript:;" onClick="closeAddressEntry()" class="delivery_info_continue elementor-button elementor-size-sm io_button">Continue Shopping</a></div></div> 
5443<script>/* for checking delivery */
5444  function runDeliveryCall(cart_only = false){
5445    let address_fields = jQuery("[id^='io_cd_']");
5446    let address_data = {
5447      "address": getCookie("io_address"),
5448      "state": getCookie("io_state"),
5449      "city": getCookie("io_city"),
5450      "zip": getCookie("io_zip")
5451    };
5452
5453    let times = getAvailTimes();
5454
5455    let start_date = times[0];
5456    let end_date = start_date;
5457    let start_time = times[1];
5458    let duration = times[2];
5459
5460    let rental_ids = "";
5461    simpleCart.each(function (item, x) {
5462      if(typeof item.get('timeslots') != "undefined"){
5463        if(item.get('timeslots').length > 0){
5464        var timeslots_html = item.get('timeslots');
5465        var rental_id = item.get('rentalid');
5466        if(typeof timeslots_html == "undefined") return;
5467        if(timeslots_html.length == 0) return;
5468
5469        var timeslot_name = getTimeslotName(timeslots_html);
5470        var timeslot_sel_range = jQuery(".item-timeslots [name=\""+timeslot_name+"\"] option:selected").val();
5471        if(typeof timeslot_sel_range != "undefined"){
5472          /* timeslots */
5473          setTimeslotSelected(item, timeslot_name);
5474        }else{
5475          /*  timepickers */
5476          setTimePicker(item, timeslot_name);//todo?
5477          let start_timepicker = document.getElementsByName(timeslot_name.replace("io_timepicker_", "start_timeslot_"));
5478          let end_timepicker = document.getElementsByName(timeslot_name.replace("io_timepicker_", "end_timeslot_"));
5479          timeslot_sel_range = start_timepicker[start_timepicker.length-1].value;
5480          timeslot_sel_range += " - " + end_timepicker[end_timepicker.length-1].value;
5481        }
5482
5483        var timeslot_sel_arr = "";
5484        if(typeof timeslot_sel_range != "undefined"){
5485          timeslot_sel_arr = timeslot_sel_range.split(" - ");
5486          var timeslot_start_time = timeslot_sel_arr[0].replace("am"," am").replace("pm"," pm").replace("  "," ");
5487          var timeslot_end_time = timeslot_sel_arr[1].replace("am"," am").replace("pm"," pm").replace("  "," ");
5488          if(timeslot_start_time && timeslot_end_time){
5489            let newDate1 = convertDateStringtoDateObject(start_date, timeslot_start_time);
5490            let newDate2 = convertDateStringtoDateObject(end_date, timeslot_end_time);
5491            let timeslot_duration = ((newDate2 - newDate1) / 3600) / 1000;
5492            rental_ids += rental_id+"-"+item.get("quantity")+"-"+timeslot_start_time+"-"+timeslot_duration+"|";
5493          }
5494        }
5495      }
5496    }
5497  else{
5498    var cart_id = item.get("rentalid");
5499    rental_ids += cart_id + "-" + item.get("quantity") + "|";
5500  }
5501  });
5502
5503  address_fields.each(function() {
5504    let field = this.id.split("_")[2];
5505    value = this.value;
5506    if(!value && !address_data[field]){
5507      jQuery(this).addClass("invalid_address_field")
5508    }
5509    else if(value){
5510      jQuery(this).removeClass("invalid_address_field")
5511      address_data[field] = this.value;
5512    }
5513  });
5514  if(jQuery(".invalid_address_field").length > 0){
5515    return;
5516  }
5517    let delivery_method = ""
5518    if(io_default_delivery_method)
5519    {
5520      delivery_method = io_default_delivery_method;
5521    }
5522    else if(getCookie("io_delivery_method"))
5523    {
5524      delivery_method = getCookie("io_delivery_method");
5525    }
5526
5527
5528  setCookie("io_address", address_data["address"], 14);
5529  setCookie("io_city", address_data["city"], 14);
5530  setCookie("io_state", address_data["state"], 14);
5531  setCookie("io_zip", address_data["zip"], 14);
5532
5533  cart_total = simpleCart.total();
5534  if(cart_total === "TBD") cart_total = 0;
5535  url = "https://rental.software/quotes/get_delivery_info.php?callback=?";
5536  if(window.location.href.indexOf("localhost") > -1){
5537    //url = "http://localhost/bugs/quotes/get_delivery_info.php?callback=?";
5538    url = "http://localhost/io/bugs/quotes/get_delivery_info.php?callback=?";
5539  }
5540  url +=
5541          "&name=" + encodeURIComponent("Inflatable Event Professionals LLC") +
5542          "&rental_ids=" + rental_ids +
5543          "&street=" + encodeURIComponent(address_data["address"]) +
5544          "&city=" + encodeURIComponent(address_data["city"]) +
5545          "&state=" + encodeURIComponent(address_data["state"]) +
5546          "&zip=" + encodeURIComponent(address_data["zip"]) +
5547          "&startdate=" + start_date +
5548          "&starttime=" + start_time +
5549          "&duration=" + duration +
5550          "&delivery_method=" + encodeURIComponent(delivery_method) +
5551          "&total=" + cart_total +
5552          "&cart_only=" + cart_only;
5553  jQuery.getJSON(url, function(data){
5554    if(data["delivery_restrict"] === 1){
5555      data["charge"] = 0;
5556    }
5557    handleDeliveryInfo(data, cart_only);
5558  });
5559  }
5560
5561  function handleDeliveryInfo(data, cart_only = false){
5562    jQuery("#deliverSubtotalContainer").show();
5563    jQuery("#checkDeliveryMessage").hide();
5564    let info_box = jQuery("#delivery_charge_info_box");
5565    if(data["delivery_restrict"] == 1){
5566      jQuery("#info_box_header").text("Sorry...");
5567      jQuery("#info_box_information").text(data["error"])
5568      setDeliverySubtotal(data["charge"], true)
5569    }
5570    else{
5571      setDeliverySubtotal(data["charge"])
5572      jQuery("#info_box_header").text("Success!");
5573      if(data["charge"] > 0){
5574        jQuery("#info_box_information").html("We are able to deliver to your location with a " + simpleCart.toCurrency(data["charge"]) +" fee!");
5575      }
5576      else{
5577        jQuery("#info_box_information").html("We are able to deliver to your location with no charge!");
5578      }
5579    }
5580    if(simpleCart.items().length == 0 && cart_only){
5581      jQuery("#info_box_header").text("Items Required.");
5582      jQuery("#info_box_information").html("There needs to be items in your cart to check for delivery fees. But we will save the address information so you don't have to enter it again!")
5583    }
5584    info_box.show();
5585    jQuery.fancybox.update(jQuery(".address_entry"));
5586  }
5587  function showAddressEntry(cart_only=false){
5588    cartHide();
5589    jQuery(".invalid_address_field").removeClass("invalid_address_field")
5590    jQuery("#delivery_charge_info_box").hide();
5591    jQuery("#io_cd_address").val(getCookie("io_address"));
5592    jQuery("#io_cd_state").val(getCookie("io_state"));
5593    jQuery("#io_cd_city").val(getCookie("io_city"));
5594    jQuery("#io_cd_zip").val(getCookie("io_zip"));
5595    if(!cart_only){
5596      jQuery("#address_entry_submit").on("click", null, function(){ runDeliveryCall(); });
5597    } else{
5598      jQuery("#address_entry_submit").on("click", null, function(){ runDeliveryCall(cart_only); });
5599    }
5600    jQuery.fancybox.open(jQuery(".address_entry"));
5601  }
5602
5603  function closeAddressEntry(){
5604    jQuery.fancybox.close();
5605  }
5606
5607  function setDeliverySubtotal(amount, unavailable=false){
5608    if(unavailable){
5609      jQuery("#deliverySubtotal").html("Unavailable");
5610    } else{
5611      jQuery("#deliverySubtotal").html(simpleCart.toCurrency(amount));
5612    }
5613  }
5614
5615  function addressCookiesSet(){
5616    if(getCookie("address") && getCookie("state") && getCookie("city") && getCookie("zip")){
5617      return true;
5618    } else{
5619      return false
5620    }
5621  }</script>
vendor: 1 bytes, line 5621
5621
5622<script>let map;
5623  let geocoder;
5624  let item_id_map;
5625  let drawingManager;
5626  let drawingListener;
5627
5628  let polygons = new Array();
5629
5630  let polyline_markers = new Array();
5631  let polylines = new Array();
5632  let previous_marker;
5633  current_polyline = undefined;
5634  let previous_map_height = "";
5635
5636  function initMap() {
5637    map = new google.maps.Map(document.getElementById("map_container"), {
5638      center: { lat: -34.397, lng: 150.644 },
5639      zoom: 8,
5640      mapTypeId: "hybrid",
5641      disableDefaultUI: true,
5642      tilt: 0
5643    });
5644    drawingManager = new google.maps.drawing.DrawingManager({
5645      drawingControl: true,
5646      drawingControlOptions: {
5647        position: google.maps.ControlPosition.TOP_CENTER,
5648        drawingModes: [
5649          google.maps.drawing.OverlayType.POLYGON,
5650        ],
5651      }
5652    });
5653
5654    geocoder = new google.maps.Geocoder();
5655  }
5656
5657  function io_geocode(){
5658    let prefix = "#io_mc_"
5659    let request = ""
5660    let address_value = "";
5661    if(jQuery(prefix+"address").length) {
5662      address_value = jQuery(prefix+"address").val();
5663      if(address_value) setCookie("address", jQuery("#io_mc_address").val(), 14);
5664    }
5665    let city_value = "";
5666    if(jQuery(prefix+"city").length){
5667      city_value = jQuery(prefix+"city").val();
5668      if(city_value) setCookie("city", jQuery("#io_mc_city").val(), 14);
5669    }
5670    let state_value = "";
5671    if(jQuery(prefix+"state").length){
5672      state_value = jQuery(prefix+"state").val();
5673      if(state_value) setCookie("state", jQuery("#io_mc_state").val(), 14);
5674    }
5675    let zip_value = "";
5676    if(jQuery(prefix+"zip").length){
5677      zip_value = jQuery(prefix+"zip").val();
5678      if(zip_value) setCookie("zip", jQuery("#io_mc_zip").val(), 14);
5679    }
5680
5681    request = address_value + " " + city_value + " " + state_value + " " + zip_value;
5682    if(request){
5683      geocoder.geocode({address:request}).then((result) => {
5684        const { results } = result;
5685        map.setCenter(results[0].geometry.location);
5686        map.setZoom(24);
5687        return results;
5688      });
5689
5690    }
5691
5692    if(!addressProvided()) {
5693      jQuery("#io_map_address_entry").attr("open", "open");
5694    }else{
5695      jQuery("#io_map_address_entry").removeAttr("open");
5696    }
5697  }
5698
5699  function openMap(element){
5700    cartHide()
5701    io_map_clear()
5702    let unit = "meters"
5703    if(country === "US") unit = "feet"
5704    polygons = new Array();
5705    polyline_marker_sets = new Array();
5706    polylines = new Array();
5707    previous_marker = undefined;
5708    current_polyline = undefined;
5709
5710    jQuery("#io_mc_address").val(getCookie("address"));
5711    jQuery("#io_mc_state").val(getCookie("state"));
5712    jQuery("#io_mc_city").val(getCookie("city"));
5713    jQuery("#io_mc_zip").val(getCookie("zip"));
5714    io_geocode();
5715
5716    google.maps.event.removeListener(drawingListener);
5717
5718    if(element.id == "calcPriceOpenMap"){
5719      item_id_map = jQuery(".io_product_infobox .item_rentalid").text();
5720      if(jQuery(".io_product_infobox .item_qtytype").text() == "Area"){
5721        setMapTools_Area(unit, true)
5722      }else if(jQuery(".io_product_infobox .item_qtytype").text() == "Perimeter"){
5723        setMapTools_Perimeter(unit, true)
5724      }
5725    }
5726    else{
5727      item_id_map = jQuery(element).parent().parent().find(".item-rentalid").text();
5728      if(jQuery(element).parent().parent().find(".item-qtytype").text() == "Area"){
5729        setMapTools_Area(unit)
5730      }else if(jQuery(element).parent().parent().find(".item-qtytype").text() == "Perimeter"){
5731        setMapTools_Perimeter(unit)
5732      }
5733    }
5734  }
5735
5736  function addressProvided(){
5737    if(jQuery("#io_mc_address").val() && jQuery("#io_mc_state").val() &&
5738            jQuery("#io_mc_city").val() && jQuery("#io_mc_zip").val() ){
5739      return true;
5740    }
5741    return false;
5742  }
5743
5744  function setMapTools_Area(unit, item_page=false){
5745    jQuery.fancybox.open(jQuery(".map_fancybox"));
5746    drawingManager.setOptions({
5747      drawingControlOptions: {
5748        drawingModes: [google.maps.drawing.OverlayType.POLYGON]
5749      },
5750      drawingMode: google.maps.drawing.OverlayType.POLYGON,
5751      polygonOptions: {
5752        fillColor: "#0191fc",
5753        strokeColor: "#0113fc"
5754      },
5755    });
5756    let units = "meters"
5757    if(country === "US") units = "feet"
5758
5759    jQuery("#io_measurement_input_label").text("Approximate area in "+units+": ");
5760    jQuery("#io_map_manual_input").off("click");
5761    jQuery("#io_map_manual_input").on("click", function(){manual_calc_price("Area", item_page)});
5762    jQuery("#io_perimeter_options_container").hide();
5763    jQuery("#io_map_new_line_container").hide();
5764    jQuery("#io_map_instructions").html("Use the map below to take measurements by clicking on each corner of the area y
5764ou want to measure. <span id=\"io_map_additional_instructions\">You can draw multiple polygons to include multiple separate surfaces in the total area. Press Clear to remove all polygons and start again. Alternatively if you know the approximate area in "+units+" you can enter the measurement manually below. When finished press Done and the price of the item will be updated </span><i id=\"io_show_more_instructions\" onClick=\"show_more_instruct_click(this)\">(more)</i>")
5765
5766    drawingListener = google.maps.event.addListener(drawingManager, "polygoncomplete", function(polygon) {
5767      polygons.push(polygon);
5768      let convert_feet = 1;
5769      if(country === "US") convert_feet = 10.764;
5770      let approx_area = 0;
5771      polygons.forEach(function(polygon) {
5772        approx_area += google.maps.geometry.spherical.computeArea(polygon.getPath()) * convert_feet;
5773      });
5774      calcprice_approx_area(Math.round(approx_area));
5775    });
5776    drawingManager.setMap(map);
5777  }
5778
5779  function setMapTools_Perimeter(unit, item_page=false){
5780    jQuery.fancybox.open(jQuery(".map_fancybox"));
5781    drawingManager.setOptions({
5782      drawingControlOptions: {
5783        drawingModes: [google.maps.drawing.OverlayType.MARKER]
5784      },
5785      drawingMode: google.maps.drawing.OverlayType.MARKER
5786    });
5787    let height = jQuery("#perimeter_height").val();
5788    let units = "";
5789    if(height){
5790      units = "sq meters"
5791      if(country === "US") units = "sq feet"
5792      jQuery("#io_measurement_input_label").text("Approximate surface area in "+units+": ");
5793      jQuery("#io_map_instructions").html("Use the map below to take measurements by clicking on each corner of the area you want to measure. <span id=\"io_map_additional_instructions\">You can add additional lines by clicking Add New Line button to include more structures into the total. Press Clear to remove all lines and start again. Alternatively if you know the approximate surface area in "+units+" you can enter the measurement manually below. When finished press Done and the price of the item will be updated </span><i id=\"io_show_more_instructions\" onClick=\"show_more_instruct_click(this)\">(more)</i>")
5794
5795    }else{
5796      units = "meters"
5797      if(country === "US") units = "feet"
5798      jQuery("#io_measurement_input_label").text("Approximate perimeter in "+units+": ");
5799      jQuery("#io_map_instructions").html("Use the map below to take measurements by clicking on each corner of the area you want to measure. <span id=\"io_map_additional_instructions\">You can add additional lines by clicking Add New Line button to include more structures into the total. Press Clear to remove all lines and start again. Alternatively if you know the approximate perimeter in "+units+" you can enter the measurement manually below. When finished press Done and the price of the item will be updated </span><i id=\"io_show_more_instructions\" onClick=\"show_more_instruct_click(this)\">(more)</i>")
5800
5801    }
5802
5803    jQuery("#io_map_manual_input").off("click");
5804    jQuery("#io_map_manual_input").bind("click", function(){manual_calc_price("Perimeter", item_page)});
5805    jQuery("#perimeter_height").bind("change", function(){change_perimeter_instructions()});
5806    jQuery("#io_perimeter_options_container").show();
5807    jQuery("#io_map_clear_container").show();
5808    jQuery("#io_map_new_line_container").show();
5809
5810    current_polyline = new google.maps.Polyline({
5811      map: map,
5812      path: [],
5813      strokeColor: "#0113fc",
5814      strokeOpacity: 1.0,
5815      strokeWeight: 2
5816    })
5817    drawingListener = google.maps.event.addListener(drawingManager, "markercomplete", function(marker) {
5818      polyline_markers.push(marker)
5819      marker.setVisible(false);
5820      current_polyline.getPath().push(marker.getPosition())
5821      if(previous_marker){
5822        let convert_feet = 1;
5823        if(country === "US") convert_feet = 3.281;
5824        let approx_perimeter = 0;
5825        polylines.forEach(function(polyline) {
5826          if(convert_feet > 1) convert_feet = 10.764
5827          approx_perimeter += google.maps.geometry.spherical.computeArea(polyline.getPath()) * convert_feet;
5828        });
5829        approx_perimeter += google.maps.geometry.spherical.computeLength(current_polyline.getPath()) * convert_feet;
5830        calcprice_approx_perimeter(Math.round(approx_perimeter));
5831      }
5832      previous_marker = marker;
5833    });
5834
5835    jQuery("#perimeter_height_contianer").show();
5836
5837    drawingManager.setMap(map);
5838  }
5839
5840  function change_perimeter_instructions(){
5841    let height = jQuery("#perimeter_height").val();
5842    if(height){
5843      units = "sq meters"
5844      if(country === "US") units = "sq feet"
5845      jQuery("#io_measurement_input_label").text("Approximate surface area in "+units+": ");
5846      jQuery("#io_map_instructions").html("Use the map below to take measurements by clicking on each corner of the area you want to measure. <span id=\"io_map_additional_instructions\">You can add additional lines by clicking Add New Line button to include more structures into the total. Press Clear to remove all lines and start again. Alternatively if you know the approximate surface area in "+units+" you can enter the measurement manually below. When finished press Done and the price of the item will be updated </span><i id=\"io_show_more_instructions\" onClick=\"show_more_instruct_click(this)\">(more)</i>")
5847    }else {
5848      units = "meters"
5849      if(country === "US") units = "feet"
5850      jQuery("#io_measurement_input_label").text("Approximate perimeter in "+units+": ");
5851      jQuery("#io_map_instructions").html("Use the map below to take measurements by clicking on each corner of the area you want to measure. <span id=\"io_map_additional_instructions\">You can add additional lines by clicking Add New Line button to include more structures into the total. Press Clear to remove all lines and start again. Alternatively if you know the approximate perimeter in "+units+" you can enter the measurement manually below. When finished press Done and the price of the item will be updated </span><i id=\"io_show_more_instructions\" onClick=\"show_more_instruct_click(this)\">(more)</i>")
5852    }
5853  }
5854
5855  function manual_calc_price(method, item_page){
5856    let approx_measurement = parseInt(jQuery("#io_measurement_input").val());
5857    let units = "";
5858    if(approx_measurement){
5859      if(method == "Area"){
5860        units = "sq meters"
5861        if(country === "US") units = "sq feet"
5862      }else if(method == "Perimeter"){
5863        let height = jQuery("#perimeter_height").val();
5864        if(height){
5865          units = "sq meters"
5866          if(country === "US") units = "sq feet"
5867        }else{
5868          units = "meters"
5869          if(country === "US") units = "feet"
5870        }
5871      }
5872      simpleCart.items().forEach(function (item, index){
5873        if(item.get("rentalid") === item_id_map){
5874          item.set("units", units);
5875          item.set("quantity", approx_measurement);
5876        }
5877      });
5878
5879      simpleCart.update();
5880
5881      if(item_page || jQuery(".io_product_infobox .item_rentalid").text() == item_id_map) set_price_on_item_page(units, approx_measurement);
5882      if(!item_page) cartShow();
5883    }
5884    jQuery.fancybox.close();
5885  }
5886
5887  function calcprice_approx_area(approx_area){
5888    jQuery("#io_measurement_input").val(approx_area);
5889  }
5890
5891  function calcprice_approx_perimeter(approx_perimeter){
5892    let height = jQuery("#perimeter_height").val();
5893    if(height && height > 0) approx_perimeter *= parseInt(height);
5894
5895    jQuery("#io_measurement_input").val(approx_perimeter);
5896  }
5897
5898  function set_price_on_item_page(units, measurement){
5899    let measurement_price = document.querySelector(".io_product_measurement_price");
5900    if(measurement_price==undefined){
5901      var first_price = document.querySelector(".io_product_price_box");
5902      if(first_price != null){
5903        measurement_price = first_price.cloneNode(true);
5904        /* clear all classes */
5905        measurement_price.className = "";
5906        measurement_price.classList.add("io_product_price_box");
5907        measurement_price.classList.add("io_product_measurement_price");
5908        measurement_price.style.display = "grid";
5909        /* Make a hidden data span for when adding to cart */
5910        raw_measurement = document.createElement("span");
5911        raw_measurement.classList.add("io_measure_price_raw_measurement");
5912        raw_measurement.style.display = "none";
5913        raw_measurement.textContent = measurement;
5914        measurement_price.appendChild(raw_measurement);
5915        first_price.before(measurement_price);
5916      }
5917    }
5918    var price_1h = Number(jQuery(".io_product_price_1h_"+jQuery(".io_product_infobox .item_rentalid").text()).text().replace(/[^0-9.-]+/g,""));
5919    measurement_price.querySelector("p:nth-child(1)").innerHTML = simpleCart.toCurrency(price_1h*measurement);
5920    measurement_price.querySelector("p:nth-child(2)").innerHTML = "For approximately "+measurement+" "+units;
5921  }
5922
5923  function io_map_clear() {
5924    if(drawingManager.getDrawingMode() == "polygon"){
5925      drawingManager.setDrawingMode("polygon");
5926    }
5927
5928    if(polygons) polygons.forEach(function(polygon) {
5929      polygon.setMap(null);
5930    });
5931    if(current_polyline) current_polyline.setMap(null);
5932    if(polylines) polylines.forEach(function(polyline) {
5933      polyline.setMap(null);
5934    });
5935    if(polyline_markers) polyline_markers.forEach(function(marker) {
5936      marker.setMap(null);
5937    });
5938
5939    current_polyline = new google.maps.Polyline({
5940      map: map,
5941      path: [],
5942      strokeColor: "#0113fc",
5943      strokeOpacity: 1.0,
5944      strokeWeight: 2
5945    });
5946    polygons = new Array();
5947    polylines = new Array();
5948    polyline_markers = new Array();
5949    previous_marker = undefined;
5950  }
5951
5952  function io_map_new_line() {
5953    polylines.push(new google.maps.Polyline({
5954              map: map,
5955              path: current_polyline.getPath(),
5956              strokeColor: "#0113fc",
5957              strokeOpacity: 1.0,
5958              strokeWeight: 2
5959            })
5960    );
5961    previous_marker = undefined;
5962    current_polyline.setMap(null);
5963    current_polyline = new google.maps.Polyline({
5964      map: map,
5965      path: [],
5966      strokeColor: "#0113fc",
5967      strokeOpacity: 1.0,
5968      strokeWeight: 2
5969    });
5970  }
5971
5972  function show_more_instruct_click(show_more_button) {
5973    if(show_more_button.textContent == "(more)") {
5974      show_more_button.textContent = "(hide)";
5975      jQuery("#io_map_additional_instructions").show();
5976    }else if(show_more_button.textContent == "(hide)") {
5977      show_more_button.textContent = "(more)";
5978      jQuery("#io_map_additional_instructions").hide();
5979    }
5980  }
5981
5982  function perimeter_height_changed(){
5983    let current_map_height = jQuery("#perimeter_height").val();
5984    if(current_map_height && current_map_height > 0){
5985      if(jQuery("#io_measurement_input").val() && !previous_map_height){
5986        let measurement = jQuery("#io_measurement_input").val();
5987        jQuery("#io_measurement_input").val(measurement * current_map_height);
5988      }else if(jQuery("#io_measurement_input").val() && previous_map_height){
5989        let measurement = jQuery("#io_measurement_input").val();
5990        if(previous_map_height > 0){
5991          measurement = measurement / previous_map_height;
5992        }
5993        jQuery("#io_measurement_input").val(measurement * current_map_height);
5994      }
5995    }else if (!current_map_height || current_map_height == 0){
5996      if(jQuery("#io_measurement_input").val() && previous_map_height){
5997        let measurement = jQuery("#io_measurement_input").val();
5998        if(previous_map_height > 0){
5999          measurement = measurement / previous_map_height;
6000        }
6001        jQuery("#io_measurement_input").val(measurement);
6002      }
6003    }
6004    previous_map_height = current_map_height;
6005  }
6006
6007  window.initMap = initMap;</script>
6007 <div class="map_fancybox"><div class="elementor-widget-text-editor"><div> <details id="io_map_address_entry"> <summary style = "cursor:pointer">Enter Address Information (edit)</summary><table style="margin-left: 10px"><tr><td> <label for="address" id="io_mcl_address_label" style="display: table-cell"> Street Address </label></td><td> <input id="io_mc_address" style="display: table-cell" name="address" type="text"></input></td></tr><tr><td> <label for="city" id="io_mcl_city_label" style="display: table-cell"> City </label></td><td> <input id="io_mc_city" style="display: table-cell" name="city" type="text"></input></td></tr><tr id="io_mc_us-state-select"><td> <label for="state" id="io_mcl_state_label" style="display: table-cell"> State </label></td><td> <select name="state" id="io_mc_state" style="display: table-cell" class="input-mini"><option value=""></option><option value="AK">AK</option><option value="AL">AL</option><option value="AR">AR</option><option value="AZ">AZ</option><option value="CA">CA</option><option value="CO">CO</option><option value="CT">CT</option><option value="DC">DC</option><option value="DE">DE</option><option value="FL">FL</option><option value="GA">GA</option><option value="HI">HI</option><option value="IA">IA</option><option value="ID">ID</option><option value="IL">IL</option><option value="IN">IN</option><option value="KS">KS</option><option value="KY">KY</option><option value="LA">LA</option><option value="MA">MA</option><option value="MD">MD</option><option value="ME">ME</option><option value="MI">MI</option><option value="MN">MN</option><option value="MO">MO</option><option value="MS">MS</option><option value="MT">MT</option><option value="NC">NC</option><option value="ND">ND</option><option value="NE">NE</option><option value="NH">NH</option><option value="NJ">NJ</option><option value="NM">NM</option><option value="NV">NV</option><option value="NY">NY</option><option value="OH">OH</option><option value="OK">OK</option><option value="OR">OR</option><option value="PA">PA</option><option value="RI">RI</option><option value="SC">SC</option><option value="SD">SD</option><option value="TN">TN</option><option value="TX">TX</option><option value="UT">UT</option><option value="VA">VA</option><option value="VT">VT</option><option value="WA">WA</option><option value="WI">WI</option><option value="WV">WV</option><option value="WY">WY</option> </select></td></tr><tr><td> <label for="zip" id="io_mcl_zip_label" style="display: table-cell"> Zip Code </label></td><td> <input id="io_mc_zip" style="display: table-cell" name="zip" type="text"></input></td></tr></table> <a class="elementor-button elementor-size-sm io_button"
6008 id="map_geocode_submit"
6009 onClick="io_geocode()"
6010 href="javascript:;"> Locate </a> </details><div id="perimeter_height_contianer"><p>If you are taking measurements for a structure such as a building or fence, please provide the height of the structure here. If height does not apply to the wash, for instance for a gutter wash, leave this field empty. <strong> Please note if you enter a value here after taking measurements, you will need to take measurements again. </strong></p> <label> Height of structure: </label> <input type="number" id="perimeter_height" onChange="perimeter_height_changed()"/></div><div><p id="io_map_instructions"></p></div><div id="io_measurement_input_container"> <label id="io_measurement_input_label"> </label> <input type="number" id="io_measurement_input"/> <a class="elementor-button elementor-size-sm io_button"
6011 id="io_map_manual_input"
6012 href="javascript:;"> Done </a></div><div style="display: inline-flex"><div id="io_map_clear_container"> <a class="elementor-button elementor-size-sm io_button"
6013 id="io_map_clear_btn"
6014 onClick="io_map_clear()"
6015 href="javascript:;"> Clear </a></div><div id="io_map_new_line_container" style="margin-left:5px"> <a class="elementor-button elementor-size-sm io_button"
6016 id="io_map_new_line_btn"
6017 onClick="io_map_new_line()"
6018 href="javascript:;"> Add New Line </a></div></div></div></div> <br><div id="map_container"> 
6018<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyDEuvvqefKaUABPvydm00SV8Fr8tQeGVcw&libraries=drawing&callback=initMap" defer></script>
6018 </div></div>  
6018<script>jQuery(".io_testimonials, #io_testimonials").each(function(){
6019           io_get_reviews(this);
6020        })
6021        setTimeout(function(){
6022            jQuery(".io_testimonials .w3-ul li p").each(function(){
6023                const container = jQuery(this).parent()
6024                const element = jQuery(this);
6025
6026                if (element[0].scrollHeight > container[0].clientHeight) {
6027
6028                    jQuery(this).parent().parent().append(create_read_more());
6029                }
6030            });
6031        }, 500);
6032
6033        function create_read_more(){
6034            let html = "<p class=\"io_review_readmore\" onClick=\"review_readmore_clicked(this)\">read more</p>"
6035            return html;
6036        }
6037
6038        function review_readmore_clicked(element){
6039            let review_li = jQuery(element).parent().find("li:eq(3)");
6040            new_height = jQuery(review_li).find("p").height() + 16;
6041            jQuery(review_li).height(new_height);
6042            jQuery(element).hide();
6043        }
6044
6045        function io_get_reviews(element){
6046        let io_un = "FunwithIEP";
6047	  let io_loc = "41379";
6048	  let io_url1 = 'https://rental.software/testimonials_iframe.php?user=';
6049	  if (location.hostname === "localhost"){
6050	      io_url1 = 'http://localhost/io/bugs/testimonials_iframe.php?user=';
6051          //io_url1 = 'http://localhost/jbug/trunk/testimonials_iframe.php?user=';
6052        }
6053	  let io_url2 = '&location_id=';
6054	  let io_url3 = '&width=100%&number_of_reviews=15&show_average_rating=1&show_stars=1&show_date=&show_reviewer_name=1&orderby=time&iframe=0';
6055	  let io_url_c = io_url1 + io_un + io_url2 + io_loc + io_url3;
6056	  fetch(io_url_c, {
6057		method: 'get'
6058	}).then(
6059	  function(response){
6060		 return response.json();
6061		}
6062	).then(function(data) {
6063
6064
6065
6066	//let element = document.getElementById("io_testimonials");
6067	//DOM-built on purpose: literal markup in this inline script lands in the raw page
6068	//source and SEO crawlers read it as page content (IO-37932).
6069	element.textContent = "";
6070	let review_cnt=0;
6071	let rating_sum = 0;
6072	data.forEach((user) => {
6073				const { name, review, rating, time } = user;
6074				rating_sum += Number(rating);
6075				review_cnt++;
6076				let review_div = document.createElement("div");
6077				let review_list = document.createElement("ul");
6078				review_list.className = "w3-ul";
6079				let name_li = document.createElement("li");
6080				name_li.textContent = name;
6081				let rating_li = document.createElement("li");
6082				rating_li.textContent = rating + " ";
6083				let date_li = document.createElement("li");
6084				date_li.textContent = time;
6085				let review_li = document.createElement("li");
6086				let review_p = document.createElement("p");
6087				review_p.textContent = review;
6088				review_li.appendChild(review_p);
6089				let img_star = Math.round(parseFloat(rating));
6090				let star_img = document.createElement("img");
6091				star_img.className = "review_img";
6092				star_img.src = "https://rental.software/images/" + img_star + "star.png";
6093				rating_li.appendChild(star_img);
6094				review_list.appendChild(name_li);
6095				review_list.appendChild(rating_li);
6096				review_list.appendChild(date_li);
6097				review_list.appendChild(review_li);
6098				review_div.appendChild(review_list);
6099				element.appendChild(review_div);
6100	});
6101	let avg = (parseFloat(rating_sum)/parseFloat(review_cnt)).toFixed(1);
6102	let avg_img = Math.round(avg);
6103	let head = document.createElement("div");
6104	let head_h2 = document.createElement("h2");
6105	head_h2.textContent = "Avg Rating: " + avg;
6106	let head_img = document.createElement("img");
6107	head_img.className = "review_avg_img";
6108	head_img.src = "https://rental.software/images/" + avg_img + "star.png";
6109	head.appendChild(head_h2);
6110	head.appendChild(head_img);
6111	element.prepend(head);
6112	}).catch(function(err) {
6113		console.log(err);
6114	});
6115}</script>
6115 <style type="text/css">.searchio-live-search-results {
6116						opacity: 0;
6117						transition: opacity .25s ease-in-out;
6118						-moz-transition: opacity .25s ease-in-out;
6119						-webkit-transition: opacity .25s ease-in-out;
6120						height: 0;
6121						overflow: hidden;
6122						z-index: 9999995; /* Exceed searchIO Modal Search Form overlay. */
6123						position: absolute;
6124						display: none;
6125					}
6126
6127					.searchio-live-search-results-showing {
6128						display: block;
6129						opacity: 1;
6130						height: auto;
6131						overflow: auto;
6132					}
6133
6134					.searchio-live-search-no-results {
6135						padding: 3em 2em 0;
6136						text-align: center;
6137					}
6138
6139					.searchio-live-search-no-min-chars:after {
6140						content: "Continue typing";
6141						display: block;
6142						text-align: center;
6143						padding: 2em 2em 0;
6144					}</style> 
6144<script>var _searchIO_LIVE_AJAX_SEARCH_BLOCKS = true;
6145			var _searchIO_LIVE_AJAX_SEARCH_ENGINE = 'default';
6146			var _searchIO_LIVE_AJAX_SEARCH_CONFIG = 'default';</script>
6146 
6146<script>( () => {
6147					const lazyloadRunObserver = () => {
6148						const lazyloadBackgrounds = document.querySelectorAll( `.e-con.e-parent:not(.e-lazyloaded)` );
6149						const lazyloadBackgroundObserver = new IntersectionObserver( ( entries ) => {
6150							entries.forEach( ( entry ) => {
6151								if ( entry.isIntersecting ) {
6152									let lazyloadBackground = entry.target;
6153									if( lazyloadBackground ) {
6154										lazyloadBackground.classList.add( 'e-lazyloaded' );
6155									}
6156									lazyloadBackgroundObserver.unobserve( entry.target );
6157								}
6158							});
6159						}, { rootMargin: '200px 0px 200px 0px' } );
6160						lazyloadBackgrounds.forEach( ( lazyloadBackground ) => {
6161							lazyloadBackgroundObserver.observe( lazyloadBackground );
6162						} );
6163					};
6164					const events = [
6165						'DOMContentLoaded',
6166						'elementor/lazyload/observe',
6167					];
6168					events.forEach( ( event ) => {
6169						document.addEventListener( event, lazyloadRunObserver );
6170					} );
6171				} )();</script>
6171 
6171<script id="jquery-ui-core-js-before">jQuery.uiBackCompat = true;
6172//# sourceURL=jquery-ui-core-js-before</script>
6172 
6172<script id="jquery-ui-datepicker-js-after">jQuery(function(jQuery){jQuery.datepicker.setDefaults({"closeText":"Close","currentText":"Today","monthNames":["January","February","March","April","May","June","July","August","September","October","November","December"],"monthNamesShort":["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],"nextText":"Next","prevText":"Previous","dayNames":["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],"dayNamesShort":["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],"dayNamesMin":["S","M","T","W","T","F","S"],"dateFormat":"MM d, yy","firstDay":1,"isRTL":false});});
6173//# sourceURL=jquery-ui-datepicker-js-after</script>
6173 
6173<script id="slick-carousel-js-js" src="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.8.1/slick.min.js?ver=1.8.1"></script>
6173 
6173<script id="elementor-frontend-js-before">var elementorFrontendConfig = {"environmentMode":{"edit":false,"wpPreview":false,"isScriptDebug":false},"i18n":{"shareOnFacebook":"Share on Facebook","shareOnX":"Share on X","pinIt":"Pin it","download":"Download","downloadImage":"Download image","fullscreen":"Fullscreen","zoom":"Zoom","share":"Share","playVideo":"Play Video","previous":"Previous","next":"Next","close":"Close","a11yCarouselPrevSlideMessage":"Previous slide","a11yCarouselNextSlideMessage":"Next slide","a11yCarouselFirstSlideMessage":"This is the first slide","a11yCarouselLastSlideMessage":"This is the last slide","a11yCarouselPaginationBulletMessage":"Go to slide"},"is_rtl":false,"breakpoints":{"xs":0,"sm":480,"md":768,"lg":1025,"xl":1440,"xxl":1600},"responsive":{"breakpoints":{"mobile":{"label":"Mobile Portrait","value":767,"default_value":767,"direction":"max","is_enabled":true},"mobile_extra":{"label":"Mobile Landscape","value":880,"default_value":880,"direction":"max","is_enabled":false},"tablet":{"label":"Tablet Portrait","value":1024,"default_value":1024,"direction":"max","is_enabled":true},"tablet_extra":{"label":"Tablet Landscape","value":1200,"default_value":1200,"direction":"max","is_enabled":false},"laptop":{"label":"Laptop","value":1366,"default_value":1366,"direction":"max","is_enabled":false},"widescreen":{"label":"Widescreen","value":2400,"default_value":2400,"direction":"min","is_enabled":false}},"hasCustomBreakpoints":false},"version":"4.3.2","is_static":false,"experimentalFeatures":{"additional_custom_breakpoints":true,"theme_builder_v2":true,"landing-pages":true,"import-export-customization":true,"e_pro_atomic_form":true,"e_pro_collection_loop":true,"e_pro_variables":true,"e_pro_interactions":true},"urls":{"assets":"https:\/\/iepnw.com\/wp-content\/plugins\/elementor\/assets\/","ajaxurl":"https:\/\/iepnw.com\/wp-admin\/admin-ajax.php","uploadUrl":"https:\/\/iepnw.com\/wp-content\/uploads"},"nonces":{"floatingButtonsClickTracking":"1878535ad2","atomicFormsSendForm":"bdb6de24c1"},"swiperClass":"swiper","settings":{"page":[],"editorPreferences":[]},"kit":{"body_background_background":"classic","active_breakpoints":["viewport_mobile","viewport_tablet"],"lightbox_enable_counter":"yes","lightbox_enable_fullscreen":"yes","lightbox_enable_zoom":"yes","lightbox_enable_share":"yes","lightbox_title_src":"title","lightbox_description_src":"description"},"post":{"id":6230,"title":"Foam%20Party%20-%20Inflatable%20Event%20Professionals%20LLC%20Spanaway%20WA","excerpt":"","featuredImage":"https:\/\/iepnw.com\/wp-content\/uploads\/2025\/06\/Spanaway20Foam20Party_1746154102_big.jpg"}};
6174//# sourceURL=elementor-frontend-js-before</script>
6174 
6174<script id="swp-live-search-client-js-extra">var searchio_live_search_params = [];
6175searchio_live_search_params = {"ajaxurl":"https:\/\/iepnw.com\/wp-admin\/admin-ajax.php","origin_id":6230,"config":{"default":{"engine":"default","input":{"delay":300,"min_chars":3},"results":{"position":"bottom","width":"auto","offset":{"x":0,"y":5}},"spinner":{"lines":12,"length":8,"width":3,"radius":8,"scale":1,"corners":1,"color":"#424242","fadeColor":"transparent","speed":1,"rotate":0,"animation":"searchio-spinner-line-fade-quick","direction":1,"zIndex":2000000000,"className":"spinner","top":"50%","left":"50%","shadow":"0 0 1px transparent","position":"absolute"}}},"msg_no_config_found":"No valid searchIO Live Search configuration found!","aria_instructions":"When autocomplete results are available use up and down arrows to review and enter to go to the desired page. Touch device users, explore by touch or with swipe gestures.","io_search_results_same_width":"1","io_search_results_width":"400","io_search_results_align":"right"};;
6176//# sourceURL=swp-live-search-client-js-extra</script>
vendor: 131 bytes, line 6176
6176 <script id="elementor-recaptcha_v3-api-js" src="https://www.google.com/recaptcha/api.js?render=explicit&#038;ver=4.2.2"></script> 
6176<script id="wp-hooks-js" src="https://iepnw.com/wp-includes/js/dist/hooks.min.js?ver=f0f188028580e8dc1255"></script>
6176 
6176<script id="wp-i18n-js" src="https://iepnw.com/wp-includes/js/dist/i18n.min.js?ver=1dfe7db3940c23ea9216"></script>
6176 
6176<script id="wp-i18n-js-after">wp.i18n.setLocaleData( { 'text direction\u0004ltr': [ 'ltr' ] } );
6177//# sourceURL=wp-i18n-js-after</script>
6177 
6177<script id="elementor-pro-frontend-js-before">var ElementorProFrontendConfig = {"ajaxurl":"https:\/\/iepnw.com\/wp-admin\/admin-ajax.php","nonce":"d8317bc303","urls":{"assets":"https:\/\/iepnw.com\/wp-content\/plugins\/elementor-pro\/assets\/","rest":"https:\/\/iepnw.com\/wp-json\/"},"settings":{"lazy_load_background_images":true},"popup":{"hasPopUps":true},"shareButtonsNetworks":{"facebook":{"title":"Facebook","has_counter":true},"twitter":{"title":"Twitter"},"linkedin":{"title":"LinkedIn","has_counter":true},"pinterest":{"title":"Pinterest","has_counter":true},"reddit":{"title":"Reddit","has_counter":true},"vk":{"title":"VK","has_counter":true},"odnoklassniki":{"title":"OK","has_counter":true},"tumblr":{"title":"Tumblr"},"digg":{"title":"Digg"},"skype":{"title":"Skype"},"stumbleupon":{"title":"StumbleUpon","has_counter":true},"mix":{"title":"Mix"},"telegram":{"title":"Telegram"},"pocket":{"title":"Pocket","has_counter":true},"xing":{"title":"XING","has_counter":true},"whatsapp":{"title":"WhatsApp"},"email":{"title":"Email"},"print":{"title":"Print"},"x-twitter":{"title":"X"},"threads":{"title":"Threads"}},"facebook_sdk":{"lang":"en_US","app_id":""},"lottie":{"defaultAnimationUrl":"https:\/\/iepnw.com\/wp-content\/plugins\/elementor-pro\/modules\/lottie\/assets\/animations\/default.json"}};
6178//# sourceURL=elementor-pro-frontend-js-before</script>
6178 
6178<script defer src="https://iepnw.com/wp-content/cache/autoptimize/js/autoptimize_5bd5ce2c8040d050a18197fd4b7b72d2.js"></script>
6178</body></html>
6179<!-- Cached by WP-Optimize (gzip) - https://teamupdraft.com/wp-optimize/ - Last modified: September 26, 2026 10:05 am (UTC:0) -->

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.