PageSourceSearch

https://mvcpaintingandremodeling.com/

html mvcpaintingandremodeling.com collected 2026-09-29 17:16:36 UTC 143,689 bytes, 3,018 lines download raw bytes

1
2<!DOCTYPE html>
3<html>
4<head>
5    <meta charset="utf-8" />
6    <meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover, maximum-scale=1.0" />
7    <meta name="format-detection" content="telephone=no" />
8    <meta property="og:locale" content="en_US" />
9    <meta property="og:type" content="website" />
10        <meta property="og:title" content="MVC Painting &amp; Remodeling - East Dundee, IL" />
11            <meta property="og:url" content="https://mvcpaintingandremodeling.com/" />
12                <meta property="og:image" content="https://du9m0k402rjmo.cloudfront.net/images/P_42094/32d23c53-3970-48fc-80a4-e45090a1f41b.jpg" />
13            <meta property="og:description" content="MVC Painting &amp; Remodeling is a trusted remodeling business based in Palatine, IL, serving the surrounding areas since 2006. We proudly extend our high-quality painting and remodeling services to the communities of East Dundee, Arlington Heights, Barrington, Batavia, Buffalo Grove, Glenview, Northbrook, and Saint Charles, IL. Specializing in both interior and exterior transformations, our team brings years of expertise to turn your space into a work of art. Beyond our core services, we offer a range of specialized offerings, including drywall installation, window services, fascia, soffit, framing, and cedar siding. At MVC Painting &amp; Remodeling, we are committed to delivering exceptional craftsmanship and top-notch customer service for every project, big or small. Let us bring your remodeling visions to life with precision and care." />
14        <meta name="description" content="MVC Painting &amp; Remodeling is a trusted remodeling business based in Palatine, IL, serving the surrounding areas since 2006. We proudly extend our high-quality painting and remodeling services to the communities of East Dundee, Arlington Heights, Barrington, Batavia, Buffalo Grove, Glenview, Northbrook, and Saint Charles, IL. Specializing in both interior and exterior transformations, our team brings years of expertise to turn your space into a work of art. Beyond our core services, we offer a range of specialized offerings, including drywall installation, window services, fascia, soffit, framing, and cedar siding. At MVC Painting &amp; Remodeling, we are committed to delivering exceptional craftsmanship and top-notch customer service for every project, big or small. Let us bring your remodeling visions to life with precision and care." />
15            <meta name="title" content="MVC Painting & Remodeling - East Dundee IL" />
16            <meta name="keywords" content="Home Remodeler Near Me,Painting,Drywall and Plaster Repair,Drywall Installation,Flooring Installation,Interior Painting,Basement Remodel,Finished Basements,Bathroom Remodel" />
17    <title>MVC Painting & Remodeling - East Dundee, IL</title>
18    
18<script src="/Scripts/Profile/googleAnalytics.js" type="text/javascript"></script>
vendor: 112 bytes, lines 18-21
18
19    <script type="text/javascript" src="https://www.google.com/recaptcha/api.js" async defer></script>
20
21    
21<script src="https://code.jquery.com/jquery-3.5.0.min.js" integrity="sha256-xNzN2a4ltkB44Mc/Jz3pT4iU1cmeR0FkXs4pru/JxaQ=" crossorigin="anonymous"></script>
21
22    
23    
23<script>window.jQuery || document.write('
23<script src="/scripts/templates/jquery-3.5.0.min.js"><\/script>')</script>
23
24
25    
25<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/umd/popper.min.js" integrity="sha384-9/reFTGAW83EW2RDu2S0VKaIzap3H66lZH81PoYlFhbGU+6BZp6G7niu735Sk7lN" crossorigin="anonymous"></script>
25
26    
27    
27<script>if (typeof (Popper) === 'undefined') { document.write('
27<script src="/scripts/templates/popper.min.js"><\/script>') }</script>
27
28
29    <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.1.0/css/all.css" integrity="sha384-lKuwvrZot6UHsBSfcMvOkWwlCMgc0TaWr+30HWe3a4ltaBwTZhyTEggF5tJv8tbt" crossorigin="anonymous">
30
31    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" integrity="sha384-xOolHFLEh07PJGoPkLv1IbcEPTNtaed2xpHsD9ESMhqIYd0nLMwNLD69Npy4HI+N" crossorigin="anonymous">
32
33    
33<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.min.js" integrity="sha384-mrcBkRTg0HmTfecoh1I+48Ptm7cAe18uN+3GsS5SXXGSwzpjIhJZkxEJ5jYaZmE" crossorigin="anonymous"></script>
33
34    
35    
35<script>if (typeof ($.fn.modal) === 'undefined') { document.write('
35<script src="/scripts/templates/bootstrap.min.js"><\/script>') }</script>
35
36
37    
37<script src="/Scripts/Templates/googleMaps.js" type="text/javascript"></script>
37
38    <link href="/Content/Templates/custom-bootstrap.css" type="text/css" rel="stylesheet" />
39    
39<script src="/Scripts/bootbox.min.js" type="text/javascript"></script>
39
40    
40<script src="/Scripts/Profile/jquery.barrating.1.1.4.js" type="text/javascript"></script>
40
41    
41<script src="/Scripts/Templates/cleave.min.js" type="text/javascript"></script>
41
42    
42<script src="/Scripts/Templates/cleave-phone.us.js" type="text/javascript"></script>
42
43    
43<script src="/Scripts/Templates/slick.min.js" type="text/javascript"></script>
43
44    <link href="/Content/Templates/slick.css" type="text/css" rel="stylesheet" />
45    <link href="/Content/Templates/slick-theme.css" type="text/css" rel="stylesheet" />
46    
46<script src="/Scripts/Templates/googleMapsMultiLocation.js" type="text/javascript"></script>
vendor: 66 bytes, lines 46-47
46
47    <script src="https://www.google.com/recaptcha/api.js?render=
476LcokacUAAAAAH_snk3O5bpdYwjpC5XAuXNLrJLH
vendor: 40 bytes, lines 47-48
47" type="text/javascript"></script>
48    
48<script src="https://player.vimeo.com/api/player.js" type="text/javascript"></script>
48
49
50    <link href="/Content/Templates/chatbot.css" type="text/css" rel="stylesheet" />
51
52    <meta name="viewport" content="width=device-width, user-scalable=yes,initial-scale=1, maximum-scale=2" />
53    <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
54    
55    
56    <link href="/Content/Templates/platinum_fonts.css" type="text/css" rel="stylesheet" />
57    
58    <style>
59        :root {
60            --body_font: Open Sans;
61            --header_font: Roboto Slab;
62            --text_color: 255, 255, 255, 1;
63            --text_color_rgba: rgba(var(--text_color));
64            --customer_color: #77224B;
65            --slogan_font_size: 2.5rem;
66            --slogan_text_color: ;
67            --faq_question_text_color: #000000;
68            --post_text_color: 0, 0, 0, 1;
69            --post_text_color_rgba: rgba(var(--post_text_color));
70            --text-transform: capitalize;
71            --scroll-padding-top: 0px; /* Initial value */
72        }
73    </style>
74    <link href="/Content/Templates/platinum_1.css" type="text/css" rel="stylesheet" />
75
76        <link rel="canonical" href="https://mvcpaintingandremodeling.com/">
77
78
79<script type="application/ld+json">
80{
81  "@context": "https://schema.org",
82  "@graph": [
83    {
84      "@type": "LocalBusiness",
85      "@id": "https://mvcpaintingandremodeling.com/#localbusiness",
86      "name": "MVC Painting & Remodeling",
87      "url": "https://mvcpaintingandremodeling.com/",
88      "description": "MVC Painting & Remodeling is a trusted remodeling business based in Palatine, IL, serving the surrounding areas since 2006. We proudly extend our high-quality painting and remodeling services to the communities of East Dundee, Arlington Heights, Barrington, Batavia, Buffalo Grove, Glenview, Northbrook, and Saint Charles, IL. Specializing in both interior and exterior transformations, our team brings years of expertise to turn your space into a work of art. Beyond our core services, we offer a range of specialized offerings, including drywall installation, window services, fascia, soffit, framing, and cedar siding. At MVC Painting & Remodeling, we are committed to delivering exceptional craftsmanship and top-notch customer service for every project, big or small. Let us bring your remodeling visions to life with precision and care.",
89      "image": "https://du9m0k402rjmo.cloudfront.net/images/P_42094/32d23c53-3970-48fc-80a4-e45090a1f41b.jpg",
90      "logo": "https://du9m0k402rjmo.cloudfront.net/images/P_42094/32d23c53-3970-48fc-80a4-e45090a1f41b.jpg",
91      "address": {
92        "@type": "PostalAddress",
93        "addressLocality": "East Dundee",
94        "addressRegion": "IL",
95        "postalCode": "60118",
96        "addressCountry": "US"
97      },
98      "telephone": "(847) 483-4724",
99      "email": "[email protected]",
100      "openingHoursSpecification": [
101        {
102          "@type": "OpeningHoursSpecification",
103          "dayOfWeek": "Monday",
104          "opens": "07:00",
105          "closes": "19:00"
106        },
107        {
108          "@type": "OpeningHoursSpecification",
109          "dayOfWeek": "Tuesday",
110          "opens": "07:00",
111          "closes": "19:00"
112        },
113        {
114          "@type": "OpeningHoursSpecification",
115          "dayOfWeek": "Wednesday",
116          "opens": "07:00",
117          "closes": "19:00"
118        },
119        {
120          "@type": "OpeningHoursSpecification",
121          "dayOfWeek": "Thursday",
122          "opens": "07:00",
123          "closes": "19:00"
124        },
125        {
126          "@type": "OpeningHoursSpecification",
127          "dayOfWeek": "Friday",
128          "opens": "07:00",
129          "closes": "19:00"
130        },
131        {
132          "@type": "OpeningHoursSpecification",
133          "dayOfWeek": "Saturday",
134          "opens": "07:00",
135          "closes": "19:00"
136        },
137        {
138          "@type": "OpeningHoursSpecification",
139          "dayOfWeek": "Sunday",
140          "opens": "07:00",
141          "closes": "19:00"
142        }
143      ],
144      "paymentAccepted": "Discover, American Express, Debit Cards, MasterCard, Visa, PayPal, Apple Pay, Android Pay",
145      "sameAs": [
146        "https://www.facebook.com/MVCPainting/",
147        "https://www.instagram.com/mvcpainting/"
148      ]
149    },
150    {
151      "@type": "WebSite",
152      "@id": "https://mvcpaintingandremodeling.com/#website",
153      "url": "https://mvcpaintingandremodeling.com/",
154      "name": "MVC Painting & Remodeling",
155      "description": "MVC Painting & Remodeling is a trusted remodeling business based in Palatine, IL, serving the surrounding areas since 2006. We proudly extend our high-quality painting and remodeling services to the communities of East Dundee, Arlington Heights, Barrington, Batavia, Buffalo Grove, Glenview, Northbrook, and Saint Charles, IL. Specializing in both interior and exterior transformations, our team brings years of expertise to turn your space into a work of art. Beyond our core services, we offer a range of specialized offerings, including drywall installation, window services, fascia, soffit, framing, and cedar siding. At MVC Painting & Remodeling, we are committed to delivering exceptional craftsmanship and top-notch customer service for every project, big or small. Let us bring your remodeling visions to life with precision and care.",
156      "potentialAction": {
157        "@type": "SearchAction",
158        "target": "https://mvcpaintingandremodeling.com/?s={search_term_string}",
159        "query-input": "required name=search_term_string"
160      }
161    },
162    {
163      "@type": "WebPage",
164      "@id": "https://mvcpaintingandremodeling.com/#webpage",
165      "url": "https://mvcpaintingandremodeling.com/",
166      "name": "MVC Painting & Remodeling - East Dundee, IL",
167      "description": "MVC Painting & Remodeling is a trusted remodeling business based in Palatine, IL, serving the surrounding areas since 2006. We proudly extend our high-quality painting and remodeling services to the communities of East Dundee, Arlington Heights, Barrington, Batavia, Buffalo Grove, Glenview, Northbrook, and Saint Charles, IL. Specializing in both interior and exterior transformations, our team brings years of expertise to turn your space into a work of art. Beyond our core services, we offer a range of specialized offerings, including drywall installation, window services, fascia, soffit, framing, and cedar siding. At MVC Painting & Remodeling, we are committed to delivering exceptional craftsmanship and top-notch customer service for every project, big or small. Let us bring your remodeling visions to life with precision and care.",
168      "isPartOf": {
169        "@id": "https://mvcpaintingandremodeling.com/#website"
170      },
171      "about": {
172        "@id": "https://mvcpaintingandremodeling.com/#localbusiness"
173      },
174      "primaryImageOfPage": {
175        "@type": "ImageObject",
176        "url": "https://du9m0k402rjmo.cloudfront.net/images/P_42094/32d23c53-3970-48fc-80a4-e45090a1f41b.jpg"
177      },
178      "breadcrumb": {
179        "@type": "BreadcrumbList",
180        "itemListElement": [
181          {
182            "@type": "ListItem",
183            "position": 1,
184            "name": "Home",
185            "item": "https://mvcpaintingandremodeling.com/"
186          }
187        ]
188      }
189    },
190    {
191      "@type": "Service",
192      "@id": "https://mvcpaintingandremodeling.com/#service",
193      "name": "Our Services",
194      "provider": {
195        "@id": "https://mvcpaintingandremodeling.com/#localbusiness"
196      },
197      "serviceType": [
198        "Painting Services",
199        "Exterior Painting",
200        "Interior Painting",
201        "Drywall Services",
202        "Drywall Repair",
203        "Drywall Installation",
204        "Facia",
205        "Soffit",
206        "Remodeling",
207        "Plumber",
208        "Vinyl Flooring",
209        "Windows",
210        "Framing",
211        "Electrical",
212        "Cedar Siding"
213      ],
214      "description": "Professional services offered by MVC Painting & Remodeling"
215    },
216    {
217      "@type": "Service",
218      "@id": "https://mvcpaintingandremodeling.com/#service1",
219      "name": "Remodeling",
220      "provider": {
221        "@id": "https://mvcpaintingandremodeling.com/#localbusiness"
222      },
223      "serviceType": "Remodeling",
224      "description": "At MVC Painting & Remodeling, our remodeling services are designed to transform your home into a space that reflects your style and meets your needs. With over 16 years of experience, we specialize in both interior and exterior renovations, ensuring exceptional craftsmanship in every project. Whether you’re looking to update your kitchen, renovate your bathroom, or create an inviting living space, our skilled team works closely with you from concept to completion. We handle a variety of remodeling tasks, including drywall installation, framing, and window services, ensuring that every detail is executed with precision. Our commitment to quality and customer satisfaction sets us apart, as we prioritize clear communication and a collaborative approach. We believe that your home should be a true reflection of your personality, and we strive to bring your vision to life with care and attention to detail. Trust MVC Painting & Remodeling to enhance your living spaces and increase your home's value with our comprehensive remodeling services. Let us help you create the perfect environment for your family to thrive."
225    },
226    {
227      "@type": "Service",
228      "@id": "https://mvcpaintingandremodeling.com/#service2",
229      "name": "Interior Services",
230      "provider": {
231        "@id": "https://mvcpaintingandremodeling.com/#localbusiness"
232      },
233      "serviceType": "Interior Services",
234      "description": "At MVC Painting & Remodeling, our interior services are focused on transforming your home into a beautiful and functional space tailored to your lifestyle. With over 16 years of experience, we specialize in high-quality painting, drywall installation, and various remodeling projects that enhance the aesthetics and comfort of your interiors. Whether you're looking to refresh a single room or undertake a full-home renovation, our skilled team works closely with you to understand your vision and execute it with precision. We pride ourselves on our attention to detail and commitment to using top-quality materials, ensuring that every project meets our high standards. From choosing the perfect color palette to selecting the right finishes, we guide you through each step of the process, prioritizing clear communication and customer satisfaction. Our goal is to create inviting spaces that reflect your personal style and provide an atmosphere where you and your family can thrive. Trust MVC Painting & Remodeling to elevate your home's interior with our exceptional services and craftsmanship. Let us help you turn your vision into reality, creating a space you’ll love for years to come."
235    },
236    {
237      "@type": "Service",
238      "@id": "https://mvcpaintingandremodeling.com/#service3",
239      "name": "Exterior Services",
240      "provider": {
241        "@id": "https://mvcpaintingandremodeling.com/#localbusiness"
242      },
243      "serviceType": "Exterior Services",
244      "description": "At MVC Painting & Remodeling, our exterior services are designed to enhance your home’s curb appeal while providing lasting protection against the elements. With over 16 years of experience, we specialize in high-quality exterior painting, siding installation, and comprehensive remodeling solutions. Our skilled team understands the importance of first impressions and works diligently to ensure your home looks its best. We use premium materials and advanced techniques to deliver results that not only beautify but also safeguard your investment. Whether you’re looking to refresh your home’s exterior with a new coat of paint, replace aging siding, or update windows and doors, we collaborate closely with you to bring your vision to life. Our commitment to detail and customer satisfaction sets us apart, as we prioritize open communication throughout the process. At MVC Painting & Remodeling, we believe that a well-maintained exterior is key to a welcoming home. Let us help you transform your outdoor space
244s with our expert services, ensuring your home stands out for all the right reasons while providing comfort and protection for years to come."
245    },
246    {
247      "@type": "FAQPage",
248      "@id": "https://mvcpaintingandremodeling.com/#faqpage",
249      "url": "https://mvcpaintingandremodeling.com/#faq",
250      "name": "Frequently Asked Questions",
251      "description": "Frequently asked questions about MVC Painting & Remodeling",
252      "mainEntity": [
253        {
254          "@type": "Question",
255          "name": "What services do you offer?",
256          "acceptedAnswer": {
257            "@type": "Answer",
258            "text": "We are your go-to experts for interior and exterior painting, delivering seamless finishes that rejuvenate any space. Our drywall installation and repair services ensure sturdy and flawless surfaces, perfect for home renovations or commercial upgrades. Our comprehensive finished basement services transform underutilized spaces into functional living areas, handling every aspect from plumbing and electrical to refined carpentry and design. Tailored for both residential and commercial clients, our remodeling solutions are designed to enhance and elevate environments. Trust us to bring quality and precision to every project, big or small."
259          }
260        },
261        {
262          "@type": "Question",
263          "name": "How do you ensure quality in your work?",
264          "acceptedAnswer": {
265            "@type": "Answer",
266            "text": "We are proud to maintain a high standard of excellence as evidenced by our glowing reviews on Google. Our clients consistently award us a 5-star rating, praising the quality of our craftsmanship and our commitment to exemplary customer service. Each project receives personalized attention, ensuring that every detail matches our clients' needs and expectations. Our reputation for using top-tier materials and adhering to industry best practices is mirrored in the satisfaction and loyalty of our clientele, who frequently remark on the professionalism and dedication of our skilled team. Whether it's a residential or commercial project, our relentless pursuit of perfection sets us apart, making us a trusted choice in the remodeling industry."
267          }
268        },
269        {
270          "@type": "Question",
271          "name": "Do you handle plumbing and electrical work directly?",
272          "acceptedAnswer": {
273            "@type": "Answer",
274            "text": "Our team is staffed with licensed professionals who are experts in plumbing and electrical work, providing you with peace of mind that every installation is performed safely and up to the latest codes and standards. This commitment to quality ensures each basement remodel is functional and safe, reducing the need for future maintenance issues. By handling these crucial components in-house, we streamline the remodeling process, offering a seamless and coordinated project timeline. Whether it's installing new fixtures, updating wiring, or laying new pipes, our skilled technicians ensure that every detail is executed with precision and care, enhancing the overall value and safety of your property."
275          }
276        },
277        {
278          "@type": "Question",
279          "name": "What is the process for a basement remodel?",
280          "acceptedAnswer": {
281            "@type": "Answer",
282            "text": "Our streamlined process begins with an in-depth initial consultation, where we assess your space, understand your vision, and discuss budgetary considerations. Following this, our design and planning phase tailors solutions to meet your specific needs, incorporating both functionality and aesthetics. We then handle all aspects of obtaining necessary permits, ensuring compliance with local regulations and codes. Once approvals are secured, our skilled construction team takes over, adhering to a meticulously planned schedule. To wrap up, we conduct a comprehensive final walkthrough, reviewing every detail to ensure our work meets your expectations and that you are completely satisfied with the results. This structured approach guarantees a smooth, efficient remodel that realizes your dream space."
283          }
284        },
285        {
286          "@type": "Question",
287          "name": "What areas do you serve?",
288          "acceptedAnswer": {
289            "@type": "Answer",
290            "text": "We proudly extend our high-quality painting and remodeling services to the communities of East Dundee, Arlington Heights, Barrington, Batavia, Buffalo Grove, Glenview, Northbrook, and Saint Charles, IL. Specializing in both interior and exterior transformations."
291          }
292        }
293      ]
294    }
295  ]
296}
297</script>
297</head>
298<body>
299    <div id="bootstrapCssTest" class="d-none"></div>
300    
300<script>
301        $(function () {
302            
303            if ($('#bootstrapCssTest').is(':visible')) {
304                $("head").prepend('<link rel="stylesheet" href="/content/templates/bootstrap.min.css">');
305            }
306        });
307    </script>
307
308
309    
310
311
312<input type="hidden" id="areaMarkers" />
313<input type="hidden" id="selectedServiceId" value="" />
314
315<!-- NAVBAR -->
316<div class="container-fullwidth fixed-top">
317    
318
319
320
321
322<header id="headernav" class="content-header custom-background-color d-flex flex-wrap align-items-center justify-content-between py-0 px-2">
323
324    
325    <div class="nav-phone-social pb-1 d-flex flex-wrap justify-content-center">
326        <div class="my-1 header-address d-flex flex-wrap justify-content-center">
327                <div class="nav-phone text-center nav-header-item-no-spacing mx-1"><a id="PhoneNav" class="text-font-color phone-nav-mobile" href="tel:8474834724"><i class="fas fa-phone fa-inverse fa-xs fa-rotate-90 mr-1"></i>(847) 483-4724</a></div>
328                            <div class="nav-phone text-center nav-header-item-no-spacing mx-1 px-1"><a id="eMailNav" class="text-font-color phone-nav-mobile text-lowercase" href="mailto:[email protected]" target="_blank"><i class="fas fa-envelope fa-inverse fa-sm mr-1"></i>[email protected]</a></div>
329        </div>
330    </div>
331
332    
333    <div class="nav-phone-social pb-1 d-flex flex-wrap justify-content-center">
334        <div class="nav-social mx-1 px-1">
335                <div class="mx-auto text-center d-flex flex-wrap justify-content-center">
336                                            <div class="mt-1 mb-1 ml-2 mr-2">
337                            <a class="text-font-color social-link-footer" href="https://www.facebook.com/MVCPainting/" target="_blank" id="facebook-social-footer" title="Facebook">
338                                <i class="fab fa-facebook-f fa-lg"></i>
339                            </a>
340                        </div>
341                                                                                    <div class="mt-1 mb-1 ml-2 mr-2">
342                            <a class="text-font-color social-link-footer" href="https://www.instagram.com/mvcpainting/" target="_blank" id="instagram-social-footer" title="Instagram">
343                                <i class="fab fa-instagram fa-lg"></i>
344                            </a>
345                        </div>
346                                                        </div>
347        </div>
348    </div>
349</header>
350
351
352<nav class="bg-default-color bg-light navbar navbar-light navbar-expand-xl pt-1">
353
354    <div class="nav-image bg-default-color bg-light flex-column text-center nav-image-desktop">
355            <a href="#home-section" class="navbar-brand ml-3" id="HomeNav" onclick="DisplayPage('#homePage')">
356                <img src="https://du9m0k402rjmo.cloudfront.net/images/P_42094/32d23c53-3970-48fc-80a4-e45090a1f41b.jpg" alt="navbar logo" class="d-line-block align-top nav-logo-medium" />
357            </a>
358    </div>
359
360    <button class="navbar-toggler nav-menu collapsed" type="button" data-toggle="collapse" data-target="#navbarToggler" aria-controls="navbarToggler" aria-expanded="false" aria-label="Toggle navigation">
361        <span class="navbar-toggler-icon"></span>
362        <span class="my-1 mx-2 close">X</span>
363    </button>
364
365    <div class="collapse navbar-collapse flex-column mx-auto" id="navbarToggler">
366        
367        <div class="d-none d-xl-block nav-section">
368            <div class="navbar-nav d-flex flex-wrap align-items-center">
369
370
371<div class="col nav-item text-center nav-header-item mx-auto text-nowrap">            <a href="#" id="HomePageNavigationLink" class="nav-link header-font p-3" onclick="DisplayPage('#homePage')">Home</a>
372</div><div class="col nav-item text-center nav-header-item mx-auto text-nowrap">            <a href="#" id="AboutPageNavigationLink" class="nav-link header-font p-3" onclick="DisplayPage('#aboutPage')">About</a>
373</div><div class="col nav-item text-center nav-header-item mx-auto text-nowrap">            <a href="#" id="PhotosNavigationLink" class="nav-link header-font p-3" onclick="DisplayPage('#imageryPage')">Gallery</a>
374</div><div class="col nav-item text-center nav-header-item mx-auto text-nowrap">            <a href="#" id="ServicesPageNavigationLink" class="nav-link header-font p-3" onclick="DisplayPage('#servicesPage')">Services</a>
375</div>
375<div class="col nav-item text-center nav-header-item mx-auto text-nowrap">            <a href="#" id="testimonialsPageNavigationLink" class="nav-link header-font p-3" onclick="DisplayPage('#testimonialsPage')">Testimonials</a>
376</div><div class="col nav-item text-center nav-header-item mx-auto text-nowrap">            <a href="#" id="FaqPageNavigationLink" class="nav-link header-font p-3" onclick="DisplayPage('#faqPage')">FAQ</a>
377</div><div class="col nav-item text-center nav-header-item mx-auto text-nowrap">            <a href="#" id="ContactPageNavigationLink" class="nav-link header-font p-3" onclick="DisplayPage('#contactPage')">Contact</a>
378</div><div class="col nav-item text-center nav-header-item mx-auto text-nowrap">            <a href="#" id="PostsPageNavigationLink" class="nav-link header-font p-3" onclick="DisplayPage('#postsPage')">News</a>
379</div>            </div>
380        </div>
381        
382        <div class="d-xs-block d-xl-none">
383            <ul class="navbar-nav mx-auto mr-auto mt-2 mt-xl-0 mb-2">
384
385
386<li class="nav-header-item-no-spacing mr-1 ml-1 text-nowrap">            <a href="#" id="HomePageNavigationLink" class="nav-link header-font pl-3" onclick="DisplayPage('#homePage')">Home</a>
387</li><li class="nav-header-item-no-spacing mr-1 ml-1 text-nowrap">            <a href="#" id="AboutPageNavigationLink" class="nav-link header-font pl-3" onclick="DisplayPage('#aboutPage')">About</a>
388</li><li class="nav-header-item-no-spacing mr-1 ml-1 text-nowrap">            <a href="#" id="PhotosNavigationLink" class="nav-link header-font pl-3" onclick="DisplayPage('#imageryPage')">Gallery</a>
389</li><li class="nav-header-item-no-spacing mr-1 ml-1 text-nowrap">            <a href="#" id="ServicesPageNavigationLink" class="nav-link header-font pl-3" onclick="DisplayPage('#servicesPage')">Services</a>
390</li><li class="nav-header-item-no-spacing mr-1 ml-1 text-nowrap">            <a href="#" id="testimonialsPageNavigationLink" class="nav-link header-font pl-3" onclick="DisplayPage('#testimonialsPage')">Testimonials</a>
391</li><li class="nav-header-item-no-spacing mr-1 ml-1 text-nowrap">            <a href="#" id="FaqPageNavigationLink" class="nav-link header-font pl-3" onclick="DisplayPage('#faqPage')">FAQ</a>
392</li><li class="nav-header-item-no-spacing mr-1 ml-1 text-nowrap">            <a href="#" id="ContactPageNavigationLink" class="nav-link header-font pl-3" onclick="DisplayPage('#contactPage')">Contact</a>
393</li><li class="nav-header-item-no-spacing mr-1 ml-1 text-nowrap">            <a href="#" id="PostsPageNavigationLink" class="nav-link header-font pl-3" onclick="DisplayPage('#postsPage')">News</a>
394</li>            </ul>
395        </div>
396    </div>
397</nav>
398</div>
399
400<div id="pages" class="pages-left-medium">
401    <!--Home Page Information-->
402    <div class="content collapse show bg-alt-color" id="homePage">
403
404<div class="d-flex flex-wrap">
405
406        <div class="w-100 mx-auto home-banner">
407            <div id="homepagebanner" class="parallax w-100 aspect-ratio-16x9">
408                    <div class="img-fluid banner-image"><object data="https://fast.wistia.com/embed/medias/rdopklzzlc?fitStrategy=cover&endVideoBehavior=loop&controlsVisibleOnLoad=false&autoPlay=true&volumeControl=false&muted=true&playbar=false&smallPlayButton=false&settingsControl=false&control-bar-right=false" style="width: 100%; height: 100%;" onload="jQuery('.w-css-reset').hide(); jQuery('.w-bottom-bar').hide(); jQuery('.w-ui-container').remove();  "></object></div>
409
410                <div class="home-content">
411                    <div class="d-flex flex-wrap justify-content-center align-items-center px-2"></div>
412                </div>
413            </div>
414        </div>
415    
416        <div class="w-100 w-lg-80 w-sm-90 w-md-90 mx-auto p-2">
417            <div class="d-flex flex-row flex-wrap justify-content-center text-left py-2">
418                    <div class="col-md mx-auto text-center pt-2">
419                        <img alt="Image" src="https://du9m0k402rjmo.cloudfront.net/images/P_42094/8fc120dc-d04a-4ad4-b6b8-9ea9f314e161.jpg" class="img-fluid mx-auto text-center" />
420                    </div>
421                                    <div class="col-md pt-2">
422                        <div class="mx-auto mb-2 section-information">
423                            <div class="strike">
424                                <span class="text-center header-item">About Us</span>
425                            </div>
426                        </div>
427                        <div class="mx-auto mb-2 description-speakable" style="white-space: pre-line">MVC Painting &amp; Remodeling is a trusted remodeling business based in Palatine, IL, serving the surrounding areas since 2006. We proudly extend our high-quality painting and remodeling services to the communities of East Dundee, Arlington Heights, Barrington, Batavia, Buffalo Grove, Glenview, Northbrook, and Saint Charles, IL. Specializing in both interior and exterior transformations, our team brings years of expertise to turn your space into a work of art. Beyond our core services, we offer a range of specialized offerings, including drywall installation, window services, fascia, soffit, framing, and cedar siding. At MVC Painting &amp; Remodeling, we are committed to delivering exceptional craftsmanship and top-notch customer service for every project, big or small. Let us bring your remodeling visions to life with precision and care.</div>
428                    </div>
429            </div>
430        </div>
431
432        <div class="w-100 w-lg-80 w-sm-90 w-md-90 mx-auto p-2" id="photos-content">
433            <div class="mx-auto mb-2 section-information">
434                <div class="strike">
435                    <span class="text-center header-item">Highlights</span>
436                </div>
437            </div>
438            <div class="d-flex flex-row flex-wrap justify-content-center py-2">
439                    <div class="w-100 w-lg-30 w-md-30 w-sm-30 mx-auto">
440                        <div class="d-flex flex-wrap">
441                            <div class="col p-2">
442<a href="#" id="photos-image-element1" class="thumbnail mx-auto d-block">                                <img src="https://du9m0k402rjmo.cloudfront.net/images/P_42094/74d935f1-1db4-4611-b7fe-92006f5e59e2.jpg" alt="" class="img-fluid d-block rounded mx-auto photo-image" />
443                                    <div class="text-center pt-2" style="color:black">Remodeling</div>
444                                </a>                            </div>
445                        </div>
446                    </div>
447                                    <div class="w-100 w-lg-30 w-md-30 w-sm-30 mx-auto">
448                        <div class="d-flex flex-wrap">
449                            <div class="col p-2">
450<a href="#" id="photos-image-element2" class="thumbnail mx-auto d-block">                                <img src="https://du9m0k402rjmo.cloudfront.net/images/P_42094/344f5087-7685-48fe-b07c-86e99c3acd13.jpg" alt="" class="img-fluid d-block rounded mx-auto photo-image" />
451                                    <div class="text-center pt-2" style="color:black">Interior Services</div>
452                                </a>                            </div>
453                        </div>
454                    </div>
455                                    <div class="w-100 w-lg-30 w-md-30 w-sm-30 mx-auto">
456                        <div class="d-flex flex-wrap">
457                            <div class="col p-2">
458<a href="#" id="photos-image-element3" class="thumbnail mx-auto d-block">                                <img src="https://du9m0k402rjmo.cloudfront.net/images/P_42094/a4f070a0-4f60-4dfd-bb14-4e437151440f.jpg" alt="" class="img-fluid d-block rounded mx-auto photo-image" />
459                                    <div class="text-center pt-2" style="color:black">Exterior Services</div>
460                                </a>                            </div>
461                        </div>
462                    </div>
463            </div>
464        </div>
465
466</div>
467
468    </div>
469
470    <!--About Page Information-->
471    <div class="content collapse bg-alt-color" id="aboutPage"></div>
472
473    <!--Services Page Information-->
474    <div class="content collapse bg-alt-color" id="servicesPage"></div>
475
476    <!--Testimonial Page Information-->
477        <div class="content collapse bg-alt-color" id="testimonialsPage"></div>
478
479    <!-- REVIEW MODAL -->
480    <div id="reviewFormParentContainer"></div>
481
482    <!--Contact Page Information-->
483    <div class="content collapse bg-alt-color" id="contactPage"></div>
484
485    <!--Imagery Page Information-->
486    <div class="content collapse bg-alt-color" id="imageryPage"></div>
487
488    <!--Posts Page Information-->
489        <div class="content collapse bg-alt-color" id="postsPage">
490
491<div class="d-flex flex-wrap">
492
493    
494        <div class="w-100 mx-auto banner">
495            <div class="parallax w-100">
496                    <div class="img-fluid banner-image " style="background-image: url(https://du9m0k402rjmo.cloudfront.net/images/P_42094/7dceba0f-91c8-4906-835f-82b13bc552e7.jpg)"></div>
497            </div>
498        </div>
499    <div class="w-100 w-lg-80 w-sm-90 w-md-90 mx-auto p-2">
500        <div class="d-flex flex-row flex-wrap justify-content-center text-center">
501            <div class="posts-partial-content w-100">
502                <div class="mx-auto mb-2 section-information pt-3">
503                    <div class="strike">
504                        <span class="text-center header-item">News</span>
505                    </div>
506                </div>
507                
508                <div class="postsInfo" id="testimonialPostsInfo"></div>
509                <div class="text-center m-3">
510                    <button type="button" id="prevPosts" class="btn btn-light btn-md" disabled><i class="fas fa-angle-left"></i> Previous</button>
511                    <button type="button" id="nextPosts" class="btn btn-light btn-md">Next <i class="fas fa-angle-right"></i></button>
512                </div>
513            </div>
514        </div>
515    </div>
516</div>
517        </div>
518
519    <!--Locations Page Information-->
520    <div class="content collapse bg-alt-color" id="locationsPage"></div>
521
522    <!--FAQ Page Information-->
523    <div class="content collapse bg-alt-color" id="faqPage"></div>
524
525    <!--Additional Content Page Information-->
526    <div class="content collapse bg-alt-color" id="contentPage"></div>
527
528</div> 
529
530<!--FOOTER Information-->
531<footer id="footer-container" class="footer custom-background-color">
532
533
534<div class="container-fluid pt-1">
535    <div class="row pl-3 pr-3">
536            <div id="footer-address" class="col-sm-3 col-md-4 col-lg-3 mx-auto d-flex flex-wrap footer-content">
537                <div class="justify-content-left text-font-color">
538                    <div class="footer-header mb-2 mt-2 text-left text-nowrap">Contact Information</div>
539                        <div class="content-large">MVC Painting &amp; Remodeling</div>
540                                            <div class="mt-1 content-medium">
541                        </div>
542                                            <div class="content-medium">East Dundee, IL 60118</div>
543                    <div class="mt-2 mb-2">
544                            <div class="mx-auto content-medium">
545                                <strong>Phone:</strong> <a id="footer_phoneLink" href="tel:8474834724" class="text-font-color footer-link">(847) 483-4724</a>
546                            </div>
547                                                                                                    <div class="mx-auto content-medium">
548                                <strong>Email:</strong> <a id="footer_ContactEmail" title="[email protected]" class="text-font-color break-word-hyphen" href="mailto:[email protected]">Mvcpaintingandremodeling<wbr>@gmail<wbr>.com</a>
549                            </div>
550                    </div>
551                </div>
552            </div>
553        <div id="footer-hours" class='col-sm-3 col-md-4 col-lg-3 mx-auto footer-content d-flex flex-wrap justify-content-center'>
554            <div class="justify-content-left text-font-color">
555                    <div class="footer-hours-detail business-info-footer">
556                        <div class="row">
557                            <div class="col-12 footer-header mt-2 mb-2 text-nowrap">Our Hours</div>
558                        </div>
559                                                    <div class="row">
560                                <div class="col-12 content-medium pt-1 pb-1">Holiday Hours May Vary. Please Call For Details.</div>
561                            </div>
562                                                        <div class="row content-medium pt-1 pb-1">
563                                    <div class="col-6">
564                                        <div class="mr-3 font-weight-bold">
565                                            Monday
566                                        </div>
567                                    </div>
568                                    <div class="col-6">
569                                                    <div class="contact-hours ml-1 text-nowrap">
570                                                        7:00 AM - 7:00 PM
571                                                    </div>
572                                    </div>
573                                </div>
574                        
575                                <div class="row content-medium pt-1 pb-1">
576                                    <div class="col-6">
577                                        <div class="mr-3 font-weight-bold">
578                                            Tuesday
579                                        </div>
580                                    </div>
581                                    <div class="col-6">
582                                                    <div class="contact-hours ml-1 text-nowrap">
583                                                        7:00 AM - 7:00 PM
584                                                    </div>
585                                    </div>
586                                </div>
587                        
588                                <div class="row content-medium pt-1 pb-1">
589                                    <div class="col-6">
590                                        <div class="mr-3 font-weight-bold">
591                                            Wednesday
592                                        </div>
593                                    </div>
594                                    <div class="col-6">
595                                                    <div class="contact-hours ml-1 text-nowrap">
596                                                        7:00 AM - 7:00 PM
597                                                    </div>
598                                    </div>
599                                </div>
600                        
601                                <div class="row content-medium pt-1 pb-1">
602                                    <div class="col-6">
603                                        <div class="mr-3 font-weight-bold">
604                                            Thursday
605                                        </div>
606                                    </div>
607                                    <div class="col-6">
608                                                    <div class="contact-hours ml-1 text-nowrap">
609                                                        7:00 AM - 7:00 PM
610                                                    </div>
611                                    </div>
612                                </div>
613                        
614                                <div class="row content-medium pt-1 pb-1">
615                                    <div class="col-6">
616                                        <div class="mr-3 font-weight-bold">
617                                            Friday
618                                        </div>
619                                    </div>
620                                    <div class="col-6">
621                                                    <div class="contact-hours ml-1 text-nowrap">
622                                                        7:00 AM - 7:00 PM
623                                                    </div>
624                                    </div>
625                                </div>
626                        
627                                <div class="row content-medium pt-1 pb-1">
628                                    <div class="col-6">
629                                        <div class="mr-3 font-weight-bold">
630                                            Saturday
631                                        </div>
632                                    </div>
633                                    <div class="col-6">
634                                                    <div class="contact-hours ml-1 text-nowrap">
635                                                        7:00 AM - 7:00 PM
636                                                    </div>
637                                    </div>
638                                </div>
639                        
640                                <div class="row content-medium pt-1 pb-1">
641                                    <div class="col-6">
642                                        <div class="mr-3 font-weight-bold">
643                                            Sunday
644                                        </div>
645                                    </div>
646                                    <div class="col-6">
647                                                    <div class="contact-hours ml-1 text-nowrap">
648                                                        7:00 AM - 7:00 PM
649                                                    </div>
650                                    </div>
651                                </div>
652                    </div>
653            </div>
654        </div>
655            <div id="footer-certificationandassociation" class="col-sm-3 col-md-4 col-lg-3 mx-auto footer-content d-flex flex-wrap">
656                <div class="justify-content-left text-font-color">
657                        <div id="associationsHeader" class="footer-header text-left mb-2 mt-2 text-nowrap">Associations</div>
658                            <div id="associations">Better Business Bureau Accredited Business</div>
659                </div>
660            </div>
661        <div id="footer-sitenav" class='col-sm-3 col-md-4 col-lg-3 mx-auto footer-content d-flex flex-wrap justify-content-center'>
662            <div class="justify-content-left text-font-color">
663                <div class="footer-header text-left mb-2 mt-2 text-nowrap">Site Navigation</div>
664
665
666<div class="text-left content-medium mx-auto text-nowrap pb-1">            <a href="#" id="HomePageNavigationLink" class="text-font-color footer-link" onclick="DisplayPage('#homePage')">Home</a>
667</div><div class="text-left content-medium mx-auto text-nowrap pb-1">            <a href="#" id="AboutPageNavigationLink" class="text-font-color footer-link" onclick="DisplayPage('#aboutPage')">About</a>
668</div><div class="text-left content-medium mx-auto text-nowrap pb-1">            <a href="#" id="PhotosNavigationLink" class="text-font-color footer-link" onclick="DisplayPage('#imageryPage')">Gallery</a>
669</div><div class="text-left content-medium mx-auto text-nowrap pb-1">            <a href="#" id="ServicesPageNavigationLink" class="text-font-color footer-link" onclick="DisplayPage('#servicesPage')">Services</a>
670</div><div class="text-left content-medium mx-auto text-nowrap pb-1">            <a href="#" id="testimonialsPageNavigationLink" class="text-font-color footer-link" onclick="DisplayPage('#testimonialsPage')">Testimonials</a>
671</div><div class="text-left content-medium mx-auto text-nowrap pb-1">            <a href="#" id="FaqPageNavigationLink" class="text-font-color footer-link" onclick="DisplayPage('#faqPage')">FAQ</a>
672</div><div class="text-left content-medium mx-auto text-nowrap pb-1">            <a href="#" id="ContactPageNavigationLink" class="text-font-color footer-link" onclick="DisplayPage('#contactPage')">Contact</a>
673</div><div class="text-left content-medium mx-auto text-nowrap pb-1">            <a href="#" id="PostsPageNavigationLink" class="text-font-color footer-link" onclick="DisplayPage('#postsPage')">News</a>
674</div>                                    <div class="text-left content-medium mx-auto text-nowrap">
675                        <a href="/Accessibility?domain=mvcpaintingandremodeling" target="_blank" class="text-font-color footer-link">
676                            Text-Only Site Version
677                        </a>
678                    </div>
679            </div>
680        </div>
681    </div>
682</div>
683
684<div class="d-flex flex-wrap text-center justify-content-center pb-3 pl-3 pr-3">
685        <div class="d-flex text-center text-nowrap tos pt-1 w-100 justify-content-center">
686            <a class="text-font-color" href="/Home/TermsOfUse" id="tosLink" target="_blank">Terms of Use</a><div id="footerdash">&nbsp;|&nbsp;</div><a class="text-font-color" href="/Home/PrivacyPolicy" id="ppLink" target="_blank">Privacy Policy</a>
687        </div>
688        <div class="d-flex text-center pt-2 w-100 justify-content-center" style="font-size: 0.75rem; color: #999;">
689            &copy; 2026 American Marketing & Publishing, L.L.C. All rights reserved. Names, logos, and other marks displayed are the property of their respective owners.
690        </div>
691    </div>
692</footer>
693
694    <div class="accessibility-img py-2 px-2">
695        <div class="d-flex flex-wrap justify-content-center align-items-center text-center">
696            <a href="/Accessibility?domain=mvcpaintingandremodeling" target="_blank" class="dark">
697                <img src="/Content/Templates/images/accessibility_icon.png" height="60" width="42" />
698            </a>
699        </div>
700    </div>
701
702
703
704
705<div class="chatbot-toggle-container">
706  <button id="chatbot-toggle">
707    <img src="/Content/Templates/images/chat_icon.png" height="60" width="60" />
708  </button>
709</div>
710
711<!-- Chat Window -->
712<div id="chat-window">
713  <!-- Chat Header -->
714  <div class="chat-header">
715    <div class="chat-header-content">
716      <h3 class="chat-header-title">MVC Painting & Remodeling Assistant</h3>
717    </div>
718    <button id="close-chat" class="chat-close-btn" aria-label="Close chat">
719      <i class="fas fa-times"></i>
720    </button>
721  </div>
722
723  <!-- Chat Messages -->
724  <div id="chat-messages">
725    <div class="chat-message-container">
726      <div class="chat-message">
727        Hi there! How can we help you today?
728      </div>
729    </div>
730  </div>
731
732  <div id="disclaimer-info">
733    <div class="disclaimer-content">
734      <div class="disclaimer-text">
735        AI Responses not guaranteed; verify before reliance
736      </div>
737    </div>
738  </div>
739
740  <!-- Cost Display -->
741  <div id="cost-info">
742    <div class="cost-info-row">
743      <div class="cost-info-left">
744        <i class="fas fa-dollar-sign fa-xs cost-icon"></i>
745        <span id="cost-display">Cost: $0.00000</span>
746      </div>
747      <span id="percentage-display">0.0% of $0.02</span>
748    </div>
749    <div class="cost-progress-bar">
750      <div id="cost-progress"></div>
751    </div>
752  </div>
753
754  <!-- Chat Input -->
755  <div class="chat-input-container">
756    <form id="chat-form">
757      <input type="text" id="chat-input" placeholder="Type your message..." />
758      <button type="submit" id="send-message">
759        <i class="fas fa-paper-plane"></i>
760      </button>
761    </form>
762    <div id="character-count">0/250</div>
763    <div id="character-limit-message" style="display: none; color: #dc2626; font-size: 12px; margin-top: 4px;">
764      Your message is too long. Please limit your question to 250 characters or less.
765    </div>
766  </div>
767</div>
768
769<!-- Contact Form Window -->
770<div id="contact-form-window">
771  <div class="contact-form-header">
772    <h3 class="contact-form-title">Contact Form</h3>
773    <button id="close-contact-form" class="contact-form-close-btn" aria-label="Close contact form">
774      <i class="fas fa-times"></i>
775    </button>
776  </div>
777
778  <div class="contact-form-content">
779    <form id="chatbot-contact-form">
780      <input type="hidden" id="chat_captcha_alt" name="chat_captcha_alt" value="UYfyb/WERpmeMnnvZj69yeOuRchPsHZcJdam/+DPezdE5uDovSQ/j68sqE+m9ws8" />
781      <input type="hidden" id="chat_g-Recaptcha-Response-Contact" name="chat_g-Recaptcha-Response-Contact" value="" />
782      <input type="hidden" name="chat_aid" value="f1d963e9-84de-463c-ae3a-90eb1fa15290" />
783      <input type="hidden" name="chat_contactSubject" value="FrontDesk&#8482; Contact Form" />
784      <input type="hidden" name="chat_contactAddress" value="" />
785      <input type="hidden" name="chat_contactZip" value="" />
786      <input type="hidden" name="chat_contactCity" value="" />
787      <input type="hidden" name="chat_contactState" value="" />
788
789      <div class="ai-liability mt-1 mb-1">(Messages sent through this site are subject to third party moderation and are not encrypted or secure. We always try to respond as soon as possible, but off-hours inquiries may take us a little longer to reply.)</div>
790
791      <div class="form-group">
792        <label for="chat_contactName" class="form-label">Name *</label>
793        <input type="text" id="chat_contactName" name="chat_contactName" class="form-input" required />
794      </div>
795
796      <div class="form-group">
797        <label for="chat_contactEmail" class="form-label">Email *</label>
798        <input type="email" id="chat_contactEmail" name="chat_contactEmail" class="form-input" required />
799      </div>
800
801      <div class="form-group">
802        <label for="chat_contactPhone" class="form-label">Phone</label>
803        <input type="tel" id="chat_contactPhone" name="chat_contactPhone" class="form-input" />
804      </div>
805
806      <div class="form-group">
807        <label for="chat_contactMessage" class="form-label">Message *</label>
808        <textarea id="chat_contactMessage" name="chat_contactMessage" rows="4" class="form-textarea" required></textarea>
809      </div>
810
811      <div id="classicCaptcha" class="d-flex flex-column">
812        <div class="g-recaptcha ml-auto mb-3 captcha-responsive" data-sitekey="6LeprWcUAAAAAF533Xd5p6kCrnRs0z4ceJieYgeO"></div>
813      </div>
814
815      <!-- Sticky footer section with reCAPTCHA disclaimer and submit button -->
816      <div class="form-sticky-footer">
817        <div class="grecaptcha-info">
818          This site is protected by reCAPTCHA and the Google
819          <a href="https://policies.google.com/privacy">Privacy Policy</a> and
820          <a href="https://policies.google.com/terms">Terms of Service</a> apply.
821        </div>
822        <button type="submit" id="contact-submit-btn" class="form-submit-btn">Submit</button>
823      </div>
824    </form>
825  </div>
826</div>
827
828<script>
829    // Wrap entire chatbot functionality in a namespace to prevent conflicts
830    window.ChatbotModule = (function() {
831        'use strict';
832
833        // Private variables
834        let isOpen = false;
835        let contactFormOpen = false;
836        let messages = [
837            { role: 'assistant', content: 'Hi there! How can we help you today?' }
838        ];
839        let isLoading = false;
840        let showContactForm = false;
841        let limitReached = false;
842        let apiCost = 0;
843        const maxCost = 0.5;
844        const maxQuestionLength = 250;
845
846        // Private element references
847        let $chatbotToggle;
848        let $chatWindow;
849        let $contactFormWindow;
850        let $closeChat;
851        let $closeContactForm;
852        let $chatMessages;
853        let $chatForm;
854        let $chatInput;
855        let $sendMessage;
856        let $characterCount;
857        let $costDisplay;
858        let $percentageDisplay;
859        let $costProgress;
860        let $contactForm;
861
862        // Initialize element references
863        function initializeElements() {
864            $chatbotToggle = $('#chatbot-toggle');
865            $chatWindow = $('#chat-window');
866            $contactFormWindow = $('#contact-form-window');
867            $closeChat = $('#close-chat');
868            $closeContactForm = $('#close-contact-form');
869            $chatMessages = $('#chat-messages');
870            $chatForm = $('#chat-form');
871            $chatInput = $('#chat-input');
872            $sendMessage = $('#send-message');
873            $characterCount = $('#character-count');
874            $costDisplay = $('#cost-display');
875            $percentageDisplay = $('#percentage-display');
876            $costProgress = $('#cost-progress');
877            $contactForm = $('#chatbot-contact-form');
878        }
879
880        // Initialize
881        function init() {
882            // Initialize element references
883            initializeElements();
884
885            // Load cost from localStorage
886            const savedCost = localStorage.getItem('api_cost');
887            if (savedCost) {
888                apiCost = parseFloat(savedCost);
889
890                // Check if cost limit is reached
891                if (apiCost >= maxCost) {
892                    limitReached = true;
893                    updateChatInputState();
894                }
895            }
896
897            // Initialize character count display
898            updateCharacterCount();
899
900            document.documentElement.style.setProperty('--adaptive-text-color', '#374151');
901            document.documentElement.style.setProperty('--image-invert', 'none');
902
903            setTimeout(updateTextColors, 100);
904
905            // Ensure chatbot stays on top even when modals are opened
906            $(document).on('shown.bs.modal', function (e) {
907              // Temporarily boost chatbot z-index when modals are shown
908              $('.chatbot-toggle-container').css('z-index', '2147483647');
909              $('#chat-window').css('z-index', '2147483646');
910              $('#contact-form-window').css('z-index', '2147483645');
911            });
912
913            // Set up event listeners
914            setupEventListeners();
915        }
916
917        // Event Listeners with namespacing
918        function setupEventListeners() {
919            // Remove any existing chatbot event listeners to prevent duplicates
920            $chatbotToggle.off('.chatbot');
921            $closeChat.off('.chatbot');
922            $closeContactForm.off('.chatbot');
923            $chatForm.off('.chatbot');
924            $chatInput.off('.chatbot');
925            $contactForm.off('.chatbot');
926
927            // Toggle chat window
928            $chatbotToggle.on('click.chatbot', function(e) {
929                e.preventDefault();
930                e.stopPropagation();
931                toggleChat();
932            });
933
934            $closeChat.on('click.chatbot', function(e) {
935                e.preventDefault();
936                e.stopPropagation();
937                closeChat();
938            });
939
940            $closeContactForm.on('click.chatbot', function(e) {
941                e.preventDefault();
942                e.stopPropagation();
943                hideContactForm();
944            });
945
946            // Send message
947            $chatForm.on('submit.chatbot', function (e) {
948                e.preventDefault();
949                e.stopPropagation();
950
951                // Check if submit button is disabled
952                if ($sendMessage.prop('disabled') || $sendMessage.hasClass('disabled')) {
953                    return false;
954                }
955
956                sendMessage();
957            });
958
959            // Character count - update on every keystroke
960            $chatInput.on('input.chatbot', function(e) {
961                // Only handle if this is specifically the chatbot input
962                if ($(this).attr('id') === 'chat-input') {
963                    updateCharacterCount();
964                }
965            });
966
967            // Also check on keyup to catch paste events
968            $chatInput.on('keyup.chatbot paste.chatbot', function(e) {
969                // Only handle if this is specifically the chatbot input
970                if ($(this).attr('id') === 'chat-input') {
971                    setTimeout(updateCharacterCount, 10);
972                }
973            });
974
975            // Handle "Enter" key for sending messages
976            $chatInput.on('keydown.chatbot', function (e) {
977                // Only handle if this is specifically the chatbot input
978                if ($(this).attr('id') !== 'chat-input') {
979                    return;
980                }
981
982                if (e.key === 'Enter' && !e.shiftKey && !limitReached) {
983                    e.preventDefault();
984                    e.stopImmediatePropagation();
985
986                    // Check if submit button is disabled
987                    if ($sendMessage.prop('disabled') || $sendMessage.hasClass('disabled')) {
988                        return false;
989                    }
990
991                    sendMessage();
992                    return;
993                }
994            });
995
996            // Contact form submission
997            $contactForm.on('submit.chatbot', function (e) {
998                e.preventDefault();
999                e.stopPropagation();
1000                submitContactForm();
1001            });
1002        }
1003
1004        // Toggle chat window
1005      function toggleChat() {
1006        if (!isOpen) {
1007          // Opening the chat
1008          isOpen = true;
1009
1010          // Hide toggle button on both mobile and desktop
1011          $('.chatbot-toggle-container').addClass('hide-toggle');
1012
1013          // First show the window (still off-screen)
1014          $chatWindow.show();
1015
1016          // Force a reflow to ensure the transition will work
1017          $chatWindow[0].offsetHeight;
1018
1019          // Then add the class that triggers the slide-in animation
1020          setTimeout(function () {
1021            $chatWindow.addClass('show');
1022            scrollToBottom();
1023          }, 10);
1024        } else {
1025          // Closing the chat
1026          isOpen = false;
1027
1028          // Show toggle button again
1029          $('.chatbot-toggle-container').removeClass('hide-toggle');
1030
1031          // Remove the show class to trigger slide-out animation
1032          $chatWindow.removeClass('show');
1033
1034          // Hide the window after the animation completes
1035          setTimeout(function () {
1036            $chatWindow.hide();
1037          }, 300); // Match the CSS transition duration
1038
1039          // Also hide contact form if open
1040          if (contactFormOpen) {
1041            hideContactForm();
1042          }
1043        }
1044      }
1045
1046        // Close chat window
1047      function closeChat() {
1048        if (isOpen) {
1049          isOpen = false;
1050
1051          // Show toggle button again
1052          $('.chatbot-toggle-container').removeClass('hide-toggle');
1053
1054          // Trigger slide-out animation
1055          $chatWindow.removeClass('show');
1056
1057          // Hide after animation
1058          setTimeout(function () {
1059            $chatWindow.hide();
1060          }, 300);
1061
1062          if (contactFormOpen) {
1063            hideContactForm();
1064          }
1065        }
1066      }
1067
1068        // Update character count and submit button state
1069        function updateCharacterCount() {
1070            const count = $chatInput.val().length;
1071            const remaining = maxQuestionLength - count;
1072            const $limitMessage = $('#character-limit-message');
1073
1074            if (count > maxQuestionLength) {
1075                // Over limit - disable submit button and show message
1076                $characterCount.text(`${count}/${maxQuestionLength} (${Math.abs(remaining)} over limit)`).css('color', '#dc2626');
1077                $limitMessage.text(`Your message is too long. Please limit your question to ${maxQuestionLength} characters or less. Your message is currently ${count} characters.`).show();
1078                $chatInput.addClass('over-limit');
1079
1080                // Disable submit button with proper styling
1081                $sendMessage.prop('disabled', true).addClass('disabled');
1082                $sendMessage.css({
1083                    'background-color': '#9ca3af',
1084                    'color': '#6b7280',
1085                    'cursor': 'not-allowed',
1086                    'opacity': '0.5',
1087                    'pointer-events': 'none'
1088                });
1089
1090            } else if (remaining <= 20) {
1091                // Close to limit - show warning but allow submit
1092                $characterCount.text(`${count}/${maxQuestionLength}`).css('color', '#f59e0b');
1093                $limitMessage.hide();
1094                $chatInput.removeClass('over-limit');
1095
1096                // Enable submit button and reset styling
1097                $sendMessage.prop('disabled', false).removeClass('disabled');
1098                $sendMessage.css({
1099                    'background-color': '',
1100                    'color': '',
1101                    'cursor': '',
1102                    'opacity': '',
1103                    'pointer-events': ''
1104                });
1105
1106            } else {
1107                // Within limit - normal state
1108                $characterCount.text(`${count}/${maxQuestionLength}`).css('color', '#6b7280');
1109                $limitMessage.hide();
1110                $chatInput.removeClass('over-limit');
1111
1112                // Enable submit button and reset styling
1113                $sendMessage.prop('disabled', false).removeClass('disabled');
1114                $sendMessage.css({
1115                    'background-color': '',
1116                    'color': '',
1117                    'cursor': '',
1118                    'opacity': '',
1119                    'pointer-events': ''
1120                });
1121            }
1122        }
1123
1124        // Send message
1125        function sendMessage() {
1126            const message = $chatInput.val().trim();
1127            if (!message || isLoading || limitReached) return;
1128
1129            // Double check character limit including whitespace
1130            if (message.length > maxQuestionLength) {
1131                appendMessage('assistant', `Your message is too long. Please limit your question to ${maxQuestionLength} characters or less. Your message is currently ${message.length} characters.`);
1132                return;
1133            }
1134
1135            // Add user message to chat
1136            messages.push({ role: 'user', content: message });
1137            appendMessage('user', message);
1138
1139            // Clear input
1140            $chatInput.val('');
1141            updateCharacterCount();
1142
1143            // Send to API
1144            fetchChatResponse(messages);
1145        }
1146
1147        // Fetch chat response from API
1148        function fetchChatResponse(messages) {
1149            isLoading = true;
1150            showLoadingIndicator();
1151
1152            $.ajax({
1153                url: '/Home/Chat',
1154                type: 'POST',
1155                contentType: 'application/json',
1156                data: JSON.stringify({
1157                    Messages: messages,
1158                    ProfileId: '42094'
1159                }),
1160                headers: {
1161                    'RequestVerificationToken': $('input[name="__RequestVerificationToken"]').val()
1162                },
1163                success: function (response) {
1164                    hideLoadingIndicator();
1165
1166                    if (response.error) {
1167                        appendMessage('assistant', `Error: ${response.error}`);
1168                        console.error('API Error:', response.error);
1169                        isLoading = false;
1170                        return;
1171                    }
1172
1173                    // Update cost
1174                    apiCost = response.Cost;
1175                    localStorage.setItem('api_cost', apiCost.toString());
1176
1177                    // Check if limit reached
1178                    if (response.LimitReached) {
1179                        limitReached = true;
1180                        showContactFormWindow();
1181                        appendMessage('assistant', 'Our AI chat has reached its capacity. Please use the contact form to get in touch directly with us.');
1182                    } else {
1183                        // Check if response contains contact form trigger
1184                        if (response.Message.includes('<start_contact_form>')) {
1185                            const cleanResponse = response.Message.replace('<start_contact_form>', '');
1186                            appendMessage('assistant', cleanResponse);
1187                            showContactFormWindow();
1188                        } else {
1189                            appendMessage('assistant', response.Message);
1190                        }
1191
1192                        // Add response to messages array
1193                        messages.push({ role: 'assistant', content: response.Message });
1194                    }
1195
1196                    isLoading = false;
1197                    updateChatInputState();
1198                },
1199                error: function (xhr, status, error) {
1200                    hideLoadingIndicator();
1201                    appendMessage('assistant', 'Sorry, I encountered an error. Please try again later.');
1202                    console.error('AJAX Error:', error);
1203                    isLoading = false;
1204                }
1205            });
1206        }
1207
1208        // Append message to chat
1209        function appendMessage(role, content) {
1210            content = convertMarkdownLinksToHTML(content);
1211            const rootStyles = getComputedStyle(document.documentElement);
1212            const customerColor = rootStyles.getPropertyValue('--customer_color').trim();
1213            const adaptivefontColor = rootStyles.getPropertyValue('--adaptive-text-color').trim();
1214
1215            const messageClass = role === 'user' ? 'flex-end' : 'flex-start';
1216            const bgColor = role === 'user' ? customerColor : 'white';
1217            const textColor = role === 'user' ? adaptivefontColor : '#374151';
1218            const borderRadius = role === 'user' ? 'border-bottom-right-radius: 0;' : 'border-bottom-left-radius: 0;';
1219            const border = role === 'user' ? '' : 'border: 1px solid #e5e7eb;';
1220
1221            const messageHtml = `
1222                <div style="display: flex; justify-content: ${messageClass}; margin-bottom: 16px;">
1223                    <div style="max-width: 75%; padding: 12px; border-radius: 8px; background-color: ${bgColor}; ${border} ${borderRadius} color: ${textColor}; word-wrap: break-word; overflow-wrap: break-word;">
1224                        ${content}
1225                    </div>
1226                </div>
1227            `;
1228
1229            $chatMessages.append(messageHtml);
1230            scrollToBottom();
1231        }
1232
1233        // Show loading indicator
1234        function showLoadingIndicator() {
1235            const loadingHtml = `
1236                <div id="loading-indicator" style="display: flex; justify-content: flex-start; margin-bottom: 16px;">
1237                    <div style="max-width: 75%; padding: 12px; border-radius: 8px; background-color: white; border: 1px solid #e5e7eb; color: #374151; display: flex; gap: 4px;">
1238                        <div class="loading-dot" style="width: 8px; height: 8px; background-color: #9ca3af; border-radius: 50%;"></div>
1239                        <div class="loading-dot" style="width: 8px; height: 8px; background-color: #9ca3af; border-radius: 50%;"></div>
1240                        <div class="loading-dot" style="width: 8px; height: 8px; background-color: #9ca3af; border-radius: 50%;"></div>
1241                    </div>
1242                </div>
1243            `;
1244
1245            $chatMessages.append(loadingHtml);
1246            animateLoadingDots();
1247            scrollToBottom();
1248
1249            // Disable input while loading
1250            $chatInput.prop('disabled', true);
1251            $sendMessage.prop('disabled', true);
1252        }
1253
1254        // Animate loading dots
1255        function animateLoadingDots() {
1256            if (!$("#loading-indicator").length) return;
1257
1258            $(".loading-dot").each(function (index) {
1259                var $dot = $(this);
1260                setTimeout(function () {
1261                    $dot.animate({ opacity: 0.3 }, 300)
1262                        .animate({ opacity: 1 }, 300);
1263                }, index * 200);
1264            });
1265
1266            setTimeout(function () {
1267                animateLoadingDots();
1268            }, 900);
1269        }
1270
1271        // Hide loading indicator
1272        function hideLoadingIndicator() {
1273            $('#loading-indicator').remove();
1274
1275            // Enable input after loading (unless limit reached)
1276            if (!limitReached) {
1277                $chatInput.prop('disabled', false);
1278                updateCharacterCount(); // This will set the correct submit button state
1279            }
1280        }
1281
1282        // Scroll to bottom of chat
1283        function scrollToBottom() {
1284            $chatMessages.scrollTop($chatMessages[0].scrollHeight);
1285        }
1286
1287        // Update cost display
1288        function updateCostDisplay() {
1289            $("#cost-info").show();
1290            $costDisplay.text(`Cost: $${apiCost.toFixed(5)}`);
1291
1292            const percentage = (apiCost / maxCost) * 100;
1293            $percentageDisplay.text(`${percentage.toFixed(1)}% of $${maxCost.toFixed(2)}`);
1294
1295            $costProgress.css('width', `${percentage}%`);
1296
1297            // Change progress bar color if near limit
1298            if (percentage > 80) {
1299                $costProgress.css("background-color", "#dc2626");
1300            } else {
1301                $costProgress.css("background-color", "#4f46e5");
1302            }
1303
1304            // Update chat input state
1305            updateChatInputState();
1306        }
1307
1308        // Update chat input state based on limit
1309        function updateChatInputState() {
1310            if (limitReached) {
1311                $chatInput.prop('disabled', true);
1312                $sendMessage.prop('disabled', true);
1313                $chatInput.attr('placeholder', 'Chat Unavailable.');
1314            } else {
1315                $chatInput.prop('disabled', false);
1316                updateCharacterCount(); // This will set the correct submit button state
1317                $chatInput.attr('placeholder', 'Type your message...');
1318            }
1319        }
1320
1321        // Show contact form
1322      function showContactFormWindow() {
1323        if (!contactFormOpen) {
1324          contactFormOpen = true;
1325
1326          // Hide toggle button when contact form opens
1327          $('.chatbot-toggle-container').addClass('hide-toggle');
1328
1329          if (isMobile()) {
1330            // On mobile, slide out chat and slide in contact form
1331            $chatWindow.removeClass('show');
1332            setTimeout(function () {
1333              $chatWindow.hide();
1334              $contactFormWindow.show();
1335              // Force reflow
1336              $contactFormWindow[0].offsetHeight;
1337              // Add show class for slide animation
1338              setTimeout(function () {
1339                $contactFormWindow.addClass('show');
1340                $('.contact-form-content').scrollTop(0);
1341              }, 10);
1342            }, 300);
1343          } else {
1344            // Desktop - slide chat to left and slide in contact form
1345            $chatWindow.animate({ right: '390px' }, 300);
1346            $contactFormWindow.show();
1347            setTimeout(function () {
1348              $contactFormWindow.animate({ right: '20px' }, 300);
1349            }, 50);
1350          }
1351        }
1352      }
1353
1354      // Hide contact form - slides out and chat returns to original position
1355      function hideContactForm() {
1356        if (contactFormOpen) {
1357          contactFormOpen = false;
1358
1359          if (isMobile()) {
1360            // Slide out contact form
1361            $contactFormWindow.removeClass('show');
1362
1363            setTimeout(function () {
1364              $contactFormWindow.hide();
1365              // Show chat window again if it was open
1366              if (isOpen) {
1367                $chatWindow.show();
1368                // Force reflow
1369                $chatWindow[0].offsetHeight;
1370                setTimeout(function () {
1371                  $chatWindow.addClass('show');
1372                }, 10);
1373              } else {
1374                // If chat is not open, show toggle button
1375                $('.chatbot-toggle-container').removeClass('hide-toggle');
1376              }
1377            }, 300);
1378          } else {
1379            // Desktop - animate back
1380            $contactFormWindow.animate({ right: '-370px' }, 300, function () {
1381              $contactFormWindow.hide();
1382            });
1383            $chatWindow.animate({ right: '20px' }, 300);
1384
1385            // Only show toggle if both windows are closed
1386            if (!isOpen) {
1387              $('.chatbot-toggle-container').removeClass('hide-toggle');
1388            }
1389          }
1390        }
1391      }
1392
1393      // Submit contact form
1394        function submitContactForm() {
1395            const name = $('#chat_contactName').val();
1396            const email = $('#chat_contactEmail').val();
1397            const phone = $('#chat_contactPhone').val();
1398            const message = $('#chat_contactMessage').val();
1399
1400            // Basic validation
1401            if (!name || !email || !message) {
1402                alert('Please fill out all required fields.');
1403                return;
1404            }
1405
1406            // Email validation
1407            const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
1408            if (!emailRegex.test(email)) {
1409                alert('Please enter a valid email address.');
1410                return;
1411            }
1412
1413            // Message length validation
1414            if (message.length < 10) {
1415                alert('Your message must be at least 10 characters long.');
1416                return;
1417            }
1418
1419            // Disable form during submission
1420            $('#contact-submit-btn').prop('disabled', true).text('Sending...');
1421
1422            var form = $("#chatbot-contact-form");
1423
1424            // Execute reCAPTCHA before submitting
1425            grecaptcha.ready(function() {
1426                grecaptcha.execute('6LcokacUAAAAAH_snk3O5bpdYwjpC5XAuXNLrJLH', {action: 'contact_us'}).then(function(token) {
1427                    // Set the reCAPTCHA token
1428                    $("#chat_g-Recaptcha-Response-Contact").val(token);
1429
1430                    // Submit the form with reCAPTCHA token
1431                    $.ajax({
1432                        url: "/Home/ChatContactPost",
1433                        type: 'POST',
1434                        data: form.serialize(),
1435                        success: function (response) {
1436                            if (typeof response === 'string' && response.indexOf('{"message":') != -1) {
1437                                var jsonData = JSON.parse(response);
1438                                if (jsonData.success) {
1439                                    appendMessage('assistant', 'Thanks for providing your information! We will get back to you soon.');
1440                                    hideContactForm();
1441
1442                                    // Reset the form
1443                                    $('#chat_contactName').val('');
1444                                    $('#chat_contactEmail').val('');
1445                                    $('#chat_contactPhone').val('');
1446                                    $('#chat_contactMessage').val('');
1447                                } else {
1448                                    alert(jsonData.message || 'There was an error processing your request.');
1449                                }
1450                            } else if (response.success) {
1451                                appendMessage('assistant', 'Thanks for providing your information! We will get back to you soon.');
1452                                hideContactForm();
1453
1454                                // Reset the form
1455                                $('#chat_contactName').val('');
1456                                $('#chat_contactEmail').val('');
1457                                $('#chat_contactPhone').val('');
1458                                $('#chat_contactMessage').val('');
1459
1460                            } else {
1461                                alert(response.message || 'There was an error processing your request.');
1462                            }
1463
1464                            $('#contact-submit-btn').prop('disabled', false).text('Submit');
1465                        },
1466                        error: function (xhr, status, error) {
1467                            alert('Failed to submit your information. Please try again.');
1468                            console.error('AJAX Error:', error);
1469                            $('#contact-submit-btn').prop('disabled', false).text('Submit');
1470                        }
1471                    });
1472                });
1473            });
1474        }
1475
1476        function convertMarkdownLinksToHTML(text) {
1477            return text.replace(/\[([^\]]+)\]\(([^)]+)\)/g, (match, linkText, url) => {
1478                // Add target="_blank" for http/https links
1479                if (url.startsWith('http://') || url.startsWith('https://')) {
1480                    return `<a href="${url}" target="_blank" rel="noopener noreferrer">${linkText}</a>`;
1481                }
1482                // Keep tel: and mailto: links as-is
1483                return `<a href="${url}">${linkText}</a>`;
1484            });
1485        }
1486
1487        function getLuminance(hex) {
1488            // Remove # if present
1489            hex = hex.replace('#', '');
1490
1491            // Convert hex to RGB
1492            const r = parseInt(hex.substr(0, 2), 16) / 255;
1493            const g = parseInt(hex.substr(2, 2), 16) / 255;
1494            const b = parseInt(hex.substr(4, 2), 16) / 255;
1495
1496            // Calculate relative luminance
1497            const rLum = r <= 0.03928 ? r / 12.92 : Math.pow((r + 0.055) / 1.055, 2.4);
1498            const gLum = g <= 0.03928 ? g / 12.92 : Math.pow((g + 0.055) / 1.055, 2.4);
1499            const bLum = b <= 0.03928 ? b / 12.92 : Math.pow((b + 0.055) / 1.055, 2.4);
1500
1501            return 0.2126 * rLum + 0.7152 * gLum + 0.0722 * bLum;
1502        }
1503
1504        function isLightColor(hex) {
1505            const luminance = getLuminance(hex);
1506            return luminance > 0.5; // Threshold for light vs dark
1507        }
1508
1509        function updateTextColors() {
1510            const rootStyles = getComputedStyle(document.documentElement);
1511            let customerColor = rootStyles.getPropertyValue('--customer_color').trim();
1512
1513            // Check if customer color is not set or is empty
1514            if (!customerColor || customerColor === '') {
1515                const defaultColor = '#f3f3f3';
1516
1517                // Set the default customer color
1518                document.documentElement.style.setProperty('--customer_color', defaultColor);
1519                customerColor = defaultColor;
1520            }
1521
1522            const isLight = isLightColor(customerColor);
1523            const textColor = isLight ? '#000000b3' : '#ffffff';
1524
1525            const $chatbotToggle = $('#chatbot-toggle');
1526            if (isLight) {
1527                $chatbotToggle.removeClass('dark-background').addClass('light-background');
1528            } else {
1529                $chatbotToggle.removeClass('light-background').addClass('dark-background');
1530            }
1531
1532            // Update the CSS custom property
1533            document.documentElement.style.setProperty('--adaptive-text-color', textColor);
1534        }
1535
1536        function isMobile() {
1537            return window.innerWidth <= 768;
1538        }
1539
1540        // Public interface
1541        return {
1542            init: init
1543        };
1544    })();
1545
1546    // Initialize the chatbot module when document is ready
1547    $(document).ready(function () {
1548        if (window.ChatbotModule) {
1549            window.ChatbotModule.init();
1550        }
1551    });
1552</script>
1552
1553<div id="loadingImg" class="loader" style="display:none !important">
1554    <i class="fas fa-circle"></i>
1555    <i class="fas fa-circle"></i>
1556    <i class="fas fa-circle"></i>
1557</div>
1558
1559<script type="text/javascript">
1560    var isMobile = false;
1561    var isTablet = false;
1562    var itemsVisible = false; // false indicates that items are initially hidden
1563    var pageSize = 5;
1564    var pageIndex = 0;
1565    var hasbanner = false;
1566    var keepPostUp = false;
1567    var listOfSites = "";
1568    var testimonialPageBackgroundColor = '#77224B';
1569    var numOfPosts = 5;
1570    var postsPageIndex = 0;
1571    var geocode = null;
1572    var selectedServiceId = null;
1573    var servicesRendered = false;
1574    var aboutRendered = false;
1575    var testimonialsRendered = false;
1576    var contactRendered = false;
1577    var photosRendered = false;
1578    var faqRendered = false;
1579    var locationsRendered = false;
1580    var additionalContentRendered = false;
1581    var isSubmittingReview = false; //global flag to track submission
1582
1583    $(document).ready(function () {
1584         if ($("#contact_us_phone").length > 0) {
1585            var cleave = new Cleave('#contact_us_phone', {
1586                phone: true,
1587                phoneRegionCode: 'US'
1588            });
1589        }
1590
1591        checkMobile();
1592        checkTablet();
1593        checkHashRoute();
1594        PauseVideoPlayer();
1595
1596         if(hasbanner){
1597            GetPostsBanner();
1598        }
1599
1600        $(window).on('hashchange', function(){
1601            checkHashRoute();
1602        });
1603
1604        var navMain = $("#navbarToggler");
1605        navMain.on("click", "a", null, function () {
1606            navMain.collapse('hide');
1607        });
1608
1609        document.addEventListener("visibilitychange", function () {
1610            if (document["hidden"]) {
1611                PauseVideoPlayer();
1612            }
1613        });
1614
1615        $(window).scroll(function () {
1616            var scroll = $(window).scrollTop();
1617            if (('False' == 'False') || ('False' == 'True' && window.outerWidth > 767.98)) {
1618                if (scroll > 150){
1619                    $(".content").addClass("page-section-adjust");
1620                    $(".nav-logo").addClass("nav-logo-adjust");
1621                    $(".nav-location").addClass("nav-item-adjust");
1622                }
1623                else if(scroll <= 150){
1624                    $(".content").removeClass("page-section-adjust");
1625                    $(".nav-logo").removeClass("nav-logo-adjust");
1626                    $(".nav-location").removeClass("nav-item-adjust");
1627                }
1628            }
1629        });
1630
1631        $(document).on("click", "#btnContactPost", function (e) {
1632            $("#btnContactPost").prop('disabled', true);
1633            $("#btnContactPost").css('font-weight', 'normal');
1634            contactUsPost(e);
1635        });
1636
1637        var analyticsCategory = "Desktop";
1638        if (isMobile == true) {
1639            analyticsCategory = "Mobile";
1640            if ($(window).width() < 576) {
1641                if ($("#headernav").hasClass('justify-content-between')) {
1642                    $("#headernav").removeClass('justify-content-between');
1643                }
1644                if (!$("#headernav").hasClass('justify-content-center')) {
1645                    $("#headernav").addClass('justify-content-center');
1646                }
1647                if ($("#footer-address").hasClass('justify-content-center')) {
1648                    $("#footer-address").removeClass('justify-content-center');
1649                }
1650                if ($("#footer-hours").hasClass('justify-content-center')) {
1651                    $("#footer-hours").removeClass('justify-content-center');
1652                }
1653                if ($("#footer-sitenav").hasClass('justify-content-center')) {
1654                    $("#footer-sitenav").removeClass('justify-content-center');
1655                }
1656            }
1657        }
1658
1659        if (testimonialPageBackgroundColor != null && testimonialPageBackgroundColor != '' && testimonialPageBackgroundColor != "#F5F5F5") {
1660            //set footer background color
1661            $('.custom-background-color').css('background-color', testimonialPageBackgroundColor);
1662        }
1663        else {
1664            //set footer background color to white
1665            var white = "#FFFFFF";
1666            $('.custom-background-color').css('background-color', white);
1667        }
1668
1669        $("#HomePageNavigationLink").click(function(e){
1670            $('html, body').animate({ scrollTop: 0 }, 'fast');
1671        });
1672
1673        $(".business-name").click(function(e){
1674            $('html, body').animate({ scrollTop: 0 }, 'fast');
1675        });
1676
1677        if(numOfPosts > 0){
1678            GetPostsData(0);
1679        }
1680
1681        $(document).on('click', "#nextPosts", function (e) {
1682            ScrollForPosts(e);
1683            GetPostsData(1);
1684        });
1685
1686        $(document).on('click', "#prevPosts", function (e) {
1687            ScrollForPosts(e);
1688            GetPostsData(-1);
1689        });
1690
1691        $(document).on('click', "#postReview", function (e) {
1692            e.preventDefault();
1693            e.stopPropagation();
1694
1695            if (isSubmittingReview) {
1696                console.log('Review submission already in progress - blocking duplicate submission');
1697                return false;
1698            }
1699
1700            var $button = $(this);
1701            var $form = $("#postReviewForm");
1702            var $modal = $("#reviewFormSection");
1703
1704            isSubmittingReview = true;
1705            console.log('Starting review submission');
1706
1707            setProcessingState($button, $form, true);
1708
1709            var alertType = "success";
1710
1711            if(validateReview("#postReview")) {
1712                console.log('Review validation passed');
1713                ShowLoading();
1714
1715                grecaptcha.ready(function() {
1716                    grecaptcha.execute('6LcokacUAAAAAH_snk3O5bpdYwjpC5XAuXNLrJLH', {action: 'testimonial_review'}).then(function(token) {
1717                        $("#g-Recaptcha-Response-Review").attr("value", token);
1718
1719                        var rating = null;
1720                        var selectElement = document.getElementById('starRating');
1721                        var selectRating = selectElement ? selectElement.value : null;
1722                        var selectedOption = $('#starRating option:selected').val();
1723                        var barRating = null;
1724                        var reviewerAlias = $('#review_alias').val() || '';
1725                        var reviewHeading = $('#review_heading').val() || '';
1726                        var antiForgeryToken = $('input[name="__RequestVerificationToken"]').val();
1727                        var recaptchaToken = $('#g-Recaptcha-Response-Review').val();
1728                        var timeToPost = $('#phoneNumber_alternative').val();
1729
1730                        var reviewText = $('#review').val() || '';
1731                        var profileId = 42094;
1732
1733                        console.log('Trying to get rating value...');
1734
1735                        var selectRating = $('#starRating')[0] ? $('#starRating')[0].value : null;
1736                        console.log('Select element direct value:', selectRating);
1737
1738                        var jqueryRating = $('#starRating').val();
1739                        console.log('jQuery val() result:', jqueryRating, typeof jqueryRating);
1740
1741                        if (typeof $('#starRating').barrating === 'function') {
1742                            try {
1743                                var barResult = $('#starRating').barrating('show');
1744
1745                                if (barResult && typeof barResult === 'string') {
1746                                    barRating = barResult;
1747                                } else if (barResult && typeof barResult === 'number') {
1748                                    barRating = barResult.toString();
1749                                }
1750                            } catch (e) {
1751                                console.log('Error getting barrating value:', e);
1752                            }
1753                        }
1754
1755                        var selectedOption = $('#starRating option:selected').val();
1756                        console.log('Selected option value:', selectedOption);
1757
1758                        var jqueryResult = $('#starRating').val();
1759                        var jqueryRating = null;
1760
1761                        if (jqueryResult && typeof jqueryResult === 'string') {
1762                            jqueryRating = jqueryResult;
1763                        } else if (jqueryResult && typeof jqueryResult === 'number') {
1764                            jqueryRating = jqueryResult.toString();
1765                        }
1766
1767                        if (barRating && barRating !== "" && barRating !== "0") {
1768                            rating = barRating;
1769                        } else if (selectRating && selectRating !== "" && selectRating !== "0") {
1770                            rating = selectRating;
1771                        } else if (selectedOption && selectedOption !== "" && selectedOption !== "0") {
1772                            rating = selectedOption;
1773                        } else if (jqueryRating && jqueryRating !== "" && jqueryRating !== "0") {
1774                            rating = jqueryRating;
1775                        }
1776
1777                        if (rating && typeof rating !== 'string') {
1778                            console.log('WARNING: Rating is not a string, converting:', rating, typeof rating);
1779                            rating = String(rating);
1780                        }
1781
1782                        if (rating && typeof rating === 'object') {
1783                            console.error('CRITICAL ERROR: Rating is still an object!', rating);
1784                            rating = null;
1785                        }
1786
1787                        console.log('Validation check - rating found:', rating, typeof rating);
1788                        console.log('Final rating value:', rating, typeof rating);
1789
1790                        console.log('Form values before sending:');
1791                        console.log('- Review text:', reviewText);
1792                        console.log('- Rating:', rating);
1793                        console.log('- Profile ID:', profileId);
1794                        console.log('- Reviewer alias:', reviewerAlias);
1795                        console.log('- Review heading:', reviewHeading);
1796                        console.log('- Anti-forgery token:', antiForgeryToken ? 'Present' : 'Missing');
1797
1798                        // Build form data
1799                        var formDataArray = [
1800                            { name: 'profile_id', value: profileId },
1801                            { name: 'review', value: reviewText },
1802                            { name: 'review_rating', value: rating },
1803                            { name: 'reviewer_alias', value: reviewerAlias },
1804                            { name: 'review_heading', value: reviewHeading },
1805                            { name: '__RequestVerificationToken', value: antiForgeryToken },
1806                            { name: 'g-Recaptcha-Response-Review', value: recaptchaToken },
1807                            { name: 'phoneNumber_alternative', value: timeToPost },
1808                            { name: '_t', value: new Date().getTime() }
1809                        ];
1810
1811                        var formData = formDataArray
1812                            .filter(item => item.value !== undefined && item.value !== null && item.value !== '')
1813                            .map(item => encodeURIComponent(item.name) + '=' + encodeURIComponent(item.value))
1814                            .join('&');
1815
1816                        console.log('Manual form data built:', formData);
1817
1818                        $.ajax({
1819                            url: "/Home/ReviewPost",
1820                            type: "POST",
1821                            data: formData,
1822                            contentType: "application/x-www-form-urlencoded; charset=UTF-8",
1823                            dataType: "json",
1824                            success: function(data) {
1825                                console.log('Review submission response:', data);
1826
1827                                if (!data.message || data.message.trim() === '') {
1828                                    data.message = data.success ?
1829                                        'Thank you for your review! It has been submitted successfully.' :
1830                                        'There was an issue submitting your review. Please check all fields and try again.';
1831                                }
1832
1833                                alertType = data.success ? "success" : "warning";
1834
1835                                if (!data.success) {
1836                                    recaptchaReviewIncomplete();
1837                                    showClassicCaptcha("review");
1838                                }
1839
1840                                $form.find('.alert').remove();
1841
1842                                var alertHtml = '<div class="alert alert-' + alertType + ' alert-dismissible" role="alert">' +
1843                                                '<button type="button" class="close" data-dismiss="alert" aria-label="Close">' +
1844                                                '<span aria-hidden="true">&times;</span></button>' +
1845                                                data.message + '</div>';
1846
1847                                $form.prepend(alertHtml);
1848
1849                                $modal.find('.modal-body').scrollTop(0);
1850
1851                                if(alertType === "success") {
1852                                    // Auto-hide modal after showing success message
1853                                    setTimeout(function () {
1854                                        $modal.modal('hide');
1855                                        ClearReviewFields();
1856                                    }, 3000);
1857                                }
1858
1859                                // Fade out alert after delay
1860                                setTimeout(function() {
1861                                    $form.find('.alert').fadeOut(500, function() {
1862                                        $(this).remove();
1863                                    });
1864                                }, 6000);
1865                            },
1866                            error: function(xhr, status, error) {
1867                                console.error('AJAX Error:', status, error);
1868                                console.error('Response Text:', xhr.responseText);
1869
1870                                $form.find('.alert').remove();
1871                                var errorHtml = '<div class="alert alert-danger alert-dismissible" role="alert">' +
1872                                                '<button type="button" class="close" data-dismiss="alert" aria-label="Close">' +
1873                                                '<span aria-hidden="true">&times;</span></button>' +
1874                                                'An error occurred while submitting your review. Please try again.</div>';
1875                                $form.prepend(errorHtml);
1876
1877                                $modal.find('.modal-body').scrollTop(0);
1878                            },
1879                            complete: function() {
1880                                // Reset states
1881                                console.log('Resetting processing state');
1882                                setProcessingState($button, $form, false);
1883                                HideLoading();
1884                                isSubmittingReview = false;
1885                                console.log('Review submission completed');
1886                            }
1887                        });
1888
1889                    }).catch(function(error) {
1890                        console.error('reCAPTCHA Error:', error);
1891
1892                        $form.find('.alert').remove();
1893                        var captchaErrorHtml = '<div class="alert alert-danger alert-dismissible" role="alert">
1893' +
1894                                                '<button type="button" class="close" data-dismiss="alert" aria-label="Close">' +
1895                                                '<span aria-hidden="true">&times;</span></button>' +
1896                                                'Security verification failed. Please refresh the page and try again.</div>';
1897                        $form.prepend(captchaErrorHtml);
1898
1899                        $modal.find('.modal-body').scrollTop(0);
1900                        setProcessingState($button, $form, false);
1901                        HideLoading();
1902                        isSubmittingReview = false;
1903                    });
1904                });
1905            } else {
1906                console.log('Review validation failed');
1907
1908                var missingFields = [];
1909                if (!$('#review').val() || $('#review').val().trim() === '') {
1910                    missingFields.push('review text');
1911                }
1912
1913                var rating = null;
1914                var selectRating = $('#starRating')[0] ? $('#starRating')[0].value : null;
1915                var jqueryRating = $('#starRating').val();
1916                var selectedOption = $('#starRating option:selected').val();
1917                var barRating = null;
1918
1919                if (typeof $('#starRating').barrating === 'function') {
1920                    try {
1921                        barRating = $('#starRating').barrating('show');
1922                    } catch (e) {
1923                        // Ignore error
1924                    }
1925                }
1926
1927                if (barRating && barRating !== "" && barRating !== "0") {
1928                    rating = barRating;
1929                } else if (selectRating && selectRating !== "" && selectRating !== "0") {
1930                    rating = selectRating;
1931                } else if (selectedOption && selectedOption !== "" && selectedOption !== "0") {
1932                    rating = selectedOption;
1933                } else if (typeof jqueryRating === 'string' && jqueryRating !== "" && jqueryRating !== "0") {
1934                    rating = jqueryRating;
1935                }
1936
1937                console.log('Validation check - rating found:', rating);
1938
1939                if (!rating || rating === "" || rating === "0") {
1940                    missingFields.push('rating');
1941                }
1942
1943                var validationMessage = 'Please fill out the following required fields: ' + missingFields.join(' and ') + '.';
1944                console.log('Validation message:', validationMessage);
1945
1946                $form.find('.alert').remove();
1947                var validationHtml = '<div class="alert alert-warning alert-dismissible" role="alert">' +
1948                                    '<button type="button" class="close" data-dismiss="alert" aria-label="Close">' +
1949                                    '<span aria-hidden="true">&times;</span></button>' +
1950                                    validationMessage + '</div>';
1951                $form.prepend(validationHtml);
1952
1953                $modal.find('.modal-body').scrollTop(0);
1954                setProcessingState($button, $form, false);
1955                isSubmittingReview = false;
1956
1957                return false;
1958            }
1959        });
1960
1961        $('#reviewFormSection').on('hidden.bs.modal', function () {
1962            console.log('Modal hidden - resetting submission state');
1963            isSubmittingReview = false;
1964            setProcessingState($("#postReview"), $("#postReviewForm"), false);
1965            $(this).find('.alert').remove();
1966        });
1967
1968        $('#reviewFormSection').on('show.bs.modal', function () {
1969            console.log('Modal shown - ensuring clean state');
1970            isSubmittingReview = false;
1971            setProcessingState($("#postReview"), $("#postReviewForm"), false);
1972
1973            $("#postReview").prop('disabled', false);
1974            $("#postReview").css('font-weight', 'bold');
1975
1976            setTimeout(function () {
1977                console.log('=== STAR RATING DEBUG ===');
1978                console.log('Star rating element:', $('#starRating')[0]);
1979                console.log('Star rating jQuery object:', $('#starRating'));
1980                console.log('Star rating direct value:', $('#starRating')[0] ? $('#starRating')[0].value : 'N/A');
1981                console.log('Star rating jQuery val():', $('#starRating').val());
1982                console.log('Star rating selected option:', $('#starRating option:selected').val());
1983                console.log('Barrating plugin available:', typeof $('#starRating').barrating === 'function');
1984                if (typeof $('#starRating').barrating === 'function') {
1985                    try {
1986                        console.log('Barrating current value:', $('#starRating').barrating('show'));
1987                    } catch (e) {
1988                        console.log('Error getting barrating value:', e);
1989                    }
1990                }
1991                console.log('=== END STAR RATING DEBUG ===');
1992            }, 100);
1993        });
1994
1995        // Prevent modal from closing during submission
1996        $('#reviewFormSection').on('hide.bs.modal', function (e) {
1997            if (isSubmittingReview) {
1998                console.log('Preventing modal close during submission');
1999                e.preventDefault();
2000                return false;
2001            }
2002        });
2003
2004        $('a').on('click', function () {
2005            if (this.id !== "undefined" && this.id !== "") {
2006                gtag('event', 'Link Click', {
2007                    'event_category': analyticsCategory,
2008                    'event_label': this.id
2009                });
2010            }
2011        });
2012
2013        $('#PhoneNav').on('click', function () {
2014            gtag('event', 'Link Click', {
2015                'event_category': analyticsCategory,
2016                'event_label': "CustomerBusinessPhoneLinkPlatinum1"
2017            });
2018        });
2019        $('.phoneLinkInput').on('click', function () {
2020            gtag('event', 'Link Click', {
2021                'event_category': analyticsCategory,
2022                'event_label': "CustomerBusinessPhoneLinkPlatinum1-1"
2023            });
2024        });
2025        $('#contactPhoneLink').on('click', function () {
2026            gtag('event', 'Link Click', {
2027                'event_category': analyticsCategory,
2028                'event_label': "CustomerBusinessPhoneLinkPlatinum1-2"
2029            });
2030        });
2031        $('#contactPrimaryPhoneLink').on('click', function () {
2032            gtag('event', 'Link Click', {
2033                'event_category': analyticsCategory,
2034                'event_label': "CustomerBusinessPhoneLinkPlatinum1-3"
2035            });
2036        });
2037        $('#contactSecondaryPhoneLink').on('click', function () {
2038            gtag('event', 'Link Click', {
2039                'event_category': analyticsCategory,
2040                'event_label': "CustomerBusinessPhoneLinkPlatinum1-4"
2041            });
2042        });
2043        $('#contactMobilePhoneLink').on('click', function () {
2044            gtag('event', 'Link Click', {
2045                'event_category': analyticsCategory,
2046                'event_label': "CustomerBusinessPhoneLinkPlatinum1-5"
2047            });
2048        });
2049        $('#contactFaxPhoneLink').on('click', function () {
2050            gtag('event', 'Link Click', {
2051                'event_category': analyticsCategory,
2052                'event_label': "CustomerBusinessPhoneLinkPlatinum1-6"
2053            });
2054        });
2055        $('#contactTollfreePhoneLink').on('click', function () {
2056            gtag('event', 'Link Click', {
2057                'event_category': analyticsCategory,
2058                'event_label': "CustomerBusinessPhoneLinkPlatinum1-7"
2059            });
2060        });
2061        $('#contactPhoneC1').on('click', function () {
2062            gtag('event', 'Link Click', {
2063                'event_category': analyticsCategory,
2064                'event_label': "CustomerContactPhoneLinkPlatinum1-8"
2065            });
2066        });
2067        $('#contactPhoneC2').on('click', function () {
2068            gtag('event', 'Link Click', {
2069                'event_category': analyticsCategory,
2070                'event_label': "CustomerContactPhoneLinkPlatinum1-9"
2071            });
2072        });
2073        $('#contactPhoneC3').on('click', function () {
2074            gtag('event', 'Link Click', {
2075                'event_category': analyticsCategory,
2076                'event_label': "CustomerContactPhoneLinkPlatinum1-10"
2077            });
2078        });
2079        $('#contactPhoneC4').on('click', function () {
2080            gtag('event', 'Link Click', {
2081                'event_category': analyticsCategory,
2082                'event_label': "CustomerContactPhoneLinkPlatinum1-11"
2083            });
2084        });
2085        $('#contactPhoneC5').on('click', function () {
2086            gtag('event', 'Link Click', {
2087                'event_category': analyticsCategory,
2088                'event_label': "CustomerContactPhoneLinkPlatinum1-12"
2089            });
2090        });
2091        $('#contactEmail').on('click', function () {
2092            gtag('event', 'Link Click', {
2093                'event_category': analyticsCategory,
2094                'event_label': "CustomerBusinessEmailLinkPlatinum1"
2095            });
2096        });
2097        $('#writeReviewBt').on('click', function () {
2098            gtag('event', 'Button Click', {
2099                'event_category': analyticsCategory,
2100                'event_label': "WriteReviewButtonPlatinum1"
2101            });
2102        });
2103        $(document).on('click', '#postReview', function () {
2104            gtag('event', 'Button Click', {
2105                'event_category': analyticsCategory,
2106                'event_label': "PostReviewButtonPlatinum1"
2107            });
2108        });
2109        $('#nextReview').on('click', function () {
2110            gtag('event', 'Button Click', {
2111                'event_category': analyticsCategory,
2112                'event_label': "ShowNextReviewsButtonPlatinum1"
2113            });
2114        });
2115        $('#prevReview').on('click', function () {
2116            gtag('event', 'Button Click', {
2117                'event_category': analyticsCategory,
2118                'event_label': "ShowPreviousReviewsButtonPlatinum1"
2119            });
2120        });
2121        $('#google-social').on('click', function () {
2122            gtag('event', 'Link Click', {
2123                'event_category': analyticsCategory,
2124                'event_label': "CustomerGoogleSocialLinkPlatinum1-1"
2125            });
2126        });
2127        $('#facebook-social').on('click', function () {
2128            gtag('event', 'Link Click', {
2129                'event_category': analyticsCategory,
2130                'event_label': "CustomerFacebookSocialLinkPlatinum1-1"
2131            });
2132        });
2133        $('#yelp-social').on('click', function () {
2134            gtag('event', 'Link Click', {
2135                'event_category': analyticsCategory,
2136                'event_label': "CustomerYelpSocialLinkPlatinum1-1"
2137            });
2138        });
2139        $('#twitter-social').on('click', function () {
2140            gtag('event', 'Link Click', {
2141                'event_category': analyticsCategory,
2142                'event_label': "CustomerTwitterSocialLinkPlatinum1-1"
2143            });
2144        });
2145        $('#linkedin-social').on('click', function () {
2146            gtag('event', 'Link Click', {
2147                'event_category': analyticsCategory,
2148                'event_label': "CustomerLinkedinSocialLinkPlatinum1-1"
2149            });
2150        });
2151        $('#instagram-social').on('click', function () {
2152            gtag('event', 'Link Click', {
2153                'event_category': analyticsCategory,
2154                'event_label': "CustomerInstagramSocialLinkPlatinum1-1"
2155            });
2156        });
2157        $('#google-social-footer').on('click', function () {
2158            gtag('event', 'Link Click', {
2159                'event_category': analyticsCategory,
2160                'event_label': "CustomerGoogleSocialLinkPlatinum1-2"
2161            });
2162        });
2163        $('#facebook-social-footer').on('click', function () {
2164            gtag('event', 'Link Click', {
2165                'event_category': analyticsCategory,
2166                'event_label': "CustomerFacebookSocialLinkPlatinum1-2"
2167            });
2168        });
2169        $('#yelp-social-footer').on('click', function () {
2170            gtag('event', 'Link Click', {
2171                'event_category': analyticsCategory,
2172                'event_label': "CustomerYelpSocialLinkPlatinum1-2"
2173            });
2174        });
2175        $('#twitter-social-footer').on('click', function () {
2176            gtag('event', 'Link Click', {
2177                'event_category': analyticsCategory,
2178                'event_label': "CustomerTwitterSocialLinkPlatinum1-2"
2179            });
2180        });
2181        $('#linkedin-social-footer').on('click', function () {
2182            gtag('event', 'Link Click', {
2183                'event_category': analyticsCategory,
2184                'event_label': "CustomerLinkedinSocialLinkPlatinum1-2"
2185            });
2186        });
2187        $('#instagram-social-footer').on('click', function () {
2188            gtag('event', 'Link Click', {
2189                'event_category': analyticsCategory,
2190                'event_label': "CustomerInstagramSocialLinkPlatinum1-2"
2191            });
2192        });
2193        $('#contactEmailFooter').on('click', function () {
2194            gtag('event', 'Link Click', {
2195                'event_category': analyticsCategory,
2196                'event_label': "CustomerBusinessEmailLinkPlatinum1-2"
2197            });
2198        });
2199        $('#btnContactPost').on('click', function () {
2200            gtag('event', 'Link Click', {
2201                'event_category': analyticsCategory,
2202                'event_label': "CustomerContactLeadPostPlatinum1"
2203            });
2204        });
2205        $("#external-review-link").on('click', function () {
2206            gtag('event', 'Link Click', {
2207                'event_category': analyticsCategory,
2208                'event_label': "CustomerExternalReviewLinkPlatinum1"
2209            });
2210        });
2211        $('#video').on('click', function () {
2212            gtag('event', 'Video Click', {
2213                'event_category': analyticsCategory,
2214                'event_label': "CustomerVideoPlatinum1"
2215            });
2216        });
2217        $('#website-social').on('click', function () {
2218            gtag('event', 'Link Click', {
2219                'event_category': analyticsCategory,
2220                'event_label': "CustomerWebsiteSocialLinkPlatinum1-1"
2221            });
2222        });
2223        $('#website-social-footer').on('click', function () {
2224            gtag('event', 'Link Click', {
2225                'event_category': analyticsCategory,
2226                'event_label': "CustomerWebsiteSocialLinkPlatinum1-2"
2227            });
2228        });
2229        $('#accessibility-social-footer').on('click', function () {
2230            gtag('event', 'Link Click', {
2231                'event_category': analyticsCategory,
2232                'event_label': "CustomerWebsiteAccessibilityLinkPlatinum1"
2233            });
2234        });
2235        $('#photos-image-element').on('click', function () {
2236            gtag('event', 'Link Click', {
2237                'event_category': analyticsCategory,
2238                'event_label': "CustomerWebsiteImageryPhotoPlatinum1"
2239            });
2240        });
2241        $('#HomePageNavigationLink').on('click', function () {
2242            gtag('event', 'Link Click', {
2243                'event_category': analyticsCategory,
2244                'event_label': "CustomerHomePageNavLinkPlatinum1"
2245            });
2246        });
2247        $('#AccessibilityPageNavigationLink').on('click', function () {
2248            gtag('event', 'Link Click', {
2249                'event_category': analyticsCategory,
2250                'event_label': "CustomerAccessibilityPageNavLinkPlatinum1"
2251            });
2252        });
2253        $('#ContactPageNavigationLink').on('click', function () {
2254            gtag('event', 'Link Click', {
2255                'event_category': analyticsCategory,
2256                'event_label': "CustomerContactPageNavLinkPlatinum1"
2257            });
2258        });
2259        $('#PhotosNavigationLink').on('click', function () {
2260            gtag('event', 'Link Click', {
2261                'event_category': analyticsCategory,
2262                'event_label': "CustomerPhotosPageNavLinkPlatinum1"
2263            });
2264        });
2265        $('#testimoinalsPageNavigationLink').on('click', function () {
2266            gtag('event', 'Link Click', {
2267                'event_category': analyticsCategory,
2268                'event_label': "CustomerTestimonialsPageNavLinkPlatinum1"
2269            });
2270        });
2271        $('#ServicesPageNavigationLink').on('click', function () {
2272            gtag('event', 'Link Click', {
2273                'event_category': analyticsCategory,
2274                'event_label': "CustomerServicesPageNavLinkPlatinum1"
2275            });
2276        });
2277        $('#AboutPageNavigationLink').on('click', function () {
2278            gtag('event', 'Link Click', {
2279                'event_category': analyticsCategory,
2280                'event_label': "CustomerAboutPageNavLinkPlatinum1"
2281            });
2282        });
2283
2284         $(document).on('click', '.btn-link', function() {
2285             // Find the closest parent that includes both the button and the items to be toggled
2286             var $parentNav = $(this).closest('.navbar-attribute');
2287
2288             // Toggle the visibility of hidden items within this specific parent
2289             var $hiddenItems = $parentNav.find('.hidden-item');
2290             $hiddenItems.toggle();
2291
2292             // Find the arrow within the clicked button
2293             var $arrow = $(this).find('.arrow');
2294
2295             // Toggle arrow direction by switching classes
2296             if ($arrow.hasClass('arrow-down')) {
2297                 $arrow.removeClass('arrow-down').addClass('arrow-up');
2298             } else {
2299                 $arrow.removeClass('arrow-up').addClass('arrow-down');
2300             }
2301         });
2302
2303        $(document).on('click', '#photos-image-element1', function () {
2304            $('#selectedServiceId').val('service1');
2305            DisplayPage('#servicesPage');
2306        });
2307        $(document).on('click', '#photos-image-element2', function () {
2308            $('#selectedServiceId').val('service2');
2309            DisplayPage('#servicesPage');
2310        });
2311        $(document).on('click', '#photos-image-element3', function () {
2312            $('#selectedServiceId').val('service3');
2313            DisplayPage('#servicesPage');
2314        });
2315
2316        //unable to directly track cross domain iFrame clicks. Track only first click on the iFrame itself
2317        var monitor = setInterval(function () {
2318            var elem = document.activeElement;
2319            if (elem && elem.tagName == "IFRAME" && elem.id == "googleMapEmbed") {
2320                gtag('event', 'iFrame Click', {
2321                    'event_category': analyticsCategory,
2322                    'event_label': "GoogleDirectionsPlatinum1"
2323                });
2324                clearInterval(monitor);
2325            }
2326        }, 1000);
2327
2328        var navbarHeight = $('#headernav').outerHeight();  // Make sure this matches your navbar class
2329        document.documentElement.style.setProperty('--scroll-padding-top', navbarHeight + 'px');
2330    });
2331
2332    function scrollToService(serviceId) {
2333        var targetElement = document.getElementById(serviceId);
2334        if (targetElement) {
2335            var headerHeight = document.querySelector('#headernav').offsetHeight;
2336            var descriptionOffset = 165; // Adjust this value as needed
2337            var scrollPosition = targetElement.offsetTop - headerHeight - descriptionOffset;
2338
2339            window.scrollTo({
2340                top: scrollPosition,
2341                behavior: 'smooth'
2342            });
2343        } else {
2344            console.log('Service section element not found');
2345        }
2346    }
2347
2348    function DisplayPage(page, serviceId) {
2349        PauseVideoPlayer();
2350
2351        if (!$(page).hasClass("show")) {
2352            $("#pages div.collapse.show").collapse("hide");
2353        }
2354        $(page).collapse("show");
2355
2356        if(page == "#homePage")
2357        {
2358            var carousel = $(".slick-slider");
2359            if(carousel != null)
2360            {
2361                carousel.slick('refresh');
2362            }
2363        }
2364
2365        if (page == "#testimonialsPage") {
2366             // Load Testimonials via Ajax if not already loaded
2367            if (!testimonialsRendered) {
2368                ShowLoading();
2369                $.get('/Home/GetTestimonialsContent', { id: 42094, template: "Platinum_1"}, function (data) {
2370                    if (data != "")
2371                    {
2372                        $("#testimonialsPage").append(data);
2373                    }
2374                }).always(function() {
2375                    HideLoading();
2376                    testimonialsRendered = true;
2377                });
2378            }
2379
2380            $("html, body").animate({ scrollTop: 0 }, "fast");
2381        }
2382
2383        if (page == "#aboutPage") {
2384            // Load About via Ajax if not already loaded
2385            if (!aboutRendered) {
2386                ShowLoading();
2387                $.get('/Home/GetAboutContent', { id: 42094, template: "Platinum_1"}, function (data) {
2388                    if (data != "")
2389                    {
2390                        $("#aboutPage").append(data);
2391                        $.getScript("https://maps.googleapis.com/maps/api/js?key=AIzaSyB2UoPWVWPR8WrIFK_zqJ5nTN1NvGm9dqY&callback=initMap");
2392
2393                    }
2394                }).always(function() {
2395                    HideLoading();
2396                    aboutRendered = true;
2397                });
2398            }
2399        }
2400
2401        if (page === "#servicesPage")
2402        {
2403            // Load Services via Ajax if not already loaded
2404            if (!servicesRendered) {
2405                ShowLoading();
2406                $.get('/Home/GetServicesContent', { id: 42094, template: "Platinum_1" })
2407                    .done(function (data) {
2408                        if (data !== "") {
2409                            $("#servicesPage").append(data);
2410                            servicesRendered = true;
2411                            // Trigger the scroll after a short delay
2412                            setTimeout(function() {
2413                                var selectedServiceId = $('#selectedServiceId').val();
2414                                if (selectedServiceId) {
2415                                    scrollToService(selectedServiceId);
2416                                    $('#selectedServiceId').val('');
2417                                }
2418                            }, 300); // Adjust the delay as needed
2419                        }
2420                    })
2421                    .always(function () {
2422                        HideLoading();
2423                    });
2424            } else {
2425                // If the services are already rendered, trigger the scroll after a short delay
2426                setTimeout(function() {
2427                    var selectedServiceId = $('#selectedServiceId').val();
2428                    if (selectedServiceId) {
2429                        scrollToService(selectedServiceId);
2430                        $('#selectedServiceId').val('');
2431                    }
2432                }, 100); // Adjust the delay as needed
2433            }
2434        } else {
2435            window.scrollTo(0, 0);
2436        }
2437
2438        if (page == "#imageryPage") {
2439            // Load photos via Ajax if not already loaded
2440            if (!photosRendered) {
2441                ShowLoading();
2442                $.get('/Home/GetPhotosContent', { id: 42094, template: "Platinum_1"}, function (data) {
2443                    if (data != "")
2444                    {
2445                        $("#imageryPage").append(data);
2446                    }
2447                }).always(function() {
2448                    HideLoading();
2449                    photosRendered = true;
2450                });
2451            }
2452        }
2453
2454        if (page == "#contactPage") {
2455            // Load Contact via Ajax if not already loaded
2456            if (!contactRendered) {
2457                ShowLoading();
2458                $.get('/Home/GetContactContent', { id: 42094, template: "Platinum_1"}, function (data) {
2459                    if (data != "")
2460                    {
2461                        $("#contactPage").append(data);
2462                    }
2463                }).always(function() {
2464                    HideLoading();
2465                    contactRendered = true;
2466                });
2467            }
2468        }
2469
2470         if (page == "#locationsPage") {
2471            // Load Locations via Ajax if not already loaded
2472             if (!locationsRendered) {
2473                 ShowLoading();
2474
2475                 $.get('/Home/GetLocationsContent', { id: 42094, template: "Platinum_1" }, function (data) {
2476                     if (data != "")
2477                     {
2478                        $("#locationsPage").append(data);
2479                     }
2480                 }).always(function() {
2481                    HideLoading();
2482                    locationsRendered = true;
2483                 });
2484             }
2485        }
2486
2487        if (page == "#faqPage") {
2488            // Load Faqs via Ajax if not already loaded
2489            if (!faqRendered) {
2490                ShowLoading();
2491
2492                $.get('/Home/GetFAQContent', { id: 42094, template: "Platinum_1" }, function (data) {
2493                    if (data != "") {
2494                        $("#faqPage").append(data);
2495                    }
2496                }).always(function () {
2497                    HideLoading();
2498                    faqRendered = true;
2499                });
2500            }
2501        }
2502
2503        if (page == "#contentPage") {
2504            // Load Additional Content via Ajax if not already loaded
2505            if (!additionalContentRendered) {
2506                ShowLoading();
2507
2508                $.get('/Home/GetAdditionalContentContent', { id: 42094, template: "Platinum_1" }, function (data) {
2509                    if (data != "") {
2510                        $("#contentPage").append(data);
2511                    }
2512                }).always(function () {
2513                    HideLoading();
2514                    additionalContentRendered = true;
2515                });
2516            }
2517        }
2518    }
2519
2520    function PauseVideoPlayer() {
2521
2522        var videos = document.querySelectorAll('video');
2523        var iframes = document.querySelectorAll('iframe');
2524
2525        //mp4
2526        Array.prototype.forEach.call(videos, video => {
2527            video.pause();
2528        });
2529
2530        //youtube
2531        Array.prototype.forEach.call(iframes, iframe => {
2532            iframe.contentWindow.postMessage(JSON.stringify({
2533                event: 'command',
2534                func: 'pauseVideo'
2535            }), '*');
2536        });
2537
2538        //wistia + vimeo
2539        Array.prototype.forEach.call(iframes, iframe => {
2540            iframe.contentWindow.postMessage(JSON.stringify({
2541                "method": "pause",
2542                "value": "true"
2543            }), '*');
2544        });
2545    }
2546
2547    function GetPostsData(i)
2548    {
2549        if(i != 0){
2550            ShowLoading();
2551        }
2552        postsPageIndex = postsPageIndex + i;
2553        $.get('/Home/GetTestimonialPostsInfo', {id: 42094, program_id: 13, profileDomain: 'https://mvcpaintingandremodeling.com/', subdomain: 'mvcpaintingandremodeling', testimonialSSL : 'False', domainSSL : 'True', pageIndex: postsPageIndex, pageSize: pageSize, file: '_TestimonialPostsContent'}, function (data) {
2554            if (data != "")
2555            {
2556                $(".postsInfo").html(data);
2557            }
2558        }).always(function() {
2559            HideLoading();
2560        });
2561        SetPostsPaginationButtons();
2562    }
2563
2564    function GetPostsBanner()
2565    {
2566        ShowLoading();
2567        var bannerObj = null;
2568        $.ajax({
2569            method: "POST",
2570            url: "/Home/GetPostBanner",
2571            data:JSON.stringify(
2572            {
2573                banner: bannerObj,
2574                testimonialPageColor: (false) ? 'transparent' :'#FFFFFF',
2575                postsColor: '#FFFFFF'
2576            }),
2577            contentType: 'application/json',
2578            success: function (data) {
2579                var holdaspect = "";
2580                if ($("#homepagebanner").hasClass('aspect-ratio-16x9')) {
2581                    $('#homepagebanner').removeClass('aspect-ratio-16x9');
2582                    holdaspect = "aspect-ratio-16x9";
2583                }
2584
2585                if(isMobile || isTablet){
2586                    setTimeout(function(){
2587                        $(".home-content").prepend(data);
2588                    }, 5000);
2589                }
2590                else{
2591                    $(".home-content").prepend(data);
2592                }
2593
2594                $('#bannerclose').click(function() {
2595                    if (holdaspect != "") {
2596                        $('#homepagebanner').addClass('aspect-ratio-16x9');
2597                    }
2598                });
2599
2600                /*remove banner after 30 seconds regardless of mobile/tablet/desktop*/
2601                if (!keepPostUp) {
2602                    setTimeout(function () {
2603                        $("#posts-banner-alert").remove();
2604                        if (holdaspect != "" && !(isMobile || isTablet)) {
2605                            $('#homepagebanner').addClass('aspect-ratio-16x9');
2606                        }
2607                    }, 30000);
2608                }
2609            }
2610        }).always(function() {
2611            HideLoading();
2612            if (holdaspect != "" && !(isMobile || isTablet)) {
2613                $('#homepagebanner').addClass('aspect-ratio-16x9');
2614            }
2615        });
2616    }
2617
2618    function SetPostsPaginationButtons()
2619    {
2620        //look ahead by one
2621        if (((postsPageIndex + 1) * pageSize) >= numOfPosts) {
2622            $("#nextPosts").hide();
2623        }
2624        else {
2625            $("#nextPosts").show();
2626            $("#nextPosts").prop('disabled', false);
2627        }
2628
2629        if (postsPageIndex <= 0) {
2630            postsPageIndex = 0;
2631            $("#prevPosts").hide();
2632        }
2633        else if (postsPageIndex > 0) {
2634            $("#prevPosts").show();
2635            $("#prevPosts").prop('disabled', false);
2636        }
2637    }
2638
2639    function ShowLoading()
2640    {
2641        $("#loadingImg").show();
2642    }
2643
2644    function HideLoading()
2645    {
2646        $("#loadingImg").hide();
2647    }
2648
2649    function checkMobile() {
2650        var windowsize = $(window).width();
2651        switch (true) {
2652        case /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent):
2653            isMobile = true;
2654            break;
2655        case windowsize < 800:
2656            isMobile = true;
2657            break;
2658        default:
2659            isMobile = false;
2660      }
2661    }
2662
2663    function checkTablet() {
2664        var windowsize = $(window).width();
2665        switch (true) {
2666        case (windowsize >= 800) && (windowsize < 1200):
2667            isTablet = true;
2668            break;
2669        default:
2670            isTablet = false;
2671      }
2672    }
2673
2674    function checkHashRoute() {
2675        if ((location.hash != null) && (location.hash != "") && (location.hash == '#homePage' || location.hash == '#aboutPage' || location.hash == '#servicesPage' || location.hash == '#testimonialsPage' || location.hash == '#contactPage' || location.hash == '#locationsPage' || location.hash == '#faqPage' || location.hash == '#contentPage')) {
2676            DisplayPage(location.hash);
2677        }
2678    }
2679
2680  function contactUsPost(event) {
2681    var _contactForm = $("#ContactPostForm");
2682
2683    // Clear previous validation states
2684    $('.validation-error-message').remove();
2685    _contactForm.find('.validation-error').removeClass('validation-error');
2686    $("#contactResponseMessage").empty();
2687
2688    if (_contactForm[0].checkValidity()) {
2689      contactUsSubmit(event);
2690    } else {
2691      var firstInvalidField = null;
2692
2693      _contactForm.find('input[required], textarea[required], select[required]').each(function () {
2694        var $field = $(this);
2695
2696        if (!this.checkValidity()) {
2697          var fieldId = $field.attr('id') || $field.attr('name');
2698          var fieldLabel = getFieldLabel(fieldId);
2699
2700          $field.addClass('validation-error');
2701
2702          var errorMessage = getCustomErrorMessage($field, fieldLabel);
2703          $field.after(`<div class="validation-error-message">${errorMessage}</div>`);
2704
2705          if (!firstInvalidField) {
2706            firstInvalidField = $field;
2707          }
2708        }
2709      });
2710
2711      // Focus first invalid field
2712      if (firstInvalidField) {
2713        firstInvalidField.focus();
2714      }
2715
2716      // Re-enable submit button
2717      $("#btnContactPost").prop('disabled', false);
2718      $("#btnContactPost").css('font-weight', 'bold');
2719    }
2720  }
2721
2722  function getFieldLabel(fieldId) {
2723    var labels = {
2724      'contact_us_phone': 'Phone Number',
2725      'contact_us_address': 'Address',
2726      'contact_us_city': 'City',
2727      'contact_us_state': 'State',
2728      'contact_us_zip': 'ZIP Code',
2729      'contact_us_subject': 'Subject',
2730      'contact_us_name': 'Name',
2731      'contact_us_email': 'Email',
2732      'contact_us_message': 'Message'
2733    };
2734    return labels[fieldId] || 'This field';
2735  }
2736
2737  function getCustomErrorMessage($field, fieldLabel) {
2738    if ($field.prop('required') && !$field.val().trim()) {
2739      return `${fieldLabel} required`;
2740    }
2741
2742    if ($field.attr('type') === 'email' && $field.val()) {
2743      return `Please enter a valid email address.`;
2744    }
2745
2746    return `Please enter a valid ${fieldLabel.toLowerCase()}.`;
2747  }
2748
2749    function contactUsSubmit(event) {
2750        event.preventDefault();
2751
2752        var form = $("#ContactPostForm");
2753        grecaptcha.ready(function() {
2754            grecaptcha.execute('6LcokacUAAAAAH_snk3O5bpdYwjpC5XAuXNLrJLH', {action: 'contact_us'}).then(function(token) {
2755                $("#g-Recaptcha-Response-Contact").attr("value", token); //add token for server side validation
2756                $.ajax({
2757                    type: "POST",
2758                    url: "/Home/ContactPost",
2759                    data: form.serialize(),
2760                    success: function(data){
2761                        if (data.indexOf('{"message":') != -1) {
2762                            var jsonData = JSON.parse(data);
2763                            if (!jsonData.success) {
2764                                $("#contactResponseMessage").html('<div class="alert alert-warning alert-dissmisable" role="alert"><button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">&times;</span></button>' + jsonData.message + '</div>');
2765                                recaptchaContactUsInComplete();
2766                                showClassicCaptcha("contact");
2767                            }
2768                            else{
2769                                $("#contactResponseMessage").html('<div class="alert alert-success alert-dissmisable" role="alert"><button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">&times;</span></button>' + jsonData.message + '</div>');
2770                                recaptchaContactUsComplete();
2771                            }
2772                        }
2773                    }
2774                });
2775            });
2776        });
2777    }
2778
2779    function ScrollForPosts(e){
2780        // target element
2781        var $id = $(".posts-partial-content");
2782        if ($id.length === 0) {
2783            return;
2784        }
2785
2786        // prevent standard hash navigation (avoid blinking in IE)
2787        e.preventDefault();
2788
2789        // top position relative to the document
2790        var pos = $id.offset().top - $('.navbar').height();
2791
2792        // animated top scrolling
2793        // .stop() keeps from scrolling to top then to element
2794        $('body, html').stop().animate({ scrollTop: pos }, 500);
2795    }
2796
2797    function recaptchaContactUsInComplete(){
2798        $("#btnContactPost").prop('disabled', false);
2799        $("#btnContactPost").css('font-weight', 'bold');
2800    }
2801
2802  function recaptchaContactUsComplete() {
2803    $("#btnContactPost").prop('disabled', false);
2804    $("#btnContactPost").css('font-weight', 'normal');
2805    $("#ContactPostForm").trigger("reset");
2806  }
2807
2808    function recaptchaReviewIncomplete(){
2809        $("#postReview").prop('disabled', false);
2810        $("#postReview").css('font-weight', 'bold');
2811    }
2812
2813    function recaptchaReviewComplete(){
2814        $("#postReview").css('font-weight', 'normal');
2815        $("#postReviewForm").trigger("reset");
2816        $("#postReview").prop('disabled', false);
2817    }
2818
2819    function ClearReviewFields() {
2820        $('#starRating').barrating('clear');
2821        $("#review").val("");
2822        $("#review_alias").val("");
2823        $("#review_heading").val("");
2824        $("#reviewCaptcha").val("");
2825    }
2826
2827    function resetReviewButton($button) {
2828        var $buttonText = $button.find('.button-text');
2829        var $spinner = $button.find('.spinner');
2830
2831        $button.prop('disabled', false);
2832
2833        if ($buttonText.length && $spinner.length) {
2834            $buttonText.show();
2835            $spinner.hide();
2836        } else {
2837            var originalText = $button.data('original-text');
2838            if (originalText) {
2839                $button.html(originalText);
2840            }
2841        }
2842    }
2843
2844    function setProcessingState($button, $form, isProcessing) {
2845        var $buttonText = $button.find('.button-text');
2846        var $spinner = $button.find('.spinner');
2847
2848        if (isProcessing) {
2849            $button.prop('disabled', true);
2850            $form.addClass('review-form-processing');
2851            $form.find('input, textarea, select').not('#profile_id, #g-Recaptcha-Response-Review, [type="hidden"]').prop('disabled', true);
2852
2853            if ($buttonText.length && $spinner.length) {
2854                $buttonText.hide();
2855                $spinner.show();
2856            } else {
2857                $button.data('original-text', $button.html());
2858                $button.html('<i class="fas fa-spinner fa-spin"></i> Processing...');
2859            }
2860        } else {
2861            $button.prop('disabled', false);
2862            $form.removeClass('review-form-processing');
2863            $form.find('input, textarea, select').prop('disabled', false);
2864
2865            if ($buttonText.length && $spinner.length) {
2866                $buttonText.show();
2867                $spinner.hide();
2868            } else {
2869                var originalText = $button.data('original-text');
2870                if (originalText) {
2871                    $button.html(originalText);
2872                }
2873            }
2874        }
2875    }
2876
2877    function ClearReviewFields() {
2878        console.log('Clearing review fields');
2879        $('#starRating').barrating('clear');
2880        $("#review").val("");
2881        $("#review_alias").val("");
2882        $("#review_heading").val("");
2883        $("#reviewCaptcha").val("");
2884
2885        $("#postReviewForm input, #postReviewForm textarea").removeClass('error');
2886        $("#postReviewForm .br-widget").removeClass('error');
2887    }
2888
2889    function validateReview(btn) {
2890        var $form = $("#postReviewForm");
2891        var isValid = true;
2892
2893        console.log('Starting validation...');
2894
2895        $form.find('input, textarea').removeClass('error');
2896        $form.find('.br-widget').removeClass('error');
2897
2898        var reviewText = $('#review').val();
2899        console.log('Review text length:', reviewText ? reviewText.trim().length : 0);
2900
2901        if (!reviewText || reviewText.trim().length === 0) {
2902            console.log('Review text validation failed - empty or whitespace only');
2903            $('#review').addClass('error');
2904            $('#review').focus();
2905            isValid = false;
2906        } else {
2907            console.log('Review text validation passed');
2908        }
2909
2910        var rating = null;
2911        var selectRating = $('#starRating')[0] ? $('#starRating')[0].value : null;
2912        var jqueryRating = $('#starRating').val();
2913        var selectedOption = $('#starRating option:selected').val();
2914        var barRating = null;
2915
2916        if (typeof $('#starRating').barrating === 'function') {
2917            try {
2918                var barResult = $('#starRating').barrating('show');
2919                if (barResult && typeof barResult === 'string') {
2920                    barRating = barResult;
2921                } else if (barResult && typeof barResult === 'number') {
2922                    barRating = barResult.toString();
2923                }
2924            } catch (e) {
2925                console.log('Error getting barrating value:', e);
2926            }
2927        }
2928
2929        if (jqueryRating && typeof jqueryRating === 'string') {
2930        } else if (jqueryRating && typeof jqueryRating === 'number') {
2931            jqueryRating = jqueryRating.toString();
2932        } else {
2933            jqueryRating = null;
2934        }
2935
2936        if (barRating && barRating !== "" && barRating !== "0") {
2937            rating = barRating;
2938        } else if (selectRating && selectRating !== "" && selectRating !== "0") {
2939            rating = selectRating;
2940        } else if (selectedOption && selectedOption !== "" && selectedOption !== "0") {
2941            rating = selectedOption;
2942        } else if (jqueryRating && jqueryRating !== "" && jqueryRating !== "0") {
2943            rating = jqueryRating;
2944        }
2945
2946        if (rating && typeof rating !== 'string') {
2947            console.log('WARNING: Rating is not a string, converting:', rating, typeof rating);
2948            rating = String(rating);
2949        }
2950
2951        if (rating && typeof rating === 'object') {
2952            console.error('CRITICAL ERROR: Rating is still an object!', rating);
2953            rating = null;
2954        }
2955
2956        console.log('Validation - Final rating value:', rating, typeof rating);
2957
2958        if (!rating || rating === "" || rating === "0") {
2959            console.log('Rating validation failed');
2960            $('.br-widget').addClass('error');
2961            isValid = false;
2962        } else {
2963            console.log('Rating validation passed with value:', rating);
2964        }
2965
2966        console.log('Validation result:', isValid);
2967        return isValid;
2968    }
2969
2970    function validateReviewLength() {
2971        var text = $('#review').val();
2972        var success = true;
2973
2974        if (text.trim().length == 0) {
2975            $('#review').addClass('error');
2976            success = false;
2977        }
2978        return success;
2979    }
2980
2981    function validateRating() {
2982        var rating = null;
2983
2984        // Use the same rating detection logic
2985        var selectRating = $('#starRating')[0] ? $('#starRating')[0].value : null;
2986        var jqueryRating = $('#starRating').val();
2987        var selectedOption = $('#starRating option:selected').val();
2988        var barRating = null;
2989
2990        if (typeof $('#starRating').barrating === 'function') {
2991            try {
2992                barRating = $('#starRating').barrating('show');
2993            } catch (e) {
2994                console.log('Error getting barrating value in validateRating:', e);
2995            }
2996        }
2997
2998        // Determine which rating to use
2999        if (barRating && barRating !== "" && barRating !== "0") {
3000            rating = barRating;
3001        } else if (selectRating && selectRating !== "" && selectRating !== "0") {
3002            rating = selectRating;
3003        } else if (selectedOption && selectedOption !== "" && selectedOption !== "0") {
3004            rating = selectedOption;
3005        } else if (typeof jqueryRating === 'string' && jqueryRating !== "" && jqueryRating !== "0") {
3006            rating = jqueryRating;
3007        }
3008
3009        var success = true;
3010        if (!rating || rating === "" || rating === "0") {
3011            $('.br-widget').addClass('error');
3012            success = false;
3013        }
3014        return success;
3015    }
3016</script>
3016
3017</body>
3018</html>

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.