PageSourceSearch

https://trillionrealestate.com/blog

html trillionrealestate.com collected 2026-10-10 00:13:58 UTC 525,712 bytes, 9,678 lines download raw bytes

1<!DOCTYPE html>
2<html class="no-js" lang=en>
3<head>
4    <meta charset="utf-8">
5    <meta http-equiv="x-ua-compatible" content="ie=edge">
6    <meta name="viewport" content="width=device-width, initial-scale=1.0">
7    <meta name="twitter:card" content="summary_large_image">
8    <meta property="og:type" content="website">
9        <title>Blog - Trillion Real Estate</title>
10        <meta property="og:title" content="Blog - Trillion Real Estate">
11        <meta name="twitter:title" content="Blog - Trillion Real Estate">
12        <meta name="description" content="Keep up with the latest real estate trends and news happening in California. For even faster service, call Trillion Real Estate and get on board with the team!">
13        <meta property="og:description" content="Keep up with the latest real estate trends and news happening in California. For even faster service, call Trillion Real Estate and get on board with the team!">
14        <meta name="twitter:description" content="Keep up with the latest real estate trends and news happening in California. For even faster service, call Trillion Real Estate and get on board with the team!">
15        <meta property="og:image" content="https://media-production.lp-cdn.com/media/48787991-3ed4-4fb4-9169-d1ada07c0646">
16        <meta name="twitter:image" content="https://media-production.lp-cdn.com/media/48787991-3ed4-4fb4-9169-d1ada07c0646">
17        <meta property="og:url" content="https://trillionrealestate.com/blog">
18        <link rel="canonical" href="https://trillionrealestate.com/blog">
19    
19<script>(function(html){html.className = html.className.replace(/\bno-js\b/,'js')})(document.documentElement);</script>
19
20    <link rel="preconnect" href="https://fonts.googleapis.com">
21    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
22    <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Montserrat:100,100i,200,200i,300,300i,400,400i,500,500i,600,600i,700,700i,800,800i,900,900i">
23    <link rel="preload" href="https://cdnjs.cloudflare.com/ajax/libs/ion-rangeslider/2.3.1/css/ion.rangeSlider.min.css" as="style" onload="this.onload=null;this.rel='stylesheet'">
24    <noscript><link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/ion-rangeslider/2.3.1/css/ion.rangeSlider.min.css"></noscript>
25    <link rel="icon" type="image/x-icon" href="/favicon.ico">
26    <link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
27    <link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
28    <link rel="icon" type="image/png" sizes="48x48" href="/favicon-48x48.png">
29    <style id="global-css">:root{--global-primary-font-family:Montserrat,sans-serif;--global-primary-font-family-short:Montserrat;--global-secondary-font-family:Montserrat,sans-serif;--global-secondary-font-family-short:Montserrat;--global-body-padding:0px;--global-background-color:#fff;--global-body-font-size:16px;--global-h1-font-size:45px;--global-h2-font-size:40px;--global-h3-font-size:35px;--global-h4-font-size:28px;--global-h5-font-size:22px;--global-h6-font-size:20px;--global-section-padding:96px;}@media (max-width: 768px){:root{--global-section-padding:64px;}}body{padding:0px;background-color:#fff;font-family:Montserrat,sans-serif;font-size:16px;}@media (min-width: 768px){body{padding:0px 0px 0px 0px;}}h1,h2,h3,h4,h5,h6,button{font-family:Montserrat,sans-serif;}h1{font-size:45px;}h2{font-size:40px;}h3{font-size:35px;}h4{font-size:28px;}h5{font-size:22px;}h6{font-size:20px;}</style>
30        <link rel="stylesheet" type="text/css" href="https://styles.luxurypresence.com/masterpiece/index.css" />
31    <style id="website-css">body>div.mobile-contact-wrapper .mobile-contact.with-search div.buttons-holder{bottom:150px;}@media only screen and (max-width: 768px){iframe[name='widgetCta']{bottom:55px!important;right:10px!important;}}iframe[name='widgetCta']{bottom:50px!important;right:15px!important;}nav#global-navbar .header.theme-light .header__hamburger circle{fill:#fff;}nav#global-navbar .header.theme-light .header__hamburger svg rect{fill:#4a7da6!important;}nav#global-navbar .header.theme-light ul.navigation li.navigation__item{color:#fff;}nav#global-navbar .header.theme-light ul.navigation li.navigation__item .sub-nav__link{color:#000;background-color:#fff;}nav#global-navbar .header.theme-light ul.navigation li.navigation__item .sub-nav__link:hover{color:#000;background-color:#4a7da6;}nav#global-navbar .header.theme-light ul.navigation li.navigation__item .navigation__link:after{background:#fff;}nav#global-navbar .header.theme-light .search__btn svg{color:#fff;}nav#global-navbar .header.theme-light a.header__btn-contact{background:transparent;color:#fff!important;border-color:#fff!important;}nav#global-navbar .header.theme-light a.header__btn-contact:hover{background:#fff!important;color:#000!important;border-color:#fff!important;}nav#global-navbar .header .header__hamburger circle{fill:#4a7da6;}nav#global-navbar .header .header__hamburger svg rect{fill:#fff!important;}nav#global-navbar .header ul.navigation li.navigation__item{color:#000;}nav#global-navbar .header ul.navigation li.navigation__item .sub-nav__link{color:#FFF;background-color:#000;}nav#global-navbar .header ul.navigation li.navigation__item .sub-nav__link:hover{color:#FFF;background-color:#2f4f6a;}nav#global-navbar .header ul.navigation li.navigation__item .navigation__link:after{background:#4a7da6;}nav#global-navbar .header .search__btn svg{color:#000;}nav#global-navbar.scroll .header{background-color:#fff;}nav#global-navbar.scroll .header .header__hamburger circle{fill:#4a7da6;}nav#global-navbar.scroll .header .header__hamburger svg rect{fill:#fff!important;}nav#global-navbar.scroll .header ul.navigation li.navigation__item{color:#000;}nav#global-navbar.scroll .header ul.navigation li.navigation__item .sub-nav__link{color:#FFF;background-color:#000;}nav#global-navbar.scroll .header ul.navigation li.navigation__item .sub-nav__link:hover{color:#FFF;background-color:#2f4f6a;}nav#global-navbar.scroll .header ul.navigation li.navigation__item .navigation__link:after{background:#4a7da6;}nav#global-navbar.scroll .header .search__btn svg{color:#FFF;}nav#global-navbar.scroll .header a.header__btn-contact{background:transparent;color:#fff!important;border-color:#fff!important;}nav#global-navbar.scroll .header a.header__btn-contact:hover{background:#fff!important;color:#000!important;border-color:#fff!important;}@media only screen and (min-width:534px){nav#global-navbar .header__logo a.logo{width:350px;height:70px;max-width:350px;}nav#global-navbar .header__logo a.logo .logo__img{width:350px;height:70px;}}nav#global-navbar.scroll .header.theme-light .logo__img.light{display:none;}nav#global-navbar.scroll .header.theme-light .logo__img.dark{display:block;}nav#global-navbar.scroll .header.theme-auto .logo__img.light{display:none;}nav#global-navbar.scroll .header.theme-auto .logo__img.dark{display:block;}#modal-global-contact-us .contact-form__submit{background-color:transparent;border-color:#fff;}#modal-global-contact-us .contact-form__submit:hover{background-color:#fff;color:#000;border-color:#fff;}@media only screen and (max-width: 1024px){#modal-global-contact-us div.contact-form__container{width:100%;}#modal-global-contact-us div.contact-form__close.close{color:#fff;opacity:1;}}footer#global-footer a{color:#000;}footer#global-footer a:hover{color:#4a7da6;}
31footer#global-footer div.site-footer__col-content.lp-a{opacity:1;}footer#global-footer .site-footer__logo-container img{max-height:80px;}#global-footer .site-footer__disclaimer{opacity:1;color:#000;}#global-mobile-contact .mobile-contact .item{background-color:#4a7da6;color:#fff;}#global-mobile-contact .mobile-contact .item svg{fill:#fff;}</style>
32    <style id="wow-hide-elements">.wow{visibility:hidden!important}</style>
33        <style id="page-css">
34            #section-28f45f08-c7d4-49ae-b152-9a02d549e538{color:#ffffff;--fontColor:#ffffff;--fontColor_H:0;--fontColor_S:0%;--fontColor_L:100%;--fontColor_A:1;--fontColor_darkenDir:-1;--bgColor:#000000;--bgColor_H:0;--bgColor_S:0%;--bgColor_L:0%;--bgColor_A:1;--bgColor_darkenDir:1;background-color:#000000;--gradient-color:var(--overlay-color, rgba(0, 0, 0, 0.45));background-image:linear-gradient(var(--gradient-color), var(--gradient-color)),url('https://media-production.lp-cdn.com/cdn-cgi/image/format=auto,quality=85,fit=scale-down,width=1280/https://media-production.lp-cdn.com/media/vn5berhnrnmdykj03bky');background-repeat:no-repeat;-webkit-background-position:center;background-position:center;-webkit-background-size:cover;background-size:cover;}#section-28f45f08-c7d4-49ae-b152-9a02d549e538 .video-wrapper .full-screen-video-component .video-wrapper::before{content:'';position:absolute;width:100%;height:100%;top:0;left:0;background-color:#000;z-index:-1000;}#section-28f45f08-c7d4-49ae-b152-9a02d549e538 .video-wrapper .full-screen-video-component .video-wrapper video{-webkit-transition:opacity 2s cubic-bezier(0.835, 0, 0.19, 1);transition:opacity 2s cubic-bezier(0.835, 0, 0.19, 1);opacity:0!important;}#section-28f45f08-c7d4-49ae-b152-9a02d549e538 .video-wrapper .full-screen-video-component .video-wrapper.playing video{opacity:1!important;}#section-28f45f08-c7d4-49ae-b152-9a02d549e538 .lp-play{opacity:0;background-color:transparent;display:inline-block;border:none;position:absolute;bottom:50px;right:50px;width:27px;height:24px;z-index:3;-webkit-transition:opacity .2s ease-in-out;transition:opacity .2s ease-in-out;cursor:unset;}#section-28f45f08-c7d4-49ae-b152-9a02d549e538 .lp-play.visible{opacity:1;cursor:pointer;}@media (max-width: 900px){#section-28f45f08-c7d4-49ae-b152-9a02d549e538 .lp-play.visible{display:none;}}@media (max-width: 900px){#section-28f45f08-c7d4-49ae-b152-9a02d549e538 .lp-play{display:none;}}#section-28f45f08-c7d4-49ae-b152-9a02d549e538.parallax-enabled{z-index:unset;}#section-28f45f08-c7d4-49ae-b152-9a02d549e538.parallax-enabled .lp-container{position:relative;}#section-28f45f08-c7d4-49ae-b152-9a02d549e538.parallax-enabled>div.video-wrapper{position:fixed;left:var(--global-body-padding, 0);top:var(--global-body-padding, 0);width:calc(100% - var(--global-body-padding, 0px) * 2);z-index:-1001;}@media (max-width: 767px){#section-28f45f08-c7d4-49ae-b152-9a02d549e538.parallax-enabled>div.video-wrapper{left:0;top:0;width:100%;}}#section-28f45f08-c7d4-49ae-b152-9a02d549e538.parallax-enabled>div.overlay-component{position:fixed;left:var(--global-body-padding, 0);top:var(--global-body-padding, 0);right:unset;width:calc(100% - var(--global-body-padding, 0px) * 2);}@media (max-width: 767px){#section-28f45f08-c7d4-49ae-b152-9a02d549e538.parallax-enabled>div.overlay-component{left:0;top:0;width:100%;}}#section-28f45f08-c7d4-49ae-b152-9a02d549e538.parallax-enabled .opening-with-search:before{display:block;content:'';left:var(--global-body-padding, 0);top:var(--global-body-padding, 0);width:calc(100% - var(--global-body-padding, 0px) * 2);background:var(--sectionBackground) center no-repeat;-webkit-background-size:cover;background-size:cover;background-position-y:22%;position:fixed;z-index:-1001;height:100%;}@media (max-width: 767px){#section-28f45f08-c7d4-49ae-b152-9a02d549e538.parallax-enabled .opening-with-search:before{left:0;top:0;width:100%;}}#section-28f45f08-c7d4-49ae-b152-9a02d549e538 .opening-with-search{position:relative;--top-padding:170px;--bottom-padding:30px;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;width:100%;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;min-height:770px;padding-top:var(--top-padding);padding-bottom:var(--bottom-padding);}#section-28f45f08-c7d4-49ae-b152-9a02d549e538 .opening-with-search:before{display:none;}#section-28f45f08-c7d4-49ae-b152-9a02d549e538 .opening-with-search.height-class-Full{min-height:100vh;}#section-28f45f08-c7d4-49ae-b152-9a02d549e538 .opening-with-search.height-class-Full>div.video-wrapper{height:100vh;}#section-28f45f08-c7d4-49ae-b152-9a02d549e538 .opening-with-search.height-class-Full:before{min-height:100vh;}#section-28f45f08-c7d4-49ae-b152-9a02d549e538 .opening-with-search.height-class-770px{min-height:770px;}#section-28f45f08-c7d4-49ae-b152-9a02d549e538 .opening-with-search.height-class-770px>div.video-wrapper{height:770px;}#section-28f45f08-c7d4-49ae-b152-9a02d549e538 .opening-with-search.height-class-770px:before{min-height:770px;}#section-28f45f08-c7d4-49ae-b152-9a02d549e538 .opening-with-search.height-class-600px{min-height:600px;}#section-28f45f08-c7d4-49ae-b152-9a02d549e538 .opening-with-search.height-class-600px>div.video-wrapper{height:600px;}#section-28f45f08-c7d4-49ae-b152-9a02d549e538 .opening-with-search.height-class-600px:before{min-height:600px;}#section-28f45f08-c7d4-49ae-b152-9a02d549e538 .opening-with-search .bottom-sp
34acer{-webkit-flex:1 0 0%;-ms-flex:1 0 0%;flex:1 0 0%;max-height:calc(var(--top-padding) - var(--bottom-padding));}#section-28f45f08-c7d4-49ae-b152-9a02d549e538 .opening-with-search .center-block{-webkit-flex:1 0 auto;-ms-flex:1 0 auto;flex:1 0 auto;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;text-align:center;}#section-28f45f08-c7d4-49ae-b152-9a02d549e538 .opening-with-search .opening-description{letter-spacing:.1em;margin-bottom:15px;max-width:640px;margin-left:auto;margin-right:auto;}#section-28f45f08-c7d4-49ae-b152-9a02d549e538 .opening-with-search .opening-description a,#section-28f45f08-c7d4-49ae-b152-9a02d549e538 .opening-with-search .opening-description a[x-apple-data-detectors]{color:inherit!important;-webkit-text-decoration:none!important;text-decoration:none!important;font-size:inherit!important;font-family:inherit!important;}#section-28f45f08-c7d4-49ae-b152-9a02d549e538 .opening-with-search .opening-pretitle{margin-bottom:15px;max-width:860px;margin-left:auto;margin-right:auto;white-space:pre-line;}#section-28f45f08-c7d4-49ae-b152-9a02d549e538 .opening-with-search .opening-title{margin-bottom:15px;max-width:860px;margin-left:auto;margin-right:auto;white-space:pre-line;}#section-28f45f08-c7d4-49ae-b152-9a02d549e538 .opening-with-search .opening-button{margin:0 15px;}@media (max-width: 768px){#section-28f45f08-c7d4-49ae-b152-9a02d549e538 .opening-with-search .opening-button{margin:0;}}#section-28f45f08-c7d4-49ae-b152-9a02d549e538 .opening-with-search .search-form{margin-top:30px;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;width:100%;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;-webkit-align-items:stretch;-webkit-box-align:stretch;-ms-flex-align:stretch;align-items:stretch;}#section-28f45f08-c7d4-49ae-b152-9a02d549e538 .opening-with-search .search-form.with-filters{padding-top:32px;}#section-28f45f08-c7d4-49ae-b152-9a02d549e538 .opening-with-search .search-button{margin:5px;border:none;border-radius:0;outline:none;background-color:#000;color:#fff;height:44px;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;padding-left:50px;padding-right:50px;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;cursor:pointer;-webkit-transition:all .3s ease;transition:all .3s ease;}#section-28f45f08-c7d4-49ae-b152-9a02d549e538 .opening-with-search .search-button:hover{background-color:#fff;color:#000;}#section-28f45f08-c7d4-49ae-b152-9a02d549e538 .opening-with-search .search-lease-tabs{position:absolute;left:0;bottom:100%;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;}#section-28f45f08-c7d4-49ae-b152-9a02d549e538 .opening-with-search .search-lease-tab{padding:4px 20px;background-color:#000;color:#fff;cursor:pointer;}#section-28f45f08-c7d4-49ae-b152-9a02d549e538 .opening-with-search .search-lease-tab.active{background-color:#fff;color:#000;}#section-28f45f08-c7d4-49ae-b152-9a02d549e538 .opening-with-search .search-wrapper{margin:5px;letter-spacing:normal;width:100%;max-width:444px;position:relative;}#section-28f45f08-c7d4-49ae-b152-9a02d549e538 .opening-with-search .search-input-container{width:100%;border:none;height:43px;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;padding:0 16px;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;background-color:#fff;}#section-28f45f08-c7d4-49ae-b152-9a02d549e538 .opening-with-search .search-input-container .search-icon{color:#c0c0c0;margin-right:10px;-webkit-flex:0 0 auto;-ms-flex:0 0 auto;flex:0 0 auto;font-size:20px;line-height:0;}#section-28f45f08-c7d4-49ae-b152-9a02d549e538 .opening-with-search .search-input-container .search-input{color:#000;-webkit-flex:1 0 auto;-ms-flex:1 0 auto;flex:1 0 auto;width:50px;border:none;border-radius:0;outline:none;background:transparent;font-size:16px;padding:0;}#section-28f45f08-c7d4-49ae-b152-9a02d549e538 .opening-with-search .search-results{line-height:normal;text-align:left;background-color:rgba(0, 0, 0, 0.8);position:absolute;width:100%;left:0;top:100%;border:none;overflow:hidden;-webkit-transition:height 0.3s ease;transition:height 0.3s ease;height:0;}#section-28f45f08-c7d4-49ae-b152-9a02d549e538 .opening-with-search .results-container,#section-28f45f08-c7d4-49ae-b152-9a02d549e538 .opening-with-search .predefined-links{padding:10px 0;}#section-28f45f08-c7d4-49ae-b152-9a02d549e538 .opening-with-search .results-container a,#section-28f45f08-c7d4-49ae-b152-9a02d549e538 .opening-with-search .predefined-links a{color:#b6b6b6;-webkit-transition:color 0.3s ease;transition:color 0.3s ease;}#section-28f45f08-c7d4-49ae-b152-9a02d549e538 .opening-with-search .results-container a:hover,#section-28f45f08-c7d4-49ae-b152-9a02d549e538 .opening-with-search .predefined-links a:hover{color:#fff;}#section-28f45f08-c7d4-49ae-b152-9a02d549e538 .opening-with-search .predefined-links{max-height:400px;overflow:auto;}#section-28f45f08-c7d4-49ae-b152-9a02d549e538 .opening-with-search .results-block{margin:15px 0;}#section-28f45f08-c7d4-49ae-b152-9a02d549e538 .opening-with-search .results-block-title{margin:0;padding:0 48px;}#section-28f45f08-c7d4-49ae-b152-9a02d549e538 .opening-with-search .results-block-title .results-title-label{margin:0 20px 10px 0;}#section-28f45f08-c7d4-49ae-b152-9a02d549e538 .opening-with-search .results-block-title .search-near-container{margin-bottom:15px;}#section-28f45f08-c7d4-49ae-b152-9a02d549e538 .opening-with-search .results-block:nth-child(n + 2) .search-near-container{display:none;}#section-28f45f08-c7d4-49ae-b152-9a02d549e538 .opening-with-search .results-link{display:block;padding:4px 48px;width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}#section-28f45f08-c7d4-49ae-b152-9a02d549e538 .opening-with-search .results-link.selected-link{color:#fff;background-color:rgba(255, 255, 255, 0.2);}#section-28f45f08-c7d4-49ae-b152-9a02d549e538 .opening-with-search .search-in-progress{padding:30px 0;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;
34-webkit-justify-content:center;justify-content:center;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;font-size:30px;opacity:0.5;}#section-28f45f08-c7d4-49ae-b152-9a02d549e538 .opening-with-search .not-visible{display:none!important;}#section-28f45f08-c7d4-49ae-b152-9a02d549e538 .opening-with-search .nothing-found{width:100%;padding:20px;}@media (max-width: 560px){#section-28f45f08-c7d4-49ae-b152-9a02d549e538 .opening-with-search .search-form{-webkit-box-flex-wrap:wrap;-webkit-flex-wrap:wrap;-ms-flex-wrap:wrap;flex-wrap:wrap;}#section-28f45f08-c7d4-49ae-b152-9a02d549e538 .opening-with-search .search-button{width:100%;max-width:444px;}}#section-28f45f08-c7d4-49ae-b152-9a02d549e538 .opening-with-search .search-near{cursor:pointer;}#section-28f45f08-c7d4-49ae-b152-9a02d549e538 .loc-msg-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;-webkit-transition:background-color 0.3s ease;transition:background-color 0.3s ease;background-color:transparent;}#section-28f45f08-c7d4-49ae-b152-9a02d549e538 .loc-msg-wrap{width:100%;height:100%;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;padding:20px;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-clip-path:polygon(50% 50%, 50% 50%, 50% 50%, 50% 50%);clip-path:polygon(50% 50%, 50% 50%, 50% 50%, 50% 50%);-webkit-transition:clip-path 0.4s ease;transition:clip-path 0.4s ease;}#section-28f45f08-c7d4-49ae-b152-9a02d549e538 .loc-msg-modal{border-radius:20px;padding:10px 20px 20px;max-width:400px;min-width:100px;background-color:rgba(0,0,0,0.9);color:#fff;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;position:relative;-webkit-flex:0 1 auto;-ms-flex:0 1 auto;flex:0 1 auto;max-height:100%;}#section-28f45f08-c7d4-49ae-b152-9a02d549e538 .loc-msg-close{position:absolute;width:40px;height:40px;top:10px;right:10px;cursor:pointer;-webkit-transition:all 0.3s ease;transition:all 0.3s ease;}#section-28f45f08-c7d4-49ae-b152-9a02d549e538 .loc-msg-close:before{content:'';width:20px;height:2px;background-color:#fff;position:absolute;left:10px;top:19px;-webkit-transform:rotate(45deg);-moz-transform:rotate(45deg);-ms-transform:rotate(45deg);transform:rotate(45deg);}#section-28f45f08-c7d4-49ae-b152-9a02d549e538 .loc-msg-close:after{content:'';width:20px;height:2px;background-color:#fff;position:absolute;left:10px;top:19px;-webkit-transform:rotate(-45deg);-moz-transform:rotate(-45deg);-ms-transform:rotate(-45deg);transform:rotate(-45deg);}#section-28f45f08-c7d4-49ae-b152-9a02d549e538 .loc-msg-close:hover{-webkit-transform:scale(1.2);-moz-transform:scale(1.2);-ms-transform:scale(1.2);transform:scale(1.2);}#section-28f45f08-c7d4-49ae-b152-9a02d549e538 .search-near-hidden .search-near-container{display:none;}#section-28f45f08-c7d4-49ae-b152-9a02d549e538 .loc-msg-title{-webkit-flex:0 0 auto;-ms-flex:0 0 auto;flex:0 0 auto;margin-bottom:20px;}#section-28f45f08-c7d4-49ae-b152-9a02d549e538 .loc-msg-container{-webkit-flex:0 1 auto;-ms-flex:0 1 auto;flex:0 1 auto;overflow:auto;}#section-28f45f08-c7d4-49ae-b152-9a02d549e538 .loc-msg-container p{margin:0;}#section-28f45f08-c7d4-49ae-b152-9a02d549e538 .loc-msg-container p+p{margin-top:1em;}#section-28f45f08-c7d4-49ae-b152-9a02d549e538.visible-loc-msg{z-index:1000;}#section-28f45f08-c7d4-49ae-b152-9a02d549e538.visible-loc-msg .loc-msg-backdrop{background-color:rgba(255,255,255,0.4);}#section-28f45f08-c7d4-49ae-b152-9a02d549e538.visible-loc-msg .loc-msg-wrap{-webkit-clip-path:polygon(0 0, 0 100%, 100% 100%, 100% 0%);clip-path:polygon(0 0, 0 100%, 100% 100%, 100% 0%);}@media (min-width: 960px) and (orientation: landscape){#section-28f45f08-c7d4-49ae-b152-9a02d549e538{background-image:linear-gradient(var(--gradient-color), var(--gradient-color)),url('https://media-production.lp-cdn.com/cdn-cgi/image/format=auto,quality=85,fit=scale-down,width=1280/https://media-production.lp-cdn.com/media/vn5berhnrnmdykj03bky');}}@media (min-width: 1280px) and (orientation: landscape){#section-28f45f08-c7d4-49ae-b152-9a02d549e538{background-image:linear-gradient(var(--gradient-color), var(--gradient-color)),url('https://media-production.lp-cdn.com/cdn-cgi/image/format=auto,quality=85,fit=scale-down,width=1920/https://media-production.lp-cdn.com/media/vn5berhnrnmdykj03bky');}}@media (min-width: 1920px) and (orientation: landscape){#section-28f45f08-c7d4-49ae-b152-9a02d549e538{background-image:linear-gradient(var(--gradient-color), var(--gradient-color)),url('https://media-production.lp-cdn.com/cdn-cgi/image/format=auto,quality=85/https://media-production.lp-cdn.com/media/vn5berhnrnmdykj03bky');}}@media (min-width: 2560px) and (orientation: landscape){#section-28f45f08-c7d4-49ae-b152-9a02d549e538{background-image:linear-gradient(var(--gradient-color), var(--gradient-color)),url('https://media-production.lp-cdn.com/cdn-cgi/image/format=auto,quality=85/https://media-production.lp-cdn.com/media/vn5berhnrnmdykj03bky');}}
34#section-3087e602-065d-462f-8f31-f4819d6fc3cd{color:#211f1f;--fontColor:#211f1f;--fontColor_H:0;--fontColor_S:3%;--fontColor_L:13%;--fontColor_A:1;--fontColor_darkenDir:1;--bgColor:#fff;--bgColor_H:0;--bgColor_S:0%;--bgColor_L:100%;--bgColor_A:1;--bgColor_darkenDir:-1;--section-padding-top:calc(4 / 4 * var(--global-section-padding));--section-padding-bottom:calc(2 / 4 * var(--global-section-padding));background-color:#fff;}#section-3087e602-065d-462f-8f31-f4819d6fc3cd .collection{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-flex-wrap:wrap;-webkit-flex-wrap:wrap;-ms-flex-wrap:wrap;flex-wrap:wrap;margin:0 -10px;}@media (min-width: 1024px){#section-3087e602-065d-462f-8f31-f4819d6fc3cd .collection:not(.collection--3) .item{width:calc(50% - 20px);}#section-3087e602-065d-462f-8f31-f4819d6fc3cd .collection:not(.collection--3) .item figure{height:462px;}}#section-3087e602-065d-462f-8f31-f4819d6fc3cd .item{width:calc(33.33333% - 20px);margin:0 10px 48px;-webkit-text-decoration:none;text-decoration:none;color:inherit;}@media (max-width: 991px){#section-3087e602-065d-462f-8f31-f4819d6fc3cd .item{width:calc(50% - 20px);}}@media (max-width: 767px){#section-3087e602-065d-462f-8f31-f4819d6fc3cd .item{margin-bottom:24px;width:100%;}}@media (hover: hover) and (pointer: fine){#section-3087e602-065d-462f-8f31-f4819d6fc3cd .item:hover img{-webkit-transform:scale(1.1);-moz-transform:scale(1.1);-ms-transform:scale(1.1);transform:scale(1.1);}}#section-3087e602-065d-462f-8f31-f4819d6fc3cd .item figure{position:relative;overflow:hidden;margin:0 0 24px 0;background-color:#f2f2f2;height:310px;}#section-3087e602-065d-462f-8f31-f4819d6fc3cd .item img{-webkit-transition:all .3s;transition:all .3s;height:100%;width:100%;object-fit:cover;}#section-3087e602-065d-462f-8f31-f4819d6fc3cd .item .label{text-transform:uppercase;position:absolute;top:10px;right:10px;padding:6px 10px;background-color:rgba(255,255,255, .8);margin:0;max-width:100%;white-space:nowrap;text-overflow:ellipsis;overflow:hidden;}#section-3087e602-065d-462f-8f31-f4819d6fc3cd .item .lp-h5{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;text-overflow:ellipsis;margin:0 0 8px;}#section-3087e602-065d-462f-8f31-f4819d6fc3cd .item .bf1{margin:0 0 8px;}#section-3087e602-065d-462f-8f31-f4819d6fc3cd .item-text{margin:0;}#section-3087e602-065d-462f-8f31-f4819d6fc3cd .lp-pagination{margin-top:16px;}@media (max-width: 767px){#section-3087e602-065d-462f-8f31-f4819d6fc3cd .lp-pagination{margin-top:8px;}}#section-3087e602-065d-462f-8f31-f4819d6fc3cd>div:last-child{padding-top:calc(4 / 4 * var(--global-section-padding))!important;padding-bottom:calc(2 / 4 * var(--global-section-padding))!important;}#section-5d01005b-e93f-48f9-92b7-4822576c8b85{color:#211f1f;--fontColor:#211f1f;--fontColor_H:0;--fontColor_S:3%;--fontColor_L:13%;--fontColor_A:1;--fontColor_darkenDir:1;--bgColor:#fff;--bgColor_H:0;--bgColor_S:0%;--bgColor_L:100%;--bgColor_A:1;--bgColor_darkenDir:-1;--section-padding-top:calc(4 / 4 * var(--global-section-padding));--section-padding-bottom:calc(2 / 4 * var(--global-section-padding));background-color:#fff;}#section-5d01005b-e93f-48f9-92b7-4822576c8b85 .collection{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-flex-wrap:wrap;-webkit-flex-wrap:wrap;-ms-flex-wrap:wrap;flex-wrap:wrap;margin:0 -10px;}@media (min-width: 1024px){#section-5d01005b-e93f-48f9-92b7-4822576c8b85 .collection:not(.collection--3) .item{width:calc(50% - 20px);}#section-5d01005b-e93f-48f9-92b7-4822576c8b85 .collection:not(.collection--3) .item figure{height:462px;}}#section-5d01005b-e93f-48f9-92b7-4822576c8b85 .item{width:calc(33.33333% - 20px);margin:0 10px 48px;-webkit-text-decoration:none;text-decoration:none;color:inherit;}@media (max-width: 991px){#section-5d01005b-e93f-48f9-92b7-4822576c8b85 .item{width:calc(50% - 20px);}}@media (max-width: 767px){#section-5d01005b-e93f-48f9-92b7-4822576c8b85 .item{margin-bottom:24px;width:100%;}}@media (hover: hover) and (pointer: fine){#section-5d01005b-e93f-48f9-92b7-4822576c8b85 .item:hover img{-webkit-transform:scale(1.1);-moz-transform:scale(1.1);-ms-transform:scale(1.1);transform:scale(1.1);}}#section-5d01005b-e93f-48f9-92b7-4822576c8b85 .item figure{position:relative;overflow:hidden;margin:0 0 24px 0;background-color:#f2f2f2;height:310px;}#section-5d01005b-e93f-48f9-92b7-4822576c8b85 .item img{-webkit-transition:all .3s;transition:all .3s;height:100%;width:100%;object-fit:cover;}#section-5d01005b-e93f-48f9-92b7-4822576c8b85 .item .label{text-transform:uppercase;position:absolute;top:10px;right:10px;padding:6px 10px;background-color:rgba(255,255,255, .8);margin:0;max-width:100%;white-space:nowrap;text-overflow:ellipsis;overflow:hidden;}#section-5d01005b-e93f-48f9-92b7-4822576c8b85 .item .lp-h5{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;text-overflow:ellipsis;margin:0 0 8px;}#section-5d01005b-e93f-48f9-92b7-4822576c8b85 .item .bf1{margin:0 0 8px;}#section-5d01005b-e93f-48f9-92b7-4822576c8b85 .item-text{margin:0;}#section-5d01005b-e93f-48f9-92b7-4822576c8b85 .lp-pagination{margin-top:16px;}@media (max-width: 767px){#section-5d01005b-e93f-48f9-92b7-4822576c8b85 .lp-pagination{margin-top:8px;}}#section-5d01005b-e93f-48f9-92b7-4822576c8b85>div:last-child{padding-top:calc(4 / 4 * var(--global-section-padding))!important;padding-bottom:calc(2 / 4 * var(--global-section-padding))!important;}
34#section-c0d58c8d-bb8c-453f-9168-aa08a1cecdda{color:#211f1f;--fontColor:#211f1f;--fontColor_H:0;--fontColor_S:3%;--fontColor_L:13%;--fontColor_A:1;--fontColor_darkenDir:1;--bgColor:#fff;--bgColor_H:0;--bgColor_S:0%;--bgColor_L:100%;--bgColor_A:1;--bgColor_darkenDir:-1;--section-padding-top:calc(4 / 4 * var(--global-section-padding));--section-padding-bottom:calc(2 / 4 * var(--global-section-padding));background-color:#fff;}#section-c0d58c8d-bb8c-453f-9168-aa08a1cecdda .lp-pagination.pagination-container .paginationjs .paginationjs-pages ul li a:after{border-right:2px solid #36454d;border-top:2px solid #36454d;}#section-c0d58c8d-bb8c-453f-9168-aa08a1cecdda .lp-pagination.pagination-container .paginationjs .paginationjs-pages ul li a:hover::after{border-right:2px solid #1f282d;border-top:2px solid #1f282d;}#section-c0d58c8d-bb8c-453f-9168-aa08a1cecdda .collection{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-flex-wrap:wrap;-webkit-flex-wrap:wrap;-ms-flex-wrap:wrap;flex-wrap:wrap;margin:0 -10px;}@media (min-width: 1024px){#section-c0d58c8d-bb8c-453f-9168-aa08a1cecdda .collection:not(.collection--3) .item{width:calc(50% - 20px);}#section-c0d58c8d-bb8c-453f-9168-aa08a1cecdda .collection:not(.collection--3) .item figure{height:462px;}}#section-c0d58c8d-bb8c-453f-9168-aa08a1cecdda .item{width:calc(33.33333% - 20px);margin:0 10px 48px;-webkit-text-decoration:none;text-decoration:none;color:inherit;}@media (max-width: 991px){#section-c0d58c8d-bb8c-453f-9168-aa08a1cecdda .item{width:calc(50% - 20px);}}@media (max-width: 767px){#section-c0d58c8d-bb8c-453f-9168-aa08a1cecdda .item{margin-bottom:24px;width:100%;}}@media (hover: hover) and (pointer: fine){#section-c0d58c8d-bb8c-453f-9168-aa08a1cecdda .item:hover img{-webkit-transform:scale(1.1);-moz-transform:scale(1.1);-ms-transform:scale(1.1);transform:scale(1.1);}}#section-c0d58c8d-bb8c-453f-9168-aa08a1cecdda .item figure{position:relative;overflow:hidden;margin:0 0 24px 0;background-color:#f2f2f2;height:310px;}#section-c0d58c8d-bb8c-453f-9168-aa08a1cecdda .item img{-webkit-transition:all .3s;transition:all .3s;height:100%;width:100%;object-fit:cover;}#section-c0d58c8d-bb8c-453f-9168-aa08a1cecdda .item .label{text-transform:uppercase;position:absolute;top:10px;right:10px;padding:6px 10px;background-color:rgba(255,255,255, .8);margin:0;max-width:100%;white-space:nowrap;text-overflow:ellipsis;overflow:hidden;}#section-c0d58c8d-bb8c-453f-9168-aa08a1cecdda .item .lp-h5{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;text-overflow:ellipsis;margin:0 0 8px;}#section-c0d58c8d-bb8c-453f-9168-aa08a1cecdda .item .bf1{margin:0 0 8px;}#section-c0d58c8d-bb8c-453f-9168-aa08a1cecdda .item-text{margin:0;}#section-c0d58c8d-bb8c-453f-9168-aa08a1cecdda .lp-pagination{margin-top:16px;}@media (max-width: 767px){#section-c0d58c8d-bb8c-453f-9168-aa08a1cecdda .lp-pagination{margin-top:8px;}}#section-c0d58c8d-bb8c-453f-9168-aa08a1cecdda>div:last-child{padding-top:calc(4 / 4 * var(--global-section-padding))!important;padding-bottom:calc(2 / 4 * var(--global-section-padding))!important;}#section-42ff6c98-9b79-4ecf-b1d4-503fd5a6e14d{color:#ffffff;--fontColor:#ffffff;--fontColor_H:0;--fontColor_S:0%;--fontColor_L:100%;--fontColor_A:1;--fontColor_darkenDir:-1;--bgColor:#fff;--bgColor_H:0;--bgColor_S:0%;--bgColor_L:100%;--bgColor_A:1;--bgColor_darkenDir:-1;background-color:#fff;--gradient-color:var(--overlay-color, rgba(0, 0, 0, 0.45));background-image:linear-gradient(var(--gradient-color), var(--gradient-color)),url('https://media-production.lp-cdn.com/cdn-cgi/image/format=auto,quality=85,fit=scale-down,width=1280/https://media-production.lp-cdn.com/media/kpojpqpzs2ffhzfjpbp2');background-repeat:no-repeat;-webkit-background-position:center;background-position:center;-webkit-background-size:cover;background-size:cover;}#section-42ff6c98-9b79-4ecf-b1d4-503fd5a6e14d div.lp-container.lp-vertical-paddings{z-index:9;}#section-42ff6c98-9b79-4ecf-b1d4-503fd5a6e14d.parallax-enabled{-webkit-clip-path:polygon(0px 0px, 100% 0%, 100% 100%, 0% 100%);clip-path:polygon(0px 0px, 100% 0%, 100% 100%, 0% 100%);}#section-42ff6c98-9b79-4ecf-b1d4-503fd5a6e14d.parallax-enabled>div.video-wrapper{position:fixed;left:0;top:0;width:100vw;height:100vh;z-index:-9999;}#section-42ff6c98-9b79-4ecf-b1d4-503fd5a6e14d.parallax-enabled .work-with-us:before{display:block;content:'';left:0;top:0;width:100%;
34background:var(--sectionBackground) center no-repeat;-webkit-background-size:cover;background-size:cover;position:fixed;z-index:-1;height:100%;}#section-42ff6c98-9b79-4ecf-b1d4-503fd5a6e14d .section{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;min-height:780px;text-align:center;position:relative;z-index:2;}@media (max-width: 767px){#section-42ff6c98-9b79-4ecf-b1d4-503fd5a6e14d .section{min-height:100vh;}}#section-42ff6c98-9b79-4ecf-b1d4-503fd5a6e14d .section:before{content:'';position:absolute;bottom:0;left:0;height:50%;width:100%;pointer-events:none;z-index:3;-webkit-transform:translateZ(1px);-moz-transform:translateZ(1px);-ms-transform:translateZ(1px);transform:translateZ(1px);background:linear-gradient(180deg, rgba(0, 0, 0, 0) 0%,  var(--opacityColor) 100%);}#section-42ff6c98-9b79-4ecf-b1d4-503fd5a6e14d .section .btn-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;gap:23px;margin-top:32px;}@media(max-width: 560px){#section-42ff6c98-9b79-4ecf-b1d4-503fd5a6e14d .section .btn-container{-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;gap:10px;}}#section-42ff6c98-9b79-4ecf-b1d4-503fd5a6e14d .lp-container{-webkit-transform:translateZ(1px);-moz-transform:translateZ(1px);-ms-transform:translateZ(1px);transform:translateZ(1px);}@media (min-width: 960px) and (orientation: landscape){#section-42ff6c98-9b79-4ecf-b1d4-503fd5a6e14d{background-image:linear-gradient(var(--gradient-color), var(--gradient-color)),url('https://media-production.lp-cdn.com/cdn-cgi/image/format=auto,quality=85,fit=scale-down,width=1280/https://media-production.lp-cdn.com/media/kpojpqpzs2ffhzfjpbp2');}}@media (min-width: 1280px) and (orientation: landscape){#section-42ff6c98-9b79-4ecf-b1d4-503fd5a6e14d{background-image:linear-gradient(var(--gradient-color), var(--gradient-color)),url('https://media-production.lp-cdn.com/cdn-cgi/image/format=auto,quality=85,fit=scale-down,width=1920/https://media-production.lp-cdn.com/media/kpojpqpzs2ffhzfjpbp2');}}@media (min-width: 1920px) and (orientation: landscape){#section-42ff6c98-9b79-4ecf-b1d4-503fd5a6e14d{background-image:linear-gradient(var(--gradient-color), var(--gradient-color)),url('https://media-production.lp-cdn.com/cdn-cgi/image/format=auto,quality=85/https://media-production.lp-cdn.com/media/kpojpqpzs2ffhzfjpbp2');}}@media (min-width: 2560px) and (orientation: landscape){#section-42ff6c98-9b79-4ecf-b1d4-503fd5a6e14d{background-image:linear-gradient(var(--gradient-color), var(--gradient-color)),url('https://media-production.lp-cdn.com/cdn-cgi/image/format=auto,quality=85/https://media-production.lp-cdn.com/media/kpojpqpzs2ffhzfjpbp2');}}#section-dc35c8ba-2e7a-45c2-9887-4d2125099be8{color:#ffffff;--fontColor:#ffffff;--fontColor_H:0;--fontColor_S:0%;--fontColor_L:100%;--fontColor_A:1;--fontColor_darkenDir:-1;--bgColor:rgba(89, 123, 164, 1);--bgColor_H:213;--bgColor_S:30%;--bgColor_L:50%;--bgColor_A:1;--bgColor_darkenDir:1;background-color:rgba(89, 123, 164, 1);}#section-dc35c8ba-2e7a-45c2-9887-4d2125099be8 .section{display:none;overflow:hidden;}@media(min-width: 993px){#section-dc35c8ba-2e7a-45c2-9887-4d2125099be8 .lp-container{padding-bottom:200px;}}@media(min-width: 769px){#section-dc35c8ba-2e7a-45c2-9887-4d2125099be8 .lp-container{padding-bottom:194px;}}#section-dc35c8ba-2e7a-45c2-9887-4d2125099be8 .title-group{-webkit-flex-basis:100%;-ms-flex-preferred-size:100%;flex-basis:100%;display:block;margin-bottom:48px;}@media(min-width: 769px){#section-dc35c8ba-2e7a-45c2-9887-4d2125099be8 .title-group{dis
34play:none;}}#section-dc35c8ba-2e7a-45c2-9887-4d2125099be8 .collection{width:100%;min-width:400px;}#section-dc35c8ba-2e7a-45c2-9887-4d2125099be8 .collection:not(.slick-initialized){display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;}#section-dc35c8ba-2e7a-45c2-9887-4d2125099be8 .collection:not(.slick-initialized) .item-box:nth-child(n+6){display:none;}@media(max-width: 768px){#section-dc35c8ba-2e7a-45c2-9887-4d2125099be8 .collection:not(.slick-initialized){-webkit-box-flex-wrap:wrap;-webkit-flex-wrap:wrap;-ms-flex-wrap:wrap;flex-wrap:wrap;}}#section-dc35c8ba-2e7a-45c2-9887-4d2125099be8 .collection .slick-track{margin-left:0;margin-right:0;}#section-dc35c8ba-2e7a-45c2-9887-4d2125099be8 .collection .slick-list{overflow:visible;}#section-dc35c8ba-2e7a-45c2-9887-4d2125099be8 .collection img{max-width:100%;}@media(min-width: 1025px){#section-dc35c8ba-2e7a-45c2-9887-4d2125099be8 .collection .slick-slide:not(:nth-child(4n-2)){opacity:.3;-webkit-transition:opacity .4s ease-in-out;transition:opacity .4s ease-in-out;}#section-dc35c8ba-2e7a-45c2-9887-4d2125099be8 .collection .slick-slide:nth-child(4n-2) .item__img{opacity:.3;-webkit-transition:opacity .4s ease-in-out;transition:opacity .4s ease-in-out;-webkit-transform:translate(-50%, 45px);-moz-transform:translate(-50%, 45px);-ms-transform:translate(-50%, 45px);transform:translate(-50%, 45px);}#section-dc35c8ba-2e7a-45c2-9887-4d2125099be8 .collection .slick-slide:nth-child(4n-2) .item__img svg{display:block;}#section-dc35c8ba-2e7a-45c2-9887-4d2125099be8 .collection .slick-slide:nth-child(4n-2) .item__info{-webkit-transform:translate(0, calc(50% + 45px));-moz-transform:translate(0, calc(50% + 45px));-ms-transform:translate(0, calc(50% + 45px));transform:translate(0, calc(50% + 45px));}#section-dc35c8ba-2e7a-45c2-9887-4d2125099be8 .collection .slick-slide:nth-child(4n-2) .media-type-icon{top:50%;-webkit-transform:translate(0, calc(50% + 35px));-moz-transform:translate(0, calc(50% + 35px));-ms-transform:translate(0, calc(50% + 35px));transform:translate(0, calc(50% + 35px));}#section-dc35c8ba-2e7a-45c2-9887-4d2125099be8 .collection .slick-active:not(:nth-child(4n-2)){opacity:1;-webkit-transition:opacity .4s ease-in-out;transition:opacity .4s ease-in-out;}#section-dc35c8ba-2e7a-45c2-9887-4d2125099be8 .collection .slick-active:nth-child(4n-2) .item__img{opacity:1;-webkit-transition:opacity .4s ease-in-out;transition:opacity .4s ease-in-out;}}@media (min-width: 769px) and (max-width: 1025px){#section-dc35c8ba-2e7a-45c2-9887-4d2125099be8 .collection .slick-slide:not(:nth-child(even)){opacity:.3;-webkit-transition:opacity .4s ease-in-out;transition:opacity .4s ease-in-out;}#section-dc35c8ba-2e7a-45c2-9887-4d2125099be8 .collection .slick-slide:nth-child(even) .item__img{opacity:.3;-webkit-transition:opacity .4s ease-in-out;transition:opacity .4s ease-in-out;-webkit-transform:translate(-50%, 45px);-moz-transform:translate(-50%, 45px);-ms-transform:translate(-50%, 45px);transform:translate(-50%, 45px);}#section-dc35c8ba-2e7a-45c2-9887-4d2125099be8 .collection .slick-slide:nth-child(even) .item__img svg{display:block;}#section-dc35c8ba-2e7a-45c2-9887-4d2125099be8 .collection .slick-slide:nth-child(even) .item__info{-webkit-transform:translate(0, calc(50% + 45px));-moz-transform:translate(0, calc(50% + 45px));-ms-transform:translate(0, calc(50% + 45px));transform:translate(0, calc(50% + 45px));}#section-dc35c8ba-2e7a-45c2-9887-4d2125099be8 .collection .slick-slide:nth-child(even) .media-type-icon{top:50%;-webkit-transform:translate(0, calc(50% + 35px));-moz-transform:translate(0, calc(50% + 35px));-ms-transform:translate(0, calc(50% + 35px));transform:translate(0, calc(50% + 35px));}#section-dc35c8ba-2e7a-45c2-9887-4d2125099be8 .collection .slick-active:not(:nth-child(even)){opacity:1;-webkit-transition:opacity .4s ease-in-out;transition:opacity .4s ease-in-out;}#section-dc35c8ba-2e7a-45c2-9887-4d2125099be8 .collection .slick-active:nth-child(even) .item__img{opacity:1;-webkit-transition:opacity .4s ease-in-out;transition:opacity .4s ease-in-out;}}@media(max-width: 768px){#section-dc35c8ba-2e7a-45c2-9887-4d2125099be8 .collection .slick-slide{opacity:.3;-webkit-transition:opacity .4s ease-in-out;transition:opacity .4s ease-in-out;}#section-dc35c8ba-2e7a-45c2-9887-4d2125099be8 .collection .slick-active{opacity:1;-webkit-transition:opacity .4s ease-in-out;transition:opacity .4s ease-in-out;}#section-dc35c8ba-2e7a-45c2-9887-4d2125099be8 .collection .slick-slide:nth-child(4n-1),#section-dc35c8ba-2e7a-45c2-9887-4d2125099be8 .collection .slick-slide:nth-child(4n){-webkit-transform:translate(-200%, 100%);-moz-transform:translate(-200%, 100%);-ms-transform:translate(-200%, 100%);transform:translate(-200%, 100%);}}@media(min-width: 1440px){#section-dc35c8ba-2e7a-45c2-9887-4d2125099be8 .collection{overflow:hidden;height:514px;}}#section-dc35c8ba-2e7a-45c2-9887-4d2125099be8 .slider-holder{-webkit-box-flex:1;-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1;}@media(max-width: 768px){#section-dc35c8ba-2e7a-45c2-9887-4d2125099be8 .slider-holder{height:calc(100vw - 24px);}}@media(min-width: 1440px){#section-dc35c8ba-2e7a-45c2-9887-4d2125099be8 .slider-holder{width:1440px;margin-left:auto;margin-right:auto;height:310px;}}
34#section-dc35c8ba-2e7a-45c2-9887-4d2125099be8 .item{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;position:relative;z-index:1;width:310px;height:310px;overflow:visible;margin-right:67px;cursor:default;}@media(max-width: 1024px){#section-dc35c8ba-2e7a-45c2-9887-4d2125099be8 .item{width:298px;height:298px;margin-right:44px;}}@media(max-width: 768px){#section-dc35c8ba-2e7a-45c2-9887-4d2125099be8 .item{margin-right:0;margin-bottom:0;width:calc(50vw - 48px);height:calc(50vw - 48px);}}@media(max-width: 560px){#section-dc35c8ba-2e7a-45c2-9887-4d2125099be8 .item{margin-right:0;margin-bottom:0;}}#section-dc35c8ba-2e7a-45c2-9887-4d2125099be8 .item__img{top:50%;left:50%;-webkit-transform:translate(-50%, -50%);-moz-transform:translate(-50%, -50%);-ms-transform:translate(-50%, -50%);transform:translate(-50%, -50%);position:absolute;height:100%;width:100%;background-color:gray;-webkit-background-size:cover;background-size:cover;-webkit-background-position:center center;background-position:center center;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-transition:all linear 0.2s;transition:all linear 0.2s;transform-origin:bottom;}#section-dc35c8ba-2e7a-45c2-9887-4d2125099be8 .item__img svg{display:none;}#section-dc35c8ba-2e7a-45c2-9887-4d2125099be8 .item__text{top:50%;left:50%;-webkit-transform:translate(-50%, -50%);-moz-transform:translate(-50%, -50%);-ms-transform:translate(-50%, -50%);transform:translate(-50%, -50%);position:absolute;overflow:hidden;height:100%;width:100%;word-break:break-all;}@media (max-width: 768px){#section-dc35c8ba-2e7a-45c2-9887-4d2125099be8 .item__text{display:none;}}#section-dc35c8ba-2e7a-45c2-9887-4d2125099be8 .item__text .username-group{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;}#section-dc35c8ba-2e7a-45c2-9887-4d2125099be8 .item__text .username-group .lp-h5{cursor:pointer;display:inline-block;}#section-dc35c8ba-2e7a-45c2-9887-4d2125099be8 .item__text .username-group .lp-h5 span{-webkit-transition:0.2s all;transition:0.2s all;display:inline-block;}@media (hover: hover) and (pointer: fine){#section-dc35c8ba-2e7a-45c2-9887-4d2125099be8 .item__text .username-group .lp-h5:hover span{-webkit-transform:translateX(5px);-moz-transform:translateX(5px);-ms-transform:translateX(5px);transform:translateX(5px);}}#section-dc35c8ba-2e7a-45c2-9887-4d2125099be8 .item__text .username-group .arrow-icon{display:inline-block;margin-top:9px;width:21px;}@media (max-width: 768px){#section-dc35c8ba-2e7a-45c2-9887-4d2125099be8 .item-box{padding:13px;}}#section-dc35c8ba-2e7a-45c2-9887-4d2125099be8 .item__info{position:absolute;top:0;left:0;bottom:0;right:0;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;padding:10%;overflow:hidden;color:#fff;text-align:center;background-color:rgba(0, 0, 0, 0.7);opacity:0;-webkit-transition:opacity .3s ease;transition:opacity .3s ease;cursor:pointer;}@media (hover: hover){#section-dc35c8ba-2e7a-45c2-9887-4d2125099be8 .item__info:hover{opacity:1;}}#section-dc35c8ba-2e7a-45c2-9887-4d2125099be8 .item__caption{text-overflow:ellipsis;-webkit-line-clamp:5;display:-webkit-box;-webkit-box-orient:vertical;overflow:hidden;}#section-dc35c8ba-2e7a-45c2-9887-4d2125099be8 h5{color:var(--userColor);text-transform:uppercase;}#section-dc35c8ba-2e7a-45c2-9887-4d2125099be8 h3{color:var(--fontColor);margin-bottom:16px;white-space:pre-line;}@media (max-width: 768px){#section-dc35c8ba-2e7a-45c2-9887-4d2125099be8 h3{width:calc(100vw - 50px);}}#section-dc35c8ba-2e7a-45c2-9887-4d2125099be8 a{-webkit-text-decoration:none;text-decoration:none;}#section-dc35c8ba-2e7a-45c2-9887-4d2125099be8 .media-type-icon{position:absolute;top:10px;right:10px;}#section-dc35c8ba-2e7a-45c2-9887-4d2125099be8 .has-data .section{dis
34play:block;}#section-dc35c8ba-2e7a-45c2-9887-4d2125099be8.has-data .section{display:block;}#section-dc35c8ba-2e7a-45c2-9887-4d2125099be8#section-temp .section{display:block;}#modal-global-contact-us>.close{display:none;}#modal-global-contact-us .contact-form{--colorLighter1:hsla(var(--fontColor_H), var(--fontColor_S), var(--fontColor_L), 0.5);--colorLighter2:hsla(var(--fontColor_H), var(--fontColor_S), var(--fontColor_L), 0.3);width:100%;background:center no-repeat;-webkit-background-size:cover;background-size:cover;min-height:800px;height:100vh;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;background-color:#fff;color:#000;-webkit-box-pack:space-around;-ms-flex-pack:space-around;-webkit-justify-content:space-around;justify-content:space-around;}#modal-global-contact-us .contact-form ::parent{-webkit-align-items:unset;-webkit-box-align:unset;-ms-flex-align:unset;align-items:unset;}@media (max-width: 1024px){#modal-global-contact-us .contact-form{min-height:100vh;height:auto;display:block;}}#modal-global-contact-us .contact-form .input-container{width:100%;}#modal-global-contact-us .contact-form .input-container+.input-container{margin-top:8px;}#modal-global-contact-us .contact-form__container{z-index:2;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-flex:1;-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;}@media (max-width: 1024px){#modal-global-contact-us .contact-form__container{padding:0;width:100%;display:block;}}#modal-global-contact-us .contact-form__close{position:absolute;right:5px;top:5px;z-index:10;background-color:transparent;border:none;width:40px;height:40px;cursor:pointer;opacity:0.2;}#modal-global-contact-us .contact-form__close.close{color:#000;}#modal-global-contact-us .contact-form__close:before,#modal-global-contact-us .contact-form__close:after{display:block;content:'';position:absolute;width:20px;height:2px;background-color:currentColor;left:50%;top:50%;}@media (max-width: 768px){#modal-global-contact-us .contact-form__close{top:1vh;}}@media (min-width: 768px) and (max-width: 810px),(min-height: 1024px) and (max-height: 1080px){#modal-global-contact-us .contact-form__close{top:3vh;}}#modal-global-contact-us .contact-form__close:before{-webkit-transform:translate(-50%, -50%) rotate(45deg);-moz-transform:translate(-50%, -50%) rotate(45deg);-ms-transform:translate(-50%, -50%) rotate(45deg);transform:translate(-50%, -50%) rotate(45deg);}#modal-global-contact-us .contact-form__close:after{-webkit-transform:translate(-50%, -50%) rotate(-45deg);-moz-transform:translate(-50%, -50%) rotate(-45deg);-ms-transform:translate(-50%, -50%) rotate(-45deg);transform:translate(-50%, -50%) rotate(-45deg);}#modal-global-contact-us .contact-form__form{width:100%;max-width:637px;text-align:center;min-height:463px;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;position:relative;margin-right:110px;padding:64px 65px;margin-bottom:0;}@media (max-width: 1024px){#modal-global-contact-us .contact-form__form{width:100%;max-width:100%;margin-right:0;padding:44px 24px;}}#modal-global-contact-us .contact-form__details{width:100%;max-width:510px;margin-top:66px;}@media (max-width: 1024px){#modal-global-contact-us .contact-form__details{width:100%;max-width:100%;margin-top:48px;padding-left:24px;padding-right:24px;}}#modal-global-contact-us .contact-form__input{width:100%;}#modal-global-contact-us .contact-form__submit{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;
34-webkit-justify-content:center;justify-content:center;margin-top:16px;width:100%;padding-top:5px;padding-bottom:5px;height:50px;}#modal-global-contact-us .contact-form .thank-you{display:none;padding:24px;}#modal-global-contact-us .contact-form .success .thank-you{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;}#modal-global-contact-us .contact-form .success .form-group{display:none;}#modal-global-contact-us .contact-form .success .image{display:none;}#modal-global-contact-us .contact-form__title1{margin-bottom:16px;text-align:left;}#modal-global-contact-us .contact-form__title2{margin-bottom:16px;}#modal-global-contact-us .contact-form__description{margin-bottom:48px;}@media (max-width: 1024px){#modal-global-contact-us .contact-form__description{margin-bottom:32px;}}#modal-global-contact-us .form-inputs-wrap.center-aligned{margin-left:auto;margin-right:auto;}#modal-global-contact-us .company{padding-top:24px;padding-bottom:48px;border-top:1px solid rgba(0, 0, 0, 0.5);color:rgba(0, 0, 0, 0.5);}@media (max-width: 1024px){#modal-global-contact-us .company{padding-bottom:32px;}}#modal-global-contact-us .company_title{margin-bottom:0;}#modal-global-contact-us .company .lp-a a{white-space:nowrap;}#modal-global-contact-us .company p{margin-bottom:0;}#modal-global-contact-us .socials{margin:-8px;margin-bottom:20px;}@media (max-width: 767px){#modal-global-contact-us .socials{margin-left:auto;width:-webkit-max-content;width:-moz-max-content;width:max-content;margin-right:auto;max-width:100%;}}#modal-global-contact-us .socials li{margin:0;padding:8px;}#modal-global-contact-us .contact-form__submit{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;}#modal-global-contact-us .sync-icon{display:none;margin-right:10px;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}#modal-global-contact-us .success-icon{display:none;margin-right:10px;-webkit-transition:0s;transition:0s;visibility:visible;}#modal-global-contact-us .loading{pointer-events:none;}#modal-global-contact-us .loading .sync-icon{display:-webkit-inline-box;display:-webkit-inline-flex;display:-ms-inline-flexbox;display:inline-flex;}#modal-global-contact-us .success-text{display:none;}#modal-global-contact-us .success{pointer-events:none;}#modal-global-contact-us .success .success-icon{display:block;}#modal-global-contact-us .success .success-text{display:inline;}nav{-webkit-transition:0.2s all;transition:0.2s all;color:#fff;z-index:102;}nav nav{-webkit-transition:0.2s all;transition:0.2s all;color:#fff;}nav nav.scroll .header__logo .dark{display:block;}nav nav.scroll .header__logo .light{display:none;}nav.scroll .header__logo .dark{display:block;}nav.scroll .header__logo .light{display:none;}nav .header{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;padding:24px 30px;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}@media (max-width: 560px){nav .header{padding:10px 24px;}}nav .header__hamburger{background-color:transparent;cursor:pointer;outline:none;position:relative;padding:0;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;margin-left:61px;width:60px;height:60px;border:none;}@media (max-width: 768px){nav .header__hamburger{width:40px;height:40px;margin-left:15px;}}@media (hover: hover) and (pointer: fine){nav .header__hamburger:hover .line--top{width:12px;x:30px;}nav .header__hamburger:hover .line--bottom{width:24px;x:18px;}}nav .header__hamburger svg{width:100%;height:100%;}
34nav .header__hamburger circle{fill:var(--themeBeige);}nav .header__hamburger .line{fill:var(--themeWhite);height:2px;width:24px;x:18px;y:26px;-webkit-transition:0.2s all;transition:0.2s all;}nav .header__hamburger .line--bottom{width:12px;x:30px;y:32px;}nav .header__left{-webkit-flex-basis:50%;-ms-flex-preferred-size:50%;flex-basis:50%;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-flex:1;-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1;}nav .header__left .navigation{-webkit-box-pack:start;-ms-flex-pack:start;-webkit-justify-content:flex-start;justify-content:flex-start;}nav .header__logo{display:block;cursor:pointer;}nav .header__logo img{display:block;max-height:52px;max-width:250px;}nav .header__logo .dark{display:none;}nav .header__logo--center{-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;}nav .header__right{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-flex:1;-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1;-webkit-flex-basis:50%;-ms-flex-preferred-size:50%;flex-basis:50%;-webkit-box-pack:end;-ms-flex-pack:end;-webkit-justify-content:flex-end;justify-content:flex-end;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}nav .header__right .navigation__item:nth-last-child(-n + 1) .sub-nav{left:auto;right:0;}nav .sub-nav{position:absolute;left:0;top:100%;padding:0;max-height:0;z-index:5;margin:0;list-style-type:none;overflow:hidden;visibility:hidden;-webkit-transition:visibility 0s linear 0.3s,max-height 0.3s ease;transition:visibility 0s linear 0.3s,max-height 0.3s ease;}nav .sub-nav.visible{-webkit-transition:visibility 0s linear 0s,max-height 0.3s ease-in;transition:visibility 0s linear 0s,max-height 0.3s ease-in;max-height:100vh;visibility:visible;}nav .sub-nav__item{position:relative;display:block;margin:0;text-align:left;}nav .sub-nav__link{display:block;color:var(--themeWhite, #fff);font-size:14px;font-weight:600;padding:10px 18px;position:relative;width:-webkit-max-content;width:-moz-max-content;width:max-content;max-width:178px;min-width:100%;cursor:pointer;-webkit-text-decoration:none;text-decoration:none;background-color:var(--themeBlack, #211f1f);}@media (hover: hover) and (pointer: fine){nav .sub-nav__link:hover{color:var(--themeWhite, #fff);background-color:rgba(75, 75, 75, 1);}}nav .navigation{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:end;-ms-flex-pack:end;-webkit-justify-content:flex-end;justify-content:flex-end;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;list-style-type:none;margin:0;padding:0;-webkit-box-flex-wrap:wrap;-webkit-flex-wrap:wrap;-ms-flex-wrap:wrap;flex-wrap:wrap;-webkit-flex:1;-ms-flex:1;flex:1;}@media (max-width: 1200px){nav .navigation{display:none;}}nav .navigation__item{padding:0;margin:0;}nav .navigation__item+.navigation__item{padding-left:20px;}@media (hover: hover) and (pointer: fine){nav .navigation .navigation__item:not(.sub-nav-container) .navigation__link:after{content:'';position:absolute;display:block;width:0;height:2px;-webkit-transition:.3s linear;transition:.3s linear;background:var(--themeBeige, #ccb091);bottom:0;left:0;}nav .navigation .navigation__item:not(.sub-nav-container) .navigation__link:hover:after{width:100%;}}nav .navigation__link{display:block;position:relative;font-size:18px;line-height:1;background-color:transparent;border:none;border-bottom:2px solid transparent;border-top:2px solid transparent;cursor:pointer;padding:21px 10px;max-width:180px;z-index:2;outline:none;color:inherit;-webkit-text-decoration:none;text-decoration:none;max-width:180px;-webkit-font-smoothing:unset;-webkit-transition:.3s linear;transition:.3s linear;}nav .navigation__link:focus,nav .navigation__link:active{outline:none;}nav .sub-nav-container{position:relative;padding-right:21px;}nav .sub-nav-container:after{display:block;content:'';width:8px;height:8px;border-right:2px solid;border-bottom:2px solid;position:absolute;right:3px;top:50%;-webkit-transform:translate(0, calc(-50% - 3px)) rotate(45deg);-moz-transform:translate(0, calc(-50% - 3px)) rotate(45deg);-ms-transform:translate(0, calc(-50% - 3px)) rotate(45deg);transform:translate(0, calc(-50% - 3px)) rotate(45deg);-webkit-transition:0.2s all;transition:0.2s all;}nav .sub-nav-container.active:after{-webkit-transform:translate(0, calc(-50% + 3px)) rotate(-135deg);-moz-transform:translate(0, calc(-50% + 3px)) rotate(-135deg);-ms-transform:translate(0, calc(-50% + 3px)) rotate(-135deg);transform:translate(0, calc(-50% + 3px)) rotate(-135deg);}nav .search{position:relative;}nav .search__btn{border:none;background-color:transparent;margin-left:20px;cursor:pointer;display:block;color:inherit;}@media (max-width: 768px){nav .search__btn{margin-left:0;}}nav .search__btn svg{display:block;}
34nav .search.hide-desktop{left:24px;position:absolute;}nav .hide-desktop{display:block;}@media (min-width: 769px){nav .hide-desktop{display:none;}}nav .hide-mobile{display:none;}@media (min-width: 769px){nav .hide-mobile{display:block;}}nav .header.theme-light{color:#fff;}nav .header.theme-light .header__logo.dark{display:none;}nav .header.theme-light .header__logo.light{display:block;}body>div.sidemenu{background-color:rgba(255, 255, 255, 1);color:rgba(18, 18, 18, 1);--fontColor:rgba(18, 18, 18, 1);--fontColor_H:0;--fontColor_S:0%;--fontColor_L:7%;--fontColor_A:1;--fontColor_darkenDir:1;--bgColor:rgba(255, 255, 255, 1);--bgColor_H:0;--bgColor_S:0%;--bgColor_L:100%;--bgColor_A:1;--bgColor_darkenDir:-1;}body>div.sidemenu{--colorLighter1:hsla(var(--fontColor_H), var(--fontColor_S), var(--fontColor_L), 0.1);width:100%;display:block;-webkit-transform:translateY(-100%);-moz-transform:translateY(-100%);-ms-transform:translateY(-100%);transform:translateY(-100%);-webkit-transition:.1s all ease-out 2s;transition:.1s all ease-out 2s;background:transparent;}body>div.sidemenu .sidemenu__container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;}body>div.sidemenu.visible{-webkit-transition:0s all;transition:0s all;-webkit-transform:translateY(0);-moz-transform:translateY(0);-ms-transform:translateY(0);transform:translateY(0);z-index:900;background-color:transparent;}body>div.sidemenu.visible .sidemenu__img{-webkit-transform:translateY(0%);-moz-transform:translateY(0%);-ms-transform:translateY(0%);transform:translateY(0%);-webkit-transition:.7s cubic-bezier(0.645,  0.045, 0.355, 1.000);transition:.7s cubic-bezier(0.645,  0.045, 0.355, 1.000);}body>div.sidemenu.visible .sidemenu__wrapper{-webkit-transform:translateY(0%);-moz-transform:translateY(0%);-ms-transform:translateY(0%);transform:translateY(0%);-webkit-transition:1s cubic-bezier(0.645,  0.045, 0.355, 1.000);transition:1s cubic-bezier(0.645,  0.045, 0.355, 1.000);}body>div.sidemenu.visible .sidemenu__toggle{pointer-events:auto;}body>div.sidemenu .sidemenu__img{background:center no-repeat;-webkit-background-size:cover;background-size:cover;-webkit-box-flex:1;-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1;-webkit-transform:translateY(-100%);-moz-transform:translateY(-100%);-ms-transform:translateY(-100%);transform:translateY(-100%);-webkit-transition:.7s cubic-bezier(0.645,  0.045, 0.355, 1.000) .5s;transition:.7s cubic-bezier(0.645,  0.045, 0.355, 1.000) .5s;}@media (max-width: 768px){body>div.sidemenu .sidemenu__img{display:none;}}body>div.sidemenu .sidemenu__wrapper{background-color:var(--bgColor, #211F1F);-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;height:100vh;padding:80px 0 66px 0;overflow-y:auto;max-width:700px;-webkit-box-flex:1;-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1;-webkit-transform:translateY(-100%);-moz-transform:translateY(-100%);-ms-transform:translateY(-100%);transform:translateY(-100%);-webkit-transition:1s cubic-bezier(0.645,  0.045, 0.355, 1.000) .5s;transition:1s cubic-bezier(0.645,  0.045, 0.355, 1.000) .5s;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;}body>div.sidemenu .sidemenu__wrapper::-webkit-scrollbar{width:4px;background-color:transparent;}body>div.sidemenu .sidemenu__wrapper::-webkit-scrollbar-thumb{background-color:var(--fontColor, #ffffff);}body>div.sidemenu .sidemenu__wrapper::-webkit-scrollbar-track{-webkit-box-shadow:inset 0 0 4px rgba(0,0,0,0.3);background-color:var(--bgColor, #211F1F);}@media (max-width: 768px){body>div.sidemenu .sidemenu__wrapper{padding:40px 0 66px 0;}}body>div.sidemenu .sidemenu__toggle{height:48px;margin-right:auto;margin-left:70px;position:relative;border:none;background-color:transparent;outline:none;color:var(--fontColor, #ffffff);padding-right:50px;font-family:inherit;pointer-events:none;cursor:pointer;}@media (max-width: 768px){body>div.sidemenu .sidemenu__toggle{margin-left:20px;}}body>div.sidemenu .sidemenu__toggle--right{margin-left:auto;margin-right:70px;}@media (max-width: 768px){body>div.sidemenu .sidemenu__toggle--right{margin-right:20px;}}body>div.sidemenu .sidemenu__toggle:focus{outline:none;}body>div.sidemenu .sidemenu__toggle:before,body>div.sidemenu .sidemenu__toggle:after{content:'';display:block;position:absolute;width:20px;height:2px;background-color:currentColor;right:0;top:50%;}body>div.sidemenu .sidemenu__toggle:before{-webkit-transform:translate(-50%, -50%) rotate(45deg);-moz-transform:translate(-50%, -50%) rotate(45deg);-ms-transform:translate(-50%, -50%) rotate(45deg);transform:translate(-50%, -50%) rotate(45deg);}body>div.sidemenu .sidemenu__toggle:after{-webkit-transform:translate(-50%, -50%) rotate(-225deg);-moz-transform:translate(-50%, -50%) rotate(-225deg);-ms-transform:translate(-50%, -50%) rotate(-225deg);transform:translate(-50%, -50%) rotate(-225deg);}body>div.sidemenu .sidemenu__nav{margin-bottom:auto;padding:0;}body>div.sidemenu .sidemenu__socials{margin-left:auto;padding-top:30px;padding-right:70px;}@media (max-width: 768px){body>div.sidemenu .sidemenu__socials{padding-right:20px;padding-left:20px;}}body>div.sidemenu .sidemenu__socials .lp-socials li{margin-bottom:14px;}body>div.sidemenu .sidemenu__header{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;
34-webkit-justify-content:space-between;justify-content:space-between;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;padding-bottom:93px;}@media (max-width: 768px){body>div.sidemenu .sidemenu__header{padding-bottom:59px;}}body>div.sidemenu .sidemenu__logo{display:none;}@media (max-width: 768px){body>div.sidemenu .sidemenu__logo{display:block;}}body>div.sidemenu .sidemenu__logo-img{display:block;max-height:50px;}body>div.sidemenu .navigation{list-style-type:none;margin:0;padding:0;max-width:100%;}body>div.sidemenu .navigation__item{border-bottom:1px solid var(--colorLighter1);margin:0;overflow:hidden;}body>div.sidemenu .navigation__link{padding:12px 12px 12px 70px;display:block;font-size:22px;font-weight:400;line-height:48px;color:var(--fontColor, #ffffff);-webkit-transition:0.2s all;transition:0.2s all;cursor:pointer;-webkit-text-decoration:none;text-decoration:none;font-family:var(--global-primary-font-family);-webkit-transform:translateY(100%);-moz-transform:translateY(100%);-ms-transform:translateY(100%);transform:translateY(100%);opacity:0;position:relative;transition-property:transform,opacity,color;transition-duration:0.55s,0.55s,0.3s;transition-timing-function:cubic-bezier(0.645, 0.045, 0.355, 1),ease-in-out,ease-in-out;}@media(max-width: 768px){body>div.sidemenu .navigation__link{padding-left:20px;padding-right:20px;padding-bottom:16px;}}@media (hover: hover) and (pointer: fine){body>div.sidemenu .navigation__link:hover{color:var(--fontColor, #ffffff);}}body>div.sidemenu .sub-nav{list-style-type:none;display:none;margin:0;padding:10px 0 30px 85px;}@media(max-width: 768px){body>div.sidemenu .sub-nav{padding-bottom:16px;padding-left:35px;}}body>div.sidemenu .sub-nav__item{padding-bottom:10px;margin:0;opacity:0;}body>div.sidemenu .sub-nav__item.fadeInUp{-webkit-animation-duration:1s;animation-duration:1s;-webkit-animation-timing-function:ease;animation-timing-function:ease;-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards;-webkit-animation-delay:var(--delay);animation-delay:var(--delay);}body>div.sidemenu .sub-nav__link{font-size:16px;font-weight:400;cursor:pointer;color:var(--fontColor, #ffffff);font-family:var(--global-secondary-font-family);-webkit-text-decoration:none;text-decoration:none;}body>div.sidemenu .sub-nav.visible{display:block;}body>div.sidemenu .lp-socials__link{opacity:0;-webkit-transform:translateY(-50px);-moz-transform:translateY(-50px);-ms-transform:translateY(-50px);transform:translateY(-50px);position:relative;transition-property:transform,opacity,color;transition-duration:0.55s,0.55s,0.3s;transition-timing-function:cubic-bezier(0.645, 0.045, 0.355, 1),ease-in-out,ease-in-out;}body>div.sidemenu body>div.sidemenu{width:100%;}body>div.sidemenu body>div.sidemenu.visible{-webkit-transition:0s all;transition:0s all;-webkit-transform:translateY(0);-moz-transform:translateY(0);-ms-transform:translateY(0);transform:translateY(0);z-index:900;background-color:transparent;}body>div.sidemenu body>div.sidemenu.visible .sidemenu__img{-webkit-transform:translateY(0%);-moz-transform:translateY(0%);-ms-transform:translateY(0%);transform:translateY(0%);-webkit-transition:.7s cubic-bezier(0.645,  0.045, 0.355, 1.000);transition:.7s cubic-bezier(0.645,  0.045, 0.355, 1.000);}body>div.sidemenu body>div.sidemenu.visible .sidemenu__wrapper{-webkit-transform:translateY(0%);-moz-transform:translateY(0%);-ms-transform:translateY(0%);transform:translateY(0%);-webkit-transition:1s cubic-bezier(0.645,  0.045, 0.355, 1.000);transition:1s cubic-bezier(0.645,  0.045, 0.355, 1.000);}body>div.sidemenu body>div.sidemenu.visible .sidemenu__toggle{pointer-events:auto;}body>div.sidemenu .fade-in{opacity:1;-webkit-transform:translateY(0);-moz-transform:translateY(0);-ms-transform:translateY(0);transform:translateY(0);}body>div.sidemenu .arrow{vertical-align:middle;margin-bottom:10px;-webkit-transition:.4s;transition:.4s;}body>div.sidemenu .arrow.active{-webkit-transform:rotate(-180deg);-moz-transform:rotate(-180deg);-ms-transform:rotate(-180deg);transform:rotate(-180deg);-webkit-transition:.4s;transition:.4s;}footer{background-color:#ffffff;color:#14171A;--fontColor:#14171A;--fontColor_H:210;--fontColor_S:13%;--fontColor_L:9%;--fontColor_A:1;--fontColor_darkenDir:1;--bgColor:#ffffff;--bgColor_H:0;--bgColor_S:0%;--bgColor_L:100%;--bgColor_A:1;--bgColor_darkenDir:-1;}footer .lp-input--dark{background-color:#fff;}footer .site-footer__subscribe{padding-top:92px;padding-bottom:92px;background-color:rgba(0,0,0,0.1);}@media (max-width: 768px){footer .site-footer__subscribe{padding-top:64px;padding-bottom:64px;}}footer .site-footer__logo-bar{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-flex-wrap:wrap;-webkit-flex-wrap:wrap;-ms-flex-wrap:wrap;flex-wrap:wrap;padding-bottom:64px;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}@media (max-width: 768px){footer .site-footer__logo-bar{padding-bottom:24px;}}footer .site-footer__logo-container img{max-width:268px;max-height:56px;object-fit:contain;display:block;object-position:left top;}footer .site-footer__logo-container+.site-footer__logo-container{margin-left:50px;}@media (max-width: 768px){footer .site-footer__logo-container+.site-footer__logo-container{margin-left:0;margin-top:16px;width:100%;}}footer .site-footer__info{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-flex-wrap:wrap;-webkit-flex-wrap:wrap;-ms-flex-wrap:wrap;flex-wrap:wrap;-webkit-align-items:flex-start;-webkit-box-align:flex-start;-ms-flex-align:flex-start;align-items:flex-start;}@media (max-width: 768px){footer .site-footer__info{-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;}}footer .site-footer__info .lp-a a{white-space:nowrap;}
34footer .site-footer__col{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-flex-wrap:wrap;-webkit-flex-wrap:wrap;-ms-flex-wrap:wrap;flex-wrap:wrap;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;padding-right:32px;}footer .site-footer__col-title{width:100%;margin-bottom:16px;min-height:29px;}footer .site-footer__col-content{opacity:0.5;padding-bottom:16px;}footer .site-footer__col-content p{margin-bottom:0;}footer .site-footer__col-content a{color:inherit;}footer .site-footer__col-content+.site-footer__col-content{padding-left:40px;}@media (max-width: 768px){footer .site-footer__col-content+.site-footer__col-content{padding-left:0;}}footer .site-footer__navigation-wrap{width:100%;padding-top:32px;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;}@media (max-width: 992px){footer .site-footer__navigation-wrap{-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;padding-bottom:18px;}}@media (max-width: 768px){footer .site-footer__navigation-wrap{padding-top:24px;padding-bottom:0;-webkit-align-items:flex-start;-webkit-box-align:flex-start;-ms-flex-align:flex-start;align-items:flex-start;}}footer .site-footer__socials{margin-left:auto;}@media (max-width: 992px){footer .site-footer__socials{margin-left:0;}}@media (max-width: 768px){footer .site-footer__socials{margin-right:auto;}}footer .site-footer__socials li{margin-bottom:0;}footer .site-footer__disclaimer{padding-top:64px;padding-bottom:32px;position:relative;opacity:0.5;}@media (max-width: 768px){footer .site-footer__disclaimer{padding-top:18px;padding-bottom:25px;}}footer .site-footer__disclaimer:after{content:'';display:block;position:absolute;left:0;bottom:0;right:0;height:1px;background-color:currentColor;opacity:0.2;}footer .site-footer__copy{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;padding-top:32px;font-size:18px;}@media (max-width: 768px){footer .site-footer__copy{padding-top:15px;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-align-items:flex-start;-webkit-box-align:flex-start;-ms-flex-align:flex-start;align-items:flex-start;}footer .site-footer__copy>div:first-child{margin-bottom:15px;}}footer .site-footer__copy a{color:inherit;}footer .site-footer__copy-lp span{margin-right:5px;}footer .site-footer__copy-lp img{margin-right:30px;}@media (max-width: 768px){footer .site-footer__copy-lp img{margin-right:0;margin-bottom:15px;}}@media (min-width: 769px){footer .site-footer__copy-lp{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}}footer .site-footer__bottom{padding-top:96px;padding-bottom:96px;}@media (max-width: 768px){footer .site-footer__bottom{padding-top:64px;padding-bottom:64px;}}footer .footer-contact{margin-bottom:13px;}footer .footer-contact p{margin-bottom:0;opacity:.7;}footer .footer-contact ul{list-style:none;padding-left:0;margin:0;}footer .footer-subscribe{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}@media (max-width: 768px){footer .footer-subscribe{-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;}}footer .footer-subscribe__title-wrap{padding-right:50px;}@media (max-width: 768px){footer .footer-subscribe__title-wrap{padding-right:0;padding-bottom:32px;}}footer .footer-subscribe__title{margin-bottom:8px;}footer .footer-subscribe__sub-title{margin-bottom:0;}footer .footer-subscribe__form{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;width:100%;max-width:330px;margin-bottom:0;position:relative;}footer .footer-subscribe__submit{margin-top:16px;}footer .footer-subscribe__success-msg{position:absolute;top:100%;width:100%;text-align:center;opacity:.7;padding-top:10px;}footer .footer-navigation{list-style:none;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-flex-wrap:wrap;-webkit-flex-wrap:wrap;-ms-flex-wrap:wrap;flex-wrap:wrap;padding:0 20px 0 0;margin:0 -30px;}@media (max-width: 992px){footer .footer-navigation{margin-bottom:36px;}}@media (max-width: 768px){footer .footer-navigation{-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;margin:0 0 36px;}}footer .footer-navigation__item{margin:0 30px;}@media (max-width: 768px){footer .footer-navigation__item{margin:0 0 10px;}}
34footer .footer-navigation__link{color:inherit;-webkit-text-decoration:none;text-decoration:none;font-size:14px;line-height:14px;background-color:transparent;border:none;font-family:inherit;cursor:pointer;padding-left:0;padding-right:0;-webkit-transition:0.2s all;transition:0.2s all;}@media (hover: hover) and (pointer: fine){footer .footer-navigation__link:hover{color:var(--themeBeige);}}footer .lp-socials li{margin-bottom:14px;}footer .sync-icon{display:none;margin-right:10px;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}footer .success-icon{display:none;margin-right:10px;-webkit-transition:0s;transition:0s;visibility:visible;}footer .loading{pointer-events:none;}footer .loading .sync-icon{display:-webkit-inline-box;display:-webkit-inline-flex;display:-ms-inline-flexbox;display:inline-flex;}footer .success .success-icon{display:block;}footer .lp-footer-disclaimers{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;gap:20px;margin-top:32px;padding-top:32px;}@media (max-width: 768px){footer .lp-footer-disclaimers{padding-top:15px;margin-top:15px;}}body>div.mobile-contact-wrapper{z-index:200;position:relative;}body>div.mobile-contact-wrapper .lp-ico:before{content:'';width:1em;height:1em;background-color:currentColor;-webkit-background-size:cover;background-size:cover;display:block;-webkit-mask-position:center;-webkit-mask-position:center;mask-position:center;-webkit-mask-size:contain;-webkit-mask-size:contain;mask-size:contain;-webkit-mask-repeat:no-repeat;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-transition:all .3s;transition:all .3s;}body>div.mobile-contact-wrapper .lp-ico-search:before{-webkit-mask-image:url("data:image/svg+xml,%3Csvg width='25' height='25' viewB
34ox='0 0 25 25' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M21.6231 21.3002L17.1372 16.8143M19.5606 10.9877C19.5606 15.5441 15.8669 19.2377 11.3106 19.2377C6.75421 19.2377 3.06055 15.5441 3.06055 10.9877C3.06055 6.43135 6.75421 2.73769 11.3106 2.73769C15.8669 2.73769 19.5606 6.43135 19.5606 10.9877Z' stroke='black' stroke-width='1.82813' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");-webkit-mask-image:url("data:image/svg+xml,%3Csvg width='25' height='25' viewBox='0 0 25 25' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M21.6231 21.3002L17.1372 16.8143M19.5606 10.9877C19.5606 15.5441 15.8669 19.2377 11.3106 19.2377C6.75421 19.2377 3.06055 15.5441 3.06055 10.9877C3.06055 6.43135 6.75421 2.73769 11.3106 2.73769C15.8669 2.73769 19.5606 6.43135 19.5606 10.9877Z' stroke='black' stroke-width='1.82813' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");mask-image:url("data:image/svg+xml,%3Csvg width='25' height='25' viewBox='0 0 25 25' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M21.6231 21.3002L17.1372 16.8143M19.5606 10.9877C19.5606 15.5441 15.8669 19.2377 11.3106 19.2377C6.75421 19.2377 3.06055 15.5441 3.06055 10.9877C3.06055 6.43135 6.75421 2.73769 11.3106 2.73769C15.8669 2.73769 19.5606 6.43135 19.5606 10.9877Z' stroke='black' stroke-width='1.82813' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");}body>div.mobile-contact-wrapper .lp-ico-arrow-top:before{-webkit-mask-image:url("data:image/svg+xml,%3Csvg width='17' height='16' viewBox='0 0 17 16' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M12.8716 9.99976L8.87158 5.99976L4.87158 9.99976' stroke='white' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");-webkit-mask-image:url("data:image/svg+xml,%3Csvg width='17' height='16' viewBox='0 0 17 16' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M12.8716 9.99976L8.87158 5.99976L4.87158 9.99976' stroke='white' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");mask-image:url("data:image/svg+xml,%3Csvg width='17' height='16' viewBox='0 0 17 16' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M12.8716 9.99976L8.87158 5.99976L4.87158 9.99976' stroke='white' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");}body>div.mobile-contact-wrapper .lp-ico-scroll-top:before{-webkit-mask-image:url("data:image/svg+xml,%3Csvg width='24' height='24' viewBox='0 0 24 24' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M21 3H3M12 21V7M12 7L5 14M12 7L19 14' stroke='white' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E ");-webkit-mask-image:url("data:image/svg+xml,%3Csvg width='24' height='24' viewBox='0 0 24 24' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M21 3H3M12 21V7M12 7L5 14M12 7L19 14' stroke='white' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E ");mask-image:url("data:image/svg+xml,%3Csvg width='24' height='24' viewBox='0 0 24 24' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M21 3H3M12 21V7M12 7L5 14M12 7L19 14' stroke='white' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E ");}body>div.mobile-contact-wrapper .lp-ico-close:before{-webkit-mask-image:url("data:image/svg+xml,%3Csvg width='24' height='24' viewBox='0 0 24 24' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M17.5986 6.32617L5.59863 18.3262M5.59863 6.32617L17.5986 18.3262' stroke='white' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E ");-webkit-mask-image:url("data:image/svg+xml,%3Csvg width='24' height='24' viewBox='0 0 24 24' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M17.5986 6.32617L5.59863 18.3262M5.59863 6.32617L17.5986 18.3262' stroke='white' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E ");mask-image:url("data:image/svg+xml,%3Csvg width='24' height='24' viewBox='0 0 24 24' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M17.5986 6.32617L5.59863 18.3262M5.59863 6.32617L17.5986 18.3262' stroke='white' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E ");}body>div.mobile-contact-wrapper .lp-ico-phone:before{-webkit-mask-image:url("data:image/svg+xml,%3Csvg width='24' height='24' viewBox='0 0 24 24' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M13.8
34699 6.57142C14.7459 6.74157 15.551 7.16808 16.1821 7.79637C16.8132 8.42465 17.2416 9.22612 17.4126 10.0982M13.8699 3C15.6899 3.20128 17.3871 4.01265 18.6827 5.3009C19.9784 6.58914 20.7955 8.27768 21 10.0893M10.4412 13.592C9.36357 12.5192 8.51264 11.3061 7.88843 10.0118C7.83474 9.90047 7.80789 9.84481 7.78726 9.77437C7.71397 9.52405 7.76662 9.21668 7.91909 9.00469C7.962 8.94504 8.01326 8.894 8.11578 8.79194C8.42933 8.47979 8.58611 8.32372 8.6886 8.16677C9.07515 7.57491 9.07515 6.81189 8.6886 6.22002C8.58611 6.06308 8.42933 5.90701 8.11578 5.59486L7.94101 5.42087C7.46438 4.94637 7.22607 4.70912 6.97012 4.58024C6.4611 4.32392 5.85996 4.32392 5.35093 4.58024C5.09499 4.70912 4.85667 4.94637 4.38004 5.42087L4.23867 5.56161C3.76367 6.03449 3.52617 6.27093 3.34478 6.59239C3.1435 6.94909 2.99878 7.5031 3.00001 7.91222C3.00111 8.28092 3.07295 8.53291 3.21664 9.03688C3.98881 11.7453 5.44574 14.3009 7.58743 16.4331C9.72911 18.5652 12.2963 20.0156 15.0168 20.7843C15.523 20.9274 15.7761 20.9989 16.1465 21C16.5575 21.0012 17.114 20.8571 17.4723 20.6568C17.7952 20.4762 18.0327 20.2397 18.5077 19.7669L18.649 19.6261C19.1257 19.1516 19.364 18.9144 19.4934 18.6596C19.7509 18.1528 19.7509 17.5544 19.4934 17.0476C19.364 16.7928 19.1257 16.5556 18.649 16.0811L18.4743 15.9071C18.1607 15.5949 18.0039 15.4388 17.8463 15.3368C17.2518 14.952 16.4853 14.952 15.8908 15.3368C15.7332 15.4388 15.5764 15.5949 15.2628 15.9071C15.1603 16.0091 15.1091 16.0602 15.0491 16.1029C14.8362 16.2547 14.5274 16.3071 14.276 16.2341C14.2052 16.2136 14.1493 16.1869 14.0375 16.1334C12.7374 15.512 11.5189 14.6648 10.4412 13.592Z' stroke='white' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");-webkit-mask-image:url("data:image/svg+xml,%3Csvg width='24' height='24' viewBox='0 0 24 24' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M13.8699 6.57142C14.7459 6.74157 15.551 7.16808 16.1821 7.79637C16.8132 8.42465 17.2416 9.22612 17.4126 10.0982M13.8699 3C15.6899 3.20128 17.3871 4.01265 18.6827 5.3009C19.9784 6.58914 20.7955 8.27768 21 10.0893M10.4412 13.592C9.36357 12.5192 8.51264 11.3061 7.88843 10.0118C7.83474 9.90047 7.80789 9.84481 7.78726 9.77437C7.71397 9.52405 7.76662 9.21668 7.91909 9.00469C7.962 8.94504 8.01326 8.894 8.11578 8.79194C8.42933 8.47979 8.58611 8.32372 8.6886 8.16677C9.07515 7.57491 9.07515 6.81189 8.6886 6.22002C8.58611 6.06308 8.42933 5.90701 8.11578 5.59486L7.94101 5.42087C7.46438 4.94637 7.22607 4.70912 6.97012 4.58024C6.4611 4.32392 5.85996 4.32392 5.35093 4.58024C5.09499 4.70912 4.85667 4.94637 4.38004 5.42087L4.23867 5.56161C3.76367 6.03449 3.52617 6.27093 3.34478 6.59239C3.1435 6.94909 2.99878 7.5031 3.00001 7.91222C3.00111 8.28092 3.07295 8.53291 3.21664 9.03688C3.98881 11.7453 5.44574 14.3009 7.58743 16.4331C9.72911 18.5652 12.2963 20.0156 15.0168 20.7843C15.523 20.9274 15.7761 20.9989 16.1465 21C16.5575 21.0012 17.114 20.8571 17.4723 20.6568C17.7952 20.4762 18.0327 20.2397 18.5077 19.7669L18.649 19.6261C19.1257 19.1516 19.364 18.9144 19.4934 18.6596C19.7509 18.1528 19.7509 17.5544 19.4934 17.0476C19.364 16.7928 19.1257 16.5556 18.649 16.0811L18.4743 15.9071C18.1607 15.5949 18.0039 15.4388 17.8463 15.3368C17.2518 14.952 16.4853 14.952 15.8908 15.3368C15.7332 15.4388 15.5764 15.5949 15.2628 15.9071C15.1603 16.0091 15.1091 16.0602 15.0491 16.1029C14.8362 16.2547 14.5274 16.3071 14.276 16.2341C14.2052 16.2136 14.1493 16.1869 14.0375 16.1334C12.7374 15.512 11.5189 14.6648 10.4412 13.592Z' stroke='white' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");mask-image:url("data:image/svg+xml,%3Csvg width='24' height='24' viewBox='0 0 24 24' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M13.8699 6.57142C14.7459 6.74157 15.551 7.16808 16.1821 7.79637C16.8132 8.42465 17.2416 9.22612 17.4126 10.0982M13.8699 3C15.6899 3.20128 17.3871 4.01265 18.6827 5.3009C19.9784 6.58914 20.7955 8.27768 21 10.0893M10.4412 13.592C9.36357 12.5192 8.51264 11.3061 7.88843 10.0118C7.83474 9.90047 7.80789 9.84481 7.78726 9.77437C7.71397 9.52405 7.76662 9.21668 7.91909 9.00469C7.962 8.94504 8.01326 8.894 8.11578 8.79194C8.42933 8.47979 8.58611 8.32372 8.6886 8.16677C9.07515 7.57491 9.07515 6.81189 8.6886 6.22002C8.58611 6.06308 8.42933 5.90701 8.11578 5.59486L7.94101 5.42087C7.46438 4.94637 7.22607 4.70912 6.97012 4.58024C6.4611 4.32392 5.85996 4.32392 5.35093 4.58024C5.09499 4.70912 4.85667 4.94637 4.38004 5.42087L4.23867 5.56161C3.76367 6.03449 3.52617 6.27093 3.34478 6.59239C3.1435 6.94909 2.99878 7.5031 3.00001 7.91222C3.00111 8.28092 3.07295 8.53291 3.21664 9.03688C3.98881 11.7453 5.44574 14.3009 7.58743 16.4331C9.72911 18.5652 12.2963 20.0156 15.0168 20.7843C15.523 20.9274 15.7761 20.9989 16.1465 21C16.5575 21.0012 17.114 20.8571 17.4723 20.6568C17.7952 20.4762 18.0327 20.2397 18.5077 19.7669L18.649 19.6261C19.1257 19.1516 19.364 18.9144 19.4934 18.6596C19.7509 18.1528 19.7509 17.5544 19.4934 17.0476C19.364 16.7928 19.1257 16.5556 18.649 16.0811L18.4743 15.9071C18.1607 15.5949 18.0039 15.4388 17.8463 15.3368C17.2518 14.952 16.4853 14.952 15.8908 15.3368C15.7332 15.4388 15.5764 15.5949 15.2628 15.9071C15.1603 16.0091 15.1091 16.0602 15.0491 16.1029C14.8362 16.2547 14.5274 16.3071 14.276 16.2341C14.2052 16.2136 14.1493 16.1869 14.0375 16.1334C12.7374 15.512 11.5189 14.6648 10.4412 13.592Z' stroke='white' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");}body>div.mobile-contact-wrapper .lp-ico-sms:before{-webkit-mask-image:url("data:image/svg+xml,%3Csvg width='24' height='24' viewBox='0 0 24 24' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M21 11.5C21.0034 12.8199 20.6951 14.1219 20.1 15.3C19.3944 16.7117 18.3098 17.8992 16.9674 18.7293C15.6251 19.5594 14.0782 19.9994 12.5 20C11.1801 20.0034 9.87812 19.6951 8.7 19.1L3 21L4.9 15.3C4.30493 14.1219 3.99656 12.8199 4 11.5C4.00061 9.92176 4.44061 8.37485 5.27072 7.03255C6.10083 5.69025 7.28825 4.60557 8.7 3.9C9.87812 3.30493 11.1801 2.99656 12.5 3H13C15.0843 3.11499 17.053 3.99476 18.5291 5.47086C20.0052 6.94695 20.885 8.91565 21 11V11.5Z' stroke='white' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");-webkit-mask-image:url("data:image/svg+xml,%3Csvg width='24' height='24' viewBox='0 0 24 24' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M21 11.5C21.0034 12.8199 20.6951 14.1219 20.1 15.3C19.3944 16.7117 18.3098 17.8992 16.9674 18.7293C15.6251 19.5594 14.0782 19.9994 12.5 20C11.1801 20.0034 9.87812 19.6951 8.7 19.1L3 21L4.9 15.3C4.30493 14.1219 3.99656 12.8199 4 11.5C4.00061 9.92176 4.44061 8.37485 5.27072 7.03255C6.10083 5.69025 7.28825 4.60557 8.7 3.9C9.87812 3.30493 11.1801 2.99656 12.5 3H13C15.0843 3.11499 17.053 3.99476 18.5291 5.47086C20.0052 6.94695 20.885 8.91565 21 11V11.5Z' stroke='white' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");mask-image:url("data:image/svg+xml,%3Csvg width='24' height='24' viewBox='0 0 24 24' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M21 11.5C21.0034 12.8199 20.6951 14.1219 20.1 15.3C19.3944 16.7117 18.3098 17.8992 16.9674 18.7293C15.6251 19.5594 14.0782 19.9994 12.5 20C11.1801 20.0034 9.87812 19.6951 8.7 19.1L3 21L4.9 15.3C4.30493 14.1219 3.99656 12.8199 4 11.5C4.00061 9.92176 4.44061 8.37485 5.27072 7.03255C6.10083 5.69025 7.28825 4.60557 8.7 3.9C9.87812 3.30493 11.1801 2.99656 12.5 3H13C15.0843 3.11499 17.053 3.99476 18.5291 5.47086C20.0052 6.94695 20.885 8.91565 21 11V11.5Z' stroke='white' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");}body>div.mobile-contact-wrapper .lp-ico-email:before{-webkit-mask-image:url("data:image/svg+xml,%3Csvg width='24' height='24' viewBox='0 0 24 24' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M21.5 18L14.85
3471 12M9.14286 12L2.50003 18M2 7L10.1649 12.7154C10.8261 13.1783 11.1567 13.4097 11.5163 13.4993C11.8339 13.5785 12.1661 13.5785 12.4837 13.4993C12.8433 13.4097 13.1739 13.1783 13.8351 12.7154L22 7M6.8 20H17.2C18.8802 20 19.7202 20 20.362 19.673C20.9265 19.3854 21.3854 18.9265 21.673 18.362C22 17.7202 22 16.8802 22 15.2V8.8C22 7.11984 22 6.27976 21.673 5.63803C21.3854 5.07354 20.9265 4.6146 20.362 4.32698C19.7202 4 18.8802 4 17.2 4H6.8C5.11984 4 4.27976 4 3.63803 4.32698C3.07354 4.6146 2.6146 5.07354 2.32698 5.63803C2 6.27976 2 7.11984 2 8.8V15.2C2 16.8802 2 17.7202 2.32698 18.362C2.6146 18.9265 3.07354 19.3854 3.63803 19.673C4.27976 20 5.11984 20 6.8 20Z' stroke='white' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");-webkit-mask-image:url("data:image/svg+xml,%3Csvg width='24' height='24' viewBox='0 0 24 24' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M21.5 18L14.8571 12M9.14286 12L2.50003 18M2 7L10.1649 12.7154C10.8261 13.1783 11.1567 13.4097 11.5163 13.4993C11.8339 13.5785 12.1661 13.5785 12.4837 13.4993C12.8433 13.4097 13.1739 13.1783 13.8351 12.7154L22 7M6.8 20H17.2C18.8802 20 19.7202 20 20.362 19.673C20.9265 19.3854 21.3854 18.9265 21.673 18.362C22 17.7202 22 16.8802 22 15.2V8.8C22 7.11984 22 6.27976 21.673 5.63803C21.3854 5.07354 20.9265 4.6146 20.362 4.32698C19.7202 4 18.8802 4 17.2 4H6.8C5.11984 4 4.27976 4 3.63803 4.32698C3.07354 4.6146 2.6146 5.07354 2.32698 5.63803C2 6.27976 2 7.11984 2 8.8V15.2C2 16.8802 2 17.7202 2.32698 18.362C2.6146 18.9265 3.07354 19.3854 3.63803 19.673C4.27976 20 5.11984 20 6.8 20Z' stroke='white' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");mask-image:url("data:image/svg+xml,%3Csvg width='24' height='24' viewBox='0 0 24 24' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M21.5 18L14.8571 12M9.14286 12L2.50003 18M2 7L10.1649 12.7154C10.8261 13.1783 11.1567 13.4097 11.5163 13.4993C11.8339 13.5785 12.1661 13.5785 12.4837 13.4993C12.8433 13.4097 13.1739 13.1783 13.8351 12.7154L22 7M6.8 20H17.2C18.8802 20 19.7202 20 20.362 19.673C20.9265 19.3854 21.3854 18.9265 21.673 18.362C22 17.7202 22 16.8802 22 15.2V8.8C22 7.11984 22 6.27976 21.673 5.63803C21.3854 5.07354 20.9265 4.6146 20.362 4.32698C19.7202 4 18.8802 4 17.2 4H6.8C5.11984 4 4.27976 4 3.63803 4.32698C3.07354 4.6146 2.6146 5.07354 2.32698 5.63803C2 6.27976 2 7.11984 2 8.8V15.2C2 16.8802 2 17.7202 2.32698 18.362C2.6146 18.9265 3.07354 19.3854 3.63803 19.673C4.27976 20 5.11984 20 6.8 20Z' stroke='white' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");}body>div.mobile-contact-wrapper a{-webkit-text-decoration:none;text-decoration:none;}body>div.mobile-contact-wrapper .btn-holder{bottom:-50px;left:19px;position:fixed;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;gap:13px;opacity:0;-webkit-transition:all .3s;transition:all .3s;}@media (max-width: 1024px){body>div.mobile-contact-wrapper .btn-holder{right:19px;padding:0 48px;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;}}body>div.mobile-contact-wrapper .btn-holder.visible{bottom:28px;opacity:1;}body>div.mobile-contact-wrapper .search-btn{width:48px;height:48px;border-radius:999px;font-size:0;line-height:0;display:-webkit-inline-box;display:-webkit-inline-flex;display:-ms-inline-flexbox;display:inline-flex;-webkit-transition:all .3s;transition:all .3s;padding:12px;color:#141414;background:#fff;}@media (max-width: 1024px){body>div.mobile-contact-wrapper .search-btn{position:absolute;left:0;bottom:0;}}body>div.mobile-contact-wrapper .search-btn:before{width:24px;height:24px;}body>div.mobile-contact-wrapper .connect-btn{height:48px;padding:0 24px;display:-webkit-inline-box;display:-webkit-inline-flex;display:-ms-inline-flexbox;display:inline-flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;gap:4px;text-transform:uppercase;border-radius:25px;color:var(--pillTextColor);background:var(--pillBackgroundColor);border:1px solid rgba(255, 255, 255, 0.2);cursor:pointer;font-size:10px;font-style:normal;font-weight:500;line-height:16px;letter-spacing:0.4px;-webkit-flex-direction:row-reverse;-ms-flex-direction:row-reverse;flex-direction:row-reverse;-webkit-transition:all .4s;transition:all .4s;box-shadow:0 0 0 0 rgba(255, 255, 255, 0.2);-webkit-animation:pulsate 2s ease infinite;animation:pulsate 2s ease infinite;}body>div.mobile-contact-wrapper .connect-btn:before{width:16px;height:16px;}body>div.mobile-contact-wrapper .pop-up{display:none;position:fixed;bottom:0;left:0;width:100%;-webkit-transition:all .3s;transition:all .3s;border-radius:16px 16px 0 0;color:var(--textColor);background:var(--backgroundColor);}@media (min-width: 1025px){body>div.mobile-contact-wrapper .pop-up{max-width:637px;border-radius:16px;bottom:28px;left:19px;}}body>div.mobile-contact-wrapper .pop-up .lp-container{padding-top:24px;padding-bottom:24px;-webkit-box-pack:center;-ms-flex-pack:center;
34-webkit-justify-content:center;justify-content:center;}@media (min-width: 1025px){body>div.mobile-contact-wrapper .pop-up .lp-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;padding-top:40px;padding-bottom:40px;min-height:450px;padding-left:56px;padding-right:56px;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;}}body>div.mobile-contact-wrapper .pop-up .close-btn{width:44px;height:44px;background-color:transparent;border-color:transparent;display:block;margin:24px auto 0;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;color:var(--textColor);cursor:pointer;padding:10px;border:0;}body>div.mobile-contact-wrapper .pop-up .close-btn:before{width:24px;height:24px;}@media (min-width: 1025px){body>div.mobile-contact-wrapper .pop-up .close-btn{position:absolute;top:14px;right:12px;margin:0;}}body>div.mobile-contact-wrapper .pop-up .icon-btn{width:44px;height:44px;border-radius:999px;display:-webkit-inline-box;display:-webkit-inline-flex;display:-ms-inline-flexbox;display:inline-flex;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;margin-left:8px;color:var(--textColor);position:relative;}body>div.mobile-contact-wrapper .pop-up .icon-btn:after{position:absolute;bottom:0;width:100%;left:0;border-radius:999px;
34height:100%;content:'';border:solid 1px var(--textColor);opacity:.3;}body>div.mobile-contact-wrapper .pop-up .icon-btn:before{width:24px;height:24px;}body>div.mobile-contact-wrapper .success-block{display:none;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;}@media (min-width: 1025px){body>div.mobile-contact-wrapper .success-block{-webkit-align-items:flex-start;-webkit-box-align:flex-start;-ms-flex-align:flex-start;align-items:flex-start;}}body>div.mobile-contact-wrapper .success-block .lp-btn{margin-top:24px;}body>div.mobile-contact-wrapper .contact-form{margin:0;}@media (max-width: 1024px){body>div.mobile-contact-wrapper .contact-form__item{width:100%;}}body>div.mobile-contact-wrapper .contact-form__item .lp-input{width:100%;}body>div.mobile-contact-wrapper .contact-form__item .is-placeholder{color:#818181;}body>div.mobile-contact-wrapper .contact-form__item+.contact-form__item{margin-top:16px;}body>div.mobile-contact-wrapper .contact-form.show-success .contact-form__container,body>div.mobile-contact-wrapper .contact-form.success .contact-form__container{display:none;}body>div.mobile-contact-wrapper .contact-form.show-success .success-block,body>div.mobile-contact-wrapper .contact-form.success .success-block{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;}body>div.mobile-contact-wrapper .contact-form .lp-disclaimer{margin-top:16px;}body>div.mobile-contact-wrapper .contact-form .lp-h3{margin-bottom:16px;}body>div.mobile-contact-wrapper .success-message{font-size:22px;}@-webkit-keyframes pulsate{0%{box-shadow:0 0 0 0 rgba(255, 255, 255, 0.2);}50%{box-shadow:0 0 4px 6px rgba(255, 255, 255, .5);}100%{box-shadow:0 0 12px 12px rgba(255, 255, 255, 0);}}
35        </style>
36    <style id="custom-style-css">.social_icons-style-1 a{border-color:rgba(89, 123, 164, 1)!important;background-color:rgba(89, 123, 164, 1)!important;color:rgba(255, 255, 255, 1)!important;}.social_icons-style-1 a:hover{border-color:rgba(47, 79, 106, 1)!important;background-color:rgba(47, 79, 106, 1)!important;color:rgba(255, 255, 255, 1)!important;}.social_icons-style-1 a i{color:inherit!important;}
36.social_icons-style-1 a svg,.social_icons-style-1 a svg path{fill:currentColor!important;}.hyperlink-style-1{color:rgba(33, 31, 31, 1)!important;}.hyperlink-style-1:hover{color:rgba(74, 125, 166, 1)!important;}.pagination-style-1 li a{color:rgba(89, 123, 164, 1)!important;background-color:rgba(255, 255, 255, 0)!important;border-color:rgba(89, 123, 164, 1)!important;}.pagination-style-1 li a:hover{color:rgba(255, 255, 255, 1)!important;background-color:rgba(89, 123, 164, 1)!important;border-color:rgba(89, 123, 164, 1)!important;}.pagination-style-1 li.active a{color:rgba(255, 255, 255, 1)!important;background-color:rgba(89, 123, 164, 1)!important;border-color:rgba(89, 123, 164, 1)!important;}.button-style-1{color:rgba(255, 255, 255, 1)!important;background-color:rgba(89, 123, 164, 1)!important;border-color:rgba(89, 123, 164, 1)!important;}.button-style-1:hover{color:rgba(255, 255, 255, 1)!important;background-color:rgba(47, 79, 106, 1)!important;border-color:rgba(47, 79, 106, 1)!important;}.button-style-2{color:rgba(89, 123, 164, 1)!important;background-color:rgba(255, 255, 255, 1)!important;border-color:rgba(255, 255, 255, 1)!important;}.button-style-2:hover{color:rgba(255, 255, 255, 1)!important;background-color:rgba(255, 255, 255, 0)!important;border-color:rgba(255,255,255,1)!important;}.social_icons-style-2 a{border-color:rgba(255, 255, 255, 1)!important;background-color:rgba(0, 0, 0, 0)!important;color:rgba(255, 255, 255, 1)!important;}.social_icons-style-2 a:hover{border-color:rgba(255,255,255,1)!important;background-color:rgba(255, 255, 255, 1)!important;color:rgba(89, 123, 164, 1)!important;}.social_icons-style-2 a i{color:inherit!important;}
36.social_icons-style-2 a svg,.social_icons-style-2 a svg path{fill:currentColor!important;}.pagination-style-2 li a{color:rgba(255, 255, 255, 1)!important;background-color:rgba(0, 0, 0, 0)!important;border-color:rgba(255, 255, 255, 1)!important;}.pagination-style-2 li a:hover{color:rgba(89, 123, 164, 1)!important;background-color:rgba(255, 255, 255, 1)!important;border-color:rgba(255, 255, 255, 1)!important;}.pagination-style-2 li.active a{color:rgba(89, 123, 164, 1)!important;background-color:rgba(255, 255, 255, 1)!important;border-color:rgba(255, 255, 255, 1)!important;}.hyperlink-style-2{color:rgba(255, 255, 255, 1)!important;}.hyperlink-style-2:hover{color:rgba(74, 125, 166, 1)!important;}.hyperlink-style-3{color:rgba(0, 0, 0, 1)!important;}.hyperlink-style-3:hover{color:rgba(0, 0, 0, 1)!important;}.button-style-3{color:rgba(255, 255, 255, 1)!important;background-color:rgba(255, 255, 255, 0)!important;border-color:rgba(255, 255, 255, 1)!important;}.button-style-3:hover{color:rgba(89, 123, 164, 1)!important;background-color:rgba(255, 255, 255, 1)!important;border-color:rgba(255, 255, 255, 1)!important;}.hyperlink-style-4{color:rgba(255, 255, 255, 1)!important;}.hyperlink-style-4:hover{color:rgba(255,255,255,1)!important;}</style>
37
38
39        
39<script>
40            (function utmParse() {
41                const url = new URL(window.location.href);
42                if (url.search) {
43                    const utm = url.search.split(/\?|&/g).reduce((acc, current) => {
44                        const matched = current.match(/utm_(content|campaign|medium|source|term|id)|gclid/g);
45                        if (matched) {
46                        acc[matched[0]] = current.replace(`${matched[0]}=`, '');
47                        }
48                        return acc;
49                    }, {});
50                    if (Object.keys(utm).length) {
51                        window.localStorage.setItem('utm_vars', JSON.stringify(utm));
52                    } else {
53                        // Remove old utm vars
54                        window.localStorage.removeItem('utm_vars');
55                    }
56                }
57                // Set referrer in local storage
58                // This is meant to be stored once to avoid self-referrals and to have the first referrer only.
59                if (!window.localStorage.getItem('referrer')) {
60                    // Capture the Referrer URL
61                    const referrer = document.referrer;
62                    if (referrer) {
63                        // Only store the referrer if it comes from outside the current domain (to avoid self-referrals)
64                        const currentDomain = window.location.hostname;
65                        const referrerDomain = new URL(referrer).hostname;
66
67                        if (referrerDomain !== currentDomain) {
68                            // Store it in localStorage
69                            localStorage.setItem('referrer', referrer);
70                        }
71                    }
72                }
73            })();
74        </script>
74
75        <meta name="google-site-verification" content="wlEdJ5t9tMmCNjqDuHqXYjnPHrZs9ZxKa0oDcyWWkc0" />
76    <!-- GOOGLE TRANSLATE STYLES are moved to external CSS -->
77</head>
78<body>
79    <div id="google_translate_element" style="display: none"></div>
80
81        <nav id="global-navbar" data-el-id="618af1e3-0371-4759-8d9c-a88aded9bfde">
82            <div class="header theme-auto">
83  <div class="header__left">
84    <ul class="navigation">
85    </ul>
86  </div>
87  <a href="/" class="header__logo header__logo--center">
88    <img src="https://media-production.lp-cdn.com/cdn-cgi/image/format=auto,quality=85,fit=scale-down,width=960/https://media-production.lp-cdn.com/media/ntbrpekrfgwsgpcr8skr" alt="" class="dark">
89    <img src="https://media-production.lp-cdn.com/cdn-cgi/image/format=auto,quality=85,fit=scale-down,width=960/https://media-production.lp-cdn.com/media/ec8b1zyvwotmpto6hfr8" alt="" class="light">
90  </a>
91  <div class="header__right">
92    <ul class="navigation">
93      <li class="navigation__item sub-nav-container">
94        <a href="#" class="navigation__link">Properties</a>
95        <ul class="sub-nav">
96              <li class="sub-nav__item">
97                <a  href="/properties/sale" class="sub-nav__link">Active</a>
98              </li>
99              <li class="sub-nav__item">
100                <a  href="/properties/sold" class="sub-nav__link">Sold</a>
101              </li>
102        </ul>
103      </li>
104      <li class="navigation__item">
105        <a  href="/blog" class="navigation__link">Blog</a>
106      </li>
107      <li class="navigation__item">
108        <a  href="/testimonials" class="navigation__link">Testimonials</a>
109      </li>
110    </ul>
111
112
113    <button class="hamburger-component header__hamburger">
114      <svg width="60" height="60" viewBox="0 0 60 60" fill="none" xmlns="http://www.w3.org/2000/svg">
115        <circle cx="30" cy="30" r="30" />
116        <rect class="line line--top" x="18" y="26" width="24" height="2" />
117        <rect class="line line--bottom" x="30" y="32" width="12" height="2" />
118      </svg>
119    </button>
120  </div>
121</div>
122        </nav>
123        <div id="global-sidemenu" class="sidemenu" data-el-id="1575f740-92ae-4292-919d-936adffb0f46">
124            <div class="sidemenu__container">
125  
126
127  <div class="sidemenu__img" style="background-image: url('https://media-production.lp-cdn.com/media/2e6942d9-a651-4b10-a97a-10b6c52c33a0');">
128  </div>
129  
130  <div class="sidemenu__wrapper">
131    <div class="sidemenu__header">
132      <button class="sidemenu__toggle toggle sidemenu__toggle--right">Close Menu</button>
133    </div>
134    
135    <div class="sidemenu__nav">
136      <ul class="navigation">
137        <li class="navigation__item" >
138          <a  href="/" class="navigation__link" >Home</a>
139        </li>
140        <li class="navigation__item" >
141          <a  href="/properties" class="navigation__link" >Properties</a>
142        </li>
143        <li class="navigation__item sub-nav-container" data-wow-delay="2.2s">
144          <a href="#" class="navigation__link">
145          Communities
146            <svg width="24" height="24" viewBox="0 0 24 24" fill="none" class="arrow" xmlns="http://www.w3.org/2000/svg">
147              <path d="M7.41 8.58984L12 13.1698L16.59 8.58984L18 9.99984L12 15.9998L6 9.99984L7.41 8.58984Z" fill="currentColor"/>
148            </svg>
149          </a>
150          <ul class="sub-nav">
151            <li class="sub-nav__item"><a  href="/communities" class="sub-nav__link feature">All Communities</a></li>
152            <li class="sub-nav__item"><a  href="/temecula-new-homes/temecula" class="sub-nav__link feature">Temecula</a></li>
153            <li class="sub-nav__item"><a  href="/temecula-new-homes/murrieta" class="sub-nav__link feature">Murrieta</a></li>
154            <li class="sub-nav__item"><a  href="/temecula-new-homes/menifee" class="sub-nav__link feature">Menifee</a></li>
155            <li class="sub-nav__item"><a  href="/temecula-new-homes/winchester" class="sub-nav__link feature">Winchester</a></li>
156            <li class="sub-nav__item"><a  href="/temecula-new-homes/wildomar" class="sub-nav__link feature">Wildomar</a></li>
157            <li class="sub-nav__item"><a  href="/temecula-new-homes/lake-elsinore" class="sub-nav__link feature">Lake Elsinore</a></li>
158            <li class="sub-nav__item"><a  href="/temecula-new-homes/riverside-county" class="sub-nav__link feature">Riverside County</a></li>
159            <li class="sub-nav__item"><a  href="/temecula-new-homes/san-diego-county" class="sub-nav__link feature">San Diego County</a></li>
160          </ul>
161    
162        </li>
163        <li class="navigation__item" >
164          <a  href="/buying" class="navigation__link" >Buying</a>
165        </li>
166        <li class="navigation__item" >
167          <a  href="/selling" class="navigation__link" >Selling</a>
168        </li>
169        <li class="navigation__item" >
170          <a  href="/trade-in" class="navigation__link" >Trade In</a>
171        </li>
172        <li class="navigation__item" >
173          <a  href="/cash-offer" class="navigation__link" >Cash Offer</a>
174        </li>
175        <li class="navigation__item" >
176          <a  href="/home-search/listings?search_type&#x3D;envelope&amp;south&#x3D;33.49325661696914&amp;west&#x3D;-117.2894014548828&amp;north&#x3D;33.55936994697054&amp;east&#x3D;-117.04632894511718&amp;property_type%5B%5D&#x3D;Co-op&amp;property_type%5B%5D&#x3D;Condo&amp;property_type%5B%5D&#x3D;Commercial&amp;property_type%5B%5D&#x3D;Land&amp;property_type%5B%5D&#x3D;Multi-family&amp;property_type%5B%5D&#x3D;Manufactured&amp;property_type%5B%5D&#x3D;Residential&amp;property_type%5B%5D&#x3D;Townhouse&amp;property_type%5B%5D&#x3D;Other&amp;property_type%5B%5D&#x3D;Co-op&amp;property_type%5B%5D&#x3D;Condo&amp;property_type%5B%5D&#x3D;Commercial&amp;property_type%5B%5D&#x3D;Land&amp;property_type%5B%5D&#x3D;Multi-family&amp;property_type%5B%5D&#x3D;Manufactured&amp;property_type%5B%5D&#x3D;Residential&amp;property_type%5B%5D&#x3D;Townhouse&amp;property_type%5B%5D&#x3D;Other&amp;status%5B%5D&#x3D;Active&amp;status_days%5BActive%5D&#x3D;36500&amp;status%5B%5D&#x3D;Under+Contract&amp;status_days%5BUnder+Contract%5D&#x3D;36500&amp;status%5B%5D&#x3D;Pending&amp;status_days%5BPending%5D&#x3D;36500&amp;status_days%5BSold%5D&#x3D;180&amp;mailer_schedule&#x3D;instant&amp;order&#x3D;status_modified_at%3Adesc&amp;page&#x3D;1" class="navigation__link" >Search Homes </a>
177        </li>
178        <li class="navigation__item sub-nav-container" data-wow-delay="2.8s">
179          <a href="#" class="navigation__link">
180          About Us
181            <svg width="24" height="24" viewBox="0 0 24 24" fill="none" class="arrow" xmlns="http://www.w3.org/2000/svg">
182              <path d="M7.41 8.58984L12 13.1698L16.59 8.58984L18 9.99984L12 15.9998L6 9.99984L7.41 8.58984Z" fill="currentColor"/>
183            </svg>
184          </a>
185          <ul class="sub-nav">
186            <li class="sub-nav__item"><a  href="/about-us" class="sub-nav__link feature">Meet the Team</a></li>
187            <li class="sub-nav__item"><a  href="/testimonials" class="sub-nav__link feature">Testimonials</a></li>
188            <li class="sub-nav__item"><a  href="/blog" class="sub-nav__link feature">Blog</a></li>
189            <li class="sub-nav__item"><a  href="/past-sales" class="sub-nav__link feature">Past Sales</a></li>
190          </ul>
191    
192        </li>
193        <li class="navigation__item" >
194          <a  href="/contact" class="navigation__link" >Contact Us</a>
195        </li>
196      </ul>
197    </div>
198  
199    <div class="sidemenu__socials">
200          <ul class="lp-socials social_icons-style-1 sidemenu-social-links">
201          
202                  <li>
203                    <a
204                      href="https://www.facebook.com/TrillionRE/"
205                      class="lp-socials__link socials__item"
206                      data-wow-delay="0s"
207                      target="_blank"
208                      aria-label="FACEBOOK"
209                    >
210                        <span class="lp-i lp-i--facebook" aria-hidden="true"></span>
211                    </a>
212                  </li>
213                  <li>
214                    <a
215                      href="https://www.instagram.com/trillionrealestate/"
216                      class="lp-socials__link socials__item"
217                      data-wow-delay="0.1s"
218                      target="_blank"
219                      aria-label="INSTAGRAM"
220                    >
221                        <span class="lp-i lp-i--instagram" aria-hidden="true"></span>
222                    </a>
223                  </li>
224                  <li>
225                    <a
226                      href="https://www.zillow.com/profile/tysonrobinson"
227                      class="lp-socials__link socials__item"
228                      data-wow-delay="0.2s"
229                      target="_blank"
230                      aria-label="ZILLOW"
231                    >
232                        <span class="lp-i lp-i--zillow" aria-hidden="true"></span>
233                    </a>
234                  </li>
235                  <li>
236                    <a
237                      href="https://www.yelp.com/biz/tyson-robinson-temecula-real-estate-team-temecula?osq&#x3D;tyson+Trillion"
238                      class="lp-socials__link socials__item"
239                      data-wow-delay="0.3s"
240                      target="_blank"
241                      aria-label="YELP"
242                    >
243                        <span class="lp-i lp-i--yelp" aria-hidden="true"></span>
244                    </a>
245                  </li>
246            </ul>    </div>
247  </div>
248</div>
249
250        </div>
251        <div  id="global-mobile-contact" class="mobile-contact-wrapper" data-el-id="befe5af2-a6ca-4119-924a-a85d96d36b51">
252            <div class="btn-holder" 
253style="
254--backgroundColor: rgba(20, 20, 20, 1); 
255--textColor: rgba(255, 255, 255, 1); 
256--pillTextColor: rgba(26, 26, 26, 1); 
257--pillBackgroundColor: rgba(255, 255, 255, 1);">
258
259    <button type="button" class="connect-btn lp-ico lp-ico-arrow-top visible">Let&#x27;s Connect</button>
260</div>
261
262
263<div class="pop-up" style="--backgroundColor: rgba(20, 20, 20, 1); --textColor: rgba(255, 255, 255, 1);">
264  <div class="lp-container">
265    <form data-type="contact-form" class="contact-form">
266      <div class="contact-form__container">
267          <h3 class="lp-h3">Leave a Message</h3>
268      
269        <div class="contact-form__content">
270          <div class="contact-form__inputs-container">
271            <div class="contact-form__item">
272              <input
273                id="__FullName"
274                type="text" name="name"
275                class="lp-input lp-input--light"
276                required
277                placeholder="Full Name">
278            </div>
279            <div class="contact-form__item">
280              <input
281                id="__Email"
282                type="email" name="email"
283                class="lp-input js-email-input lp-input--light"
284                required
285                placeholder="Email">
286            </div>
287            <div class="contact-form__item"> 
288              <input
289                class="lp-input lp-input--light"
290                type="tel" 
291                placeholder="Phone"
292                id="__Phone"
293                name="phone"
294                required>
295            </div>
296
297            <div class="contact-form__item input-group-select">
298              <select name="interest" id="-field-interest" placeholder="Interest"
299                class="lp-input dropdown-select js-select js-form-element lp-input--light" required>
300                <option value="" disabled selected data-label="Interest">Interested in...</option>
301                <option value="Selling &amp; Buying">Selling &amp; Buying</option>
302                <option value="Selling">Selling</option>
303                <option value="Buying">Buying</option>
304                <option value="Renting">Renting</option>
305                <option value="Other">Other</option>
306              </select>
307              <label for="-field-interest" class="lp-label sr-only">Interest</label>
308            </div>
309
310            <div class="contact-form__item">
311              <textarea
312                name="message"
313                rows="4"
314                id="__Message"
315                class="lp-input lp-input--light"
316                placeholder="Message"
317                required></textarea>
318            </div>
319            <div class="lp-disclaimer">  <label style='display: none;' for='-termsAccepted'>Opt In/Disclaimer Consent:</label>
320  <label class='lp-tcr-content'>
321    <span class='lp-tcr-checkbox'>
322      <input
323        type='checkbox'
324        id='-termsAccepted'
325        name='termsAccepted'
326        oninvalid="this.setCustomValidity('Please accept the terms and conditions')"
327        oninput="this.setCustomValidity('')"
328        required
329      /></span>
330    <span class='lp-tcr-message'>
331      
332        I agree to be contacted by
333        Trillion Real Estate
334        via call, email, and text for real estate services. To opt out, you can reply 'stop' at any time or reply 'help' for assistance.
335        You can also click the unsubscribe link in the emails. Message and data rates may apply. Message frequency may vary.
336        <a href='/terms-and-conditions' target='_blank'>Privacy Policy</a>.
337    </span>
338  </label>
339
340</div>
341            <button type="submit" class="lp-btn lp-btn--filled lp-btn--dark submit  contact-form__item">Submit</button>
342            
343            <div class="lp-h-pot">
344              <input id="__newsSignMiddleName" name="middleName" value="" autocomplete="off" tabindex="-1">
345            </div>
346            
347            <input style="display: none;" type="text" name="source" value="CONTACT_INQUIRY" />
348            <input type="hidden" name="button_text" value="Let&#x27;s Connect">
349          </div>
350        </div>
351      </div>
352
353
354      <div class="success-block">
355          <h3 class="lp-h3 success-message">Thank you for your message. We will be in touch with you shortly.</h3>
356
357      </div>
358    </form>
359
360    <button type="button" class="close-btn lp-ico lp-ico-close"></button>
361  
362  </div>
363</div>
364
365
366        </div>
367        <section  class="image-section is-font-color-light is-background-color-dark" id="section-28f45f08-c7d4-49ae-b152-9a02d549e538" data-el-id="bce33bae-7388-4ccc-abff-e0ce18ec46d2">
368    
369<script>
370  (function(){
371    const sectionId = 'section-28f45f08-c7d4-49ae-b152-9a02d549e538'
372    const section = document.querySelector(`#${sectionId}`);
373    var sectionBg = window.getComputedStyle(section, null).getPropertyValue('background-image');
374
375    if('false' === 'true') {
376      section.classList.add('parallax-enabled');
377      section.style.setProperty('--sectionBackground', sectionBg);
378      section.style.setProperty('background', 'transparent');
379    }
380  })()
381</script>
381
382
383
384<div class="opening-with-search height-class-770px ">
385  <div class="center-block">
386    <button class='lp-play video-section__play-button js-play-btn'></button>
387    <div class="container lp-container">
388
389      <div class="lp-title-group">
390        
391
392            <h1 class="h1 lp-h1 opening-title lp-pre-line" style="color: rgba(255, 255, 255, 1)">Blog</h1>
393
394        
395      </div>
396      
397      <div class="buttons"></div>
398      
399    </div>
400  </div>
401  <div class="bottom-spacer"></div>
402</div>
403</section>
404<section id="section-3087e602-065d-462f-8f31-f4819d6fc3cd"  class="solid-section is-font-color-dark is-background-color-light" data-el-id="fbce30da-e561-48a0-b724-32c0e1f42ba6">
405<script type="text/x-handlebars-template" class="blogItem pagination-script">  <a class="item" href="/blog/{{slug}}">
406		<figure>
407		  {{#if media.[0]}} 
408			  {{{mediaImage media.[0] sizes="(min-width: 769px) 381px, (min-width: 561px) 450px, 100vw" alt=../lastName}}}
409			{{/if}}
410		</figure>
411		<div class="text-wrap">
412  		<h5 class="lp-h5">{{title}}</h5>
413  		<p class="bf1">
414  		  {{hbFormatDate publishedAt}}
415  	  </p>
416  	  <p class="item-text">
417    	    {{truncate subtitle 168 "…"}}
418    	    {{#numCompare subtitle.length 168 ">"}}
419    	    <span class="hyperlink-style-3 link">Read more</span>
420    	    {{/numCompare}}
421  	    </p>
422	  </div>
423	</a> 
424</script>
424
425
426<div class="section lp-vertical-paddings"> 
427  <div class="lp-container">
428    
429    <div class="lp-title-group"> 
430      <h2 class="lp-h2">Featured</h2>
431      
432    </div>
433    
434    <div class="collection  ">
435    </div>
436  </div>
437</div>
438
439</section>
440<section id="section-5d01005b-e93f-48f9-92b7-4822576c8b85"  class="solid-section is-font-color-dark is-background-color-light" data-el-id="fbce30da-e561-48a0-b724-32c0e1f42ba6">
441<script type="text/x-handlebars-template" class="blogItem pagination-script">  <a class="item" href="/blog/{{slug}}">
442		<figure>
443		  {{#if media.[0]}} 
444			  {{{mediaImage media.[0] sizes="(min-width: 769px) 381px, (min-width: 561px) 450px, 100vw" alt=../lastName}}}
445			{{/if}}
446		</figure>
447		<div class="text-wrap">
448  		<h5 class="lp-h5">{{title}}</h5>
449  		<p class="bf1">
450  		  {{hbFormatDate publishedAt}}
451  	  </p>
452  	  <p class="item-text">
453    	    {{truncate subtitle 168 "…"}}
454    	    {{#numCompare subtitle.length 168 ">"}}
455    	    <span class="hyperlink-style-1 link">Read more</span>
456    	    {{/numCompare}}
457  	    </p>
458	  </div>
459	</a> 
460</script>
460
461
462<div class="section lp-vertical-paddings"> 
463  <div class="lp-container">
464    
465    <div class="lp-title-group"> 
466      <h2 class="lp-h2">Most Popular</h2>
467      
468    </div>
469    
470    <div class="collection collection--3 ">
471    </div>
472  </div>
473</div>
474
475</section>
476<section id="section-c0d58c8d-bb8c-453f-9168-aa08a1cecdda"  class="solid-section is-font-color-dark is-background-color-light" data-el-id="fbce30da-e561-48a0-b724-32c0e1f42ba6">
477<script type="text/x-handlebars-template" class="blogItem pagination-script">  <a class="item" href="/blog/{{slug}}">
478		<figure>
479		  {{#if media.[0]}} 
480			  {{{mediaImage media.[0] sizes="(min-width: 769px) 381px, (min-width: 561px) 450px, 100vw" alt=../lastName}}}
481			{{/if}}
482		</figure>
483		<div class="text-wrap">
484  		<h5 class="lp-h5">{{title}}</h5>
485  		<p class="bf1">
486  		  {{hbFormatDate publishedAt}}
487  	  </p>
488  	  <p class="item-text">
489    	    {{truncate subtitle 168 "…"}}
490    	    {{#numCompare subtitle.length 168 ">"}}
491    	    <span class=" link">Read more</span>
492    	    {{/numCompare}}
493  	    </p>
494	  </div>
495	</a> 
496</script>
496
497
498<div class="section lp-vertical-paddings"> 
499  <div class="lp-container">
500    
501    <div class="lp-title-group"> 
502      <h2 class="lp-h2">Recently Posted</h2>
503      
504    </div>
505    
506    <div class="collection collection--3 data-container">
507          <a class="item" href="/blog/pros-cons-of-online-real-estate-services-tysons-tips">
508        		<figure>
509        			  <img src="https://media-production.lp-cdn.com/cdn-cgi/image/format=auto,quality=85,fit=scale-down,width=1280/https://media-production.lp-cdn.com/media/dmvdvt6cmraxm1ttle5z34j2" srcset="https://media-production.lp-cdn.com/cdn-cgi/image/format=auto,quality=85,fit=scale-down,width=960/https://media-production.lp-cdn.com/media/dmvdvt6cmraxm1ttle5z34j2 960w, https://media-production.lp-cdn.com/cdn-cgi/image/format=auto,quality=85,fit=scale-down,width=1280/https://media-production.lp-cdn.com/media/dmvdvt6cmraxm1ttle5z34j2 1280w, https://media-production.lp-cdn.com/cdn-cgi/image/format=auto,quality=85/https://media-production.lp-cdn.com/media/dmvdvt6cmraxm1ttle5z34j2 1408w" alt="" sizes="(min-width: 769px) 381px, (min-width: 561px) 450px, 100vw" loading="lazy">
510        		</figure>
511        		<div class="text-wrap">
512          		<h5 class="lp-h5">Pros &amp; Cons of Online Real Estate Services | Tyson’s Tips</h5>
513          		<p class="bf1">
514          		  September 3, 2025
515          	  </p>
516          	  <p class="item-text">
517            	    If you’re thinking of using a non-traditional real estate service to sell your home (i.e. new online brokerages, Redfin, Zillow, etc) and want a little more insight, c…
518            	    <span class=" link">Read more</span>
519          	    </p>
520        	  </div>
521        	</a> 
522          <a class="item" href="/blog/becoming-a-real-estate-agent-in-2021-how-hard-work-pays-off-josh-sutton-tyson-robinson">
523        		<figure>
524        			  <img src="https://media-production.lp-cdn.com/cdn-cgi/image/format=auto,quality=85,fit=scale-down,width=1280/https://media-production.lp-cdn.com/media/dcl6ig7xf224zo533f3bwnm2" srcset="https://media-production.lp-cdn.com/cdn-cgi/image/format=auto,quality=85,fit=scale-down,width=960/https://media-production.lp-cdn.com/media/dcl6ig7xf224zo533f3bwnm2 960w, https://media-production.lp-cdn.com/cdn-cgi/image/format=auto,quality=85,fit=scale-down,width=1280/https://media-production.lp-cdn.com/media/dcl6ig7xf224zo533f3bwnm2 1280w, https://media-production.lp-cdn.com/cdn-cgi/image/format=auto,quality=85/https://media-production.lp-cdn.com/media/dcl6ig7xf224zo533f3bwnm2 1408w" alt="" sizes="(min-width: 769px) 381px, (min-width: 561px) 450px, 100vw" loading="lazy">
525        		</figure>
526        		<div class="text-wrap">
527          		<h5 class="lp-h5">Becoming a real estate agent in 2021 &amp; how hard work pays off | Josh Sutton &amp; Tyson Robinson</h5>
528          		<p class="bf1">
529          		  September 3, 2025
530          	  </p>
531          	  <p class="item-text">
532            	      It’s no secret that 2020 was a chaotic market for real estate and that has carried on into 2021. Being an intense sellers market, it has made it a super tough time t…
533            	    <span class=" link">Read more</span>
534          	    </p>
535        	  </div>
536        	</a> 
537          <a class="item" href="/blog/how-long-it-takes-to-find-a-home-tysons-tips">
538        		<figure>
539        			  <img src="https://media-production.lp-cdn.com/cdn-cgi/image/format=auto,quality=85,fit=scale-down,width=1280/https://media-production.lp-cdn.com/media/yp256lwpgb0sujld5rw4twr1" srcset="https://media-production.lp-cdn.com/cdn-cgi/image/format=auto,quality=85,fit=scale-down,width=960/https://media-production.lp-cdn.com/media/yp256lwpgb0sujld5rw4twr1 960w, https://media-production.lp-cdn.com/cdn-cgi/image/format=auto,quality=85,fit=scale-down,width=1280/https://media-production.lp-cdn.com/media/yp256lwpgb0sujld5rw4twr1 1280w, https://media-production.lp-cdn.com/cdn-cgi/image/format=auto,quality=85/https://media-production.lp-cdn.com/media/yp256lwpgb0sujld5rw4twr1 1408w" alt="" sizes="(min-width: 769px) 381px, (min-width: 561px) 450px, 100vw" loading="lazy">
540        		</figure>
541        		<div class="text-wrap">
542          		<h5 class="lp-h5">How Long It Takes to Find a Home | Tyson’s Tips</h5>
543          		<p class="bf1">
544          		  September 3, 2025
545          	  </p>
546          	  <p class="item-text">
547            	    Get a general idea of how long it takes to find a home when you are shopping around. It’s best to have a realistic idea/timeline so you can plan accordingly. Give us a…
548            	    <span class=" link">Read more</span>
549          	    </p>
550        	  </div>
551        	</a> 
552          <a class="item" href="/blog/i-was-in-a-real-estate-pickleball-commercial-and-its-awesome">
553        		<figure>
554        			  <img src="https://media-production.lp-cdn.com/cdn-cgi/image/format=auto,quality=85,fit=scale-down,width=1280/https://media-production.lp-cdn.com/media/wq60xtjtnwnk1b7cotjgg1ki" srcset="https://media-production.lp-cdn.com/cdn-cgi/image/format=auto,quality=85,fit=scale-down,width=960/https://media-production.lp-cdn.com/media/wq60xtjtnwnk1b7cotjgg1ki 960w, https://media-production.lp-cdn.com/cdn-cgi/image/format=auto,quality=85,fit=scale-down,width=1280/https://media-production.lp-cdn.com/media/wq60xtjtnwnk1b7cotjgg1ki 1280w, https://media-production.lp-cdn.com/cdn-cgi/image/format=auto,quality=85/https://media-production.lp-cdn.com/media/wq60xtjtnwnk1b7cotjgg1ki 1408w" alt="" sizes="(min-width: 769px) 381px, (min-width: 561px) 450px, 100vw" loading="lazy">
555        		</figure>
556        		<div class="text-wrap">
557          		<h5 class="lp-h5">I Was in a Real Estate Pickleball Commercial and Its AWESOME!</h5>
558          		<p class="bf1">
559          		  September 3, 2025
560          	  </p>
561          	  <p class="item-text">
562            	    Tyson is a top agent in Temecula Valley, broker owner of Trillion Real Estate!⚡️ At Trillion we take the time to teach you the rules and the strategies you need to kno…
563            	    <span class=" link">Read more</span>
564          	    </p>
565        	  </div>
566        	</a> 
567          <a class="item" href="/blog/life-balance-success-in-real-estate-brittany-nicola">
568        		<figure>
569        			  <img src="https://media-production.lp-cdn.com/cdn-cgi/image/format=auto,quality=85,fit=scale-down,width=1280/https://media-production.lp-cdn.com/media/dg2whafwrbtakc16dapztjk6" srcset="https://media-production.lp-cdn.com/cdn-cgi/image/format=auto,quality=85,fit=scale-down,width=960/https://media-production.lp-cdn.com/media/dg2whafwrbtakc16dapztjk6 960w, https://media-production.lp-cdn.com/cdn-cgi/image/format=auto,quality=85,fit=scale-down,width=1280/https://media-production.lp-cdn.com/media/dg2whafwrbtakc16dapztjk6 1280w, https://media-production.lp-cdn.com/cdn-cgi/image/format=auto,quality=85/https://media-production.lp-cdn.com/media/dg2whafwrbtakc16dapztjk6 1408w" alt="" sizes="(min-width: 769px) 381px, (min-width: 561px) 450px, 100vw" loading="lazy">
570        		</figure>
571        		<div class="text-wrap">
572          		<h5 class="lp-h5">Life Balance &amp; Success in Real Estate | Brittany Nicola</h5>
573          		<p class="bf1">
574          		  September 3, 2025
575          	  </p>
576          	  <p class="item-text">
577            	    Listen in to Tyson and Brittany as they discuss how Brittany not only kills it as a single mom of two, but is crushing the real estate game. One huge success Tyson &amp; B…
578            	    <span class=" link">Read more</span>
579          	    </p>
580        	  </div>
581        	</a> 
582          <a class="item" href="/blog/key-elements-to-being-a-solo-agent-trillion-real-estate">
583        		<figure>
584        			  <img src="https://media-production.lp-cdn.com/cdn-cgi/image/format=auto,quality=85,fit=scale-down,width=1280/https://media-production.lp-cdn.com/media/gr0rtmqehpbz0fa8b7x7wkvg" srcset="https://media-production.lp-cdn.com/cdn-cgi/image/format=auto,quality=85,fit=scale-down,width=960/https://media-production.lp-cdn.com/media/gr0rtmqehpbz0fa8b7x7wkvg 960w, https://media-production.lp-cdn.com/cdn-cgi/image/format=auto,quality=85,fit=scale-down,width=1280/https://media-production.lp-cdn.com/media/gr0rtmqehpbz0fa8b7x7wkvg 1280w, https://media-production.lp-cdn.com/cdn-cgi/image/format=auto,quality=85/https://media-production.lp-cdn.com/media/gr0rtmqehpbz0fa8b7x7wkvg 1408w" alt="" sizes="(min-width: 769px) 381px, (min-width: 561px) 450px, 100vw" loading="lazy">
585        		</figure>
586        		<div class="text-wrap">
587          		<h5 class="lp-h5">Key Elements to Being a Solo Agent | Trillion Real Estate</h5>
588          		<p class="bf1">
589          		  September 3, 2025
590          	  </p>
591          	  <p class="item-text">
592            	    What is a key element to being a solo agent? 🤔 At our monthly mastermind we had the pleasure of learning from @andrew_b_lewis &amp; @justinpatrickmccabe on all things rea…
593            	    <span class=" link">Read more</span>
594          	    </p>
595        	  </div>
596        	</a> 
597          <a class="item" href="/blog/how-to-build-wealth-with-real-estate">
598        		<figure>
599        			  <img src="https://media-production.lp-cdn.com/cdn-cgi/image/format=auto,quality=85,fit=scale-down,width=1280/https://media-production.lp-cdn.com/media/ixc6fu8gcuzkqpersyv6bvvr" srcset="https://media-production.lp-cdn.com/cdn-cgi/image/format=auto,quality=85,fit=scale-down,width=960/https://media-production.lp-cdn.com/media/ixc6fu8gcuzkqpersyv6bvvr 960w, https://media-production.lp-cdn.com/cdn-cgi/image/format=auto,quality=85,fit=scale-down,width=1280/https://media-production.lp-cdn.com/media/ixc6fu8gcuzkqpersyv6bvvr 1280w, https://media-production.lp-cdn.com/cdn-cgi/image/format=auto,quality=85/https://media-production.lp-cdn.com/media/ixc6fu8gcuzkqpersyv6bvvr 1408w" alt="" sizes="(min-width: 769px) 381px, (min-width: 561px) 450px, 100vw" loading="lazy">
600        		</figure>
601        		<div class="text-wrap">
602          		<h5 class="lp-h5">How to Build Wealth With Real Estate</h5>
603          		<p class="bf1">
604          		  September 3, 2025
605          	  </p>
606          	  <p class="item-text">
607            	    I own 6+ investment properties and plan to grow this number each year. Listen in as I discuss building long-term wealth with investment properties and taking advantage…
608            	    <span class=" link">Read more</span>
609          	    </p>
610        	  </div>
611        	</a> 
612          <a class="item" href="/blog/intro-to-dave-ramseys-7-baby-steps-to-financial-stability-elp-agent">
613        		<figure>
614        			  <img src="https://media-production.lp-cdn.com/cdn-cgi/image/format=auto,quality=85,fit=scale-down,width=1280/https://media-production.lp-cdn.com/media/naj2xblxtmwbygwkr5kq153t" srcset="https://media-production.lp-cdn.com/cdn-cgi/image/format=auto,quality=85,fit=scale-down,width=960/https://media-production.lp-cdn.com/media/naj2xblxtmwbygwkr5kq153t 960w, https://media-production.lp-cdn.com/cdn-cgi/image/format=auto,quality=85,fit=scale-down,width=1280/https://media-production.lp-cdn.com/media/naj2xblxtmwbygwkr5kq153t 1280w, https://media-production.lp-cdn.com/cdn-cgi/image/format=auto,quality=85/https://media-production.lp-cdn.com/media/naj2xblxtmwbygwkr5kq153t 1408w" alt="" sizes="(min-width: 769px) 381px, (min-width: 561px) 450px, 100vw" loading="lazy">
615        		</figure>
616        		<div class="text-wrap">
617          		<h5 class="lp-h5">Intro to Dave Ramsey’s 7 Baby Steps to Financial Stability – ELP Agent</h5>
618          		<p class="bf1">
619          		  September 3, 2025
620          	  </p>
621          	  <p class="item-text">
622            	    Tyson Robinson in a Dave Ramsey trusted, fully vetted endorsed local provider (ELP) in the Temecula Valley. In this video he briefly introduces an overview of Dave Ram…
623            	    <span class=" link">Read more</span>
624          	    </p>
625        	  </div>
626        	</a> 
627          <a class="item" href="/blog/sports-cards-investing-in-2021-sports-cards-with-tyson">
628        		<figure>
629        			  <img src="https://media-production.lp-cdn.com/cdn-cgi/image/format=auto,quality=85,fit=scale-down,width=1280/https://media-production.lp-cdn.com/media/lb77lm9zincgtzgyiej3ies9" srcset="https://media-production.lp-cdn.com/cdn-cgi/image/format=auto,quality=85,fit=scale-down,width=960/https://media-production.lp-cdn.com/media/lb77lm9zincgtzgyiej3ies9 960w, https://media-production.lp-cdn.com/cdn-cgi/image/format=auto,quality=85,fit=scale-down,width=1280/https://media-production.lp-cdn.com/media/lb77lm9zincgtzgyiej3ies9 1280w, https://media-production.lp-cdn.com/cdn-cgi/image/format=auto,quality=85/https://media-production.lp-cdn.com/media/lb77lm9zincgtzgyiej3ies9 1408w" alt="" sizes="(min-width: 769px) 381px, (min-width: 561px) 450px, 100vw" loading="lazy">
630        		</figure>
631        		<div class="text-wrap">
632          		<h5 class="lp-h5">Sports Cards Investing in 2021 | Sports Cards with Tyson</h5>
633          		<p class="bf1">
634          		  September 3, 2025
635          	  </p>
636          	  <p class="item-text">
637            	    Discussing all things sports cards, what I have, investing tips and answering questions! Visit my instagram @sportscardswithtyson to keep up with my latest new cards! …
638            	    <span class=" link">Read more</span>
639          	    </p>
640        	  </div>
641        	</a> 
642    </div>
643    <div class="lp-pagination pagination-container pagination-style-1"></div>
644  </div>
645</div>
646
647</section>
648<section  class="image-section is-font-color-light is-background-color-light" id="section-42ff6c98-9b79-4ecf-b1d4-503fd5a6e14d" data-el-id="60f303de-57c9-4a3b-87cf-c1b576e15623">
649    
649<script>
650  (function(){
651    const sectionId = 'section-42ff6c98-9b79-4ecf-b1d4-503fd5a6e14d'
652    const section = document.querySelector(`#${sectionId}`);
653    var sectionBg = window.getComputedStyle(section, null).getPropertyValue('background-image');
654
655    if('true' === 'true') {
656      section.classList.add('parallax-enabled');
657      section.style.setProperty('--sectionBackground', sectionBg);
658      section.style.setProperty('background', 'none');
659    }
660  })()
661</script>
661
662
663<div class="section work-with-us parallax" style="--opacityColor:rgba(0, 0, 0, 0);">
664  <div class="lp-container lp-vertical-paddings">
665    
666    <div class="lp-title-group">
667        <h2 class="lp-h2">Let&#x27;s Talk</h2>
668      
669      <p class="pre-line">You’ve got questions and we can’t wait to answer them.</p>
670    </div>
671
672
673
674
675    
676
677
678    <div class="btn-container">
679              <a
680                  role="button"
681                  data-type="CONTACT_US"
682                  class="btn btn--link lp-btn lp-btn--dark lp-btn--outline lp-btn--mob-full-width button-style-2"
683                  
684                  
685                  
686                  
687                  
688                  >
689                          Contact Us
690                  </a>
691    </div>
692  </div>
693</div>
694</section>
695<section id="section-dc35c8ba-2e7a-45c2-9887-4d2125099be8"  class="solid-section is-font-color-light is-background-color-dark" data-el-id="3614c9e1-cfd9-4976-8483-8f4b825fd098">
696  
696<script type="text/x-handlebars-template" class="jsIGTemplate">
697    <a href="https://www.instagram.com/{{username}}" target="_blank"  class="title-group js-title-group">
698        <h3 class="lp-h3 js-h3"></h3>
699         <div class="username-group"><h5 class="lp-h5">@{{username}}</h5><svg class="arrow-icon" width="18" height="12" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M-.002 7h14.085l-3.558 3.59L11.926 12l5.965-6-5.965-6-1.401 1.41L14.084 5H-.002v2Z" fill="#CCB091"/></svg></div>
700    </a>
701
702    {{#each items}}
703    {{#if mediaUrl}}
704    <div class="item-box">
705      <a href="https://www.instagram.com/{{../username}}" target="_blank" class="item insta-type-{{mediaType}}">
706          <div class="item__text">
707            <h3 class="lp-h3 js-h3"></h3>
708           <div class="username-group"> <h5 class="lp-h5">@{{../username}}</h5> <svg class="arrow-icon" width="18" height="12" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M-.002 7h14.085l-3.558 3.59L11.926 12l5.965-6-5.965-6-1.401 1.41L14.084 5H-.002v2Z" fill="#CCB091"/></svg></div>
709        </div>
710        <div class="item__img" style="background-image: url('{{#ifEquals mediaType 'VIDEO'}}{{thumbnailUrl}}{{else}}{{mediaUrl}}{{/ifEquals}}');"></div>
711        {{#ifEquals mediaType 'VIDEO'}}
712          <div class="media-type-icon">
713            <svg width="30px" height="30px" viewBox="0 0 30 30" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill="#fff" d="M19.369 6.042H2.082A2.086 2.086 0 000 8.125v13.71a2.086 2.086 0 002.083 2.083h17.285a2.086 2.086 0 002.084-2.083V8.125a2.086 2.086 0 00-2.084-2.083zM22.84 17.833l7.16 3.91V8.262l-7.16 3.908v5.662z"/></svg>
714          </div>
715        {{/ifEquals}}
716        {{#if caption}}
717        <div class="item__info"><div class="item__caption">{{caption}}</div></div>
718        {{/if}}
719      </a>
720     </div>
721    {{/if}}
722    {{/each}}
723</script>
723  
724
725 
726<div class="section">
727    <div class="lp-container lp-container--l lp-vertical-paddings" style="--userColor: rgba(54, 69, 77, 1);">
728      <div class="slider-holder js-slider-holder"  data-title="Follow Us on Instagram" >
729        <div class="collection js-collection jsIGContainer"></div>
730      </div>
731    </div>
732</div>
733
734
735</section>
736
737        <div id="modals" class="modals"></div>
738        <footer id="global-footer" class="is-font-color-dark is-background-color-light" data-el-id="f3892c1c-f128-483a-b998-cb1ea48c25c1">
739            <div class="site-footer">
740
741  <div class="site-footer__bottom"> 
742    <div class="lp-container">
743      
744        <div class="site-footer__logo-bar">
745          <div class="site-footer__logo-container">
746            <img src="https://media-production.lp-cdn.com/media/4cac18a3-82a3-4329-bd72-a9c00dde8378" alt="">
747          </div>
748          <div class="site-footer__logo-container">
749            
750          </div>
751        </div>
752
753      <div class="site-footer__info">
754        <div class="site-footer__col">
755            <h5 class="lp-h5 site-footer__col-title">Trillion Real Estate	</h5>
756
757            <div class="site-footer__col-content lp-a"><p><a href="/cdn-cgi/l/email-protection#5c28252f33321c282e3530303533322e393d30392f283d2839723f3331"><span class="__cf_email__" data-cfemail="77030e0418193703051e1b1b1e18190512161b1204031603125914181a">[email&#160;protected]</span></a></p></div>
758        </div>
759
760
761          <div class="site-footer__col">
762              <h5 class="lp-h5 site-footer__col-title">Address</h5>
763
764              <div class="site-footer__col-content lp-a"><p>41689 Enterprise Circle N, Suite 218</p>
765<p>Temecula, CA 92590</p></div>
766          </div>
767        
768        <div class="site-footer__navigation-wrap">
769          <ul class="footer-navigation">
770            <li class="footer-navigation__item">
771              <a  href="/" class="footer-navigation__link">Home</a>
772            </li>
773            <li class="footer-navigation__item">
774              <a  href="/properties" class="footer-navigation__link">Properties</a>
775            </li>
776            <li class="footer-navigation__item">
777              <a  href="/communities" class="footer-navigation__link">Communities</a>
778            </li>
779            <li class="footer-navigation__item">
780              <a  href="/home-search/listings?search_type&#x3D;envelope&amp;south&#x3D;33.49325661696914&amp;west&#x3D;-117.2894014548828&amp;north&#x3D;33.55936994697054&amp;east&#x3D;-117.04632894511718&amp;property_type%5B%5D&#x3D;Co-op&amp;property_type%5B%5D&#x3D;Condo&amp;property_type%5B%5D&#x3D;Commercial&amp;property_type%5B%5D&#x3D;Land&amp;property_type%5B%5D&#x3D;Multi-family&amp;property_type%5B%5D&#x3D;Manufactured&amp;property_type%5B%5D&#x3D;Residential&amp;property_type%5B%5D&#x3D;Townhouse&amp;property_type%5B%5D&#x3D;Other&amp;property_type%5B%5D&#x3D;Co-op&amp;property_type%5B%5D&#x3D;Condo&amp;property_type%5B%5D&#x3D;Commercial&amp;property_type%5B%5D&#x3D;Land&amp;property_type%5B%5D&#x3D;Multi-family&amp;property_type%5B%5D&#x3D;Manufactured&amp;property_type%5B%5D&#x3D;Residential&amp;property_type%5B%5D&#x3D;Townhouse&amp;property_type%5B%5D&#x3D;Other&amp;status%5B%5D&#x3D;Active&amp;status_days%5BActive%5D&#x3D;36500&amp;status%5B%5D&#x3D;Under+Contract&amp;status_days%5BUnder+Contract%5D&#x3D;36500&amp;status%5B%5D&#x3D;Pending&amp;status_days%5BPending%5D&#x3D;36500&amp;status_days%5BSold%5D&#x3D;180&amp;mailer_schedule&#x3D;instant&amp;order&#x3D;status_modified_at%3Adesc&amp;page&#x3D;1" class="footer-navigation__link">Search Homes</a>
781            </li>
782            <li class="footer-navigation__item">
783              <a  href="/about-us" class="footer-navigation__link">Meet the Team</a>
784            </li>
785            <li class="footer-navigation__item">
786              <a  href="/contact" class="footer-navigation__link">Contact Us</a>
787            </li>
788          </ul>
789        
790          <ul class="lp-socials social_icons-style-1 site-footer__socials socials">
791          
792                  <li>
793                    <a
794                      href="https://www.facebook.com/TrillionRE/"
795                      class="lp-socials__link socials__item"
796                      data-wow-delay="0s"
797                      target="_blank"
798                      aria-label="FACEBOOK"
799                    >
800                        <span class="lp-i lp-i--facebook" aria-hidden="true"></span>
801                    </a>
802                  </li>
803                  <li>
804                    <a
805                      href="https://www.instagram.com/trillionrealestate/"
806                      class="lp-socials__link socials__item"
807                      data-wow-delay="0.1s"
808                      target="_blank"
809                      aria-label="INSTAGRAM"
810                    >
811                        <span class="lp-i lp-i--instagram" aria-hidden="true"></span>
812                    </a>
813                  </li>
814                  <li>
815                    <a
816                      href="https://www.zillow.com/profile/tysonrobinson"
817                      class="lp-socials__link socials__item"
818                      data-wow-delay="0.2s"
819                      target="_blank"
820                      aria-label="ZILLOW"
821                    >
822                        <span class="lp-i lp-i--zillow" aria-hidden="true"></span>
823                    </a>
824                  </li>
825                  <li>
826                    <a
827                      href="https://www.yelp.com/biz/tyson-robinson-temecula-real-estate-team-temecula?osq&#x3D;tyson+Trillion"
828                      class="lp-socials__link socials__item"
829                      data-wow-delay="0.3s"
830                      target="_blank"
831                      aria-label="YELP"
832                    >
833                        <span class="lp-i lp-i--yelp" aria-hidden="true"></span>
834                    </a>
835                  </li>
836            </ul>
837
838        </div>
839      </div>
840      
841      <div class="site-footer__disclaimer"><p style="font-size: 12px;">All information is deemed reliable but not guaranteed and should be independently reviewed and verified.<br><img style="margin-top: 10px;" src="https://media-production.lp-cdn.com/media/47161e93-f284-42a5-9511-41c21270ea27" width="100px;" height="auto;">&nbsp; &nbsp; &nbsp;</p></div>
842
843      <div class="site-footer__copy">
844        <div class="lp-a site-footer__copy-lp">
845        <span>Powered by</span>
846        <a href="https://www.luxurypresence.com/" class="" target="_blank">Luxury Presence</a>
847        </div>
848        <div>Copyright © <span class="auto-year-update">2026</span> | <a href="/terms-and-conditions">Privacy Policy</a></div>
849      </div>
850      
851    </div>
852  </div>
853
854  
855    
856</div>
857
858        </footer>
859
860        <div id="modal-global-contact-us" class="modal "
861            data-el-id=""
862            style="background-color: ;"
863            >
864            <div class="modal-content">
865                  <div class="contact-form">
866            <div class="contact-form__close close"></div>
867            <div class="contact-form__container">
868        
869              <form class="contact-form__form" data-type="contact-form" style="color: #FFFFFF; background: rgba(54, 69, 77, 1);  fill: #FFFFFF;">
870                <h5 class="lp-h5 contact-form__title1">Get in Touch</h5>
871                <div class="input-container">
872                  <input id="-cmp-name" name="name" type="text" class="lp-input lp-input--light contact-form__input" placeholder="Name" required>
873                  <span class="input-icon"></span>
874                </div>
875        
876                <div class="input-container">
877                  <input id="-cmp-email" name="email" type="email" class="lp-input lp-input--light contact-form__input" placeholder="Email" required pattern="[a-zA-Z0-9.!#$%&amp;’*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)+">
878                  <span class="input-icon"></span>
879                </div>
880        
881                <div class="input-container">
882                  <input id="-cmp-phone" name="phone" type="tel" class="lp-input lp-input--light  contact-form__input" placeholder="Phone" required>
883                  <span class="input-icon"></span>
884                </div>
885        
886                <div class="input-container">
887                  <textarea id="-cmp-contactMessage" placeholder="Message" name="message" required type="text" class="lp-input lp-input--light  contact-form__input"></textarea>
888                  <span class="input-icon"></span>
889                </div>
890        
891                <div class="h-pot">
892                  <label for="-cmp-middleName">Middle Name</label>
893                  <input id="-cmp-middleName" name="middleName" value="" autocomplete="off" tabindex="-1">
894                </div>
895        
896                <div class="lp-disclaimer">  <label style='display: none;' for='-termsAccepted'>Opt In/Disclaimer Consent:</label>
897          <label class='lp-tcr-content'>
898            <span class='lp-tcr-checkbox'>
899              <input
900                type='checkbox'
901                id='-termsAccepted'
902                name='termsAccepted'
903                oninvalid="this.setCustomValidity('Please accept the terms and conditions')"
904                oninput="this.setCustomValidity('')"
905                required
906              /></span>
907            <span class='lp-tcr-message'>
908              
909                I agree to be contacted by
910                Trillion Real Estate
911                via call, email, and text for real estate services. To opt out, you can reply 'stop' at any time or reply 'help' for assistance.
912                You can also click the unsubscribe link in the emails. Message and data rates may apply. Message frequency may vary.
913                <a href='/terms-and-conditions' target='_blank'>Privacy Policy</a>.
914            </span>
915          </label>
916        
917        </div>
918        
919                <input type="hidden" name="source" value="CONTACT_INQUIRY">
920                <button class="contact-form__submit btn lp-btn lp-btn--filled button-style-1" type="submit">
921        
922                  <span class="sync-icon lp-i--spin">
923                    <svg width="20" height="15" viewBox="0 0 20 15" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
924                      <path d="M16.3636 3.66667L12.7273 7.33333H15.4545C15.4545 10.3675 13.0091 12.8333 10 12.8333C9.08182 12.8333 8.20909 12.6042 7.45455 12.1917L6.12727 13.53C7.24545 14.245 8.57273 14.6667 10 14.6667C14.0182 14.6667 17.2727 11.385 17.2727 7.33333H20L16.3636 3.66667ZM4.54545 7.33333C4.54545 4.29917 6.99091 1.83333 10 1.83333C10.9182 1.83333 11.7909 2.0625 12.5455 2.475L13.8727 1.13667C12.7545 0.421666 11.4273 0 10 0C5.98182 0 2.72727 3.28167 2.72727 7.33333H0L3.63636 11L7.27273 7.33333H4.54545Z" />
925                    </svg>
926                  </span>
927        
928                  <span class="success-icon">
929                    <svg width="20" height="20" viewBox="0 0 20 20" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
930                      <path d="M10 0C4.48 0 0 4.48 0 10C0 15.52 4.48 20 10 20C15.52 20 20 15.52 20 10C20 4.48 15.52 0 10 0ZM10 18C5.59 18 2 14.41 2 10C2 5.59 5.59 2 10 2C14.41 2 18 5.59 18 10C18 14.41 14.41 18 10 18ZM14.59 5.58L8 12.17L5.41 9.59L4 11L8 15L16 7L14.59 5.58Z" />
931                    </svg>
932                  </span>
933        
934                  Submit<span class="success-text">ted</span>
935                </button>
936              </form>
937              
938              <div class="contact-form__details">
939                <h5 class="lp-h5 contact-form__title2">Contact Details</h5>
940                <div class="company">
941                  <div class="company_contact lp-a">
942                    <p><strong>Trillion Real Estate</strong></p>
943        <p><a href="/cdn-cgi/l/email-protection#a1d5d8d2cecfe1d5d3c8cdcdc8cecfd3c4c0cdc4d2d5c0d5c48fc2cecc"><span class="__cf_email__" data-cfemail="b7c3cec4d8d9f7c3c5dedbdbded8d9c5d2d6dbd2c4c3d6c3d299d4d8da">[email&#160;protected]</span></a></p>
944        <p><br /><br /></p>
945        <p>27247 Madison Ave., #300<br />Temecula, CA 92590</p>
946                  </div>
947                </div>
948                
949                <div class="socials">
950                  <ul class="lp-socials social_icons-style-1 lp-socials socials--theme-1">
951                  
952                          <li>
953                            <a
954                              href="https://www.facebook.com/TrillionRE/"
955                              class="lp-socials__link lp-socials__link"
956                              data-wow-delay="0s"
957                              target="_blank"
958                              aria-label="FACEBOOK"
959                            >
960                                <span class="lp-i lp-i--facebook" aria-hidden="true"></span>
961                            </a>
962                          </li>
963                          <li>
964                            <a
965                              href="https://www.instagram.com/trillionrealestate/"
966                              class="lp-socials__link lp-socials__link"
967                              data-wow-delay="0.1s"
968                              target="_blank"
969                              aria-label="INSTAGRAM"
970                            >
971                                <span class="lp-i lp-i--instagram" aria-hidden="true"></span>
972                            </a>
973                          </li>
974                          <li>
975                            <a
976                              href="https://www.zillow.com/profile/tysonrobinson"
977                              class="lp-socials__link lp-socials__link"
978                              data-wow-delay="0.2s"
979                              target="_blank"
980                              aria-label="ZILLOW"
981                            >
982                                <span class="lp-i lp-i--zillow" aria-hidden="true"></span>
983                            </a>
984                          </li>
985                          <li>
986                            <a
987                              href="https://www.yelp.com/biz/tyson-robinson-temecula-real-estate-team-temecula?osq&#x3D;tyson+Trillion"
988                              class="lp-socials__link lp-socials__link"
989                              data-wow-delay="0.3s"
990                              target="_blank"
991                              aria-label="YELP"
992                            >
993                                <span class="lp-i lp-i--yelp" aria-hidden="true"></span>
994                            </a>
995                          </li>
996                    </ul>        </div>
997              </div>
998            </div>
999        </div>
1000        <!-- version 1 -->
1001            </div>
1002            <button class="close lp-close" type="button" aria-label="close modal">
1003                <span class="lp-close-icon" aria-hidden="true"></span>
1004            </button>
1005        </div>
1006        <div id="qualifying-questions-modal" tabindex="-1" role="dialog" aria-modal="true" aria-labelledby="qualifying-questions-modal-title" aria-hidden="true" style="position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.7); z-index: 1050; display: none; align-items: center; justify-content: center;">
1007          <style>
1008            #qualifying-questions-modal .custom-select-toggle {
1009              border: 1px solid #848484;
1010              border-radius: 8px;
1011              padding: 12px 16px;
1012            }
1013        
1014            #qualifying-questions-modal .custom-select-toggle.is-placeholder {
1015              color: #848484;
1016            }
1017        
1018            #qualifying-questions-modal #qualifying-questions-modal-phoneNumber::placeholder {
1019              color: #848484;
1020              opacity: 1;
1021            }
1022        
1023            #qualifying-questions-modal .disclaimer-more {
1024              display: none;
1025            }
1026        
1027            #qualifying-questions-modal #qualifying-questions-modal-disclaimer-text:not(.collapsed) .disclaimer-more {
1028              display: inline;
1029            }
1030        
1031            #qualifying-questions-modal #qualifying-questions-modal-disclaimer-text:not(.collapsed) .disclaimer-ellipsis {
1032              display: none;
1033            }
1034          </style>
vendor: 119 bytes, lines 1034-1035
1034
1035          <script data-cfasync="false" src="/cdn-cgi/scripts/5c5dd728/cloudflare-static/email-decode.min.js"></script>
1035<script>
1036            function toggleDisclaimerQualifyingQuestionsModal() {
1037              const disclaimerText = document.getElementById('qualifying-questions-modal-disclaimer-text');
1038              const toggleButton = document.getElementById('qualifying-questions-modal-toggle-disclaimer');
1039        
1040              if (disclaimerText.classList.contains('collapsed')) {
1041                disclaimerText.classList.remove('collapsed');
1042                toggleButton.textContent = 'Read less';
1043                toggleButton.setAttribute('aria-expanded', 'true');
1044              } else {
1045                disclaimerText.classList.add('collapsed');
1046                toggleButton.textContent = 'Read more';
1047                toggleButton.setAttribute('aria-expanded', 'false');
1048              }
1049            }
1050          </script>
1050
1051          <div style="max-width: 400px; width: 95%; margin: 0 auto;">
1052            <div style="background: #fff; border: none; border-radius: 16px; color: black; box-shadow: none; position: relative;">
1053              <button type="button" data-dismiss="modal" aria-label="Close" style="position: absolute; right: 20px; top: 10px; font-size: 28px; font-weight: 300; color: black; opacity: 1; background: none; border: none; padding: 0; width: auto; height: auto; cursor: pointer; z-index: 10;">
1054                <span aria-hidden="true">&times;</span>
1055              </button>
1056              <div style="padding: 40px 30px 32px;">
1057                <div style="text-align: left; margin-bottom: 32px;">
1058                  <h2 id="qualifying-questions-modal-title" style="margin: 0; color: #333; font-size: 18px; line-height: 1.4; text-transform: uppercase; letter-spacing: 0.5px; font-weight: normal;">
1059                    Thanks, please provide more information to help serve you
1060                  </h2>
1061                </div>
1062                <form id="qualifying-questions-modal-form" data-type="contact-form">
1063                  <input type="hidden" name="source" value="PROFILE_UPDATE" />
1064                  <input type="hidden" name="email" value="" id="qualifying-questions-modal-email" />
1065                  <input type="hidden" name="triggerSource" id="qualifying-questions-modal-triggerSource" value="" />
1066                  <label for="qualifying-questions-modal-email" style="display:none;">
1067                    Email
1068                  </label>
1069                  <label for="qualifying-questions-modal-triggerSource" style="display:none;">
1070                    Trigger Source
1071                  </label>
1072        
1073                  <div style="margin-bottom: 20px;">
1074                    <label for="qualifying-questions-modal-phoneNumber" style="display:none;">
1075                      Phone Number
1076                    </label>
1077                    <input
1078                      type="tel"
1079                      id="qualifying-questions-modal-phoneNumber"
1080                      name="phoneNumber"
1081                      style="padding: 12px 16px; font-size: 16px; border: 1px solid #848484; border-radius: 8px; background: transparent; color: black; width: 100%; box-sizing: border-box; outline: none;"
1082                      pattern="^\+?1?[-.\s]?\(?[0-9]{3}\)?[-.\s]?[0-9]{3}[-.\s]?[0-9]{4}$"
1083                      required
1084                      placeholder="Phone"
1085                      aria-label="Phone Number"
1086                      inputmode="tel"
1087                      autocomplete="tel"
1088                      onfocus="this.style.borderColor='black';"
1089                      onblur="this.style.borderColor='#848484';"
1090                    />
1091                  </div>
1092        
1093                  <div style="margin-bottom: 20px;">
1094                    <label for="qualifying-questions-modal-interest" style="display:none;">
1095                      Interest
1096                    </label>
1097                    <select
1098                      id="qualifying-questions-modal-interest"
1099                      name="interest"
1100                      required
1101                      data-label="Interest"
1102                      aria-label="Interest"
1103                      style="padding: 12px 16px; font-size: 16px; border: 1px solid #848484; border-radius: 8px; background: #fff; color: #848484; width: 100%; box-sizing: border-box; outline: none; appearance: none; -webkit-appearance: none; -moz-appearance: none; background-image: url('data:image/svg+xml;charset=utf8,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 16 16%22%3E%3Cpath fill=%22%23666%22 d=%22M4.427 7.427l3.396 3.396a.25.25 0 00.354 0l3.396-3.396A.25.25 0 0011.396 7H4.604a.25.25 0 00-.177.427z%22/%3E%3C/svg%3E'); background-repeat: no-repeat; background-position: right 16px center; background-size: 16px;"
1104                      onfocus="this.style.borderColor='black'; this.style.color='black';"
1105                      onblur="this.style.borderColor='#848484'; if(this.value === '') this.style.color='#848484'; else this.style.color='black';"
1106                    >
1107                      <option value="" style="background: #fff; color: #848484;" disabled selected>Interested in...</option>
1108                      <option value="Selling & Buying" style="background: #fff; color: black;">Selling & Buying</option>
1109                      <option value="Selling" style="background: #fff; color: black;">Selling</option>
1110                      <option value="Buying" style="background: #fff; color: black;">Buying</option>
1111                      <option value="Renting" style="background: #fff; color: black;">Renting</option>
1112                      <option value="Other" style="background: #fff; color: black;">Other</option>
1113                    </select>
1114                  </div>
1115        
1116                  <div style="margin-bottom: 32px; font-size: 12px; line-height: 1.2;">
1117                    <label style='display: none;' for='qualifying-questions-modal-qualifying-questions-termsAccepted'>Opt In/Disclaimer Consent:</label>
1118                    <label class='lp-tcr-content'>
1119                      <span class='lp-tcr-checkbox'>
1120                        <input
1121                          type='checkbox'
1122                          id='qualifying-questions-modal-qualifying-questions-termsAccepted'
1123                          name='termsAccepted'
1124                          aria-describedby='qualifying-questions-modal-disclaimer-text'
1125                          oninvalid="this.setCustomValidity('Please accept the terms and conditions')"
1126                          oninput="this.setCustomValidity('')"
1127                          required
1128                        /></span>
1129                      <span class='lp-tcr-message'>
1130                        <div id="qualifying-questions-modal-disclaimer-text" class="collapsed" style="color: #848484;">
1131                          
1132                            I agree to be contacted by
1133                            <strong>Trillion Real Estate</strong>
1134                            via call, email, and text <span class="disclaimer-more">for real estate services. 
1135                            To opt out, you can reply 'stop' at any time or reply 'help' for assistance. 
1136                            You can also click the unsubscribe link in the emails. 
1137                            Message and data rates may apply. Message frequency may vary.</span>
1138                            <span class="disclaimer-ellipsis">...</span>
1139                            <a href='/terms-and-conditions' target='_blank' rel='noopener noreferrer' style='text-decoration: underline;'>Privacy Policy</a>.
1140                        </div>
1141                        <button
1142                          id="qualifying-questions-modal-toggle-disclaimer"
1143                          type="button"
1144                          style="background: none; border: none; color: #848484; font-size: inherit; font-weight: bold; padding: 0; margin-top: 4px; cursor: pointer;"
1145                          aria-expanded="false"
1146                          onclick="toggleDisclaimerQualifyingQuestionsModal()"
1147                        >
1148                          Read more
1149                        </button>
1150                      </span>
1151                    </label>
1152                  </div>
1153        
1154                  <div>
1155                    <button
1156                      type="submit"
1157                      style="padding: 12px 24px; font-size: 16px; font-weight: normal; border-radius: 8px; border: 1px solid black; background: black; color: white; width: 100%; cursor: pointer; transition: all 0.2s ease; text-transform: uppercase; letter-spacing: 0.5px;"
1158                      onmouseover="this.style.background='transparent'; this.style.color='black';"
1159                      onmouseout="this.style.background='black'; this.style.color='white';"
1160                    >
1161                      Submit
1162                    </button>
1163                  </div>
1164                </form>
1165              </div>
1166            </div>
1167          </div>
1168        </div>
1169
1170    
1170<script>
1171        (function() {
1172        var lazyVideos = [].slice.call(document.querySelectorAll("video.lazy"));
1173
1174        if ("IntersectionObserver" in window && lazyVideos.length > 0) {
1175            var lazyVideoObserver = new IntersectionObserver(function(entries, observer) {
1176            entries.forEach(function(video) {
1177                if (video.isIntersecting) {
1178                for (var source in video.target.children) {
1179                    var videoSource = video.target.children[source];
1180                    if (typeof videoSource.tagName === "string" && videoSource.tagName === "SOURCE") {
1181                    videoSource.src = videoSource.dataset.src;
1182                    }
1183                }
1184
1185                video.target.load();
1186                video.target.classList.remove("lazy");
1187                lazyVideoObserver.unobserve(video.target);
1188                }
1189            });
1190            });
1191
1192            lazyVideos.forEach(function(lazyVideo) {
1193                lazyVideoObserver.observe(lazyVideo);
1194            });
1195        }
1196        })();
1197    </script>
1197
1198
1199        <!-- Global site tag (gtag.js) - Google Analytics -->
1200        
1200<script defer src="https://www.googletagmanager.com/gtag/js"></script>
1200
1201
1202            <!-- Google Tag Manager -->
1203            
1203<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
1204                new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
1205                j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.defer=true;j.async=false;j.src=
1206                'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
1207            })(window,document,'script','dataLayer','GTM-5P9WP78');</script>
1207
1208            <!-- End Google Tag Manager -->
1209            <!-- Google Tag Manager -->
1210            
1210<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
1211                new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
1212                j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.defer=true;j.async=false;j.src=
1213                'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
1214            })(window,document,'script','dataLayer','GTM-T9SFQGHZ');</script>
1214
1215            <!-- End Google Tag Manager -->
1216
1217
1218        <!-- LP Tracker (divolte.js) - LP Divolte -->
1219            
1219<script>window.divolteLp=window.divolteLp||function(){(divolteLp.q=divolteLp.q||[]).push(arguments)}</script>
1219
1220        <!-- LP Tracker (eventBus) - LP EventBus -->
1221            
1221<script>window.eventBusLp=window.eventBusLp||function(){(eventBusLp.q=eventBusLp.q||[]).push(arguments)}</script>
1221
1222
1223    
1223<script>
1224        window.dataLayer = window.dataLayer || [];
1225        document.sendGoogleTagManagerEvent = function() {
1226            /* Honor GPC-enabled browsers and prevent GTM event if GPC is enabled. More details: https://global-privacy-control.glitch.me/ */
1227            if (window.navigator.globalPrivacyControl) {
1228                return;
1229            }
1230
1231            dataLayer.push(arguments);
1232        }
1233
1234        document.sendGoogleTagManagerEvent('js', new Date());
1235        document.sendGoogleAnalyticsEvent = function(googleEvent) {
1236            document.sendGoogleTagManagerEvent('event', googleEvent.eventAction || googleEvent.hitType, {
1237                event_category: googleEvent.eventCategory,
1238                event_label: googleEvent.eventLabel,
1239                value: googleEvent.eventValue,
1240                page: googleEvent.page,
1241                location: googleEvent.location
1242            })
1243        };
1244
1245        document.addEventListener("DOMContentLoaded", function() {
1246            (function() {
1247                //If the page has an element with ID of auto-year-update the element will be populated with the current year.
1248                var date = new Date();
1249                var elements = document.getElementsByClassName('auto-year-update');
1250                var i;
1251                for (i = 0; i < elements.length; i++) {
1252                    elements[i].innerText = date.getFullYear();
1253                }
1254            })();
1255            if (window.divolteLp) {
1256                window.divolteLp('sendLpPageView', {});
1257            }
1258            if (window.eventBusLp) {
1259                window.eventBusLp('sendLpPageView', {});
1260            }
1261        });
1262    </script>
1262
1263
1264            <!-- Facebook Pixel Code -->
1265            
1265<script>
vendor: 575 bytes, lines 1265-1274
1265
1266                !function(f,b,e,v,n,t,s)
1267                {if(f.fbq)return;n=f.fbq=function(){n.callMethod?
1268                        n.callMethod.apply(n,arguments):n.queue.push(arguments)};
1269                    if(!f._fbq)f._fbq=n;n.push=n;n.loaded=!0;n.version='2.0';
1270                    n.queue=[];t=b.createElement(e);t.async=!0;
1271                    t.src=v;s=b.getElementsByTagName(e)[0];
1272                    s.parentNode.insertBefore(t,s)}(window, document,'script',
1273                        'https://connect.facebook.net/en_US/fbevents.js');
1274                fbq('init', '
1274762334809718416
vendor: 58 bytes, lines 1274-1276
1274');
1275                fbq('track', 'PageView');
1276            
1276</script>
1276
1277            <noscript><img height="1" width="1" style="display:none"
1278                           src="https://www.facebook.com/tr?id=762334809718416&ev=PageView&noscript=1"
1279                /></noscript>
1280            <!-- End Facebook Pixel Code -->
1281
1282    
1282<script>
1283    // Function to dynamically load a script
1284    function loadScript(url, callback) {
1285        var script = document.createElement('script');
1286        script.type = 'text/javascript';
1287        script.src = url;
1288        script.defer = true;
1289        script.async = true;
1290        script.onload = callback;
1291        document.head.appendChild(script);
1292    }
1293
1294    // Function to dynamically load CSS file
1295    function loadCSS(url) {
1296        var link = document.createElement("link");
1297        link.rel = "stylesheet";
1298        link.href = url;
1299        document.head.appendChild(link);
1300    }
1301
1302    // Global methods / variables that can be accessed by element js
1303    window.luxuryPresence = {
1304        libs: {
1305            loadJs: loadScript,
1306            loadCss: loadCSS,
1307            jsLibsMap: {
1308                paroller: {
1309                    jsSrc: 'https://d1e1jt2fj4r8r.cloudfront.net/javascript/jquery.paroller.min.js',
1310                    isLoaded: false,
1311                },
1312                ionRangeSlider: {
1313                    jsSrc: 'https://cdnjs.cloudflare.com/ajax/libs/ion-rangeslider/2.3.1/js/ion.rangeSlider.min.js',
1314                    cssSrc: 'https://cdnjs.cloudflare.com/ajax/libs/ion-rangeslider/2.3.1/css/ion.rangeSlider.min.css',
1315                    isLoaded: false,
1316                    requires: ['jquery'],
1317                },
1318                splide: {
1319                    jsSrc: 'https://cdnjs.cloudflare.com/ajax/libs/splidejs/4.1.4/js/splide.min.js',
1320                    cssSrc: 'https://cdnjs.cloudflare.com/ajax/libs/splidejs/4.1.4/css/splide-core.min.css',
1321                    isLoaded: false,
1322                },
1323                wow: {
1324                    jsSrc: 'https://cdnjs.cloudflare.com/ajax/libs/wow/1.1.2/wow.min.js',
1325                    isLoaded: false,
1326                },
1327                jquery: {
1328                    jsSrc: 'https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js',
1329                    isLoaded: false,
1330                },
1331                slick: {
1332                    jsSrc: 'https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.8.1/slick.min.js',
1333                    isLoaded: false,
1334                    requires: ['jquery'],
1335                },
1336                libphonenumber: {
1337                    jsSrc: 'https://cdnjs.cloudflare.com/ajax/libs/libphonenumber-js/1.11.8/libphonenumber-js.min.js',
1338                    isLoaded: false,
1339                },
1340            },
1341        },
1342    };
1343    </script>
1343
1344    
1344<script defer src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js" integrity="sha512-v2CJ7UaYy4JwqLDIrZUI/4hqeoQieOmAZNXBeQyjo21dadnwR+8ZaIJVT8EE2iyI61OV8e6M8PP2/4hpQINQ/g==" crossorigin="anonymous" referrerpolicy="no-referrer" onload="window.luxuryPresence.libs.jsLibsMap.jquery.isLoaded = true"></script>
1344
1345    
1345<script defer src="https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/4.7.8/handlebars.min.js"></script>
1345
1346    
1346<script defer src="https://cdn.jsdelivr.net/npm/[email protected]/dist/handlebars-intl.min.js"></script>
1346
1347    
1347<script defer src="https://cdnjs.cloudflare.com/ajax/libs/superagent/4.1.0/superagent.min.js"></script>
1347
1348    
1348<script defer src="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.8.1/slick.min.js" onload="window.luxuryPresence.libs.jsLibsMap.slick.isLoaded = true"></script>
1348
1349    
1349<script defer src="https://cdnjs.cloudflare.com/ajax/libs/wow/1.1.2/wow.min.js" onload="window.luxuryPresence.libs.jsLibsMap.wow.isLoaded = true"></script>
1349
1350    
1350<script defer src="https://cdnjs.cloudflare.com/ajax/libs/ion-rangeslider/2.3.1/js/ion.rangeSlider.min.js" onload="window.luxuryPresence.libs.jsLibsMap.ionRangeSlider.isLoaded = true"></script>
1350
1351
1352    <!-- GOOGLE TRANSLATE SCRIPT -->
1353    
1353<script>
1354        function googleTranslateElementInit() {
1355            // list of languages can be overridden by setting window.customLanguages in the head JS. example `window.customLanguages = 'en,de,fr,ro,sk,pl'`
1356            // Language codes can be taken from here https://cloud.google.com/translate/docs/languages
1357            const DEFAULT_LANGUAGES = 'en,es,zh-CN,zh-TW,tl,vi,ar,ko,ru,de,fr,hi,pt';
1358            document.querySelectorAll('[data-type="TRANSLATE"]').forEach(function(translate){
1359                translate.innerText = '';
1360                new google.translate.TranslateElement({
1361                    pageLanguage: 'en',
1362                    layout: google.translate.TranslateElement.InlineLayout.SIMPLE,
1363                    includedLanguages: window.customLanguages || DEFAULT_LANGUAGES,
1364                }, translate);
1365            });
1366        }
1367    </script>
1367
1368    
1368<script defer src="//translate.google.com/translate_a/element.js?cb=googleTranslateElementInit"></script>
1368
1369
1370    <!-- GOOGLE TRANSLATE SCRIPT END-->
1371    
1371<script>
1372
1373        // UI helpers
1374        (function () {
1375
1376            function getSideMenu () {
1377                return document.querySelector('body > div.sidemenu');
1378            }
1379
1380            function sideMenuHide (instant) {
1381                var sideMenu = getSideMenu();
1382                if (!sideMenu || !sideMenu.classList.contains('visible')) {
1383                  return;
1384                }
1385                sideMenu.classList.remove('visible');
1386                sideMenu.dispatchEvent(new CustomEvent('lpui-hide', { detail: { instant: !!instant } }));
1387                window.dispatchEvent(new CustomEvent('lpui-sidemenu-hide', { detail: {instant: !!instant} }));
1388            }
1389
1390            function sideMenuShow () {
1391                var sideMenu = getSideMenu();
1392                if (!sideMenu || sideMenu.classList.contains('visible')) {
1393                  return;
1394                }
1395                sideMenu.classList.add('visible');
1396                sideMenu.dispatchEvent(new Event('lpui-show'));
1397                window.dispatchEvent(new Event('lpui-sidemenu-show'));
1398            }
1399
1400            function sideMenuToggle () {
1401                var sideMenu = getSideMenu();
1402                if (!sideMenu) {
1403                  return;
1404                }
1405                var isSideMenuVisible = sideMenu.classList.contains('visible');
1406                if (isSideMenuVisible) {
1407                    sideMenuHide();
1408                } else {
1409                    sideMenuShow();
1410                }
1411            }
1412
1413            var scrollLockRequests = {};
1414            window.__debug_scrollLockRequests = scrollLockRequests;
1415            var hideScrollStyles = ''+
1416                    'body {'+
1417                    'overflow: hidden;' +
1418                    '}';
1419            var hideScrollId = 'hide-body-scroll-style';
1420
1421            function scrollLock () {
1422                var style = document.createElement('style');
1423                style.id = hideScrollId;
1424                style.textContent = hideScrollStyles;
1425                document.head.appendChild(style);
1426                window.dispatchEvent(new Event('lpui-scroll-locked'));
1427            }
1428
1429            function scrollUnlock () {
1430                document.getElementById(hideScrollId)?.remove();
1431                window.dispatchEvent(new Event('lpui-scroll-unlocked'));
1432            }
1433
1434            function requestScrollLock (lockId) {
1435                var wasLocked = Object.keys(scrollLockRequests).length > 0;
1436                scrollLockRequests[lockId || '__anonymous_lock'] = true;
1437                if (!wasLocked) {
1438                    scrollLock();
1439                }
1440            }
1441
1442            function releaseScrollLock (lockId) {
1443                if (lockId) {
1444                    delete scrollLockRequests[lockId];
1445                    if (!Object.keys(scrollLockRequests).length) {
1446                        scrollUnlock();
1447                    }
1448                } else {
1449                    scrollLockRequests = {};
1450                    window.__debug_scrollLockRequests = scrollLockRequests;
1451                    scrollUnlock();
1452                }
1453            }
1454
1455            function showModal (modalId, options) {
1456                var modal = document.getElementById(modalId);
1457                if (!modal) {
1458                    return;
1459                }
1460
1461                if (!modal.classList.contains('visible')) {
1462                    modal.classList.add('visible');
1463                    if (options && options.scrollLock) {
1464                        window.lpUI.requestScrollLock(modalId);
1465                    }
1466                    modal.dispatchEvent(new Event('lpui-show'));
1467                    window.dispatchEvent(new CustomEvent('lpui-modal-show', { detail: { id: modalId } }));
1468                }
1469
1470                const visibleModals = document.querySelectorAll('.modal.visible');
1471
1472                if (visibleModals.length > 1) {
1473
1474                    const maxZIndex = Array.from(visibleModals).reduce((maxZIndex, modal) => {
1475                        const zIndex = window.getComputedStyle(modal).zIndex;
1476                        const parsedZIndex = zIndex !== 'auto' ? parseInt(zIndex) : 0;
1477                        return Math.max(maxZIndex, parsedZIndex);
1478                    }, 0);
1479
1480                    modal.style.zIndex = maxZIndex + 1;
1481                }
1482
1483            }
1484
1485            function _hideModal (modalEl) {
1486                if (!modalEl) {
1487                    return;
1488                }
1489                if (!modalEl.classList.contains('visible')) {
1490                    return;
1491                }
1492                modalEl.classList.remove('visible');
1493                modalEl.style.zIndex = '';
1494                modalEl.dispatchEvent(new Event('lpui-hide'));
1495                var modalId = modalEl.getAttribute('id');
1496                if (modalId) {
1497                    window.lpUI.releaseScrollLock(modalId);
1498                    window.dispatchEvent(new CustomEvent('lpui-modal-hide', { detail: { id: modalId } }));
1499                }
1500            }
1501
1502            function hideModal (modalId) {
1503                _hideModal(document.getElementById(modalId));
1504            }
1505
1506            function hideClosestModal (el) {
1507              const modal = el?.closest('.modal');
1508              if (!modal) {
1509                return;
1510              }
1511              if (modal.classList) {
1512                _hideModal(modal);
1513                return;
1514              }
1515              if (modal.length && modal[0].classList) {
1516                _hideModal(modal[0]);
1517              }
1518            }
1519
1520            window.lpUI = {
1521                sideMenuHide: sideMenuHide,
1522                sideMenuShow: sideMenuShow,
1523                sideMenuToggle: sideMenuToggle,
1524                requestScrollLock: requestScrollLock,
1525                releaseScrollLock: releaseScrollLock,
1526                showModal: showModal,
1527                hideModal: hideModal,
1528                hideClosestModal: hideClosestModal
1529            }
1530        })();
1531
1532        var stringifyPrimitive = function(v) {
1533            switch (typeof v) {
1534                case 'string':
1535                    return v;
1536
1537                case 'boolean':
1538                    return v ? 'true' : 'false';
1539
1540                case 'number':
1541                    return isFinite(v) ? v : '';
1542
1543                default:
1544                    return '';
1545            }
1546        };
1547
1548        function objectToQuerystring(obj, sep, eq, name) {
1549            // https://github.com/Gozala/querystring/blob/master/encode.js
1550            sep = sep || '&';
1551            eq = eq || '=';
1552            if (obj === null) {
1553                obj = undefined;
1554            }
1555
1556            if (typeof obj === 'object') {
1557                return Object.keys(obj).map(function(k) {
1558                    var ks = encodeURIComponent(stringifyPrimitive(k)) + eq;
1559                    if (Array.isArray(obj[k])) {
1560                        return obj[k].map(function(v) {
1561                            return ks + encodeURIComponent(stringifyPrimitive(v));
1562                        }).join(sep);
1563                    } else {
1564                        return ks + encodeURIComponent(stringifyPrimitive(obj[k]));
1565                    }
1566                }).filter(Boolean).join(sep);
1567
1568            }
1569
1570            if (!name) return '';
1571            return encodeURIComponent(stringifyPrimitive(name)) + eq +
1572                    encodeURIComponent(stringifyPrimitive(obj));
1573        }
1574
1575        function getPath(url, options) {
1576            var parser = document.createElement('a');
1577            parser.href = url || '';
1578            var path = parser.pathname || '';
1579            if (path[0] !== '/') {
1580              // IE does not return path starting with a slash
1581              path = '/' + path;
1582            }
1583
1584            if (options && options.queryString) {
1585                path += parser.search;
1586            }
1587
1588            return path;
1589        }
1590
1591        function getMLSAutocomplete(keyword) {
1592            var searchURL = window.location.protocol + '//' + window.location.hostname + '/home-search/auto_complete';
1593            var query = {
1594                kind: 'listings',
1595                query: keyword
1596            };
1597
1598            return superagent
1599                .get(searchURL)
1600                .query(query)
1601                .then(function(res) {
1602                    var data = res.body || [];
1603                    /*
1604                        Of the format:
1605                          [{
1606                            "_index": "listing_auto_completes_production_20190723232720775",
1607                            "_type": "listing_auto_complete",
1608                            "_id": "235875624",
1609                            "_score": 0,
1610                            "status_modified_at": 1553250708,
1611                            "city": "Jupiter",
1612                            "price": 1335743,
1613                            "display_address": "10088 Calabrese Trail Unit: 9 Jupiter FL 33478",
1614                            "sold_price": null,
1615                            "id": 235875624,
1616                            "state": "FL",
1617                            "photo_urls": [
1618                              "http://cdn.photos.sparkplatform.com/fl/20190322153144208228000000-o.jpg"
1619                            ],
1620                            "status": "Pending"
1621                          }, ...]
1622                      */
1623
1624                    return data;
1625                });
1626        }
1627
1628        function getMLSAutocompleteWithFilters(keyword, filters = {}) {
1629            var searchURL = window.location.protocol + '//' + window.location.hostname + '/home-search/auto_complete';
1630
1631            return superagent
1632                .get(searchURL)
1633                .query({ kind: 'listings', query: keyword, ...filters })
1634                .then(function(res) {
1635                    /*
1636                        Of the format:
1637                          [{
1638                            "_index": "listing_auto_completes_production_20190723232720775",
1639                            "_type": "listing_auto_complete",
1640                            "_id": "235875624",
1641                            "_score": 0,
1642                            "status_modified_at": 1553250708,
1643                            "city": "Jupiter",
1644                            "price": 1335743,
1645                            "display_address": "10088 Calabrese Trail Unit: 9 Jupiter FL 33478",
1646                            "sold_price": null,
1647                            "id": 235875624,
1648                            "state": "FL",
1649                            "photo_urls": [
1650                              "http://cdn.photos.sparkplatform.com/fl/20190322153144208228000000-o.jpg"
1651                            ],
1652                            "status": "Pending"
1653                          }, ...]
1654                    */
1655                    return res.body || [];
1656                });
1657        }
1658
1659        function makeMlsLink(data) {
1660            // Code Dupe from utils/googlePlace
1661            // mapping of google data type to mls data type
1662            var mapping = {
1663                neighborhood: 'neighborhood',
1664                locality: 'place',
1665                administrative_area_level_2: 'county',
1666                administrative_area_level_1: 'state',
1667                postal_code: 'postalcode',
1668            };
1669
1670            function _filterTypes(types) {
1671                return types.filter(function(type) { return type !== 'political' });
1672            }
1673
1674            if (!data || !Object.keys(data).length) {
1675                return '/home-search/listings';
1676            }
1677
1678            var newData = {};
1679            _filterTypes(data.types).forEach(function(type) {
1680                if (mapping[type]) {
1681                    newData.search_type = mapping[type];
1682                }
1683            });
1684            newData.omnibox = data.formatted_address;
1685            data.address_components.forEach(function(component) {
1686                _filterTypes(component.types).forEach(function(type) {
1687                    if (mapping[type]) {
1688                        newData[mapping[type]] = component.long_name;
1689                    }
1690                });
1691            });
1692            var bounds = data.geometry.bounds;
1693            var convertedData = Object.assign(bounds, newData);
1694
1695            return '/home-search/listings?' + objectToQuerystring(convertedData);
1696        }
1697
1698        function debounce(func, wait) {
1699            let timeout;
1700            return function(...args) {
1701                const context = this;
1702                clearTimeout(timeout);
1703                timeout = setTimeout(() => func.apply(context, args), wait)
1704            }
1705        }
1706
1707        // Global methods / variables that can be accessed by element js
1708        window.luxuryPresence = {
1709            ...window.luxuryPresence,
1710            defaults: {
1711                companyId: '2c02232f-2988-4a2c-a284-887b44b8c4fc',
1712                apiGatewayUrl: '/api-gw',
1713                routerUrl: '/api-nv',
1714                gql: {"agents":"\n  query Agents (\n    $agentId: ID\n    $agentIds: [ID!]\n    $companyId: String\n    $network: Boolean\n    $networkId: String\n    $officeId: [ID!]\n    $excludeOfficeId: [ID!]\n    $offset: Int\n    $limit: Int\n    $sort: String\n    $sortDir: SortDirectionEnum\n    $search: String\n    $tags: [String]\n    $tagsMode: TagsModeEnum\n    $teamId: [ID!]\n    $developmentId: [ID!]\n    $prioritizeIds: Boolean\n  ) {\n    agents (\n      agentId: $agentId\n      agentIds: $agentIds\n      companyId: $companyId\n      network: $network\n      networkId: $networkId\n      officeId: $officeId\n      excludeOfficeId: $excludeOfficeId\n      offset: $offset\n      limit: $limit\n      sort: $sort\n      sortDir: $sortDir\n      search: $search\n      tags: $tags\n      tagsMode: $tagsMode\n      teamId: $teamId\n      developmentId: $developmentId\n      prioritizeIds: $prioritizeIds\n    ) {\n      id\n      firstName\n      lastName\n      avatar {\n        smallUrl\n        mediumUrl\n        largeUrl\n        height\n        width\n      }\n      position\n      bioLong\n      bioShort\n      seoTitle\n      seoDescription\n      slug\n      phoneNumber\n      phoneNumber2\n      license\n      email\n      leadAgent\n      greaterArea\n      tags\n    }\n    agentsCount(\n      agentIds: $agentIds\n      companyId: $companyId\n      network: $network\n      networkId: $networkId\n      officeId: $officeId\n      excludeOfficeId: $excludeOfficeId\n      search: $search\n      tags: $tags\n      tagsMode: $tagsMode\n      teamId: $teamId\n      developmentId: $developmentId\n      prioritizeIds: $prioritizeIds\n    ) {\n      count\n    }\n  }\n","properties":"\n  query Properties(\n    $agentIds: [ID!]\n    $teamIds: [ID!]\n    $neighborhoodIds: [ID!]\n    $officeIds: [ID!]\n    $propertyId: ID\n    $companyId: String\n    $networkId: String\n    $network: Boolean\n    $statusId: String\n    $propertyIds: [ID!]\n    $prioritizeIds: Boolean\n    $statusIds: [String!]\n    $excludeStatusId: [String!]\n    $neighborhoodId: String\n    $addressState: [String!]\n    $addressCity: [String!]\n    $relatedNeighborhoodPropertyId: String\n    $developmentId: String\n    $featuredListing: Boolean\n    $leaseProperty: Boolean\n    $search: String\n    $searchTermMode: SearchTermModeEnum\n    $globalProperty: Boolean\n    $archived: Boolean\n    $salesPriceGTE: Float\n    $salesPriceLTE: Float\n    $leasePriceGTE: Float\n    $leasePriceLTE: Float\n    $livingSpaceSizeGTE: Float\n    $livingSpaceSizeLTE: Float\n    $bathCountGTE: Float\n    $bathCountLTE: Float\n    $bedroomCountGTE: Float\n    $bedroomCountLTE: Float\n    $architectureStyle: String\n    $lifestyle: String\n    $propertyTypeId: String\n    $propertyTypeIds: [String!]\n    $spaceTypeIds: [ID!]\n    $tag: String\n    $backfillMLSResults: Boolean\n    $displayMLSListings: String\n    $hostname: String\n    $websiteId: ID\n    $backfillProviders: [String!]\n    $backfillMLSListingIds: [String!]\n    $backfillMLSAgentIds: [String!]\n    $backfillMLSOfficeIds: [String!]\n    $backfillBoundary: JSON\n    $openHouse: Boolean\n    $withGeo: Boolean\n    $advancedFilters: JSON\n    $seasonalPriceId: ID\n    $offset: Int\n    $limit: Int\n    $sort: String\n    $sortDir: SortDirectionEnum\n  ) {\n    properties(\n      \n      agentIds: $agentIds\n      teamIds: $teamIds\n      propertyId: $propertyId\n      propertyIds: $propertyIds\n      prioritizeIds: $prioritizeIds\n      companyId: $companyId\n      network: $network\n      networkId: $networkId\n      statusId: $statusId\n      statusIds: $statusIds\n      excludeStatusId: $excludeStatusId\n      neighborhoodId: $neighborhoodId\n      neighborhoodIds: $neighborhoodIds\n      officeIds: $officeIds\n      addressState: $addressState\n      addressCity: $addressCity\n      developmentId: $developmentId\n      featuredListing: $featuredListing\n      leaseProperty: $leaseProperty\n      search: $search\n      searchTermMode: $searchTermMode\n      salesPriceGTE: $salesPriceGTE\n      salesPriceLTE: $salesPriceLTE\n      leasePriceGTE: $leasePriceGTE\n      leasePriceLTE: $leasePriceLTE\n      livingSpaceSizeGTE: $livingSpaceSizeGTE\n      livingSpaceSizeLTE: $livingSpaceSizeLTE\n      bathCountGTE: $bathCountGTE\n      bathCountLTE: $bathCountLTE\n      bedroomCountGTE: $bedroomCountGTE\n      bedroomCountLTE: $bedroomCountLTE\n      architectureStyle: $architectureStyle\n      lifestyle: $lifestyle\n      propertyTypeId: $propertyTypeId\n      propertyTypeIds: $propertyTypeIds\n      spaceTypeIds: $spaceTypeIds\n      tag: $tag\n      archived: $archived\n      globalProperty: $globalProperty\n      withGeo: $withGeo\n      openHouse: $openHouse\n      displayMLSListings: $displayMLSListings\n      advancedFilters: $advancedFilters\n      seasonalPriceId: $seasonalPriceId\n\n      relatedNeighborhoodPropertyId: $relatedNeighborhoodPropertyId\n      backfillMLSResults: $backfillMLSResults\n      hostname: $hostname\n      websiteId: $websiteId\n      backfillProviders: $backfillProviders\n      backfillMLSListingIds: $backfillMLSListingIds\n      backfillMLSAgentIds: $backfillMLSAgentIds\n      backfillMLSOfficeIds: $backfillMLSOfficeIds\n      backfillBoundary: $backfillBoundary\n      offset: $offset\n      limit: $limit\n      sort: $sort,\n      sortDir: $sortDir\n    ){\n      id\n      name\n      status\n      originalStatus {\n        id\n        name\n      }\n      salesPrice\n      reducedPrice\n      isPasswordProtected\n      bedroomCount\n      bathCount\n      fullBathCount\n      halfBathCount\n      threeQuarterBathCount\n      fullAddress\n      addressLine1\n      addressLine2\n      addressCity\n      addressState\n      addressCountry\n      postalCode\n      description\n      syncedAt\n      officeName\n      attributionContact\n      neighborhood {\n        id\n      }\n      media {\n        smallUrl\n        mediumUrl\n        largeUrl\n        xLargeUrl\n        xxLargeUrl\n        height\n        width\n      }\n      seoTitle\n      seoDescription\n      slug\n      fromMLS\n      mlsId\n      mlsLogo\n      mlsAttribution\n      openHouse\n      openHouseHours\n      priceUponRequest\n      privateAddress\n      leaseProperty\n      leasePrice\n      currency\n      leaseTermFrequencyInterval\n      leaseTermFrequencyCount\n      leasePeriod\n      livingSpaceSize\n      livingSpaceUnits\n      lotAreaSize\n      lotAreaUnits\n      tags\n      latitude\n      longitude\n      soldDate\n      timeZone\n      buyerAgencyCompensation\n      buyerAgencyCompensationType\n      landIdUrl\
1714n    }\n    propertiesCount(\n    \n      agentIds: $agentIds\n      teamIds: $teamIds\n      propertyId: $propertyId\n      propertyIds: $propertyIds\n      prioritizeIds: $prioritizeIds\n      companyId: $companyId\n      network: $network\n      networkId: $networkId\n      statusId: $statusId\n      statusIds: $statusIds\n      excludeStatusId: $excludeStatusId\n      neighborhoodId: $neighborhoodId\n      neighborhoodIds: $neighborhoodIds\n      officeIds: $officeIds\n      addressState: $addressState\n      addressCity: $addressCity\n      developmentId: $developmentId\n      featuredListing: $featuredListing\n      leaseProperty: $leaseProperty\n      search: $search\n      searchTermMode: $searchTermMode\n      salesPriceGTE: $salesPriceGTE\n      salesPriceLTE: $salesPriceLTE\n      leasePriceGTE: $leasePriceGTE\n      leasePriceLTE: $leasePriceLTE\n      livingSpaceSizeGTE: $livingSpaceSizeGTE\n      livingSpaceSizeLTE: $livingSpaceSizeLTE\n      bathCountGTE: $bathCountGTE\n      bathCountLTE: $bathCountLTE\n      bedroomCountGTE: $bedroomCountGTE\n      bedroomCountLTE: $bedroomCountLTE\n      architectureStyle: $architectureStyle\n      lifestyle: $lifestyle\n      propertyTypeId: $propertyTypeId\n      propertyTypeIds: $propertyTypeIds\n      spaceTypeIds: $spaceTypeIds\n      tag: $tag\n      archived: $archived\n      globalProperty: $globalProperty\n      withGeo: $withGeo\n      openHouse: $openHouse\n      displayMLSListings: $displayMLSListings\n      advancedFilters: $advancedFilters\n      seasonalPriceId: $seasonalPriceId\n\n    ) {\n      count\n    }\n  }\n","pressReleases":"\n  query PressReleases (\n    $pressReleaseId: ID\n    $companyId: String\n    $offset: Int\n    $limit: Int\n    $sort: String\n    $sortDir: SortDirectionEnum\n    $search: String\n    $categories: [String!]\n    $propertyId: [String!]\n    $developmentId: [String!]\n    $agentId: [String!]\n    $teamId: [String!]\n  ) {\n    pressReleases (\n      pressReleaseId: $pressReleaseId\n      companyId: $companyId\n      offset: $offset\n      limit: $limit\n      sort: $sort\n      sortDir: $sortDir\n      search: $search\n      categories: $categories\n      propertyId: $propertyId\n      developmentId: $developmentId\n      agentId: $agentId\n      teamId: $teamId\n    ) {\n      id\n      title\n      description\n      author\n      externalUrl\n      media {\n        smallUrl\n        mediumUrl\n        largeUrl\n        xLargeUrl\n        xxLargeUrl\n        height\n        width\n      }\n      publishedAt\n      categories\n    }\n    pressReleasesCount(\n      companyId: $companyId\n      search: $search\n      categories: $categories\n      propertyId: $propertyId\n      developmentId: $developmentId\n      agentId: $agentId\n      teamId: $teamId\n    ) {\n      count\n    }\n  }\n","posts":"\n  query Posts (\n    $postId: ID\n    $companyId: String\n    $offset: Int\n    $limit: Int\n    $order: String\n    $sortDir: SortDirectionEnum\n    $search: String\n    $featured: Boolean\n    $categoryId: String\n    $categoryIds: [String!]\n    $neighborhoodId: [String!]\n    ) {\n    posts (\n      postId: $postId\n      companyId: $companyId\n      offset: $offset\n      limit: $limit\n      order: $order\n      sortDir: $sortDir\n      search: $search\n      featured: $featured\n      postStatusId: \"5f528253-abb7-484e-95c3-330269ac1102\"\n      categoryId: $categoryId\n      categoryIds: $categoryIds\n      neighborhoodId: $neighborhoodId\n    ) {\n      id\n      title\n      subtitle\n      description\n      status\n      featured\n      slug\n      categories {\n        id\n        name\n      }\n      createdAt\n      publishedAt\n      scheduledAt\n      createdBy {\n        firstName\n        lastName\n      }\n      customAuthor\n      media {\n        smallUrl\n        mediumUrl\n        largeUrl\n        xLargeUrl\n        xxLargeUrl\n        height\n        width\n      }\n      seoTitle\n      seoDescription\n      slug\n    }\n    postsCount(\n      companyId: $companyId\n      search: $search\n      featured: $featured\n      postStatusId: \"5f528253-
1714abb7-484e-95c3-330269ac1102\"\n      categoryId: $categoryId\n      categoryIds: $categoryIds\n      neighborhoodId: $neighborhoodId\n    ) {\n      count\n    }\n  }\n","testimonials":"\n  query Testimonials(\n    $testimonialId: ID\n    $agentId: ID\n    $teamId: ID\n    $companyId: String\n    $offset: Int\n    $limit: Int\n    $sort: String\n    $sortDir: SortDirectionEnum\n    $search: String\n  ) {\n    testimonials(\n      testimonialId: $testimonialId\n      agentId: $agentId\n      teamId: $teamId\n      companyId: $companyId\n      offset: $offset\n      limit: $limit\n      sort: $sort\n      sortDir: $sortDir\n      search: $search\n    ){\n      id\n      body\n      author\n      position\n      media {\n        smallUrl\n        mediumUrl\n        largeUrl\n        xLargeUrl\n        xxLargeUrl\n        height\n        width\n      }\n      seoTitle\n      seoDescription\n      agents {\n        slug\n        email\n        firstName\n        lastName\n        avatar {\n          smallUrl\n          height\n          width\n        }\n      }\n    }\n    testimonialsCount(\n      companyId: $companyId\n      agentId: $agentId\n      teamId: $teamId\n      search: $search\n    ) {\n      count\n    }\n  }\n","neighborhoods":"\n  query Neighborhoods (\n    $neighborhoodId: ID\n    $companyId: String\n    $search: String\n    $tag: String\n    $offset: Int\n    $limit: Int\n    $sort: String\n    $sortDir: SortDirectionEnum\n  ) {\n    neighborhoods (\n      neighborhoodId: $neighborhoodId\n      companyId: $companyId\n      search: $search\n      tag: $tag\n      offset: $offset\n      limit: $limit\n      sort: $sort\n      sortDir: $sortDir\n    ) {\n      id\n      name\n      description\n      descriptionShort\n      slug\n      tags\n      googlePlaceData\n      mlsLink\n      createdAt\n      media {\n        smallUrl\n        mediumUrl\n        largeUrl\n        xLargeUrl\n        xxLargeUrl\n        height\n        width\n      }\n      seoTitle\n      seoDescription\n    }\n    neighborhoodsCount(\n      companyId: $companyId\n      search: $search\n      tag: $tag\n    ) {\n      count\n    }\n  }\n","developments":"\n  query Developments (\n    $developmentId: ID\n    $companyId: String\n    $offset: Int\n    $limit: Int\n    $sort: String\n    $sortDir: SortDirectionEnum\n    $search: String\n    $tag: [String!]\n    $agentId: [ID!]\n    $neighborhoodId: ID\n    $neighborhoodIds: [ID!]\n  ) {\n    developments (\n      developmentId: $developmentId\n      companyId: $companyId\n      offset: $offset\n      limit: $limit\n      sort: $sort\n      sortDir: $sortDir\n      search: $search\n      tag: $tag\n      agentId: $agentId\n      neighborhoodId: $neighborhoodId\n      neighborhoodIds: $neighborhoodIds\n    ) {\n      id\n      name\n      description\n      descriptionShort\n      slug\n      createdAt\n      media {\n        smallUrl\n        mediumUrl\n        largeUrl\n        xLargeUrl\n        xxLargeUrl\n        height\n        width\n      }\n      googlePlaceData\n      seoTitle\n      seoDescription\n      tags\n    }\n    developmentsCount(\n      companyId: $companyId\n      search: $search\n      tag: $tag\n      agentId: $agentId\n      neighborhoodId: $neighborhoodId\n      neighborhoodIds: $neighborhoodIds\n    ) {\n      count\n    }\n  }\n","pois":"\nquery PointsOfInterest(\n  $regionId: String!,\n  $radius: Int,\n  $offset: Int,\n  $limit: Int,\n  $categories: [PoiCategoryEnum!],\n  $sortBy: PoiSortByEnum\n) {\n pois(\n     regionId: $regi
1714onId,\n     radius: $radius,\n     offset: $offset,\n     limit: $limit,\n     categories: $categories,\n     sortBy: $sortBy\n ) {\n  name\n  imageUrl\n  url\n  reviewCount\n  rating\n  price\n  displayPhone\n  distance\n  category\n  location {\n      address1\n      address2\n      address3\n      city\n      zipCode\n      country\n      state\n      }\n  }\n }\n","offices":"\n  query Offices (\n    $officeId: ID\n    $officeIds: [ID!]\n    $companyId: String\n    $slug: String\n    $sort: String\n    $sortDir: SortDirectionEnum\n    $search: String\n    $tags: [String]\n    $offset: Int\n    $limit: Int\n  ) {\n    offices (\n      officeId: $officeId\n      officeIds: $officeIds\n      companyId: $companyId\n      slug: $slug\n      sort: $sort\n      sortDir: $sortDir\n      search: $search\n      tags: $tags\n      offset: $offset\n      limit: $limit\n    ) {\n      id\n      companyId\n      name\n      slug\n      officeMlsId\n      shortDescription\n      fullDescription\n      addressLine1\n      addressLine2\n      addressCity\n      addressState\n      addressPostalCode\n      addressCountry\n      phone\n      email\n      officeHours\n      coordinates\n      googlePlaceData \n      seoTitle\n      seoDescription\n      fullAddress\n      media {\n        id\n        originalUrl\n        thumbnailUrl\n        smallUrl\n        mediumUrl\n        largeUrl\n        xLargeUrl\n        xxLargeUrl\n      }\n    }\n    officesCount(\n      companyId: $companyId\n      officeId: $officeId\n      officeIds: $officeIds\n      slug: $slug\n      search: $search\n      tags: $tags\n    ) {\n      count\n    }\n  }\n","teams":"query TeamsAndCount(\n  $offset: Int\n  $limit: Int\n  $search: String\n  $sort: String\n  $sortDir: SortDirectionEnum\n  $companyId: ID\n) {\n  teams(\n    offset: $offset\n    limit: $limit\n    sort: $sort\n    sortDir: $sortDir\n    search: $search\n    companyId: $companyId\n  ) {\n    \n  id\n  companyId\n  name\n  email\n  shortBio\n  fullBio\n  addressLine1\n  addressLine2\n  addressCity\n  addressState\n  addressCountry\n  phoneNumber1\n  phoneNumber2\n  postalCode\n  avatar {\n    id\n    thumbnailUrl\n    smallUrl\n    mediumUrl\n    largeUrl\n  }\n  urlWebsite\n  socialLinks\n  socialLinksArray\n  tags\n  seoTitle\n  seoDesc\n  slug\n  displayOrder\n\n  }\n  teamsCount(\n    search: $search\n    companyId: $companyId\n  ) {\n    count\n  }\n}"},
1715                propertyPlaceholderImage: {"id":"bb5bdaa1-db39-4d77-81d2-681e739efdf2","alt":null,"bytes":15291,"width":1500,"format":"png","height":500,"shared":true,"curated":false,"duration":null,"largeUrl":"https://media-production.lp-cdn.com/cdn-cgi/image/format=auto,quality=85/https://media-production.lp-cdn.com/media/mvhcuodaq6xmb56rdja9","smallUrl":"https://media-production.lp-cdn.com/cdn-cgi/image/format=auto,quality=85,fit=scale-down,width=960/https://media-production.lp-cdn.com/media/mvhcuodaq6xmb56rdja9","authorUrl":null,"createdAt":"2023-03-23T16:05:55.316Z","mediumUrl":"https://media-production.lp-cdn.com/cdn-cgi/image/format=auto,quality=85,fit=scale-down,width=1280/https://media-production.lp-cdn.com/media/mvhcuodaq6xmb56rdja9","sourceUrl":null,"updatedAt":"2023-03-23T16:05:55.316Z","xLargeUrl":"https://media-production.lp-cdn.com/cdn-cgi/image/format=auto,quality=85/https://media-production.lp-cdn.com/media/mvhcuodaq6xmb56rdja9","__typename":"Media","altTagText":null,"authorName":null,"sourceName":"r2","xxLargeUrl":"https://media-production.lp-cdn.com/cdn-cgi/image/format=auto,quality=85/https://media-production.lp-cdn.com/media/mvhcuodaq6xmb56rdja9","description":null,"displayName":"pink-pastel-gradient-twitter-header","originalUrl":"https://media-production.lp-cdn.com/cdn-cgi/image/format=auto,quality=85/https://media-production.lp-cdn.com/media/mvhcuodaq6xmb56rdja9","resourceType":"image","thumbnailUrl":"https://media-production.lp-cdn.com/cdn-cgi/image/format=auto,quality=85,fit=scale-down,width=320/https://media-production.lp-cdn.com/media/mvhcuodaq6xmb56rdja9","originalFileName":"Pink Pastel Gradient Twitter Header"}
1716            },
1717            objectToQuerystring: objectToQuerystring,
1718            getPath: getPath,
1719            getMLSAutocomplete: getMLSAutocomplete,
1720            getMLSAutocompleteWithFilters: getMLSAutocompleteWithFilters,
1721            makeMlsLink: makeMlsLink,
1722            debounce: debounce,
1723        };
1724
1725        var wowOffset = 100;
1726    </script>
1726
1727    
1727<script>
1728        (() => {
1729
1730function $parcel$interopDefault(a) {
1731  return a && a.__esModule ? a.default : a;
1732}
1733// Entry point for lp-sdk bundle
1734// This file exists to ensure Parcel v2 outputs the correct filename
1735/* global window */ var $53de3c160faf5a81$exports = {};
1736/*
1737WARNING!!! This file is used both on the server and in client's web-browser
1738please don't require/import any server-side related config/functions here
1739If we need something, let's pass it as a parameter of the factory
1740*/ var $0ce6edea77f7b81a$exports = {};
1741$0ce6edea77f7b81a$exports = {
1742    getVideoFirstFrame (videoUrl) {
1743        // The default Cloudinary asset delivery URL has the following structure: https://res.cloudinary.com/<cloud_name>/<asset_type>/<delivery_type>/<transformations>/<version>/<public_id>.<extension>
1744        //  https://cloudinary.com/documentation/video_manipulation_and_delivery#transformation_url_structure
1745        // The problem is that <transformations> and <version> are optional, and <transformations> can be chained separated by '/'
1746        // One more issue to be handled https://cloudinary.com/documentation/advanced_url_delivery_options#seo_friendly_media_asset_urls
1747        const CLOUDINARY_URL = 'https://res.cloudinary.com/';
1748        const invalid = !videoUrl || !videoUrl.startsWith(CLOUDINARY_URL);
1749        if (invalid) return null;
1750        const urlComponents = videoUrl.replace(CLOUDINARY_URL, '').replace('f_auto:video', 'f_auto').split('/');
1751        // checking if <asset_type> is not video or videos
1752        if (urlComponents[1].toLowerCase().indexOf('video') === -1) return null;
1753        // Filename is last urlComponent <public_id>.<extension>
1754        let filename = urlComponents[urlComponents.length - 1];
1755        if (filename.lastIndexOf('.') > -1) filename = `${filename.slice(0, filename.lastIndexOf('.'))}.jpg`;
1756        else filename += '.jpg';
1757        urlComponents[urlComponents.length - 1] = filename;
1758        // We need to add so_0,eo_0 transformation to the url to target the first frame.
1759        // we want to find the position at which we want to insert it as a chained transformation
1760        const firstFrameTransformation = 'so_0,eo_0';
1761        let firstFrameTransformationPosition = 3;
1762        // checking cases for SEO-friendly URLs
1763        if (urlComponents[1].toLowerCase() === 'videos' && urlComponents[2] !== '') firstFrameTransformationPosition = 2;
1764        // checking the last transformation position in the url
1765        // https://cloudinary.com/documentation/transformation_reference
1766        // https://regex101.com/r/lE3W6u/1
1767        const transformationRegex = /^(?:[a-z]{1,3}|\$\w+)_\S+$/;
1768        while(firstFrameTransformationPosition < urlComponents.length - 1 && transformationRegex.test(urlComponents[firstFrameTransformationPosition]))firstFrameTransformationPosition++;
1769        urlComponents.splice(firstFrameTransformationPosition, 0, firstFrameTransformation);
1770        return CLOUDINARY_URL + urlComponents.join('/');
1771    }
1772};
1773
1774
1775/**
1776 * Create helpers with given Handlebars instance
1777 *
1778 * @param {Object} HandlebarsInstance
1779 * @param {Function} isEqual - we use different implementation if isEqual on server and on client
1780 * @return {Object}
1781 */ function $53de3c160faf5a81$var$handlebarsHelpersFactory(HandlebarsInstance, { isEqual: isEqual }) {
1782    // notice!: code below assumes list is ordered lowest to highest width
1783    const MEDIA_SIZES = [
1784        {
1785            field: 'thumbnailUrl',
1786            w: 320
1787        },
1788        {
1789            field: 'smallUrl',
1790            w: 960
1791        },
1792        {
1793            field: 'mediumUrl',
1794            w: 1280
1795        },
1796        {
1797            field: 'largeUrl',
1798            w: 1920
1799        },
1800        {
1801            field: 'xLargeUrl',
1802            w: 2560
1803        },
1804        {
1805            field: 'xxLargeUrl',
1806            w: 3456
1807        }
1808    ];
1809    const MEDIA_SIZE_FOR_SRC = 1280;
1810    const lpFormatNumber = function(number, unit, precision) {
1811        const localization = 'en-US';
1812        if (!number) return '';
1813        if (typeof number === 'string') {
1814            const trimmed = number.trim();
1815            if (/[^+\-0-9.]/.test(trimmed)) return number; // returning text 'as is' assuming it already has all formatting
1816            // eslint-disable-next-line
1817            number = parseFloat(trimmed);
1818            if (!number) return '';
1819        }
1820        const currencyPrecision = typeof precision === 'number' ? precision : 0;
1821        const currencyFractionDigits = Number.isInteger(number) ? 0 : currencyPrecision;
1822        const currencyFractionOptions = {
1823            minimumFractionDigits: currencyFractionDigits,
1824            maximumFractionDigits: currencyFractionDigits
1825        };
1826        if (unit === 'USD') return `$${number.toLocaleString(localization, currencyFractionOptions)}`;
1827        if (unit === 'CAD') return `$${number.toLocaleString(localization, currencyFractionOptions)} CAD`;
1828        if (unit === 'EUR') return `\u{20AC}${number.toLocaleString(localization, currencyFractionOptions)}`;
1829        if (unit === 'GBP') return `\xa3${number.toLocaleString(localization, currencyFractionOptions)}`;
1830        if (unit === 'PERCENT') return `${number}%`;
1831        if (typeof precision === 'number' && precision > -1) return number.toLocaleString(localization, {
1832            maximumFractionDigits: precision
1833        });
1834        return number.toLocaleString(localization);
1835    };
1836    const formatFrequency = function(freqUnit) {
1837        switch(freqUnit){
1838            case 'DAY':
1839                return 'daily';
1840            case 'MONTH':
1841                return 'monthly';
1842            case 'WEEK':
1843                return 'weekly';
1844            case 'YEAR':
1845                return 'yearly';
1846            case 'QUARTER':
1847                return 'quarterly';
1848            case 'HALF_YEAR':
1849                return 'semi-annually';
1850            case 'NIGHTLY':
1851                return 'nightly';
1852            case 'SEASONAL':
1853                return 'seasonally';
1854            default:
1855                return '';
1856        }
1857    };
1858    const formatFrequencyShort = function(freqUnit) {
1859        switch(freqUnit){
1860            case 'DAY':
1861                return 'day';
1862            case 'WEEK':
1863                return 'wk';
1864            case 'MONTH':
1865                return 'mo';
1866            case 'YEAR':
1867                return 'yr';
1868            case 'QUARTER':
1869                return '3 mos';
1870            case 'HALF_YEAR':
1871                return '6 mos';
1872            case 'NIGHTLY':
1873                return 'night';
1874            case 'SEASONAL':
1875                return 'season';
1876            default:
1877                return '';
1878        }
1879    };
1880    const formatFrequencyStd = function(freqUnit) {
1881        switch(freqUnit){
1882            case 'DAY':
1883                return 'day';
1884            case 'WEEK':
1885                return 'week';
1886            case 'MONTH':
1887                return 'month';
1888            case 'YEAR':
1889                return 'year';
1890            case 'QUARTER':
1891                return 'quarter';
1892            case 'HALF_YEAR':
1893                return '6 months';
1894            case 'NIGHTLY':
1895                return 'night';
1896            case 'SEASONAL':
1897                return 'season';
1898            default:
1899                return '';
1900        }
1901    };
1902    const formatFrequencyExt = function(unit, options) {
1903        let val;
1904        let separator;
1905        const opts = options || {};
1906        switch(opts.mode){
1907            case 'short':
1908                val = formatFrequencyShort(unit);
1909                separator = opts.frequencySeparator || '/';
1910                break;
1911            case 'standard':
1912            case 'std':
1913                val = formatFrequencyStd(unit);
1914                separator = opts.frequencySeparator || '/';
1915                break;
1916            case 'long':
1917            default:
1918                val = formatFrequency(unit);
1919                separator = opts.frequencySeparator || ' ';
1920        }
1921        if (!val) return '';
1922        if (!opts.frequencyTag && !opts.frequencyClass) return separator + val;
1923        return `${separator}<${opts.frequencyTag || 'span'}${opts.frequencyClass ? ` class="${opts.frequencyClass}"` : ''}>${val}</${opts.frequencyTag || 'span'}>`;
1924    };
1925    return {
1926        isEmpty (arg1, options) {
1927            const result = !arg1 || (typeof arg1 === 'string' ? !arg1.trim() : false) || !Object.keys(arg1).length;
1928            if (options.fn) return result ? options.fn(this) : options.inverse(this);
1929            return result;
1930        },
1931        ifEquals (arg1, arg2, options) {
1932            return isEqual(arg1, arg2) ? options.fn(this) : options.inverse(this);
1933        },
1934        'raw-helper': function(options) {
1935            return options.fn();
1936        },
1937        striptags (txt) {
1938            if (!txt) return '';
1939            // Remove HTML Comments (escaping something to not make real html comment by expression)
1940            // eslint-disable-next-line no-useless-escape,no-param-reassign
1941            txt = txt.replace(/<\!--(.|[\r\n])*?-\->/g, '');
1942            // Remove XML fragments and <style> and <svg> tags with content
1943            // eslint-disable-next-line
1944            txt = txt.replace(/<(xml|style|svg)("[^"]*"|'[^']*'|[^>])*>(.|[\r\n])*?<\/\1>/gi, '');
1945            // Replace &nbsp; with space
1946            // eslint-disable-next-line no-param-reassign
1947            txt = txt.replace(/&nbsp;/g, ' ');
1948            // Remove HTML Tags
1949            const regexp = /<\/?("[^"]*"|'[^']*'|[^>])*(>|$)/g;
1950            return txt.replace(regexp, '');
1951        },
1952        striptagsLineBreaks (txt) {
1953            if (!txt) return '';
1954            // Remove HTML Comments (escaping something to not make real html comment by expression)
1955            // eslint-disable-next-line no-useless-escape,no-param-reassign
1956            txt = txt.replace(/<\!--(.|[\r\n])*?-\->/g, '');
1957            // Remove XML fragments and <style> and <svg> tags with content
1958            // eslint-disable-next-line no-param-reassign
1959            txt = txt.replace(/<(xml|style|svg)("[^"]*"|'[^']*'|[^>])*>(.|[\r\n])*?<\/\1>/gi, '');
1960            // Replace <br> and </p> tags with line break char, skipping last </p> which is not followed by <br> or </p>
1961            // eslint-disable-next-line no-param-reassign
1962            txt = txt.replace(/(<br\s*\/?>)|(<\/p\s*>)(?=.*(<\/p\s*>|<br\s*\/?>))/g, '&#10;');
1963            // Replace &nbsp; with space
1964            // eslint-disable-next-line no-param-reassign
1965            txt = txt.replace(/&nbsp;/g, ' ');
1966            // Remove HTML Tags
1967            const regexp = /<\/?("[^"]*"|'[^']*'|[^>])*(>|$)/g;
1968            return txt.replace(regexp, '');
1969        },
1970        truncate (text, limit, suffix) {
1971            if (!text) return '';
1972            if (text.length > limit) return typeof suffix === 'string' ? text.slice(0, limit - suffix.length) + suffix : text.slice(0, limit);
1973            return text;
1974        },
1975        // eslint-disable-next-line
1976        setSubArray (items = [], start, end, subArrayName, options) {
1977            // eslint-disable-next-line
1978            options.data.root[subArrayName] = items.slice(start, end);
1979        },
1980        formatAreaUnit (areaUnit) {
1981            switch(areaUnit){
1982                case 'ACRE':
1983                    return 'Acres';
1984                case 'SQUARE_METER':
1985                    return 'Sq.M.';
1986                case 'SQUARE_YARD':
1987                    return 'Sq.Yd.';
1988                default:
1989                    return 'Sq.Ft.';
1990            }
1991        },
1992        formatFrequency: formatFrequency,
1993        formatFrequencyShort: formatFrequencyShort,
1994        lpFormatFrequency (freqUnit, options) {
1995            return formatFrequencyExt(freqUnit, options && options.hash);
1996        },
1997        subArray (index, start, end, options) {
1998            return index >= start && index < end ? options.fn(this) : options.inverse(this);
1999        },
2000        formatPropertyStatus (status, showSoldDate, date) {
2001            let formattedStatus = '';
2002            switch(status){
2003                case 'SOLD':
2004                    formattedStatus = 'Sold';
2005                    break;
2006                case 'FOR_SALE':
2007                    formattedStatus = 'For Sale';
2008                    break;
2009                case 'COMING_SOON':
2010                    formattedStatus = 'Coming Soon';
2011                    break;
2012                case 'INACTIVE':
2013                    formattedStatus = 'Inactive';
2014                    break;
2015                case 'POCKET_LISTING':
2016                    formattedStatus = 'Pocket Listing';
2017                    break;
2018                case 'PENDING':
2019                    formattedStatus = 'Pending';
2020                    break;
2021                case 'UNDER_CONTRACT':
2022                    formattedStatus = 'Under Contract';
2023                    break;
2024                case 'ACTIVE_UNDER_CONTRACT':
2025                    formattedStatus = 'Active Under Contract';
2026                    break;
2027                default:
2028                    formattedStatus = status;
2029            }
2030            // `typeof date === 'string'` matters: when called as
2031            // `{{formatPropertyStatus status}}` Handlebars passes its options object
2032            // as `showSoldDate`/`date`, and this guard keeps the legacy output.
2033            if ((formattedStatus === 'Sold' || formattedStatus === 'Leased') && showSoldDate && typeof date === 'string' && date) formattedStatus += ` on ${date}`;
2034            return formattedStatus;
2035        },
2036        formatGrade (gradeValue) {
2037            switch(gradeValue){
2038                case 'UNDERGRADUATE_COURSES':
2039                    return 'Undergrad';
2040                case 'PRE_KINDERGARTEN':
2041                    return 'PreK';
2042                case 'KINDERGARTEN':
2043                    return 'K';
2044                case 'FIRST_GRADE':
2045                    return '1st';
2046                case 'SECOND_GRADE':
2047                    return '2nd';
2048                case 'THIRD_GRADE':
2049                    return '3rd';
2050                case 'FOURTH_GRADE':
2051                    return '4th';
2052                case 'FIFTH_GRADE':
2053                    return '5th';
2054                case 'SIXTH_GRADE':
2055                    return '6th';
2056                case 'SEVENTH_GRADE':
2057                    return '7th';
2058                case 'EIGHTH_GRADE':
2059                    return '8th';
2060                case 'NINTH_GRADE':
2061                    return '9th';
2062                case 'TENTH_GRADE':
2063                    return '10th';
2064                case 'ELEVENTH_GRADE':
2065                    return '11th';
2066                case 'TWELFTH_GRADE':
2067                    return '12th';
2068                default:
2069                    return '';
2070            }
2071        },
2072        encodeURI (uri) {
2073            return encodeURI(uri);
2074        },
2075        encodeURIComponent (txt) {
2076            return encodeURIComponent(txt);
2077        },
2078        hbFormatDate (date, type) {
2079            if (!date) return '';
2080            const newDate = date === 'current' ? new Date() : new Date(date);
2081            if (Number.isNaN(newDate.getTime())) return '';
2082            const months = [
2083                'January',
2084                'February',
2085                'March',
2086                'April',
2087                'May',
2088                'June',
2089                'July',
2090                'August',
2091                'September',
2092                'October',
2093                'November',
2094                'December'
2095            ];
2096            if (type === 'YYYY' || type === 'year') return `${newDate.getFullYear()}`;
2097            if (type === 'MM/DD/YY') {
2098                let month = newDate.getMonth() + 1;
2099                if (month < 10) month = `0${month.toString()}`;
2100                return `${month}/${newDate.getDate()}/${newDate.getFullYear().toString().substr(-2)}`;
2101            }
2102            return `${months[newDate.getMonth()]} ${newDate.getDate()}, ${newDate.getFullYear()}`;
2103        },
2104        openHousesFormat (startDate, endDate, timeZone) {
2105            if (!startDate || !endDate) return '';
2106            /**
2107       * return formatted time.
2108       * @param {date} date
2109       * @return {time} time.
2110       */ const getTime = (date)=>{
2111                let hours = date.getHours();
2112                if (hours > 12) hours -= 12;
2113                const prefix = '0';
2114                let time = `${hours}:${date.getMinutes() > 9 ? date.getMinutes() : prefix + date.getMinutes()}`;
2115                if (date.getHours() > 11) time += 'PM';
2116                else time += 'AM';
2117                return time;
2118            };
2119            let tz = '';
2120            let startFDate = startDate;
2121            let endFDate = endDate;
2122            if (timeZone) {
2123                startFDate = new Date(startDate).toLocaleString('en-US', {
2124                    timeZone: timeZone
2125                });
2126                endFDate = new Date(endDate).toLocaleString('en-US', {
2127                    timeZone: timeZone
2128                });
2129                [, , , tz] = new Date(endDate).toLocaleString('en-US', {
2130                    timeZone: timeZone,
2131                    timeZoneName: 'short'
2132                }).split(' ');
2133            }
2134            const date = new Date(startFDate);
2135            const openHouseDate = date.toLocaleDateString('en-US');
2136            const time1 = getTime(date);
2137            const date2 = new Date(endFDate);
2138            const time2 = getTime(date2);
2139            return `${openHouseDate} ${time1} - ${time2} ${tz}`;
2140        },
2141        math (lvalue, operator, rvalue) {
2142            // eslint-disable-next-line
2143            lvalue = parseFloat(lvalue);
2144            // eslint-disable-next-line
2145            rvalue = parseFloat(rvalue);
2146            return ({
2147                '+': lvalue + rvalue,
2148                '-': lvalue - rvalue,
2149                '*': lvalue * rvalue,
2150                '/': lvalue / rvalue,
2151                '%': lvalue % rvalue
2152            })[operator];
2153        },
2154        findByKey (values, key, value, options) {
2155            const result = (values || []).find((entry)=>entry[key] === value);
2156            return options.fn(result);
2157        },
2158        capitalize (string, split, options) {
2159            let capitalized;
2160            if (typeof string === 'string' && string.length) capitalized = string.toLowerCase().split(split).map((w)=>w.charAt(0).toUpperCase() + w.slice(1)).join(' ').toString();
2161            return capitalized;
2162        },
2163        and (...arg) {
2164            return Array.prototype.slice.call(arg).every(Boolean);
2165        },
2166        or (...arg) {
2167            return Array.prototype.slice.call(arg, 0, -1).some(Boolean);
2168        },
2169        not (arg) {
2170            return !arg;
2171        },
2172        orderByIds (items, orderedIds, options) {
2173            let ret = '';
2174            let data = null;
2175            if (options.data) data = HandlebarsInstance.createFrame(options.data);
2176            // When passed orderedIds, filter out empty items including empty strings and
2177            // only show items (and in that order) in a loop
2178            //  If no orderedIds provided, show all items
2179            const filteredIds = (orderedIds || []).filter(Boolean);
2180            if (filteredIds && filteredIds.length) {
2181                let skippedItems = 0;
2182                ret = filteredIds.reduce((res, id, idx)=>{
2183                    const item = (items || []).find((item)=>item.id === id);
2184                    // ID doesn't exist so ditch it
2185                    if (!item) {
2186                        skippedItems += 1;
2187                        return res;
2188                    }
2189                    if (data) data.index = idx - skippedItems;
2190                    return res + options.fn(item, {
2191                        data: data
2192                    });
2193                }, '');
2194            } else for(let i = 0, j = (items || []).length; i < j; i++){
2195                if (data) data.index = i;
2196                ret += options.fn(items[i], {
2197                    data: data
2198                });
2199            }
2200            return ret;
2201        },
2202        ifIn (elem, list, options) {
2203            if (list && list.indexOf(elem) > -1) return options.fn(this);
2204            return options.inverse(this);
2205        },
2206        partial (name, options) {
2207            // Register a partial and output the content in a script for clientside rendering
2208            HandlebarsInstance.registerPartial(name, HandlebarsInstance.compile(options.fn()));
2209            // eslint-disable-next-line
2210            const script = `
2210<script type="text/x-handlebars-template" class="${name} pagination-script">${options.fn()}</${'script'}>`;
2211            return script;
2212        },
2213        numCompare (l, r, operator, options) {
2214            const operators = {
2215                '==': function(l, r) {
2216                    // eslint-disable-next-line
2217                    return l == r;
2218                },
2219                '===': function(l, r) {
2220                    return l === r;
2221                },
2222                '!=': function(l, r) {
2223                    // eslint-disable-next-line
2224                    return l != r;
2225                },
2226                '<': function(l, r) {
2227                    return l < r;
2228                },
2229                '>': function(l, r) {
2230                    return l > r;
2231                },
2232                '<=': function(l, r) {
2233                    return l <= r;
2234                },
2235                '>=': function(l, r) {
2236                    return l >= r;
2237                }
2238            };
2239            const result = operators[operator](l, r);
2240            if (result) return options.fn ? options.fn(this) : true;
2241            return options.fn ? options.inverse(this) : false;
2242        },
2243        lpFormatNumber: lpFormatNumber,
2244        arrayToHtmlList (arr, options) {
2245            // eslint-disable-next-line
2246            return arr.reduce((acc, current)=>{
2247                try {
2248                    if (typeof current === 'object' || current === null) return acc;
2249                    // eslint-disable-next-line
2250                    return acc += `<li>${current}</li>`;
2251                } catch (e) {
2252                /* empty */ }
2253            }, '');
2254        },
2255        join (array, separator, options) {
2256            if (!array || !array.join) return '';
2257            return array.join(typeof separator === 'string' ? separator : ', ');
2258        },
2259        dedupe (items, key, options) {
2260            let data = null;
2261            let skippedItems = 0;
2262            const list = new Set();
2263            if (options.data) data = HandlebarsInstance.createFrame(options.data);
2264            return (items || []).reduce((res, item, idx)=>{
2265                const val = key ? item[key] : item;
2266                // Item is unique if we're passed a key that is not defined
2267                const isUnique = !list.has(val) || key && val === undefined;
2268                if (isUnique) list.add(val);
2269                else {
2270                    skippedItems += 1;
2271                    return res;
2272                }
2273                if (data) data.index = idx - skippedItems;
2274                return res + options.fn(item, {
2275                    data: data
2276                });
2277            }, '');
2278        },
2279        JSONstringify (obj, options) {
2280            return JSON.stringify(obj);
2281        },
2282        // eslint-disable-next-line sonarjs/cognitive-complexity
2283        formatPropertyPrice (...args) {
2284            const options = args[args.length - 1];
2285            const opts = options.hash;
2286            const property = args.length > 1 ? args[0] : opts.property;
2287            const precision = opts.precision || 0;
2288            if (args.length > 2) // eslint-disable-next-line
2289            opts.mode = args[1];
2290            if (!opts.mode) opts.mode = 'short';
2291            let separator = args.length > 3 ? args[2] : opts.separator;
2292            if (typeof separator !== 'string') separator = ' | ';
2293            if (property.isPasswordProtected) return 'Exclusive Listing';
2294            let priceUponRequestText = args.length > 4 ? args[3] : opts.priceUponRequestText;
2295            if (typeof priceUponRequestText !== 'string') priceUponRequestText = 'Price Upon Request';
2296            if (property.priceUponRequest) return priceUponRequestText;
2297            let price = property.salesPrice;
2298            let reduced = null;
2299            // eslint-disable-next-line sonarjs/no-collapsible-if
2300            if (property.status !== 'SOLD' && property.status !== 'Leased') {
2301                if (property.reducedPrice) {
2302                    if (!opts.reducedClass) price = property.reducedPrice;
2303                    else reduced = property.reducedPrice;
2304                }
2305            }
2306            let result = '';
2307            if (reduced) result += `<${opts.reducedTag || 'span'} class="${opts.reducedClass}">${lpFormatNumber(reduced, property.currency, precision)}</${opts.reducedTag || 'span'}>`;
2308            if (price) {
2309                price = lpFormatNumber(price, property.currency, precision);
2310                if (opts.priceTag || opts.priceClass) result += `<${opts.priceTag || 'span'}${opts.priceClass ? ` class="${opts.priceClass}"` : ''}>${price}</${opts.priceTag || 'span'}>`;
2311                else result += price;
2312            }
2313            const leasePrice = property.leasePrice && lpFormatNumber(property.leasePrice, property.currency, precision);
2314            if (leasePrice) {
2315                if (result) result += separator;
2316                const leaseText = `${leasePrice}${formatFrequencyExt(property.leasePeriod, opts)}`;
2317                if (opts.leaseTag || opts.leaseClass) result += `<${opts.leaseTag || 'span'}${opts.leaseClass ? ` class="${opts.leaseClass}"` : ''}>${leaseText}</${opts.leaseTag || 'span'}>`;
2318                else result += leaseText;
2319            }
2320            return new HandlebarsInstance.SafeString(result);
2321        },
2322        // eslint-disable-next-line sonarjs/cognitive-complexity
2323        mediaImage (mediaSource, options = {}) {
2324            if (!mediaSource) return;
2325            const { lazy: lazy, ...attributes } = options.hash;
2326            let src = '';
2327            let srcset = '';
2328            if (typeof mediaSource === 'string') src = mediaSource;
2329            else {
2330                const srcMap = {};
2331                const { height: height, width: width, altTagText: altTagText } = mediaSource;
2332                MEDIA_SIZES.forEach((src)=>{
2333                    if (mediaSource[src.field] && !srcMap[mediaSource[src.field]]) srcMap[mediaSource[src.field]] = src.w;
2334                });
2335                const srcs = Object.keys(srcMap);
2336                if (!srcs.length) return;
2337                if (altTagText) attributes.alt = altTagText;
2338                if (height && width) {
2339                    if (height >= width) {
2340                        if (attributes.class) attributes.class += ' portrait';
2341                        else attributes.class = 'portrait';
2342                    }
2343                    if ('setDims' in options.hash) {
2344                        attributes.width = width;
2345                        attributes.height = height;
2346                    }
2347                }
2348                if (srcs.length > 1 && width && width < srcMap[srcs[srcs.length - 1]]) {
2349                    const maxSrc = srcs.findIndex((src)=>
2349srcMap[src] >= width);
2350                    srcs.splice(maxSrc + 1);
2351                    srcMap[srcs[srcs.length - 1]] = width;
2352                }
2353                if (srcs.length > 1) {
2354                    srcset = srcs.map((s)=>`${s} ${srcMap[s]}w`).join(', ');
2355                    srcs.sort((a, b)=>Math.abs(srcMap[a] - MEDIA_SIZE_FOR_SRC) - Math.abs(srcMap[b] - MEDIA_SIZE_FOR_SRC));
2356                }
2357                // eslint-disable-next-line
2358                src = srcs[0];
2359            }
2360            delete attributes.setDims;
2361            if (!srcset) delete attributes.sizes;
2362            if (!('alt' in attributes)) attributes.alt = '';
2363            if (!('loading' in attributes) && (options?.data?.root?.sectionIndex > 1 || lazy)) attributes.loading = 'lazy';
2364            const attrs = Object.keys(attributes).map((k)=>`${HandlebarsInstance.escapeExpression(k)}="${HandlebarsInstance.escapeExpression(attributes[k])}"`).join(' ');
2365            return new HandlebarsInstance.SafeString(// eslint-disable-next-line sonarjs/no-nested-template-literals
2366            `<img src="${src}"${srcset ? ` srcset="${srcset}"` : ''}${attrs ? ` ${attrs}` : ''}>`);
2367        },
2368        bgImage (mediaSource) {
2369            if (!mediaSource) return '';
2370            if (typeof mediaSource === 'string') return mediaSource;
2371            return mediaSource.largeUrl || mediaSource.url || '';
2372        },
2373        concat (...rest) {
2374            let outStr = '';
2375            // rest params are Array instances while arguments object is not
2376            for(const arg in rest)if (rest[arg] !== null && rest[arg] !== undefined && typeof rest[arg] !== 'object') outStr += rest[arg];
2377            return outStr;
2378        },
2379        setVideoExtension (uri, format) {
2380            if (!uri || !format) return '';
2381            const decodedUri = new URL(uri);
2382            if (decodedUri.host !== 'res.cloudinary.com') {
2383                // Not a cloudinary uri, do not rewrite
2384                if (decodedUri.pathname.endsWith(`.${format}`)) return uri;
2385                return '';
2386            }
2387            // Rewrite the cloudinary uri
2388            const lastPeriodIdx = decodedUri.pathname.lastIndexOf('.');
2389            let pathWithoutFormat = decodedUri.pathname;
2390            if (lastPeriodIdx !== -1) pathWithoutFormat = decodedUri.pathname.substr(0, lastPeriodIdx);
2391            decodedUri.pathname = `${pathWithoutFormat}.${format}`;
2392            return decodedUri.toString();
2393        },
2394        addVideoSources (uri) {
2395            if (!uri) return '';
2396            const VIDEO_VARIANTS = [
2397                {
2398                    format: 'webm',
2399                    codec: 'vp9',
2400                    htmlCodecs: ';codecs=vp9'
2401                },
2402                {
2403                    format: 'mp4',
2404                    codec: 'h265',
2405                    htmlCodecs: ';codecs=hvc1'
2406                },
2407                {
2408                    format: 'mp4',
2409                    codec: 'h264',
2410                    htmlCodecs: ''
2411                }
2412            ];
2413            const VIDEO_EXT_REGEXP = /\.(?:3gp|mpeg|mp4|m4v|m4p|ogv|ogg|mov|webm)$/;
2414            if (!uri.includes('res.cloudinary.com')) // keep existing or no extension for non Cloudinary urls
2415            return `<source data-src="${uri}">`;
2416            // Cap delivery at 1080p (1920px wide) while preserving aspect ratio. Width-only:
2417            // c_limit never upscales, so portrait sources are left at their native size.
2418            // No q_auto: quality is left to Cloudinary's default rather than forced down.
2419            // Note the regex below consumes any q_auto in the source URL, so it is dropped
2420            // rather than carried through.
2421            const CONSTRAINED_DELIVERY = 'w_1920,c_limit';
2422            const uriNoExt = uri.replace(VIDEO_EXT_REGEXP, '');
2423            const sources = VIDEO_VARIANTS.map((type)=>{
2424                const cloudinaryFormatUrl = `${uriNoExt.replace(/f_auto(?::video)?(?:,q_auto(?::\w+)?)?/, `f_${type.format},vc_${type.codec},${CONSTRAINED_DELIVERY}`)}.${type.format}`;
2425                return `<source data-src="${cloudinaryFormatUrl}" type="video/${type.format}${type.htmlCodecs}">`;
2426            });
2427            return sources.join('\n');
2428        },
2429        cloudinaryVideoFirstFrame: $0ce6edea77f7b81a$exports.getVideoFirstFrame,
2430        initials (text, options) {
2431            if (!text) return '';
2432            if (options?.hash?.endChar) // eslint-disable-next-line
2433            text = text.split(options.hash.endChar)[0];
2434            // eslint-disable-next-line
2435            const maxChars = +options?.hash?.maxChars || 2; // we do not allow this to be 0
2436            let result = text.match(/\b\w/g)?.slice(0, maxChars);
2437            if (!result) return '';
2438            if (options?.hash?.addText) result = result.map((item)=>item + options.hash.addText);
2439            return result.join(options?.hash?.joinWith || '').toUpperCase();
2440        },
2441        normalizePhone (phone) {
2442            if (!phone) return '';
2443            const str = String(phone).trim();
2444            return (str.startsWith('+') ? '+' : '') + str.replace(/\D/g, '');
2445        }
2446    };
2447}
2448$53de3c160faf5a81$exports = $53de3c160faf5a81$var$handlebarsHelpersFactory;
2449
2450
2451/* global window, document */ // eslint-disable-next-line import/prefer-default-export
2452class $dc851cf3939b6ef5$export$ff0712c26d5458f7 {
2453    /**
2454   * Initialize Modal Controller
2455   * @param {Object} options
2456   */ constructor(options){
2457        this.isBuilder = false;
2458        this.companyId = null;
2459        this.websiteId = null;
2460        this.pageId = null;
2461        this.shareId = null;
2462        this.pageMeta = null;
2463        this.websiteApiGatewayUrl = null;
2464        this.buyerSellerServiceUrl = null;
2465        this.leadIngesterUrl = null;
2466        this.divolteServiceUrl = null;
2467        this.eventBus = null;
2468        this.templateId = null;
2469        this.myhomeDashboardEnabled = false;
2470        this.mlsEnabled = false;
2471        this.hstValuationRedirectEnabled = false;
2472        this.googleMapsAPIKey = null;
2473    }
2474    /**
2475   * Controllers must implement a "destroy" method to be called
2476   * after page navigation to remove event handlers / cleanup
2477   */ destroy() {}
2478    /**
2479   * Set page and supporting data
2480   * @param {string} pageId
2481   * @param {Object} options
2482   */ setPage(pageId, options = {}) {
2483        this.pageId = pageId;
2484        this.shareId = options.shareId || null;
2485        this.pageMeta = {
2486            sourceResource: options.sourceResource,
2487            pageElementId: options.pageElementId,
2488            pageQueryVariables: options.pageQueryVariables || {}
2489        };
2490    }
2491    /**
2492   * Sets if we are in pagebuilder context or not
2493   * @param {boolean} isBuilder
2494   */ setIsBuilder(isBuilder) {
2495        this.isBuilder = isBuilder;
2496    }
2497    /**
2498   * Set Company and supporting data
2499   * @param {string} companyId
2500   * @param {Object} options
2501   */ setCompany(companyId, options = {}) {
2502        this.companyId = companyId;
2503    }
2504    /**
2505   * Set website and supporting data
2506   * @param {string} websiteId
2507   * @param {Object} options
2508   */ setWebsite(websiteId, options = {}) {
2509        this.websiteId = websiteId;
2510        if (options.myhomeDashboardEnabled) this.myhomeDashboardEnabled = options.myhomeDashboardEnabled;
2511        if (options.mlsEnabled) this.mlsEnabled = options.mlsEnabled;
2512        if (options.hstValuationRedirectEnabled) this.hstValuationRedirectEnabled = options.hstValuationRedirectEnabled;
2513    }
2514    /**
2515   * Set websiteApiGatewayUrl
2516   * @param {string} websiteApiGatewayUrl
2517   * @param {Object} options
2518   */ setWebsiteApiGatewayUrl(websiteApiGatewayUrl, options = {}) {
2519        this.websiteApiGatewayUrl = websiteApiGatewayUrl;
2520    }
2521    /**
2522   * Set buyerSellerServiceUrl
2523   * @param {string} buyerSellerServiceUrl
2524   * @param {Object} options
2525   */ setBuyerSellerServiceUrl(buyerSellerServiceUrl, options = {}) {
2526        this.buyerSellerServiceUrl = buyerSellerServiceUrl;
2527    }
2528    /**
2529   * Set divolteServiceUrl and supporting data
2530   * @param {string} divolteServiceUrl
2531   * @param {Object} options
2532   */ setDivolteServiceUrl(divolteServiceUrl, options = {}) {
2533        this.divolteServiceUrl = divolteServiceUrl;
2534    }
2535    /**
2536   * Set eventBusUrl
2537   * @param {string} eventBusUrl
2538   * @param {Object} options
2539   */ setEventBusUrl(eventBusUrl, options = {}) {
2540        this.eventBusUrl = eventBusUrl;
2541    }
2542    /**
2543   * Set templateId and supporting data
2544   * @param {string} templateId
2545   * @param {Object} options
2546   */ setTemplateId(templateId, options = {}) {
2547        this.templateId = templateId;
2548    }
2549    /**
2550   * Set leadIngesterUrl
2551   * @param {string} leadIngesterUrl
2552   * @param {Object} options
2553   */ setLeadIngesterUrl(leadIngesterUrl, options = {}) {
2554        this.leadIngesterUrl = leadIngesterUrl;
2555    }
2556    /**
2557   * Set googleMapsAPIKey
2558   * @param {string} googleMapsAPIKey
2559   * @param {Object} options
2560   */ setGoogleMapsAPIKey(googleMapsAPIKey, options = {}) {
2561        this.googleMapsAPIKey = googleMapsAPIKey;
2562    }
2563    /**
2564   * Set eventBus
2565   * @param {Object} options
2566   */ setEventBus({ enabled: enabled, apiKey: apiKey, url: url }) {
2567        this.eventBus = {
2568            enabled: enabled,
2569            apiKey: apiKey,
2570            url: url
2571        };
2572    }
2573}
2574
2575
2576/* eslint-disable import/prefer-default-export */ // eslint-disable-next-line import/prefer-default-export
2577class $7c391e2f7931d60d$export$3b5bd9381a52554c {
2578    /**
2579   * Initialize Base Controller at build time
2580   * @param { ConfigController } config
2581   * @param {Window} window
2582   * @param {Document} document
2583   */ constructor(config, window, document){
2584        // TODO: Listen for events from configController to update configuration
2585        this.config = config;
2586        this.window = window;
2587        this.document = document;
2588        if (!this.destroy) // With turbolinks, we want to ensure that on each page load we have the latest version of the sdk
2589        //  Controllers are deconstructed and replaced (on the window object) per request
2590        //  Controllers must use the destory method to remove event handlers to prevent undefined behavior
2591        throw new Error('Controllers must implement a deconstructor');
2592    }
2593}
2594
2595
2596// eslint-disable-next-line import/prefer-default-export
2597const $a3e97e89bbc2a366$export$f037eeffb5561205 = 2000;
2598
2599
2600class $0ead03fdb95fa9ce$export$d507f25e63650365 extends (0, $7c391e2f7931d60d$export$3b5bd9381a52554c) {
2601    /**
2602   * Initialize Modal Controller at build time
2603   * @param { ConfigController } config
2604   * @param {Window} window
2605   * @param {Document} document
2606   */ constructor(config, window, document){
2607        super(config, window, document);
2608        this.setLoginState = this.setLoginState.bind(this);
2609        this.pageId = null;
2610        this.modals = [];
2611        this.exitModalTriggered = {};
2612        this.exitModalEventListeners = [];
2613    }
2614    /**
2615   * Initialize Modal Controller at run time
2616   * Attach handlers and events to DOM
2617   * @param {Object} options
2618   */ initialize(options) {
2619        try {
2620            const { config: config, document: document } = this;
2621            this.pageId = config.pageId;
2622            this.modals = document.querySelectorAll('body > #modals > .modal');
2623            options.modals.forEach((m)=>{
2624                this._attachModalHandler(m);
2625            });
2626        } catch (e) {
2627            // eslint-disable-next-line no-console
2628            console.log(e);
2629        }
2630    }
2631    /**
2632   * Controllers must implement a "destroy" method to be called
2633   * after page navigation to remove event handlers / cleanup
2634   */ destroy() {
2635        const { document: document } = this;
2636        this.exitModalEventListeners.forEach((listener)=>{
2637            document.removeEventListener('mouseout', listener);
2638        });
2639        this.modals = [];
2640        this.exitModalTriggered = {};
2641        this.exitModalEventListeners = [];
2642    }
2643    /**
2644   * Set modal to local storage with expiration
2645   * @param {string} modalId
2646   */ setModalWithExpiry(modalId) {
2647        const { window: window } = this;
2648        const TTL = 86400000; // 24 hours
2649        const now = new Date();
2650        const expiry = now.getTime() + TTL;
2651        const key = `modal-controller-${modalId}`;
2652        try {
2653            window.localStorage.setItem(key, JSON.stringify(expiry));
2654        } catch (err) {
2655        // catch error when setting item to storage on iOS private browser
2656        }
2657    }
2658    /**
2659   * Save success login modal to local storage
2660   */ setLoginState() {
2661        const { window: window } = this;
2662        try {
2663            window.localStorage.setItem('isSignedUp', 'true');
2664        } catch (err) {
2665        // catch error when setting item to storage on iOS private browser
2666        }
2667    }
2668    /**
2669   * Get modal and check expiration
2670   * @param {string} modalId
2671   * @return {boolean}
2672   */ getModalWithExpiry(modalId) {
2673        const { window: window } = this;
2674        const storage = window.localStorage;
2675        const expirationTime = storage.getItem(`modal-controller-${modalId}`);
2676        if (!expirationTime) return false;
2677        const expiry = JSON.parse(expirationTime);
2678        const now = new Date();
2679        if (now.getTime() > expiry) {
2680            storage.removeItem(`modal-controller-${modalId}`);
2681            return false;
2682        }
2683        return true;
2684    }
2685    /**
2686   * Make a modal visible
2687   * @param {string} modalId
2688   * @param {Object} options
2689   */ show(modalId, options = {}) {
2690        // TODO: migrate logic from page.handlebars
2691        const { window: window } = this;
2692        const modalViewed = this.getModalWithExpiry(modalId);
2693        // Only show a modal if it has not been seen
2694        // Does not affect "show modal on button click"
2695        if (modalId && !modalViewed || options.forced === true) {
2696            window.lpUI.showModal(`modal-${modalId}`, options);
2697            this.setModalWithExpiry(modalId);
2698        }
2699    }
2700    /**
2701   * Attach events based on Modal type and page settings
2702   * @param {Modal} modal
2703   */ _attachModalHandler(modal) {
2704        const { pageId: pageId } = this;
2705        const { trigger: trigger, pageSpecific: pageSpecific } = modal;
2706        if (pageSpecific) {
2707            const pageIds = modal.pages.map((p)=>p.pageId);
2708            if (!pageIds.includes(pageId)) // Modal does not belong to this page
2709            return;
2710        }
2711        if (trigger === 'EXIT') this._exitModalHandler(modal);
2712        else if (trigger === 'TIMER') this._timerModalHandler(modal);
2713        else if (trigger === 'FORCED') this._forcedModalHandler(modal);
2714    }
2715    /**
2716   * Attach events for exit Modals
2717   * @param {Modal} modal
2718   */ _exitModalHandler(modal) {
2719        // eslint-disable-next-line
2720        const that = this;
2721        const { document: document, exitModalTriggered: exitModalTriggered } = this;
2722        const { modalId: modalId } = modal;
2723        /**
2724     * Handle the mouseout dom event
2725     * @param {Event} event
2726     */ function triggerExitModal(event) {
2727            if (exitModalTriggered[modalId]) return;
2728            if (!event.toElement && !event.relatedTarget) {
2729                that.show(modalId);
2730                exitModalTriggered[modalId] = true;
2731            }
2732        }
2733        document.addEventListener('mouseout', triggerExitModal);
2734        this.exitModalEventListeners.push(triggerExitModal);
2735    }
2736    /**
2737   * Attach events for timer Modals
2738   * @param {Modal} modal
2739   */ _timerModalHandler(modal) {
2740        const { modalId: modalId, timerDelay: timerDelay } = modal;
2741        setTimeout(()=>{
2742            this.show(modalId);
2743        }, timerDelay);
2744    }
2745    /**
2746   * Attach events for Forced Modals
2747   * @param {Modal} modal
2748   */ _forcedModalHandler(modal) {
2749        const { modalId: modalId } = modal;
2750        const { window: window, document: document } = this;
2751        const isLoggedIn = window.localStorage.getItem('isSignedUp') === 'true';
2752        if (!isLoggedIn) {
2753            // watch for event triggering success login
2754            const forcedModal = document.querySelector(`#modal-${modalId}`);
2755            const contactForm = forcedModal?.querySelector('form');
2756            const MODAL_CLOSE_DELAY = contactForm?.dataset.delay || (0, $a3e97e89bbc2a366$export$f037eeffb5561205);
2757            // form submit autoclose is handled by contactForms controller
2758            contactForm.addEventListener('formsubmitted', ()=>{
2759                this.setLoginState();
2760            });
2761            window.addEventListener('oauthSuccess', ()=>{
2762                this.setLoginState();
2763                contactForm.classList.add('success');
2764                setTimeout(()=>{
2765                    window.lpUI.hideModal(`modal-${modalId}`);
2766                    contactForm.reset();
2767                    contactForm.classList.remove('success');
2768                }, MODAL_CLOSE_DELAY);
2769            });
2770            this.show(modalId, {
2771                forced: true
2772            });
2773        }
2774    }
2775}
2776
2777
2778/* eslint-disable import/prefer-default-export */ /* global window */ /* eslint-disable import/prefer-default-export */ /**
2779 * Handle navigation push
2780 * @param {string} href
2781 * @param {boolean} _blank
2782 */ const $fc0a058ae42af628$export$95e8d77caafa3e06 = (href, _blank = false)=>{
2783    if (!href) return;
2784    if (_blank) {
2785        window.open(href);
2786        return;
2787    }
2788    window.location.assign(href);
2789};
2790const $fc0a058ae42af628$export$267a1435fe18b8d4 = (obj, path, defValue)=>{
2791    if (!path) return undefined;
2792    const pathArray = Array.isArray(path) ? path : path.match(/([^[.\]])+/g);
2793    const result = pathArray.reduce((prevObj, key)=>prevObj && prevObj[key], obj);
2794    return result === undefined ? defValue : result;
2795};
2796
2797
2798
2799class $d48f9f944810f613$export$ca3218b7861b9cb0 extends (0, $7c391e2f7931d60d$export$3b5bd9381a52554c) {
2800    /**
2801   * Initialize Button Controller at build time
2802   * @param { ConfigController } config
2803   * @param {Window} window
2804   * @param {Document} document
2805   */ constructor(config, window, document){
2806        super(config, window, document);
2807        this._boundClickHandler = this._buttonClickHandler.bind(this);
2808    }
2809    /**
2810   * Initialize Button Controller at run time
2811   * Attach handlers and events to DOM
2812   * @param {Object} options
2813   */ initialize(options = {}) {
2814        try {
2815            const { document: document } = this;
2816            document.body.removeEventListener('click', this._boundClickHandler);
2817            document.body.addEventListener('click', this._boundClickHandler);
2818        } catch (e) {
2819            // eslint-disable-next-line no-console
2820            console.error(e);
2821        }
2822    }
2823    /**
2824   * Controllers must implement a "destroy" method to be called
2825   * after page navigation to remove event handlers / cleanup
2826   */ destroy() {
2827        const { document: document } = this;
2828        document.body.removeEventListener('click', this._boundClickHandler);
2829    }
2830    /**
2831   * Buttons click handler
2832   * @param {event} e
2833   */ _buttonClickHandler(e) {
2834        this._handleButtonClick(e).catch((e)=>console.error(e));
2835    }
2836    /**
2837   * Handle button click
2838   * We need special function to have easy way to detach listener
2839   * @param {Event} e
2840   */ async _handleButtonClick(e) {
2841        const { window: window, document: document } = this;
2842        const button = e.target.closest('button, a');
2843        if (!button) return;
2844        const type = button.dataset.type || '';
2845        const href = button.href || button.dataset.href || '';
2846        const target = button.target || '';
2847        const { submit: submit } = button.dataset;
2848        if (submit) {
2849            try {
2850                await this._handleSubmit(button);
2851            } catch (err) {
2852                // eslint-disable-next-line no-console
2853                console.error(err);
2854            }
2855            (0, $fc0a058ae42af628$export$95e8d77caafa3e06)(href, target === '_blank');
2856        }
2857        this._trackConversion(button);
2858        if (type === 'VIDEO') {
2859            this._handleVideoButton(button);
2860            return;
2861        }
2862        if (type === 'CONTACT_US') {
2863            this._handleContactUsButton(button);
2864            return;
2865        }
2866        if (type === 'SUBSCRIBE') {
2867            // TODO: Extend for an overwritten subscribe
2868            window.lpUI.showModal('modal-global-subscribe');
2869            return;
2870        }
2871        if (type === 'MY_ACCOUNT') {
2872            // TODO: Extend for an overwritten subscribe
2873            window.lpUI.showModal('modal-global-my-account');
2874            return;
2875        }
2876        if (type === 'SHARE_POPUP') {
2877            // TODO: Extend for an overwritten subscribe
2878            const sharePopup = button.querySelector('.share-popup');
2879            if (sharePopup) sharePopup.style.display = 'flex';
2880            e.stopPropagation(); // this may not work in current 'delegate' mode
2881            return;
2882        }
2883        // Custom modals
2884        if (type.substring(0, 6) === 'MODAL_') {
2885            const modalId = type.substring(6);
2886            window.lpUI.showModal(`modal-${modalId}`);
2887            return;
2888        }
2889        // MAILTO / TEL Event
2890        if (href?.startsWith('mailto:')) {
2891            const email = href.substring(7);
2892            // TODO: Replace with SDK method
2893            document.sendGoogleAnalyticsEvent({
2894                hitType: 'event',
2895                eventCategory: 'button',
2896                eventAction: 'click',
2897                eventLabel: 'Email',
2898                eventValue: email
2899            });
2900        } else if (href?.startsWith('tel:')) {
2901            const phoneNumber = href.substring(4);
2902            // TODO: Replace with SDK method
2903            document.sendGoogleAnalyticsEvent({
2904                hitType: 'event',
2905                eventCategory: 'button',
2906                eventAction: 'click',
2907                eventLabel: 'Phone',
2908                eventValue: phoneNumber
2909            });
2910        }
2911    }
2912    /**
2913   * Handle submit
2914   * @param {HTMLButtonElement|HTMLAnchorElement} button
2915   */ async _handleSubmit(button) {
2916        const form = button.closest('form');
2917        const { window: window } = this;
2918        if (form) return await window.luxuryPresence.contactForms.submitForm(form);
2919        return null;
2920    }
2921    _getVimeoSrc(link) {
2922        if (!link || !link.includes('vimeo.com') || link.length > 2000) return null;
2923        const matchResult = link.match(/(?:(?:www\.)?vimeo\.com\/(?:showcase\/\d+(?:\/video\/|\?video[=/])|channels\/(?:\w+\/)?|groups\/(?:[^/]*)\/videos\/|)|player\.vimeo\.com\/video\/)(\d+)(?:(?:\?.*&*h=|\/)+([\d,a-f]+))?/);
2924        if (!matchResult) return null;
2925        const [, vimeoId, vimeoHashParameter] = matchResult;
2926        let src = `https://player.vimeo.com/video/${vimeoId}?`;
2927        if (vimeoHashParameter) src += `h=${vimeoHashParameter}&`;
2928        src += 'autoplay=1';
2929        return src;
2930    }
2931    /**
2932   * Handle type video click
2933   * @param {HTMLElement} button
2934   */ // eslint-disable-next-line sonarjs/cognitive-complexity
2935    _handleVideoButton(button) {
2936        const { document: document } = this;
2937        const section = button.closest('section');
2938        // Embed youtube/vimeo video url
2939        let { src: src } = button.dataset;
2940        let youtubeId = '';
2941        if (src && (src.includes('youtube.com') || src.includes('youtu.be')) && !src.includes('youtube.com/embed')) {
2942            // test link: https://regexr.com/3anm9
2943            const youtubeRegex = /(?:youtube\.com\/\S*(?:(?:\/e(?:mbed))?\/|watch\?(?:\S*?&?v=)
2943)|youtu.be\/)([a-zA-Z0-9_-]{6,11})/;
2944            const youtubeResult = src.match(youtubeRegex);
2945            // eslint-disable-next-line
2946            if (youtubeResult) youtubeId = youtubeResult[1];
2947        }
2948        const vimeoSrc = this._getVimeoSrc(src);
2949        if (youtubeId) src = `https://youtube.com/embed/${youtubeId}?autoplay=1&controls=0`;
2950        else if (vimeoSrc) src = vimeoSrc;
2951        if (!src || !section) return;
2952        const isVideoFile = src.endsWith('.mp4') || src.endsWith('.webm') || src.includes('cloudinary.com');
2953        const modalHtml = `
2954      <div id="modal-${section.id}" class="modal visible">
2955        <div class="modal-content">
2956          <div class="lightbox-video">
2957            <div class="video-player">
2958              <div class="embed-container">
2959                ${isVideoFile ? `<video controls autoplay src="${src}"></video>` : `<iframe frameborder="0" allowfullscreen="1" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" title="YouTube video player" width="100%" height="100%" src="${src}"></iframe>`}
2960              </div>
2961            </div>
2962          </div>
2963        </div>
2964        <button class="close lp-close" type="button" aria-label="close modal"><span class="lp-close-icon" aria-hidden="true"></span></button>
2965      </div>
2966    `;
2967        document.body.insertAdjacentHTML('beforeend', modalHtml);
2968        const modal = document.getElementById(`modal-${section.id}`);
2969        const closeModal = modal.querySelector('.close');
2970        closeModal.addEventListener('click', ()=>{
2971            modal.remove();
2972        });
2973    }
2974    /**
2975   * Handle type contact us click
2976   * @param {HTMLElement} button
2977   */ _handleContactUsButton(button) {
2978        const { window: window, document: document } = this;
2979        // TODO: Extend for an overwritten contact us
2980        document.sendGoogleAnalyticsEvent({
2981            hitType: 'event',
2982            eventCategory: 'button',
2983            eventAction: 'click',
2984            eventLabel: 'contact'
2985        });
2986        window.lpUI.showModal('modal-global-contact-us', {
2987            scrollLock: true
2988        });
2989    }
2990    /**
2991   * Track conversion
2992   * @param {HTMLElement} button
2993   */ _trackConversion(button) {
2994        const { window: window, document: document } = this;
2995        // Conversion Tracking Options
2996        const { gtagConversionId: gtagConversionId, gtagConversionLabel: gtagConversionLabel, fbEventName: fbEventName } = button.dataset;
2997        if (gtagConversionId && gtagConversionLabel) {
2998            if (window.dataLayer && window.dataLayer.length) {
2999                const configured = window.dataLayer.some((layer)=>layer.length && layer[0] === 'config' && layer[1] === gtagConversionId);
3000                if (!configured) document.sendGoogleTagManagerEvent('config', gtagConversionId);
3001            }
3002            const sentTo = `${gtagConversionId}/${gtagConversionLabel}`;
3003            document.sendGoogleTagManagerEvent('event', 'conversion', {
3004                send_to: sentTo
3005            });
3006        }
3007        if (window.fbq && fbEventName) window.fbq('track', fbEventName, {});
3008    }
3009}
3010
3011
3012/* eslint-disable import/prefer-default-export */ 
3013class $68a2d4aa500c7a05$export$61ec8f2b6291ec31 extends (0, $7c391e2f7931d60d$export$3b5bd9381a52554c) {
3014    /**
3015   * Initialize Validation Controller at build time
3016   * @param { ConfigController } config
3017   * @param {Window} window
3018   * @param {Document} document
3019   */ constructor(config, window, document){
3020        super(config, window, document);
3021        this.validatedForms = [];
3022    }
3023    /**
3024   * Initialize Contact Form Controller at run time
3025   * Attach handlers and events to DOM
3026   * @param {Object} options
3027   */ initialize(options = {}) {
3028        try {
3029            const { window: window, document: document } = this;
3030            const { selector: selector } = options;
3031            let validatedForms = [];
3032            if (selector) validatedForms = document.querySelectorAll(`${selector} form[data-type="contact-form"]`);
3033            else validatedForms = document.querySelectorAll('form[data-type="contact-form"]');
3034            const isPhoneValidationLibRequired = !!document.querySelectorAll('input[type="tel"]').length;
3035            // we are loading the phone validation lib from the globally defined list of libs
3036            if (isPhoneValidationLibRequired && !window.libphonenumber && window?.luxuryPresence?.libs) {
3037                const { loadJs: loadJs, jsLibsMap: jsLibsMap } = window.luxuryPresence.libs;
3038                const { libphonenumber: libphonenumber } = jsLibsMap;
3039                loadJs(libphonenumber.jsSrc, this.attachValidation.bind(this, validatedForms));
3040            }
3040 else this.attachValidation(validatedForms);
3041            this.validatedForms = this.validatedForms.concat(validatedForms);
3042        } catch (e) {
3043            // eslint-disable-next-line no-console
3044            console.log(e);
3045        }
3046    }
3047    /**
3048   * Controllers must implement a "destroy" method to be called
3049   * after page navigation to remove event handlers / cleanup
3050   */ destroy() {
3051        this.validatedForms = [];
3052    }
3053    /**
3054   * Validate all forms in the document
3055   * @param {NodeListOf<HTMLFormElement>} forms
3056   */ attachValidation(forms) {
3057        forms.forEach((form)=>{
3058            const inputs = form.querySelectorAll('input, select, textarea');
3059            inputs.forEach((input)=>{
3060                this.applyFieldValidation(input);
3061            });
3062        });
3063    }
3064    /**
3065   * Field Validation Handler from global context
3066   * @param {HTMLInputElement|HTMLTextAreaElement|HTMLSelectElement} inputField
3067   */ applyFieldValidation(inputField) {
3068        const fieldType = inputField.getAttribute('type');
3069        if (fieldType === 'tel') this._applyPhoneValidation(inputField);
3070    }
3071    /**
3072   * Phone Field Validation Handler
3073   * @param {HTMLInputElement} inputField
3074   */ _applyPhoneValidation(inputField) {
3075        const { window: window } = this;
3076        if (window.libphonenumber) {
3077            // https://codepen.io/coinscope/pen/BaXBvBp?editors=1010
3078            const phoneUtil = window.libphonenumber.isValidPhoneNumber;
3079            inputField.addEventListener('keyup', function() {
3080                if (this.hasAttribute('required') || this.value.replace(/\s/g, '').length) try {
3081                    const phoneNumber = this.value;
3082                    const region = 'US';
3083                    const isValidNumber = phoneUtil(phoneNumber, region);
3084                    if (!isValidNumber) this.setCustomValidity('Please enter a valid phone number.');
3085                    else this.setCustomValidity('');
3086                } catch (e) {
3087                    this.setCustomValidity('Please enter a valid phone number.');
3088                }
3089                else this.setCustomValidity('');
3090            });
3091        }
3092    }
3093}
3094
3095
3096
3097
3098/**
3099 * Fires the `generate_lead` Google Ads conversion on any marketing-site lead
3100 * event — lead-form submits (all routed through ContactFormController) and
3101 * social sign-in (oauth.js) — at most once per session.
3102 *
3103 * Reuses the same `generate_lead` event the Home Search Tool fires; the page
3104 * template already configures the LP Google tags, so no new Google Ads setup is
3105 * needed. Cross-tab/visitor dedupe is left to the conversion action's
3106 * Count="One" — localStorage is intentionally avoided as it would suppress a
3107 * returning visitor's later lead.
3108 */ const $3ec2bf3965f87ecc$export$78b64890ea40f4e4 = 'generate_lead';
3109const $3ec2bf3965f87ecc$export$568da12be2433b06 = 'lp_lead_form_conversion_fired';
3110function $3ec2bf3965f87ecc$var$alreadyFired(window) {
3111    try {
3112        return window.sessionStorage.getItem($3ec2bf3965f87ecc$export$568da12be2433b06) === 'true';
3113    } catch  {
3114        // sessionStorage can throw in private browsing; fail open so we still fire.
3115        return false;
3116    }
3117}
3118function $3ec2bf3965f87ecc$var$markFired(window) {
3119    try {
3120        window.sessionStorage.setItem($3ec2bf3965f87ecc$export$568da12be2433b06, 'true');
3121    } catch  {
3122    // Ignore — see alreadyFired().
3123    }
3124}
3125function $3ec2bf3965f87ecc$export$e70565180c0e6950(window, document) {
3126    if (!window || !document) return;
3127    // GA bootstrap may not have run yet (or no pixel on this page); don't throw,
3128    // and don't burn the once-per-session flag if we can't actually fire.
3129    if (typeof document.sendGoogleTagManagerEvent !== 'function') return;
3130    if ($3ec2bf3965f87ecc$var$alreadyFired(window)) return;
3131    try {
3132        // Mark fired only AFTER a successful send, so a thrown GTM call doesn't
3133        // permanently suppress the conversion for the rest of the session — and
3134        // never let an analytics failure break the caller's success flow.
3135        document.sendGoogleTagManagerEvent('event', $3ec2bf3965f87ecc$export$78b64890ea40f4e4);
3136        $3ec2bf3965f87ecc$var$markFired(window);
3137    } catch  {
3138    // Swallow — analytics must not break form submit / sign-in.
3139    }
3140}
3141
3142
3143
3144const $2aefad83322125c9$var$homeValuationRoute = '/api/v1/home-valuation';
3145class $2aefad83322125c9$export$2e2bcd8739ae039 extends (0, $7c391e2f7931d60d$export$3b5bd9381a52554c) {
3146    destroy() {
3147    //
3148    }
3149    /**
3150   * Clean address string by removing call time frame suffix and extra whitespace
3151   *
3152   * Handles 17 templates that append ", call time frame: [value]" to the address:
3153   * - TheTrailblazerSir_2, TheMasterpiece (2x), TheInspirationSir_1, TheIconSir_3
3154   * - Influencer, GlobalCollective, Evolution, CorcoranAgent_1
3155   * - CompassSE (2x), CompassPrestige (2x), CompassNavigator
3156   * - ColdwellBanker (2x), Classic
3157   *
3158   * @param {string} address - Raw address string that may contain time frame info
3159   * @return {string} - Cleaned address string
3160   */ _cleanAddressString(address) {
3161        if (!address || typeof address !== 'string') return '';
3162        let cleaned = address.trim();
3163        // Fix 1: Handle "User entered address:\n..." pattern from TheProducer templates
3164        // Extract only the user entered address, ignore geocoded part
3165        if (cleaned.includes('User entered address:')) {
3166            const match = cleaned.match(/User entered address:\s*\n?\s*([^\n]+)/);
3167            if (match && match[1]) cleaned = match[1].trim();
3168        }
3169        // Fix 2: Remove ", call time frame: ..." suffix if present (affects 17 templates)
3170        const timeFrameIndex = cleaned.indexOf(', call time frame:');
3171        if (timeFrameIndex !== -1) cleaned = cleaned.substring(0, timeFrameIndex).trim();
3172        return cleaned;
3173    }
3174    /**
3175   * Transform Google Maps address components to structured format
3176   * @param {Array} addressComponents - Google Maps address components
3177   * @return {Object} - Structured address object
3178   */ _transformAddressComponents(addressComponents) {
3179        const get = (t)=>(addressComponents.find((c)=>c.componentType === t) || {}).componentName?.text;
3180        const structuredAddress = {};
3181        const streetNumber = get('street_number');
3182        const streetName = get('route');
3183        const state = get('administrative_area_level_1');
3184        const zipcode = get('postal_code');
3185        const addressLine2 = get('subpremise');
3186        // explicit precedence for city
3187        const city = get('locality') || get('sublocality_level_1') || get('neighborhood');
3188        if (streetNumber) structuredAddress.streetNumber = streetNumber;
3189        if (streetName) structuredAddress.streetName = streetName;
3190        if (city) structuredAddress.city = city;
3191        if (state) structuredAddress.state = state;
3192        if (zipcode) structuredAddress.zipcode = zipcode;
3193        if (addressLine2) structuredAddress.addressLine2 = addressLine2;
3194        return structuredAddress;
3195    }
3196    /**
3197   * Extract address and coordinates from Google Maps validation data
3198   * @param {Object} validatedAddressData - Google Maps validation result
3199   * @return {Object} - Object containing structuredAddress and coordinates
3200   */ _extractAddressAndCoordinates(validatedAddressData) {
3201        let structuredAddress = null;
3202        let coordinates = null;
3203        if (validatedAddressData?.result) {
3204            const { result: result } = validatedAddressData;
3205            // Extract structured address components
3206            if (result.address?.addressComponents) structuredAddress = this._transformAddressComponents(result.address.addressComponents);
3207            // Extract coordinates
3208            if (result.geocode?.location) coordinates = {
3209                latitude: result.geocode.location.latitude,
3210                longitude: result.geocode.location.longitude
3211            };
3212        }
3213        return {
3214            structuredAddress: structuredAddress,
3215            coordinates: coordinates
3216        };
3217    }
3218    /**
3219   * Filter out empty string values from an object, keeping only non-empty values
3220   * @param {Object} obj - Object to filter
3221   * @return {Object} - Filtered object without empty strings
3222   */ _filterEmptyStrings(obj) {
3223        const filtered = {};
3224        for (const [key, value] of Object.entries(obj))if (value !== '' && value !== null && value !== undefined) filtered[key] = value;
3225        return filtered;
3226    }
3227    /**
3228   * Extract raw address from form data with priority fallback chain.
3229   * Order is critical to handle 38 home valuation templates with different field naming:
3230   *
3231   * IMPORTANT: contactForms.js (line 189) stores name="message" in comments_attributes[0].text
3232   * because 'message' is in DEFAULT_LEAD_FIELDS. Fields NOT in DEFAULT_LEAD_FIELDS go to content.
3233   *
3234   * Priority (most specific → most generic):
3235   * 1. address           - Pattern 1: 9 templates (explicit address, stored in content)
3236   * 2. property-address  - Pattern 3: 4 templates (dash variant with JS, stored in content)
3237   * 3. property_address  - Pattern 4: 3 templates (underscore, stored in content - handles VanguardProperties!)
3238   * 4. Property_Address  - Pattern 5: 1 template (capital P - TheProducer/HomeValuationRansomHouse, stored in content)
3239   * 5. comments_attributes[0].text - Pattern 2: ALL 17 templates with name="message" store HERE!
3240   *                                   (e.g., Evolution/HomeValuation, TheProducer/HomeValuation, etc.)
3241   * 6. message           - Pattern 6: 4 templates with JS-populated message (rare, checked last)
3242   * 7-8. homeValuationAddress, propertyAddress - Legacy/unknown formats
3243   *
3244   * Critical: Each field is cleaned BEFORE checking, so dropdown values are skipped and we try next field
3245   *
3246   * @param {Object} data - Form data
3247   * @return {string} - Raw address string (may contain trailing text like ", call time frame: ...")
3248   */ _getRawAddress(data) {
3249        const content = data.activity.content || {};
3250        const comments = data.activity.comments_attributes?.[0]?.text;
3251        const possibleFields = [
3252            content.address,
3253            content['property-address'],
3254            content.property_address,
3255            content.Property_Address,
3256            comments,
3257            content.message,
3258            content.homeValuationAddress,
3259            content.propertyAddress
3260        ];
3261        return possibleFields.map((field)=>field && this._cleanAddressString(field)).find(Boolean) || '';
3262    }
3263    /**
3264   * Logs lead-related events for monitoring
3265   * @param {string} eventType - Type of event
3266   * @param {Object} data - Form data
3267   * @param {Error} error - Optional error object
3268   */ _logLeadEvent(eventType, data, error = null) {
3269        const eventPayload = {
3270            event: eventType,
3271            companyId: this.config.companyId,
3272            websiteId: this.config.websiteId,
3273            timestamp: new Date().toISOString(),
3274            hasEmail: !!data.activity?.author_email,
3275            hasAddress: !!this._getRawAddress(data)
3276        };
3277        if (error) {
3278            // Use userMessage (sanitized) instead of raw message to prevent PII exposure
3279            // userMessage is set by _getUserFriendlyErrorMessage() which provides safe messages
3280            eventPayload.errorMessage = error.userMessage || (error.status ? `Request failed with status ${error.status}` : 'An error occurred');
3281            eventPayload.errorName = error.name;
3282            eventPayload.errorStatus = error.status;
3283        }
3284        // Log to console with structured format for log aggregation
3285        // eslint-disable-next-line no-console
3286        console.error(`[HomeValuation] ${eventType}`, JSON.stringify(eventPayload));
3287        // If PostHog is available, send event for analytics
3288        // Wrap in try/catch to prevent SDK failures from blocking submissions
3289        if (this.window.posthog) try {
3290            this.window.posthog.capture(eventType, eventPayload);
3291        } catch (posthogError) {
3292            // eslint-disable-next-line no-console
3293            console.error('[HomeValuation] PostHog capture failed:', posthogError);
3294        }
3295    }
3296    /**
3297   * Maps error types to user-friendly messages
3298   * @param {Error} error - The error object
3299   * @returns {string} - User-friendly message
3300   */ _getUserFriendlyErrorMessage(error) {
3301        if (error.name === 'AbortError' || error.message?.includes('timeout')) return 'Connection timed out. Please try again.';
3302        if (error.name === 'TypeError' && error.message?.includes('fetch')) return 'Unable to connect. Please check your internet connection and try again.';
3303        if (error.status === 503 || error.status === 502 || error.status === 504) return 'Service temporarily unavailable. Please try again in a moment.';
3304        if (error.status === 400) return 'Please check your information and try again.';
3305        return 'Something went wrong. Please try again or contact us directly.';
3306    }
3307    /**
3308   * Build formatted address string from structured address components
3309   * @param {Object} structuredAddress - Structured address object
3310   * @return {string} - Formatted address string
3311   */ _formatStructuredAddress(structuredAddress) {
3312        if (!structuredAddress || Object.keys(structuredAddress).length === 0) return '';
3313        const parts = [];
3314        // Line 1: streetNumber streetName addressLine2
3315        const line1 = [
3316            structuredAddress.streetNumber,
3317            structuredAddress.streetName,
3318            structuredAddress.addressLine2
3319        ].filter(Boolean).join(' ');
3320        parts.push(line1);
3321        // Line 2: city, state zipcode
3322        const cityState = [
3323            structuredAddress.city,
3324            structuredAddress.state
3325        ].filter(Boolean).join(', ');
3326        const line2 = [
3327            cityState,
3328            structuredAddress.zipcode
3329        ].filter(Boolean).join(' ');
3330        parts.push(line2);
3331        return parts.filter(Boolean).join(', ');
3332    }
3333    /**
3334   * Build home valuation data object
3335   * @param {Object} data - Form data
3336   * @param {string} homeValuationEstimate - Home valuation estimate
3337   * @param {Object} structuredAddress - Structured address object
3338   * @param {Object} coordinates - Coordinates object
3339   * @return {Object} - Home valuation data object
3340   */ _buildHomeValuationData(data, homeValuationEstimate, structuredAddress, coordinates) {
3341        // Build homeValuationAddress from structured address (validated by Google) if available
3342        // Format: streetNumber streetName, city, state zipcode, addressLine2
3343        const homeValuationAddress = this._formatStructuredAddress(structuredAddress) || this._getRawAddress(data);
3344        // Validate that we have an address before proceeding
3345        if (!homeValuationAddress) throw new Error('Unable to extract home valuation address from form data');
3346        // Required fields that must always be included
3347        const requiredFields = {
3348            companyId: data.companyId,
3349            homeValuationAddress: homeValuationAddress,
3350            homeValuationEstimate: homeValuationEstimate ? new Intl.NumberFormat('en-US', {
3351                style: 'currency',
3352                currency: 'USD',
3353                maximumFractionDigits: 0,
3354                minimumFractionDigits: 0
3355            }).format(homeValuationEstimate) : null,
3356            websiteId: data.page.websiteId,
3357            sourceUrl: data.activity.source_url
3358        };
3359        // Optional fields that will be filtered if empty
3360        const optionalFields = {
3361            leadEmailAddress: data.activity.author_email,
3362            leadFullName: data.activity.author_name,
3363            leadPhoneNumber: data.activity.author_phone,
3364            parcelId: data.activity.content?.parcelId,
3365            resourceId: data.page.pageMeta?.resourceId,
3366            pageId: data.page.pageId,
3367            sourceResource: data.page.pageMeta?.sourceResource,
3368            pageElementId: data.page.pageMeta?.pageElementId,
3369            formId: data.page.pageMeta?.formId,
3370            utmSource: data.activity.content?.utm_source,
3371            utmMedium: data.activity.content?.utm_medium,
3372            utmCampaign: data.activity.content?.utm_campaign,
3373            utmTerm: data.activity.content?.utm_term,
3374            utmContent: data.activity.content?.utm_content,
3375            utmId: data.activity.content?.utm_id,
3376            timeToSell: data.activity.content?.timeToSell,
3377            lookingToBuy: data.activity.content?.lookingToBuy,
3378            referrer: data.referrer,
3379            content: data.activity.content || {},
3380            fields: data.fields || {}
3381        };
3382        // Filter out empty strings from optional fields
3383        const filteredOptionalFields = this._filterEmptyStrings(optionalFields);
3384        return {
3385            ...requiredFields,
3386            ...filteredOptionalFields,
3387            // Add structured address and coordinates if they exist
3388            ...structuredAddress && {
3389                address: structuredAddress
3390            },
3391            ...coordinates && {
3392                coordinates: coordinates
3393            }
3394        };
3395    }
3396    /**
3397   * Validate address with Google Maps
3398   * @param {string} rawAddress - Raw address string
3399   * @returns {Promise<Object|null>} - Validated address data or null
3400   * @throws {Error} - If validation fails, error is thrown with userMessage
3401   */ async _validateAddressSafely(rawAddress) {
3402        if (!rawAddress) {
3403            // eslint-disable-next-line no-console
3404            console.error('Home valuation: No address found in form data');
3405            return null;
3406        }
3407        try {
3408            return await this._validateAddressWithGoogleMaps(rawAddress);
3409        } catch (error) {
3410            // eslint-disable-next-line no-console
3411            console.error('Error validating address with Google Maps:', error);
3412            // Attach user-friendly message and throw so user sees the error
3413            error.userMessage = this._getUserFriendlyErrorMessage(error);
3414            throw error;
3415        }
3416    }
3417    /**
3418   * Get home valuation estimate
3419   * @param {Object} validatedAddressData - Validated address data
3420   * @returns {Promise<number|null>} - Home valuation estimate or null
3421   * @throws {Error} - If estimate fetch fails, error is thrown with userMessage
3422   */ async _getHomeValuationEstimateSafely(validatedAddressData) {
3423        try {
3424            return await this._getHomeValuationEstimate(validatedAddressData);
3425        } catch (error) {
3426            // eslint-disable-next-line no-console
3427            console.error('Error getting home valuation estimate:', error);
3428            // Attach user-friendly message and throw so user sees the error
3429            error.userMessage = this._getUserFriendlyErrorMessage(error);
3430            throw error;
3431        }
3432    }
3433    /**
3434   * Parse response text into payload object
3435   * @param {string} text - Response text
3436   * @returns {Object} - Parsed payload
3437   */ _parseResponsePayload(text) {
3438        try {
3439            return text ? JSON.parse(text) : {};
3440        } catch  {
3441            return {
3442                raw: text
3443            };
3444        }
3445    }
3446    /**
3447   * Create error from failed response
3448   * @param {Object} payload - Response payload
3449   * @param {number} status - HTTP status code
3450   * @returns {Error} - Error object with status and payload
3451   */ _createResponseError(payload, status) {
3452        const errorMessage = payload && typeof payload === 'object' && Object.keys(payload).length ? payload.message || JSON.stringify(payload) : 'Request failed';
3453        const error = new Error(errorMessage);
3454        // Preserve payload properties if it's an object
3455        if (payload && typeof payload === 'object' && Object.keys(payload).length) Object.assign(error, payload);
3456        // Preserve numeric HTTP status - must be set after Object.assign
3457        // to ensure it takes precedence over any status in payload
3458        error.status = status;
3459        return error;
3460    }
3461    /**
3462   * Submit lead to API endpoint
3463   * @param {string} leadRoute - API endpoint URL
3464   * @param {Object} homeValuationData - Data to submit
3465   * @returns {Promise<Object>} - Submission result
3466   */ async _submitLead(leadRoute, homeValuationData) {
3467        const controller = new AbortController();
3468        const timeoutId = setTimeout(()=>controller.abort(), 10000);
3469        try {
3470            const response = await fetch(leadRoute, {
3471                method: 'POST',
3472                headers: {
3473                    'Content-Type': 'application/json'
3474                },
3475                body: JSON.stringify(homeValuationData),
3476                signal: controller.signal
3477            });
3478            clearTimeout(timeoutId);
3479            const text = await response.text();
3480            const payload = this._parseResponsePayload(text);
3481            if (!response.ok) throw this._createResponseError(payload, response.status);
3482            if (payload && payload.status === 'success' && payload.redirectUrl) {
3483                this.window.location.href = payload.redirectUrl;
3484                return {
3485                    redirected: true,
3486                    url: payload.redirectUrl
3487                };
3488            }
3489            return payload;
3490        } catch (error) {
3491            clearTimeout(timeoutId);
3492            throw error;
3493        }
3494    }
3495    /**
3496   * Submit home valuation request with Google Maps validation
3497   * @param {Object} data
3498   * @return {Promise<Object>}
3499   */ async _submitHomeValuationRequest(data) {
3500        const { config: config } = this;
3501        // Use websiteApiGatewayUrl from config
3502        if (!config.websiteApiGatewayUrl) throw new Error('websiteApiGatewayUrl not configured for home valuation');
3503        // Log submission started
3504        this._logLeadEvent('home_valuation_submission_started', data);
3505        try {
3506            // Validate address with Google Maps
3507            const rawAddress = this._getRawAddress(data);
3508            let validatedAddressData = null;
3509            try {
3510                validatedAddressData = await this._validateAddressSafely(rawAddress);
3511            } catch (error) {
3512                // Error already has userMessage from _validateAddressSafely
3513                this._logLeadEvent('home_valuation_address_validation_failed', data, error);
3514                throw error;
3515            }
3516            // Get home valuation estimate.
3517            // The estimate is best-effort: many valid properties (e.g. commercial
3518            // parcels or addresses without AVM coverage) have no estimate and the
3519            // estimate endpoint returns a non-OK status for them. A missing estimate
3520            // must never block lead capture, so we log the failure and continue with
3521            // a null estimate rather than aborting the whole submission.
3522            let homeValuationEstimate = null;
3523            try {
3524                homeValuationEstimate = await this._getHomeValuationEstimateSafely(validatedAddressData);
3525            } catch (error) {
3526                // Error already has userMessage from _getHomeValuationEstimateSafely
3527                this._logLeadEvent('home_valuation_estimate_failed', data, error);
3528                homeValuationEstimate = null;
3529            }
3530            // Extract structured address and coordinates from Google Maps validation
3531            const { structuredAddress: structuredAddress, coordinates: coordinates } = this._extractAddressAndCoordinates(validatedAddressData);
3532            const leadRoute = `${config.websiteApiGatewayUrl}${$2aefad83322125c9$var$homeValuationRoute}`;
3533            const homeValuationData = this._buildHomeValuationData(data, homeValuationEstimate, structuredAddress, coordinates);
3534            const result = await this._submitLead(leadRoute, homeValuationData);
3535            // Log success
3536            this._logLeadEvent('home_valuation_submission_success', data);
3537            return result;
3538        } catch (error) {
3539            // Ensure error has user-friendly message (may already be set by helper methods)
3540            if (!error.userMessage) error.userMessage = this._getUserFriendlyErrorMessage(error);
3541            this._logLeadEvent('home_valuation_submission_failed', data, error);
3542            throw error;
3543        }
3544    }
3545    /**
3546   * Validate address using Google Maps Address Validation API
3547   * @param {string} addressStr - The address string to validate
3548   * @returns {Promise<Object|null>} - Validated address data or null if validation fails
3549   */ async _validateAddressWithGoogleMaps(addressStr) {
3550        const { config: config, window: window } = this;
3551        // Ensure Google Maps API key is loaded
3552        let apiKey = config.googleMapsAPIKey;
3553        if (!apiKey && window.luxuryPresence?.mapApiLoader) apiKey = await window.luxuryPresence.mapApiLoader.getMapApiKey();
3554        if (!apiKey) throw new Error('Google Maps API key not configured');
3555        const controller = new AbortController();
3556        const timeoutId = setTimeout(()=>controller.abort(), 10000);
3557        try {
3558            const response = await fetch(`https://addressvalidation.googleapis.com/v1:validateAddress?key=${apiKey}`, {
3559                method: 'POST',
3560                headers: {
3561                    'Content-Type': 'application/json'
3562                },
3563                body: JSON.stringify({
3564                    address: {
3565                        addressLines: [
3566                            addressStr
3567                        ]
3568                    },
3569                    enableUspsCass: false
3570                }),
3571                signal: controller.signal
3572            });
3573            clearTimeout(timeoutId);
3574            if (!response.ok) {
3575                const error = new Error(`Address validation failed: ${response.status}`);
3576                error.status = response.status;
3577                throw error;
3578            }
3579            return response.json();
3580        } catch (error) {
3581            clearTimeout(timeoutId);
3582            throw error;
3583        }
3584    }
3585    /**
3586   * Check if structured address has all mandatory fields
3587   * @param {Object} structuredAddress - Structured address object
3588   * @return {boolean}
3589   */ _hasMandatoryAddressFields(structuredAddress) {
3590        return !!(structuredAddress.streetNumber && structuredAddress.streetName && structuredAddress.city && structuredAddress.state && structuredAddress.zipcode);
3591    }
3592    /**
3593   * Log missing mandatory address fields
3594   * @param {Object} structuredAddress - Structured address object
3595   */ _logMissingAddressFields(structuredAddress) {
3596        const missingFields = [];
3597        if (!structuredAddress.streetNumber) missingFields.push('streetNumber');
3598        if (!structuredAddress.streetName) missingFields.push('streetName');
3599        if (!structuredAddress.city) missingFields.push('city');
3600        if (!structuredAddress.state) missingFields.push('state');
3601        if (!structuredAddress.zipcode) missingFields.push('zipcode');
3602        // eslint-disable-next-line no-console
3603        console.log('Home valuation estimate skipped - missing required fields:', missingFields.join(', '), 'Available fields:', Object.keys(structuredAddress).join(', '));
3604    }
3605    /**
3606   * Build query string from structured address
3607   * @param {Object} structuredAddress - Structured address object
3608   * @return {string}
3609   */ _buildAddressQueryString(structuredAddress) {
3610        return Object.entries(structuredAddress).map(([key, value])=>`${encodeURIComponent(key)}=${encodeURIComponent(value)}`).join('&');
3611    }
3612    /**
3613   * GET home valuation estimate
3614   * @param {string} address
3615   * @param {Object} validatedAddressData - Google Maps validated address data
3616   * @return {Promise<number|null>}
3617   */ async _getHomeValuationEstimate(validatedAddressData = null) {
3618        const { config: config } = this;
3619        if (!config.websiteApiGatewayUrl) throw new Error('websiteApiGatewayUrl not configured');
3620        const base = `${config.websiteApiGatewayUrl}${$2aefad83322125c9$var$homeValuationRoute}`;
3621        // Check if we have validated address data
3622        if (!validatedAddressData?.result?.address?.addressComponents) return null;
3623        const structuredAddress = this._transformAddressComponents(validatedAddressData.result.address.addressComponents);
3624        // Check if all mandatory fields exist
3625        if (!this._hasMandatoryAddressFields(structuredAddress)) {
3626            this._logMissingAddressFields(structuredAddress);
3627            return null;
3628        }
3629        // Build URL with query string
3630        const qs = this._buildAddressQueryString(structuredAddress);
3631        const homeValURL = `${base}?${qs}`;
3632        const controller = new AbortController();
3633        const timeoutId = setTimeout(()=>controller.abort(), 10000);
3634        try {
3635            const response = await fetch(homeValURL, {
3636                headers: {
3637                    Accept: 'application/json'
3638                },
3639                signal: controller.signal
3640            });
3641            clearTimeout(timeoutId);
3642            if (!response.ok) {
3643                const error = new Error(`Home valuation estimate failed: ${response.status}`);
3644                error.status = response.status;
3645                throw error;
3646            }
3647            const data = await response.json();
3648            return data?.valueDollars ?? null;
3649        } catch (error) {
3650            clearTimeout(timeoutId);
3651            // Re-throw to allow retry logic to handle it
3652            throw error;
3653        }
3654    }
3655}
3656
3657
3658const $e10bd00497be8876$export$97de66002300ed70 = 'middleName';
3659// Default lead fields
3660const $e10bd00497be8876$var$DEFAULT_LEAD_FIELDS = [
3661    'name',
3662    'firstName',
3663    'lastName',
3664    $e10bd00497be8876$export$97de66002300ed70,
3665    'email',
3666    'phone',
3667    'phoneNumber',
3668    'source',
3669    'message',
3670    'mlsId',
3671    'sourceUrl'
3672];
3673class $e10bd00497be8876$export$3c5380623cf51249 extends (0, $7c391e2f7931d60d$export$3b5bd9381a52554c) {
3674    /**
3675   * Initialize Contact Form Controller at build time
3676   * @param { ConfigController } config
3677   * @param {Window} window
3678   * @param {Document} document
3679   */ constructor(config, window, document){
3680        super(config, window, document);
3681        this.forms = [];
3682        this.homeValuationService = new (0, $2aefad83322125c9$export$2e2bcd8739ae039)(config, window, document);
3683    }
3684    /**
3685   * Initialize Contact Form Controller at run time
3686   * Attach handlers and events to DOM
3687   * @param {Object} options
3688   */ initialize(options = {}) {
3689        try {
3690            const { document: document } = this;
3691            const { selector: selector } = options;
3692            let forms = [];
3693            if (selector) forms = document.querySelectorAll(`${selector} form[data-type="contact-form"]`);
3694            else forms = document.querySelectorAll('form[data-type="contact-form"]');
3695            forms.forEach((form)=>{
3696                this._attachSubmitHandler(form);
3697            // this._attachValidation(form);
3698            });
3699            this.forms = this.forms.concat(forms);
3700        } catch (e) {
3701            // eslint-disable-next-line no-console
3702            console.log(e);
3703        }
3704    }
3705    /**
3706   * Controllers must implement a "destroy" method to be called
3707   * after page navigation to remove event handlers / cleanup
3708   */ destroy() {
3709        this.forms = [];
3710    }
3711    /**
3712   * Handle submit from global context
3713   * @param {HTMLFormElement} form
3714   */ submitForm(form) {
3715        this._handleSubmit(null, form).catch((e)=>console.error(e));
3716    }
3717    /**
3718   * Attach submit event for form
3719   * @param {HTMLFormElement} contactForm
3720   */ _attachValidation(contactForm) {
3721        const { window: window } = this;
3722        const inputs = contactForm.querySelectorAll('input, select, textarea');
3723        inputs.forEach((input)=>{
3724            window.luxuryPresence.validation.applyFieldValidation(input);
3725        });
3726    }
3727    /**
3728   * Attach submit event for form
3729   * @param {HTMLFormElement} contactForm
3730   */ _attachSubmitHandler(contactForm) {
3731        contactForm.addEventListener('submit', (e)=>this._handleSubmit(e, contactForm));
3732    }
3733    /**
3734   * Extract and process form values
3735   * @param {HTMLFormElement} contactForm
3736   * @return {Object} - Processed form values
3737   */ _extractFormValues(contactForm) {
3738        const formData = new FormData(contactForm);
3739        const values = {};
3740        const nameParts = [];
3741        const nameKeyRegex = /^name(?:-\d+)?$/;
3742        formData.forEach((value, key)=>{
3743            if (typeof value === 'string') {
3744                const curr = value.trim();
3745                if (nameKeyRegex.test(key) && curr) nameParts.push(curr);
3746                const prev = values[key];
3747                values[key] = prev ? `${prev} ${curr}` : curr;
3748            } else values[key] = value;
3749        });
3750        if (nameParts.length) values.name = nameParts.join(' ').trim();
3751        else if (!values.name && values.firstName) {
3752            values.name = values.firstName;
3753            if (values.lastName) values.name += ` ${values.lastName}`;
3754        }
3755        return values;
3756    }
3757    /**
3758   * Build submission data object
3759   * @param {Object} values - Form values
3760   * @param {Object} fields - Form fields
3761   * @param {HTMLFormElement} contactForm - Form element
3762   * @return {Object} - Submission data
3763   */ _buildSubmissionData(values, fields, contactForm) {
3764        const { window: window, config: config } = this;
3765        const content = Object.keys(values).filter((key)=>!$e10bd00497be8876$var$DEFAULT_LEAD_FIELDS.includes(key)).reduce((result, key)=>{
3766            // eslint-disable-next-line
3767            result[key] = values[key];
3768            return result;
3769        }, {});
3770        const { pageId: pageId, companyId: companyId, websiteId: websiteId, pageMeta: pageMeta } = config;
3771        const utm = window.localStorage.getItem('utm_vars') || '{}';
3772        const referrer = window.localStorage.getItem('referrer') || '';
3773        const formId = this._getFormId(contactForm);
3774        return {
3775            activity: {
3776                author_email: values.email,
3777                author_name: values.name,
3778                author_phone: values.phone || values.phoneNumber,
3779                activity_source: values.source || 'CONTACT_INQUIRY',
3780                comments_attributes: [
3781                    {
3782                        text: values.message || undefined
3783                    }
3784                ],
3785                source_url: window.location.href,
3786                content: {
3787                    ...content,
3788                    ...JSON.parse(utm)
3789                }
3790            },
3791            page: {
3792                pageId: pageId,
3793                companyId: companyId,
3794                websiteId: websiteId,
3795                pageMeta: {
3796                    ...pageMeta,
3797                    formId: formId
3798                }
3799            },
3800            companyId: companyId,
3801            referrer: referrer,
3802            fields: fields
3803        };
3804    }
3805    /**
3806   * Handle successful form submission
3807   * @param {HTMLFormElement} contactForm - Form element
3808   */ _handleSubmissionSuccess(contactForm) {
3809        const { window: window } = this;
3810        const closeDelay = contactForm.dataset.delay || (0, $a3e97e89bbc2a366$export$f037eeffb5561205);
3811        contactForm.classList.remove('loading');
3812        contactForm.classList.remove('error');
3813        contactForm.classList.add('success');
3814        // TODO: Review producer and classic to deprecate "hide"
3815        contactForm.querySelectorAll('.success').forEach((el)=>el.classList.remove('hide'));
3816        contactForm.dispatchEvent(new Event('formsubmitted'));
3817        // Any successful lead submit credits the Google Ads lead conversion
3818        // (reuses the existing `generate_lead` action), once per session.
3819        (0, $3ec2bf3965f87ecc$export$e70565180c0e6950)(this.window, this.document);
3820        setTimeout(()=>{
3821            window.lpUI.hideClosestModal(contactForm);
3822            contactForm.reset();
3823            window.lpUI.sideMenuHide();
3824            contactForm.querySelectorAll('.success').forEach((el)=>el.classList.add('hide'));
3825            contactForm.classList.remove('success');
3826        }, closeDelay);
3827    }
3828    /**
3829   * Submit Contact Form Handler
3830   * @param {Event} e
3831   * @param {HTMLFormElement} contactForm
3832   * @return {Promise<Object>}
3833   */ async _handleSubmit(e, contactForm) {
3834        if (e) e.preventDefault();
3835        if (contactForm.classList.contains('loading')) // Form already submitting
3836        return;
3837        // Hide any previous error message and clear error state
3838        this._hideSubmissionError(contactForm);
3839        contactForm.classList.remove('error');
3840        contactForm.classList.add('loading');
3841        try {
3842            // Extract form values first (before async operations)
3843            const values = this._extractFormValues(contactForm);
3844            // TODO: HoneyPot should still send request
3845            if (values.middleName) {
3846                contactForm.classList.remove('loading');
3847                return;
3848            }
3849            const fields = this._getFields(contactForm);
3850            const data = this._buildSubmissionData(values, fields, contactForm);
3851            await this._submitLeadRequest(data);
3852            this._sendGAEvent(data);
3853            this._handleSubmissionSuccess(contactForm);
3854        } catch (err) {
3855            // eslint-disable-next-line no-console
3856            console.error('Form submission failed:', err);
3857            contactForm.dispatchEvent(new Event('formsubmiterror'));
3858            contactForm.classList.remove('loading');
3859            contactForm.classList.add('error');
3860            // Show user-friendly error message if available (from home valuation service)
3861            if (err.userMessage) this._showSubmissionError(contactForm, err.userMessage);
3862            else this._showSubmissionError(contactForm, 'Something went wrong. Please try again.');
3863        }
3864    }
3865    /**
3866   * Alias anonymous user with canonical ID using event bus
3867   * Links the user's anonymous browsing session to their canonical identity
3868   * @param {Object} data - Form submission data
3869   * @private
3870   */ _aliasUserWithEventBus(data) {
3871        try {
3872            // Check if event bus library and required methods are available
3873            if (!this.window.eventBusProvider?.alias || !this.window.eventBusProvider?.isIdentified || !this.window.eventBusProvider?.getDistinctId || !this.window.LuxuryPresenceEventBus?.generateUUIDv5FromCompanyEmail) return; // Event bus or required methods not available
3874            // Skip if user is already identified
3875            if (this.window.eventBusProvider.isIdentified()) {
3876                console.log('[EventBus] User already identified, skipping alias');
3877                return;
3878            }
3879            const email = data.activity?.author_email;
3880            const { companyId: companyId } = this.config;
3881            if (!email || !companyId) {
3882                console.warn('[EventBus] Missing required data for user alias');
3883                return;
3884            }
3885            // Get the anonymous distinct ID from PostHog
3886            const anonId = this.window.eventBusProvider.getDistinctId();
3887            if (!anonId) {
3888                console.warn('[EventBus] No anonymous ID available for alias');
3889                return;
3890            }
3891            // Generate deterministic canonical ID from company + email
3892            const canonicalId = this.window.LuxuryPresenceEventBus.generateUUIDv5FromCompanyEmail(companyId, email);
3893            // Create alias linking anonymous ID to canonical ID
3894            this.window.eventBusProvider.alias({
3895                anonId: anonId,
3896                canonicalId: canonicalId
3897            });
3898            console.log('[EventBus] User aliased with canonical ID');
3899        } catch (error) {
3900            // Never block form submission due to analytics errors
3901            console.error('[EventBus] User alias failed:', error);
3902        }
3903    }
3904    /**
3905   * Send Lead Request
3906   * @param {Object} data
3907   * @return {Promise<Object>}
3908   */ async _submitLeadRequest(data) {
3909        const { config: config } = this;
3910        // Alias user with event bus before submitting the lead
3911        this._aliasUserWithEventBus(data);
3912        if (config.myhomeDashboardEnabled && (data.activity?.activity_source === 'HOME_VALUATION' || data.activity?.activity_source === 'HOME_VALUE')) return this.homeValuationService._submitHomeValuationRequest(data);
3913        const leadRoute = `${config.leadIngesterUrl}/api/v1/leads`;
3914        return fetch(leadRoute, {
3915            method: 'POST',
3916            headers: {
3917                'Content-Type': 'application/json'
3918            },
3919            body: JSON.stringify(data)
3920        }).then((response)=>{
3921            if (!response.ok) return response.json().then((error)=>{
3922                throw error;
3923            });
3924            return response.json();
3925        });
3926    }
3927    /**
3928   * Send GA event
3929   * @param {Object} data
3930   */ _sendGAEvent(data) {
3931        const { document: document } = this;
3932        let event = {
3933            hitType: 'event',
3934            eventCategory: 'button',
3935            eventAction: 'click'
3936        };
3937        switch(data.activity.activity_source){
3938            case 'NEWSLETTER_SIGNUP':
3939                event.eventLabel = 'Newsletter';
3940                document.sendGoogleTagManagerEvent('event', 'newsletter_signup');
3941                break;
3942            case 'HOME_SEARCH':
3943                event.eventLabel = 'HomeSearch';
3944                document.sendGoogleTagManagerEvent('event', 'home_search');
3945                break;
3946            case 'HOME_VALUE':
3947            case 'HOME_VALUATION':
3948                event.eventLabel = 'HomeValue';
3949                document.sendGoogleTagManagerEvent('event', 'home_valuation');
3950                break;
3951            case 'EBOOK':
3952                event.eventLabel = 'Ebook';
3953                document.sendGoogleTagManagerEvent('event', 'ebook_download');
3954                break;
3955            case 'CONTACT_INQUIRY':
3956            default:
3957                // for contact forms, Marketing has requested that they see a page-view of 'thank-you' as indication of success
3958                // Note that this will break if we have actual page with url of /thank-you
3959                event = {
3960                    hitType: 'pageview',
3961                    page: '/thank-you'
3962                };
3963                document.sendGoogleTagManagerEvent('event', 'contact_inquiry');
3964                break;
3965        }
3966        document.sendGoogleAnalyticsEvent(event);
3967    }
3968    /**
3969   * Gather fields / schema for form, used for display in CRM
3970   * @param {HTMLFormElement} form
3971   * @return {Object}
3972   */ _getFields(form) {
3973        const inputs = form.querySelectorAll('input, select, textarea');
3974        const fields = {};
3975        inputs.forEach((input)=>{
3976            const { id: id, name: name, type: inputType } = input;
3977            if (name === $e10bd00497be8876$export$97de66002300ed70) // Honeypot continue
3978            return true;
3979            let label = '';
3980            if (id) {
3981                const labelNode = form.querySelector(`label[for='${id}']`);
3982                if (labelNode) label = labelNode.textContent.trim();
3983                else if (input.placeholder) label = input.placeholder.trim();
3984            }
3985            fields[name] = {
3986                label: label,
3987                type: input.tagName,
3988                inputType: input.tagName === 'INPUT' ? inputType : 'text'
3989            };
3990        });
3991        return fields;
3992    }
3993    /**
3994   * Figure out relevant section or div ID for form
3995   * @param {HTMLFormElement} form
3996   * @return {string}
3997   */ _getFormId(form) {
3998        const SELECTORS = "section[id^='section-'], footer[id], .modal[id^='modal-']";
3999        const parent = form.closest(SELECTORS);
4000        return parent?.id ? this._cleanFormId(parent.id) : '';
4001    }
4002    /**
4003   * Remove prefix from formID
4004   * @param {string} formId
4005   * @return {string}
4006   */ _cleanFormId(formId) {
4007        const PREFIXES = [
4008            'section-',
4009            'modal-'
4010        ];
4011        for (const prefix of PREFIXES){
4012            if (formId.startsWith(prefix)) return formId.substring(prefix.length);
4013        }
4014        return formId;
4015    }
4016    /**
4017   * Show submission error message on form
4018   * @param {HTMLFormElement} form
4019   * @param {string} message
4020   */ _showSubmissionError(form, message) {
4021        const errorEl = form.querySelector('.submission-error-message');
4022        if (errorEl) {
4023            errorEl.textContent = message || 'Something went wrong. Please try again.';
4024            errorEl.style.display = 'block';
4025        }
4026    }
4027    /**
4028   * Hide submission error message on form
4029   * @param {HTMLFormElement} form
4030   */ _hideSubmissionError(form) {
4031        const errorEl = form.querySelector('.submission-error-message');
4032        if (errorEl) errorEl.style.display = 'none';
4033    }
4034}
4035
4036
4037
4038const $ea6901fdf47e0ec1$var$CALLBACK = '__googleMapsCallback';
4039const $ea6901fdf47e0ec1$var$GOOGLE_MAPS_URL = 'https://maps.googleapis.com/maps/api/js';
4040const $ea6901fdf47e0ec1$export$76299006759be400 = 1024;
4041const $ea6901fdf47e0ec1$var$KEY_FETCH_ATTEMPTS = 3;
4042const $ea6901fdf47e0ec1$var$KEY_RETRY_BASE_DELAY_MS = 300;
4043const $ea6901fdf47e0ec1$var$KEY_FAILURE_FLAG = 'lp_map_key_failed';
4044class $ea6901fdf47e0ec1$export$3c19195edca3fa5c extends (0, $7c391e2f7931d60d$export$3b5bd9381a52554c) {
4045    /**
4046   * Initialize Button Controller at build time
4047   * @param { ConfigController } config
4048   * @param {Window} window
4049   * @param {Document} document
4050   */ constructor(config, window, document){
4051        super(config, window, document);
4052        this.retries = 3;
4053        this.callbacks = [];
4054        this.id = `__googleMapsScriptId${Date.now()}`;
4055        this._apiKey = '';
4056        this.reset();
4057    }
4058    /**
4059   * Set the Google Maps api key
4060   * @param {string} apiKey
4061   */ set apiKey(apiKey) {
4062        this._apiKey = apiKey;
4063        this.config.setGoogleMapsAPIKey(apiKey);
4064    }
4065    /**
4066   * Get the Google Maps api key
4067   * @return {string}
4068   */ get apiKey() {
4069        return this._apiKey;
4070    }
4071    /**
4072   * Reset the loader state.
4073   */ reset() {
4074        this.deleteScript();
4075        this.done = false;
4076        this.loading = false;
4077        this.failed = false;
4078        this.errors = [];
4079        this.onerrorEvent = null;
4080    }
4081    /**
4082   * Destroy
4083   */ destroy() {
4084        this.reset();
4085    }
4086    /**
4087   * get map api Key
4088   * @return {Promise<string>}
4089   */ async getMapApiKey() {
4090        if (this.apiKey) return this.apiKey;
4091        const hadPreviousFailure = this._hadPreviousFailure();
4092        let recoveryReported = false;
4093        for(let attempt = 1; attempt <= $ea6901fdf47e0ec1$var$KEY_FETCH_ATTEMPTS; attempt += 1){
4094            const reportRecovery = hadPreviousFailure && !recoveryReported;
4095            try {
4096                // eslint-disable-next-line no-await-in-loop
4097                const response = await fetch(this._getMapKeyUrl(attempt, reportRecovery));
4098                // The request reached the server, so a recovery marker on it was
4099                // delivered and must not be repeated on later attempts or pages. A
4100                // rejected fetch never arrived, so the marker moves to the next
4101                // attempt.
4102                recoveryReported = recoveryReported || reportRecovery;
4103                this._setFailureFlag(false);
4104                if (!response.ok) throw new Error(`Failed to fetch API key: ${response.status}`);
4105                // eslint-disable-next-line no-await-in-loop
4106                const code = await response.text();
4107                if (!code) return '';
4108                this.apiKey = code;
4109                return this.apiKey;
4110            } catch (e) {
4111                // eslint-disable-next-line no-console
4112                console.error(e);
4113                if (attempt < $ea6901fdf47e0ec1$var$KEY_FETCH_ATTEMPTS) // eslint-disable-next-line no-await-in-loop
4114                await this._delay($ea6901fdf47e0ec1$var$KEY_RETRY_BASE_DELAY_MS * 2 ** (attempt - 1));
4115            }
4116        }
4117        this._setFailureFlag(true);
4118        return '';
4119    }
4120    /**
4121   * Build the map key request url. Retries carry their attempt number, and a
4122   * single request per session carries the recovery marker, so both are
4123   * countable in existing request logs without new infrastructure.
4124   * @param {number} attempt 1-based attempt number
4125   * @param {boolean} reportRecovery tag this request as following a session
4126   *   in which every attempt failed
4127   * @return {string}
4128   */ _getMapKeyUrl(attempt, reportRecovery) {
4129        const params = [];
4130        if (attempt > 1) params.push(`attempt=${attempt}`);
4131        if (reportRecovery) params.push('recovered_after_failure=1');
4132        const query = params.length ? `?${params.join('&')}` : '';
4133        return `${this._getBaseUrl()}/api/v1/map${query}`;
4134    }
4135    /**
4136   * Whether an earlier attempt in this session exhausted all retries.
4137   * @return {boolean}
4138   */ _hadPreviousFailure() {
4139        try {
4140            return this.window.sessionStorage.getItem($ea6901fdf47e0ec1$var$KEY_FAILURE_FLAG) === '1';
4141        } catch (e) {
4142            // Storage can throw when disabled (private browsing); absence of the
4143            // flag is the safe default.
4144            return false;
4145        }
4146    }
4147    /**
4148   * Record or clear the session-level key fetch failure flag.
4149   * @param {boolean} failed
4150   */ _setFailureFlag(failed) {
4151        try {
4152            if (failed) this.window.sessionStorage.setItem($ea6901fdf47e0ec1$var$KEY_FAILURE_FLAG, '1');
4153            else this.window.sessionStorage.removeItem($ea6901fdf47e0ec1$var$KEY_FAILURE_FLAG);
4154        } catch (e) {
4155        // Storage unavailable - reporting is best effort, never fatal.
4156        }
4157    }
4158    /**
4159   * @param {number} ms
4160   * @return {Promise}
4161   */ _delay(ms) {
4162        return new Promise((resolve)=>{
4163            this.window.setTimeout(resolve, ms);
4164        });
4165    }
4166    /**
4167   * CreateUrl returns the Google Maps JavaScript API script url ].
4168   * @return {string}
4169   */ async createUrl() {
4170        const apiKey = await this.getMapApiKey();
4171        // Google Maps loads successfully without a key and then fails at call time
4172        // with NoApiKeys, which produces a broken map and no load error. Refuse
4173        // instead, so the failure surfaces to the caller.
4174        if (!apiKey) throw new Error('Refusing to load Google Maps without an API key');
4175        let url = $ea6901fdf47e0ec1$var$GOOGLE_MAPS_URL;
4176        url += `?callback=${$ea6901fdf47e0ec1$var$CALLBACK}`;
4177        url += `&key=${apiKey}`;
4178        url += `&libraries=places`;
4179        return url;
4180    }
4181    /**
4182   * Set the script on document.
4183   */ async setScript() {
4184        if (this.document.getElementById(this.id)) {
4185            this.callback();
4186            return;
4187        }
4188        let url;
4189        try {
4190            url = await this.createUrl();
4191        } catch (e) {
4192            // eslint-disable-next-line no-console
4193            console.error(e);
4194            this.failed = true;
4195            this.loading = false;
4196            this.onerrorEvent = e;
4197            this.callback();
4198            return;
4199        }
4200        const script = this.document.createElement('script');
4201        script.id = this.id;
4202        script.type = 'text/javascript';
4203        script.src = url;
4204        script.onerror = this.loadErrorCallback.bind(this);
4205        script.defer = true;
4206        script.async = true;
4207        this.document.head.appendChild(script);
4208    }
4209    /**
4210   * Function to be called if script tag fails
4211   * @param {Error} e
4212   */ loadErrorCallback(e) {
4213        this.errors.push(e);
4214        if (this.errors.length <= this.retries) {
4215            const delay = this.errors.length * 2 ** this.errors.length;
4216            // eslint-disable-next-line no-console
4217            console.log(`Failed to load Google Maps script, retrying in ${delay} ms.`);
4218            setTimeout(()=>{
4219                this.deleteScript();
4220                this.setScript().catch((e)=>console.error(e));
4221            }, delay);
4222        } else {
4223            this.failed = true;
4224            this.onerrorEvent = e;
4225            this.callback();
4226        }
4227    }
4228    /**
4229   * Delete the script tag
4230   */ deleteScript() {
4231        const script = this.document.getElementById(this.id);
4232        if (script) script.remove();
4233    }
4234    /**
4235   * Load the Google Maps JavaScript API script and return a Promise.
4236   * @return {Promise}
4237   */ load() {
4238        return this.loadPromise();
4239    }
4240    /**
4241   * Load the Google Maps JavaScript API script and return a Promise.
4242   * @return {Promise}
4243   */ loadPromise() {
4244        return new Promise((resolve, reject)=>{
4245            this.loadCallback((err)=>{
4246                if (!err) resolve();
4247                else reject(err);
4248            });
4249        });
4250    }
4251    /**
4252   * Load the Google Maps JavaScript API script with a callback.
4253   * @param {Function<Event>} fn
4254   */ loadCallback(fn) {
4255        this.callbacks.push(fn);
4256        this.execute();
4257    }
4258    /**
4259   * Sets the callback function that will be sent as part of the script URL.
4260   */ setCallback() {
4261        this.window.__googleMapsCallback = this.callback.bind(this);
4262    }
4263    /**
4264   * Reset if failed
4265   */ resetIfRetryingFailed() {
4266        if (this.failed) this.reset();
4267    }
4268    /**
4269   * This is the function that we set the callback parameter to.
4270   */ callback() {
4271        this.done = true;
4272        this.loading = false;
4273        this.callbacks.forEach((cb)=>{
4274            cb(this.onerrorEvent);
4275        });
4276        this.callbacks = [];
4277    }
4278    /**
4279   * Set the script a if needed; set the callback
4280   */ execute() {
4281        if (this.window.google && this.window.google.maps && this.window.google.maps.version) // Google Maps already loaded
4282        this.callback();
4283        this.resetIfRetryingFailed();
4284        if (this.done) this.callback();
4285        else if (this.loading) ;
4286        else {
4287            this.loading = true;
4288            this.setCallback();
4289            this.setScript().catch((e)=>console.error(e));
4290        }
4291    }
4292    /**
4293   * get base url based on current config
4294   * @return {string}
4295   */ _getBaseUrl() {
4296        // Special handling for page builder since no wag available
4297        const { isBuilder: isBuilder, websiteApiGatewayUrl: websiteApiGatewayUrl } = this.config;
4298        return isBuilder ? websiteApiGatewayUrl : '';
4299    }
4300    /**
4301   * Resize static map requests to the max 1024px while preserving aspect ratio
4302   * @param {number} width
4303   * @param {number} height
4304   * @return {{width, height}}
4305   */ resizeStaticMapDimensions(width, height) {
4306        if (width <= $ea6901fdf47e0ec1$export$76299006759be400 && height <= $ea6901fdf47e0ec1$export$76299006759be400) return {
4307            width: width,
4308            height: height
4309        };
4310        // Size param ignored if dimensions exceed STATIC_MAP_MAX_DIM
4311        const ratio = Math.min($ea6901fdf47e0ec1$export$76299006759be400 / width, $ea6901fdf47e0ec1$export$76299006759be400 / height);
4312        return {
4313            width: parseInt(width * ratio),
4314            height: parseInt(height * ratio)
4315        };
4316    }
4317    /**
4318   * Convert theme to static api param object
4319   * @param {Object} theme
4320   * @return {Object}
4321   */ convertThemeToStaticApiUrl(theme) {
4322        // https://developers.google.com/maps/documentation/maps-static/style-reference
4323        // Google Maps Static API uses a special syntax for it's urls based on the interactive map styles
4324        return theme.map((t)=>{
4325            const styles = t.stylers.reduce((acc, s)=>{
4326                const visibility = s.visibility ? `visibility:${s.visibility}` : '';
4327                const color = s.color ? `color:${s.color.replace('#', '0x')}` : '';
4328                const lightness = s.lightness ? `lightness:${s.lightness}` : '';
4329                return `${acc}|${visibility}${color}${lightness}`;
4330            }, '');
4331            const element = t.elementType ? `|element:${t.elementType}` : '';
4332            return `feature:${t.featureType}${element}${styles}`;
4333        });
4334    }
4335    /**
4336   * generate digital signature for url
4337   * @param {string} queryString to sign
4338   * @return {Promise<string>} digitally signed url
4339   */ async getMapApiSignedUrl(queryString) {
4340        try {
4341            const response = await fetch(`${this._getBaseUrl()}/api/v1/map/signature?${queryString}`);
4342            if (!response.ok) throw new Error('Failed to fetch signed URL');
4343            const { url: url } = await response.json();
4344            return url;
4345        } catch (e) {
4346            // eslint-disable-next-line no-console
4347            console.error(e);
4348            return '';
4349        }
4350    }
4351    /**
4352   * Generate static map url
4353   * @param {number} lat
4354   * @param {number} lng
4355   * @param {number} zoom
4356   * @param {Object} theme
4357   * @param {number} srcWidth
4358   * @param {number} srcHeight
4359   * @return {string}
4360   */ generateStaticMapUrl(lat, lng, zoom, theme, srcWidth, srcHeight) {
4361        const baseUrl = 'https://maps.googleapis.com/maps/api/staticmap';
4362        const { width: width, height: height } = this.resizeStaticMapDimensions(srcWidth, srcHeight);
4363        const query = {
4364            center: `${lat},${lng}`,
4365            zoom: zoom,
4366            scale: 2,
4367            size: `${width}x${height}`,
4368            key: this.apiKey
4369        };
4370        if (theme) query.style = this.convertThemeToStaticApiUrl(theme);
4371        const params = new URLSearchParams();
4372        Object.entries(query).forEach(([key, value])=>{
4373            if (Array.isArray(value)) value.forEach((v)=>params.append(key, v.toString()));
4374            else params.append(key, value.toString());
4375        });
4376        return `${baseUrl}?${params.toString()}`;
4377    }
4378    /**
4379   * Generate static map url with digital signature
4380   * @param {Object} {
4381   *  srcWidth {number}, required
4382   *  srcHeight {number}, required
4383   *  theme {array},
4384   *  center: `${lat},${lng}`, required
4385   *  zoom: number, required
4386   *  markers: `${lat},${lng}`,
4387   *  scale: number,
4388   *  otherQueryParams... (these must match what is compatible with google maps static api query params)
4389   * }
4390   * @return {Promise<string>} digitally signed url
4391   */ async generateDigitallySignedStaticMapUrl({ srcWidth: srcWidth, srcHeight: srcHeight, theme: theme, ...query }) {
4392        const { width: width, height: height } = this.resizeStaticMapDimensions(srcWidth, srcHeight);
4393        const queryParams = {
4394            ...query,
4395            size: `${width}x${height}`
4396        };
4397        if (theme) queryParams.style = this.convertThemeToStaticApiUrl(theme);
4398        const params = new URLSearchParams();
4399        Object.entries(queryParams).forEach(([key, value])=>{
4400            if (Array.isArray(value)) value.forEach((v)=>params.append(key, v.toString()));
4401            else params.append(key, value.toString());
4402        });
4403        const queryString = params.toString();
4404        try {
4405            // fetch digitally signed url
4406            return await this.getMapApiSignedUrl(queryString);
4407        } catch (e) {
4408            console.error(e);
4409            return '';
4410        }
4411    }
4412}
4413
4414
4415/* eslint-disable import/prefer-default-export */ 
4416
4417class $0a0ad49f13c0b8fd$export$ba9afeb75f20f616 extends (0, $7c391e2f7931d60d$export$3b5bd9381a52554c) {
4418    // constructor is not needed as it is inherited from BaseController
4419    /**
4420   * Controllers must implement a "destroy" method to be called
4421   * after page navigation to remove event handlers / cleanup
4422   */ destroy() {}
4423    /**
4424   * Places (re-places) a value into the query string under specified key
4425   *   or removes it if new value is null or undefined
4426   * @param {string} key
4427   * @param {string|null|undefined|object|array} value
4428   * @param {string} url - defaults to window.location.href
4429   * @return {string}
4430   */ // eslint-disable-next-line sonarjs/cognitive-complexity
4431    updateQueryString(key, value, url) {
4432        // https://stackoverflow.com/questions/5999118/how-can-i-add-or-update-a-query-string-parameter
4433        if (!url) // eslint-disable-next-line
4434        url = this.window.location.href;
4435        let re = new RegExp(`([?&])${key}=.*?(&|#|$)`, 'i');
4436        let replacement = '';
4437        if (typeof value !== 'undefined' && value !== null) {
4438            if (Array.isArray(value)) {
4439                if (value.length) replacement = this.serializeArray(key, value);
4440            } else if (typeof value === 'object') {
4441                re = new RegExp(`([?&])${key}\\[[^=]*\\]=.*?(&|#|$)`, 'i');
4442                replacement = this.serializeObj(value, '', key);
4443            } else replacement = `${key}=${encodeURIComponent(value)}`;
4444        }
4445        const hash = url.split('#');
4446        let result = hash[0];
4447        if (re.test(url)) {
4448            let clean = result;
4449            replacement = replacement ? `$1${replacement}$2` : '$1';
4450            while(re.test(clean)){
4451                result = clean.replace(re, replacement);
4452                clean = clean.replace(re, '$1');
4453            }
4454            result = result.replace(/(&|\?)$/, '');
4455        } else if (replacement) {
4456            const separator = result.indexOf('?') !== -1 ? '&' : '?';
4457            result += `${separator}${replacement}`;
4458        }
4459        if (typeof hash[1] !== 'undefined' && hash[1] !== null) result += `#${hash[1]}`;
4460        return result;
4461    }
4462    /**
4463   * Returns variable from query string specified by parameter name
4464   * @param {string} name
4465   * @param {string} url defaults to window.location.href
4466   * @return {string|null}
4467   */ getParameterByName(name, url) {
4468        if (!url) // eslint-disable-next-line
4469        url = this.window.location.href;
4470        // eslint-disable-next-line
4471        name = name.replace(/[[\]]/g, '\\$&');
4472        const regex = new RegExp(`[?&]${name}(=([^&#]*)|&|#|$)`);
4473        let results = Array.from(RegExp.prototype[Symbol.matchAll].call(regex, url)).flat();
4474        // check for object like syntax where the last value can be an array eg. advancedFilters[query][statusIds][in][0] or advancedFilters[query][city]
4475        if (!results.length) {
4476            const objRegex = new RegExp(`[?&]${name}(\\[.*?\\])=(.*?)(?=&|#|$)`, 'g');
4477            results = Array.from(RegExp.prototype[Symbol.matchAll].call(objRegex, url)).flat();
4478            return this._parseParamToObject(results, name === 'advancedFilters');
4479        }
4480        // For multiple param values, eg arrays
4481        /* Results from regex match all come in this form:
4482    [ '&advancedFilters[query][statusIds][in]=uuid-segundo-123', '[query][statusIds][in]', 'uuid-segundo-123' ]
4483    So using every third value will be the actual value and the second value will be the path
4484    */ if (results.length > 3) return results.reduce((acc, value, index)=>{
4485            if ((index + 1) % 3 === 0) acc.push(decodeURIComponent(value.replace(/\+/g, ' ')));
4486            return acc;
4487        }, []);
4488        if (!results[2]) return '';
4489        return decodeURIComponent(results[2].replace(/\+/g, ' '));
4490    }
4491    /**
4492   * Generates section specific key to store page number in the URL
4493   * @param {string} sectionDomId
4494   * @return {string}
4495   */ makePageKey(sectionDomId) {
4496        return sectionDomId.replace('section-', '').replace(/-/g, '');
4497    }
4498    /**
4499   * Generates specific key to store parameter in the URL
4500   * uses prevsiouly calculated baseKey for section specific parameters
4501   * @param {Object} formParam
4502   * @param {string} baseKey pre-calculated base for section specific parameters
4503   * @return {string}
4504   */ makeParamKey(formParam, baseKey) {
4505        return formParam.global ? formParam.urlKey : `${baseKey}-${formParam.urlKey}`;
4506    }
4507    /**
4508   * Gets a set of parameters from window query string
4509   * always returns value of "page" parameter if present
4510   * @param {Object[]} formConfig
4511   * @param {string} sectionDomId
4512   * @return {Object}
4513   */ deserializeParams(formConfig, sectionDomId) {
4514        const params = {};
4515        const urlPageKey = this.makePageKey(sectionDomId);
4516        const page = this.getParameterByName(urlPageKey);
4517        if (page) params.page = parseInt(page);
4518        if (Array.isArray(formConfig)) formConfig.forEach((formParam)=>{
4519            const key = this.makeParamKey(formParam, urlPageKey);
4520            let urlValue = this.getParameterByName(key);
4521            if (formParam.type === 'int') {
4522                urlValue = parseInt(urlValue);
4523                // eslint-disable-next-line
4524                if (!isFinite(urlValue)) urlValue = null;
4525            } else if (formParam.type === 'bool' || formParam.type === 'boolean') urlValue = // eslint-disable-next-line
4526            urlValue === 'true' ? true : urlValue === 'false' ? false : null;
4527            else if (formParam.type === 'json') try {
4528                urlValue = JSON.parse(urlValue);
4529            } catch (e) {
4530            // no need to do anything
4531            }
4532            params[formParam.formKey || formParam.param] = urlValue;
4533        });
4534        return params;
4535    }
4536    /**
4537   * Serializes set of parameters defined by formConfig into the URL
4538   * adding or replacing or removing required parameters
4539   * @param {Object[]} formConfig
4540   * @param {string} sectionDomId
4541   * @param {Object} params
4542   * @return {string}
4543   */ serializeParams(formConfig, sectionDomId, params) {
4544        let result = this.window.location.href;
4545        const urlPageKey = this.makePageKey(sectionDomId);
4546        result = this.updateQueryString(urlPageKey, params.page, result);
4547        if (Array.isArray(formConfig)) formConfig.forEach((formParam)=>{
4548            const key = this.makeParamKey(formParam, urlPageKey);
4549            let value = params[formParam.formKey || formParam.param];
4550            if (formParam.type === 'json' && value !== null && typeof value !== 'undefined') value = JSON.stringify(value);
4551            result = this.updateQueryString(key, value, result);
4552        });
4553        return result;
4554    }
4555    /**
4556   * Formats small number for slider values
4557   * @param {number} value
4558   * @param {string} currency
4559   * @return {string}
4560   */ formatSliderAtom(value, currency = '') {
4561        const formattedValue = Number.isInteger(value) ? value : value.toFixed(2);
4562        return currency + formattedValue;
4563    }
4564    /**
4565   * Formats a number for slider values
4566   * @param {number} value
4567   * @param {string} currency
4568   * @param {string} delimiter
4569   * @return {string}
4570   */ formatSliderValue(value, currency = '', delimiter = '') {
4571        if (value < 1000) return this.formatSliderAtom(value, currency);
4572        if (value < 1000000) return `${this.formatSliderAtom(value / 1000, currency)}${delimiter}K`;
4573        return `${this.formatSliderAtom(value / 1000000, currency)}${delimiter}M`;
4574    }
4575    /**
4576   * Format price slider range
4577   * @param {number} value
4578   * @param {Object} range
4579   * @param {string} currency
4580   * @param {Object} options
4581   * @return {string}
4582   */ formatSliderPriceRange(value, range, currency, options) {
4583        if (range.min === value && value !== 0) return `${options.lowPrefix}${this.formatSliderValue(value, currency, ' ')}`;
4584        if (range.max === value) return `${this.formatSliderValue(value, currency, ' ')}${options.highSuffix}`;
4585        return `${this.formatSliderValue(value, currency, ' ')}`;
4586    }
4587    /**
4588   * Format area slider range
4589   * @param {number} value
4590   * @param {Object} range
4591   * @param {string} suffix
4592   * @param {Object} options
4593   * @return {string}
4594   */ formatSliderAreaRange(value, range, suffix, options) {
4595        if (range.min === value && value !== 0) return `${options.lowPrefix}${this.formatSliderValue(value)} ${suffix}`;
4596        if (range.max === value) return `${this.formatSliderValue(value)}${options.highSuffix} ${suffix}`;
4597        return `${this.formatSliderValue(value)} ${suffix}`;
4598    }
4599    /**
4600   * Utility function to get properties search parameters from a set of jQuery objects
4601   * @param {Object} options
4602   * @param {jQuery|HTMLElement} [options.queryElement]
4603   * @param {jQuery|HTMLElement} [options.priceSliderElement]
4604   * @param {jQuery|HTMLElement} [options.areaSliderElement]
4605   * @param {jQuery|HTMLElement} [options.neighborhoodSelect]
4606   * @return {Object}
4607   */ // eslint-disable-next-line sonarjs/cognitive-complexity
4608    getSearchFormValues(options) {
4609        const { queryElement: queryElement, priceSliderElement: priceSliderElement, areaSli
4609derElement: areaSliderElement, neighborhoodSelect: neighborhoodSelect } = options;
4610        const result = {};
4611        if (queryElement) result.search = queryElement.value || null;
4612        if (priceSliderElement) {
4613            const priceValues = priceSliderElement.value.split(';');
4614            const priceMinLimit = parseInt(priceSliderElement.dataset.min);
4615            const priceMaxLimit = parseInt(priceSliderElement.dataset.max);
4616            const priceMin = parseInt(priceValues[0]);
4617            const priceMax = parseInt(priceValues[1]);
4618            result.priceMin = priceMin !== priceMinLimit ? priceMin : null;
4619            result.priceMax = priceMax !== priceMaxLimit ? priceMax : null;
4620        }
4621        if (areaSliderElement) {
4622            const areaValues = areaSliderElement.value.split(';');
4623            const areaMinLimit = parseInt(areaSliderElement.dataset.min);
4624            const areaMaxLimit = parseInt(areaSliderElement.dataset.max);
4625            const areaMin = parseInt(areaValues[0]);
4626            const areaMax = parseInt(areaValues[1]);
4627            result.areaMin = areaMin !== areaMinLimit ? areaMin : null;
4628            result.areaMax = areaMax !== areaMaxLimit ? areaMax : null;
4629        }
4630        if (neighborhoodSelect) result.neighborhoodId = neighborhoodSelect.value || null;
4631        return result;
4632    }
4633    /**
4634   * Add supports for object typeof values to be encoded on URL
4635   * Ref: https://stackoverflow.com/questions/1714786/query-string-encoding-of-a-javascript-object
4636   * @param {*} obj
4637   * @param {string} prefix
4638   * @param {string} baseParam used for grouping in case of nested objects
4639   * @returns
4640   */ // eslint-disable-next-line sonarjs/cognitive-complexity
4641    serializeObj(obj, prefix = '', baseParam = '') {
4642        const result = [];
4643        for(const prop in obj)if (obj.hasOwnProperty(prop)) {
4644            const value = obj[prop];
4645            let k;
4646            if (baseParam) {
4647                const newPrefix = prefix ? `[${prefix}][${prop}]` : `[${prop}]`;
4648                k = `${baseParam}${newPrefix}`;
4649            } else k = prefix ? `${prefix}[${prop}]` : prop;
4650            if (value !== null && Array.isArray(value)) {
4651                if (value.length) result.push(this.serializeArray(k, value));
4652            } else if (value !== null && typeof value === 'object') result.push(this.serializeObj(value, k));
4653            else result.push(`${k}=${encodeURIComponent(value)}`);
4654        }
4655        return result.join('&');
4656    }
4657    /**
4658   * Adds support for array values to be encoded on URL
4659   * @param {string} key
4660   * @param {Array} value
4661   * @param {string} baseParam
4662   */ serializeArray(key, value, baseParam = '') {
4663        const result = [];
4664        value.forEach((val)=>{
4665            const paramName = baseParam ? `${baseParam}${key}` : key;
4666            result.push(`${paramName}=${encodeURIComponent(val)}`);
4667        });
4668        return result.join('&');
4669    }
4670    /**
4671   * Private method to process string search values.
4672   * @param {Array} results comes from regex matchAll.
4673   * @param {Boolean} isAdvancedFilters flag to determine if the search is for advanced filters.
4674   * @returns
4675   */ _parseParamToObject(results, isAdvancedFilters = false) {
4676        if (!results.length) return null;
4677        const obj = {};
4678        for(let i = 0; i < results.length; i++)/* Results from regex match all come in this form:
4679      [ '&advancedFilters[query][statusIds][in]=uuid-segundo-123', '[query][statusIds][in]', 'uuid-segundo-123' ]
4680      So using every third value will be the actual value and the second value will be the path
4681    */ if ((i + 1) % 3 === 0) {
4682            const value = decodeURIComponent(results[i].replace(/\+/g, ' '));
4683            const path = results[i - 1];
4684            Object.assign(obj, this._setObjectPath(path, value, obj, isAdvancedFilters));
4685        }
4686        return obj;
4687    }
4688    /** *
4689   * Private method to set object value given a path
4690   * @param {String} path
4691   * @param {*} value
4692   * @param {Object} baseObj
4693   * @param {Boolean} isAdvancedFilters flag to determine if the search is for advanced filters.
4694   */ _setObjectPath(path, value, baseObj, isAdvancedFilters = false) {
4695        // eslint-disable-next-line
4696        const keys = path.split(/[\[\]]/).filter(Boolean);
4697        const afArrayKeys = [
4698            'in',
4699            'nin',
4700            'btw',
4701            'ciin',
4702            'cinin'
4703        ];
4704        const obj = {};
4705        let ref = obj;
4706        const valueExists = (0, $fc0a058ae42af628$export$267a1435fe18b8d4)(baseObj, keys.join('.'));
4707        keys.forEach((key, index)=>{
4708            if (index === keys.length - 1) {
4709                if (valueExists) ref[key] = Array.isArray(valueExists) ? [
4710                    ...valueExists,
4711                    value
4712                ] : [
4713                    valueExists,
4714                    value
4715                ];
4716                else ref[key] = isAdvancedFilters && afArrayKeys.includes(key) ? [
4717                    value
4718                ] : value;
4719            } else {
4720                ref[key] = baseObj[key] ? baseObj[key] : {};
4721                ref = ref[key];
4722            }
4723        });
4724        return obj;
4725    }
4726}
4727
4728
4729/* eslint-disable import/prefer-default-export */ 
4730class $2b1790aa32f109d1$export$43e435c053a109f6 extends (0, $7c391e2f7931d60d$export$3b5bd9381a52554c) {
4731    /**
4732   * Initialize Expand Slider Controller at build time
4733   * @param { ConfigController } config
4734   * @param {Window} window
4735   * @param {Document} document
4736   */ constructor(config, window, document){
4737        super(config, window, document);
4738        this._createLightbox = this._createLightbox.bind(this);
4739        this.expandSliders = [];
4740    }
4741    /**
4742   * Initialize Expand Slider Controller at run time
4743   * Attach handlers and events to DOM
4744   * @param {Object} options
4745   */ initialize(options = {}) {
4746        try {
4747            const { document: document } = this;
4748            const expandSliders = document.querySelectorAll('.has-mobile-expand');
4749            expandSliders.forEach((block)=>{
4750                this._addExpandButton(block);
4751            });
4752            this.expandSliders = this.expandSliders.concat(expandSliders);
4753        } catch (e) {
4754            // eslint-disable-next-line no-console
4755            console.log(e);
4756        }
4757    }
4758    /**
4759   * Controllers must implement a "destroy" method to be called
4760   * after page navigation to remove event handlers / cleanup
4761   */ destroy() {
4762        const { document: document } = this;
4763        document.querySelectorAll('.lp-expand-btn, .lp-expand-btn-wrapper').forEach((element)=>element.remove());
4764        this.expandSliders = [];
4765    }
4766    /**
4767   * Create expand button for sliders
4768   * @param {HTMLElement} slider
4769   */ _addExpandButton(slider) {
4770        const { document: document } = this;
4771        const section = slider.closest('section[id]');
4772        const appendTargetSelector = slider.dataset.append;
4773        let expandBtn = section.querySelector('.lp-expand-btn');
4774        if (!expandBtn) {
4775            expandBtn = document.createElement('button');
4776            expandBtn.className = 'lp-expand-btn';
4777            expandBtn.setAttribute('aria-label', 'Open a lightbox');
4778            expandBtn.innerHTML = `<span class="lp-i lp-i--expand-alt" aria-hidden="true"></span>`;
4779            if (appendTargetSelector) {
4780                const appendTarget = section.querySelector(appendTargetSelector);
4781                if (appendTarget) appendTarget.appendChild(expandBtn);
4782            } else {
4783                const wrapper = document.createElement('div');
4784                wrapper.className = 'lp-expand-btn-wrapper';
4785                wrapper.style.position = 'relative';
4786                wrapper.appendChild(expandBtn);
4787                slider.parentNode.insertBefore(wrapper, slider.nextSibling);
4788            }
4789        }
4790        expandBtn.addEventListener('click', ()=>{
4791            this._createLightbox({
4792                slider: slider,
4793                section: section
4794            });
4795        });
4796    }
4797    /**
4798   * Creates a lightbox modal for displaying slider images in a larger view.
4799   *
4800   * @param {Object} params - The parameters for the function.
4801   * @param {HTMLElement} params.slider - The slider element containing images.
4802   * @param {HTMLElement} params.section - The section element related to the slider.
4803   * @param {number} [params.initialIndex] - Optional index of the image to show initially.
4804   */ _createLightbox({ slider: slider, section: section, initialIndex: initialIndex }) {
4805        const { window: window, document: document } = this;
4806        const modalId = `lightbox-for-${section?.id}`;
4807        const isSlickAvailable = window.$ && window.$.fn.slick;
4808        const isSectionSlickInitialized = isSlickAvailable && slider.slick;
4809        const isSplideAvailable = typeof window.Splide === 'function';
4810        const isSectionSplideInitialized = slider.classList.contains('is-initialized') && slider.classList.contains('splide');
4811        if (typeof window.lpUI.requestScrollLock === 'function') window.lpUI.requestScrollLock(modalId);
4812        else document.body.style.overflow = 'hidden';
4813        function createSlickLightbox() {
4814            const slickOverlayOptions = {
4815                arrows: true,
4816                dots: false,
4817                infinite: true,
4818                draggable: true,
4819                prevArrow: '<button type="button" class="lp-lightbox-arrow--prev lp-lightbox-arrow" aria-label="Previous"></button>',
4820                nextArrow: '<button type="button" class="lp-lightbox-arrow--next lp-lightbox-arrow" aria-label="Next"></button>'
4821            };
4822            const modal = document.createElement('div');
4823            modal.id = modalId;
4824            modal.className = 'lp-lightbox';
4825            modal.setAttribute('tabindex', '-1');
4826            modal.setAttribute('role', 'dialog');
4827            modal.setAttribute('aria-modal', 'true');
4828            modal.innerHTML = `
4829        <button class="lp-lightbox__close" aria-label="close modal"></button>
4830        <div class="lp-lightbox__content">
4831          <div class="lp-lightbox__carousel"></div>
4832        </div>
4833      `;
4834            document.body.appendChild(modal);
4835            const overlaySlider = modal.querySelector('.lp-lightbox__carousel');
4836            modal.classList.add('show');
4837            let sourceImages;
4838            if (isSectionSlickInitialized) {
4839                sourceImages = slider.slick.$slides.find('img');
4840                slickOverlayOptions.initialSlide = slider.slick?.currentSlide || 0;
4841                sourceImages.each(function() {
4842                    window.$('.lp-lightbox__carousel').append(window.$(this).clone(false).removeAttr('style').wrap('<div class="lp-lightbox__slide"></div>').parent());
4843                });
4844            } else {
4845                sourceImages = slider.querySelectorAll('img');
4846                sourceImages.forEach((img)=>{
4847                    const imgClone = img.cloneNode(true);
4848                    imgClone.removeAttribute('style');
4849                    const slide = document.createElement('div');
4850                    slide.className = 'lp-lightbox__slide';
4851                    slide.appendChild(imgClone);
4852                    overlaySlider.appendChild(slide);
4853                });
4854            }
4855            window.$(overlaySlider).slick(slickOverlayOptions);
4856            // Focus modal after it's created
4857            setTimeout(()=>{
4858                modal.focus();
4859            }, 100);
4860            // Keyboard navigation handler
4861            const handleKeydown = (e)=>{
4862                if (!modal.classList.contains('show')) return;
4863                const prevArrow = modal.querySelector('.lp-lightbox-arrow--prev');
4864                const nextArrow = modal.querySelector('.lp-lightbox-arrow--next');
4865                const closeBtn = modal.querySelector('.lp-lightbox__close');
4866                if (e.key === 'ArrowLeft' && prevArrow) {
4867                    e.preventDefault();
4868                    prevArrow.click();
4869                } else if (e.key === 'ArrowRight' && nextArrow) {
4870                    e.preventDefault();
4871                    nextArrow.click();
4872                } else if (e.key === 'Escape' && closeBtn) {
4873                    e.preventDefault();
4874                    closeBtn.click();
4875                }
4876            };
4877            document.addEventListener('keydown', handleKeydown);
4878            modal.querySelector('.lp-lightbox__close').addEventListener('click', ()=>{
4879                document.removeEventListener('keydown', handleKeydown);
4880                modal.classList.remove('show');
4881                const currentSlide = overlaySlider?.slick ? window.$(overlaySlider).slick('slickCurrentSlide') : 0;
4882                if (overlaySlider?.slick) window.$(overlaySlider).slick('unslick');
4883                if (isSectionSlickInitialized) window.$(slider).slick('slickGoTo', currentSlide);
4884                if (typeof window.lpUI.releaseScrollLock === 'function') window.lpUI.releaseScrollLock(modalId);
4885                else document.body.style.overflow = '';
4886                modal.remove();
4887            });
4888        }
4889        function createSplideLightbox() {
4890            const splideOptions = {
4891                rewind: true,
4892                arrows: true,
4893                arrowPath: '',
4894                type: 'loop',
4895                clones: 1,
4896                pagination: false,
4897                perPage: 1,
4898                perMove: 1
4899            };
4900            const modal = document.createElement('div');
4901            modal.id = modalId;
4902            modal.className = 'lp-lightbox';
4903            modal.setAttribute('tabindex', '-1');
4904            modal.setAttribute('role', 'dialog');
4905            modal.setAttribute('aria-modal', 'true');
4906            modal.innerHTML = `
4907      <button class="lp-lightbox__close" aria-label="close modal"></button>
4908      <div class="lp-lightbox__content">
4909        <div class="lp-lightbox__carousel splide" role="group" aria-label="Image Gallery">
4910          <div class="splide__arrows">
4911            <button class="splide__arrow splide__arrow--prev lp-lightbox-arrow lp-lightbox-arrow--prev"></button>
4912            <button class="splide__arrow splide__arrow--next lp-lightbox-arrow lp-lightbox-arrow--next"></button>
4913          </div>
4914          <div class="splide__track">
4915            <ul class="splide__list"></ul>
4916          </div>
4917        </div>
4918      </div>
4919    `;
4920            if (typeof window.lpUI.requestScrollLock === 'function') window.lpUI.requestScrollLock(modalId);
4921            else document.body.style.overflow = 'hidden';
4922            document.body.appendChild(modal);
4923            const overlaySlider = modal.querySelector('.lp-lightbox__carousel');
4924            const overlaySliderList = overlaySlider.querySelector('.splide__list');
4925            modal.classList.add('show');
4926            let sourceImages;
4927            if (isSectionSplideInitialized) sourceImages = slider.querySelectorAll('.splide__slide:not(.splide__slide--clone) img');
4928            else sourceImages = slider.querySelectorAll('img');
4929            sourceImages.forEach((img)=>{
4930                const imgClone = img.cloneNode(true);
4931                imgClone.removeAttribute('style');
4932                const slide = document.createElement('li');
4933                slide.className = 'lp-lightbox__slide splide__slide';
4934                slide.appendChild(imgClone);
4935                overlaySliderList.appendChild(slide);
4936            });
4937            const overlaySplide = new window.Splide(overlaySlider, splideOptions);
4938            overlaySplide.mount();
4939            // Navigate to initial index if provided
4940            if (typeof initialIndex !== 'undefined' && initialIndex >= 0) overlaySplide.go(initialIndex);
4941            // Focus modal after it's created and mounted
4942            setTimeout(()=>{
4943                modal.focus();
4944            }, 100);
4945            // Keyboard navigation handler
4946            const handleKeydown = (e)=>{
4947                if (!modal.classList.contains('show')) return;
4948                const prevArrow = modal.querySelector('.splide__arrow--prev');
4949                const nextArrow = modal.querySelector('.splide__arrow--next');
4950                const closeBtn = modal.querySelector('.lp-lightbox__close');
4951                if (e.key === 'ArrowLeft' && prevArrow) {
4952                    e.preventDefault();
4953                    prevArrow.click();
4954                } else if (e.key === 'ArrowRight' && nextArrow) {
4955                    e.preventDefault();
4956                    nextArrow.click();
4957                } else if (e.key === 'Escape' && closeBtn) {
4958                    e.preventDefault();
4959                    closeBtn.click();
4960                }
4961            };
4962            document.addEventListener('keydown', handleKeydown);
4963            modal.querySelector('.lp-lightbox__close').addEventListener('click', ()=>{
4964                document.removeEventListener('keydown', handleKeydown);
4965                modal.classList.remove('show');
4966                if (overlaySplide) overlaySplide.destroy();
4967                if (typeof window.lpUI.releaseScrollLock === 'function') window.lpUI.releaseScrollLock(modalId);
4968                else document.body.style.overflow = '';
4969                modal.remove();
4970            });
4971        }
4972        if (isSlickAvailable && !isSectionSplideInitialized) createSlickLightbox();
4973        else if (isSplideAvailable) createSplideLightbox();
4974        else {
4975            window.luxuryPresence.libs.loadCss(window.luxuryPresence.libs.jsLibsMap.splide.cssSrc);
4976            window.luxuryPresence.libs.loadJs(window.luxuryPresence.libs.jsLibsMap.splide.jsSrc, ()=>{
4977                createSplideLightbox();
4978                window.luxuryPresence.libs.jsLibsMap.splide.isLoaded = true;
4979            });
4980        }
4981    }
4982}
4983
4984
4985/* eslint-disable import/prefer-default-export */ 
4986class $4f184d9bd3037f15$export$7a6215890afba974 extends (0, $7c391e2f7931d60d$export$3b5bd9381a52554c) {
4987    // constructor is not needed as it is inherited from BaseController
4988    /**
4989   * Destroy
4990   */ destroy() {
4991        if (!this.window.divolte) this.window.divolteLp = function() {
4992            (this.window.divolteLp.q = this.window.divolteLp.q || []).push(// eslint-disable-next-line prefer-rest-params
4993            arguments);
4994        };
4995    }
4996    /**
4997   * Initialize divolte controller
4998   * @param {Object} options
4999   */ initialize(options = {}) {
5000        const { divolteServiceUrl: divolteServiceUrl } = this.config;
5001        if (!divolteServiceUrl || this.window.divolte) return;
5002        this.loadScript();
5003    }
5004    /**
5005   * loads divolte
5006   */ loadScript() {
5007        const { divolteServiceUrl: divolteServiceUrl } = this.config;
5008        const script = this.document.createElement('script');
5009        script.id = 'divolte-script';
5010        script.type = 'text/javascript';
5011        script.defer = true;
5012        script.async = true;
5013        script.src = `${divolteServiceUrl}/divolte.js`;
5014        this.document.head.appendChild(script);
5015        script.addEventListener('load', this.executeQueue.bind(this));
5016    }
5017    /**
5018   * executeQueue
5019   */ executeQueue() {
5020        (this.window.divolteLp.q || []).forEach(([methodName, params])=>{
5021            this[methodName](params);
5022        });
5023        this.window.divolteLp = this.divolteLp.bind(this);
5024    }
5025    /**
5026   * divolteLp
5027   * @param {string} name
5028   * @param {Object} params
5029   */ divolteLp(name, params) {
5030        try {
5031            this[name](params);
5032        } catch (error) {
5033            // eslint-disable-next-line no-console
5034            console.log(error);
5035        }
5036    }
5037    /**
5038   * sendLpEvent
5039   * @param {string} name
5040   * @param {Object} params
5041   */ sendLpEvent(name, params) {
5042        // Events must be defined in divolte schema! To ensure correct usage, event names are validated here.
5043        if (!name.includes('pageView')) {
5044            // Event not defined
5045            // eslint-disable-next-line no-console
5046            console.log(`${name} IS NOT SUPPORTED`);
5047            return;
5048        }
5049        const { companyId: companyId, templateId: templateId, websiteId: websiteId, pageId: pageId, shareId: shareId, pageMeta: pageMeta } = this.config;
5050        const baseParams = {
5051            companyId: companyId,
5052            templateId: templateId,
5053            websiteId: websiteId,
5054            pageId: pageId,
5055            shareId: shareId,
5056            pageMeta: pageMeta
5057        };
5058        this.window.divolte.signal(name, Object.assign(baseParams, params));
5059    }
5060    /**
5061   * sendLpPageView
5062   */ sendLpPageView() {
5063        this.sendLpEvent('pageView', {});
5064    }
5065}
5066
5067
5068/* eslint-disable import/prefer-default-export */ 
5069const $102039871668a1df$var$EVENT_BUS_SCRIPT = 'event-bus-js.js';
5070const $102039871668a1df$var$EVENT_BUS_VERSION = 'v2.8.0';
5071const $102039871668a1df$var$EVENT_BUS_DEFAULT_SOURCE = 'frontend://website-render-engine';
5072class $102039871668a1df$export$e22e4b1be0bb6c61 extends (0, $7c391e2f7931d60d$export$3b5bd9381a52554c) {
5073    // eslint-disable-next-line @typescript-eslint/no-useless-constructor
5074    constructor(config, window, document){
5075        super(config, window, document);
5076    }
5077    /**
5078   * Initialize EventBus controller
5079   * @param {Object} options
5080   */ initialize(options = {}) {
5081        const enabled = options.enabled !== undefined ? options.enabled : this.config.eventBus?.enabled;
5082        if (enabled && this.config.eventBus?.apiKey && this.config.eventBus?.url) this.loadScript();
5083    }
5084    /**
5085   * loads eventBus script
5086   */ loadScript() {
5087        const { eventBusUrl: eventBusUrl } = this.config;
5088        const script = this.document.createElement('script');
5089        script.id = 'posthog-script';
5090        script.type = 'text/javascript';
5091        script.defer = true;
5092        script.async = true;
5093        script.src = `${eventBusUrl}/${$102039871668a1df$var$EVENT_BUS_VERSION}/${$102039871668a1df$var$EVENT_BUS_SCRIPT}`;
5094        this.document.head.appendChild(script);
5095        script.addEventListener('load', this.executeQueue.bind(this));
5096    }
5097    /**
5098   * executeQueue - Process queued eventBusLp calls
5099   */ executeQueue() {
5100        // Initialize the event bus provider using the global EventBusJS
5101        if (this.window.LuxuryPresenceEventBus) this.window.eventBusProvider = this.window.LuxuryPresenceEventBus.createEventBusProvider({
5102            apiKey: this.config.eventBus.apiKey,
5103            host: this.config.eventBus.url,
5104            defaultSource: $102039871668a1df$var$EVENT_BUS_DEFAULT_SOURCE
5105        });
5106        (this.window.eventBusLp.q || []).forEach(([methodName, params])=>{
5107            this[methodName](params);
5108        });
5109        // Replace queue function with real function
5110        this.window.eventBusLp = this.eventBusLp.bind(this);
5111    }
5112    /**
5113   * Destroy
5114   */ destroy() {
5115        if (!this.window.eventBusProvider) {
5116            // Reset to queue function if no provider exists
5117            this.window.eventBusLp = function() {
5118                (this.window.eventBusLp.q = this.window.eventBusLp.q || []).push(// eslint-disable-next-line prefer-rest-params
5119                arguments);
5120            };
5121            return;
5122        }
5123        this.window.eventBusProvider.shutdown();
5124    }
5125    /**
5126   * sendLpEvent
5127   * @param {string} eventType
5128   * @param {Object} data
5129   */ sendLpEvent(eventType, data) {
5130        // Events must be defined in event-bus schema! To ensure correct usage, event types are validated here.
5131        if (eventType !== 'user.activity.page.viewed') {
5132            // Event type not defined
5133            // eslint-disable-next-line no-console
5134            console.log(`${eventType} IS NOT SUPPORTED`);
5135            return;
5136        }
5137        if (!this.window.eventBusProvider) return;
5138        const { companyId: companyId } = this.config;
5139        const eventData = {
5140            company: companyId,
5141            data: {}
5142        };
5143        try {
5144            this.window.eventBusProvider.capture(eventType, eventData);
5145        } catch (error) {
5146            // eslint-disable-next-line no-console
5147            console.log('EventBus capture error:', error);
5148        }
5149    }
5150    /**
5151   * eventBusLp
5152   * @param {string} name
5153   * @param {Object} params
5154   */ eventBusLp(name, params) {
5155        try {
5156            this[name](params);
5157        } catch (error) {
5158            // eslint-disable-next-line no-console
5159            console.log(error);
5160        }
5161    }
5162    /**
5163   * sendLpPageView
5164   */ sendLpPageView() {
5165        this.sendLpEvent('user.activity.page.viewed', {});
5166    }
5167}
5168
5169
5170/* eslint-disable import/prefer-default-export */ 
5171
5172const $0d25a3fa2e0f4f92$var$EVENT_NAME = 'oauthSuccess';
5173class $0d25a3fa2e0f4f92$export$b718a981691eae5c extends (0, $7c391e2f7931d60d$export$3b5bd9381a52554c) {
5174    /**
5175   * Initialize Button Controller at build time
5176   * @param { ConfigController } config
5177   * @param {Window} window
5178   * @param {Document} document
5179   */ constructor(config, window, document){
5180        super(config, window, document);
5181        this.successListeners = [];
5182        this._listenToMessages = this._listenToMessages.bind(this);
5183        this._listenToOneTapMessage = this._listenToOneTapMessage.bind(this);
5184    }
5185    /**
5186   * Initialize OAuth Controller at run time
5187   * Swap out special buttons for the iframe
5188   * @param {Object} options
5189   */ initialize(options = {}) {
5190        try {
5191            // handle google one tap
5192            if (options.googleSignOnEnabled && !options.iframe) this._renderGoogleOneTap();
5193            // handle google sign in buttons
5194            this.document.querySelectorAll('div[data-signin-type="google-sign-in"]').forEach((el)=>this._convertGoogleSignIn(el));
5195            // handle facebook sign in buttons
5196            this.document.querySelectorAll('div[data-signin-type="facebook-sign-in"]').forEach((el)=>this._convertFacebookSignIn(el));
5197        } catch (e) {
5198            // eslint-disable-next-line no-console
5199            console.log(e);
5200        }
5201    }
5202    /**
5203   * Controllers must implement a "destroy" method to be called
5204   * after page navigation to remove event handlers / cleanup
5205   */ destroy() {
5206        this.successListeners.forEach((callback)=>{
5207            this.window.removeEventListener('message', this._listenToMessages);
5208            this.window.removeEventListener('message', this._listenToOneTapMessage);
5209            this.window.removeEventListener($0d25a3fa2e0f4f92$var$EVENT_NAME, this.window[callback]);
5210        });
5211    }
5212    /**
5213   * Convert google one tap
5214   */ _renderGoogleOneTap() {
5215        if (!this._isGoogleOneTapOnCooldown()) {
5216            const dummyEl = this.document.createElement('div');
5217            // eslint-disable-next-line no-undef
5218            google.accounts.id.initializeIntermediate({
5219                src: this._buildUrlAndCopyAttributes(dummyEl, dummyEl, 'googleOneTap')
5220            });
5221            this.window.localStorage.removeItem('googleOneTapExpiration');
5222            this.window.addEventListener('message', this._listenToOneTapMessage);
5223        }
5224    }
5225    /**
5226   * Listening for messages from BSS one tap iframes
5227   * @param {MessageEvent} e
5228   */ _listenToOneTapMessage(e) {
5229        const messageTypes = {
5230            SHOW_INTERMEDIATE_IFRAME: 'show_intermediate_iframe',
5231            HIDE_INTERMEDIATE_IFRAME: 'hide_intermediate_iframe'
5232        };
5233        const iframeId = 'onetap_google_intermediate_iframe';
5234        const { buyerSellerServiceUrl: buyerSellerServiceUrl } = this.config;
5235        const { data: data, origin: origin } = e;
5236        const { type: type, height: height, event: event, source: source, token: token } = data;
5237        if (type === messageTypes.SHOW_INTERMEDIATE_IFRAME || type === messageTypes.HIDE_INTERMEDIATE_IFRAME) {
5238            const bssIframe = this.document.getElementById(iframeId);
5239            if (bssIframe) {
5240                bssIframe.style.height = height;
5241                bssIframe.style.display = type === messageTypes.SHOW_INTERMEDIATE_IFRAME ? 'unset' : 'none';
5242            }
5243        }
5244        // these events are generated by our code in the bss iframe
5245        if (origin === buyerSellerServiceUrl && source === 'GOOGLE_SIGN_ON') {
5246            if (event === 'success') {
5247                this._setExpirationLsItem(86400000); // 24 hours
5248                this._handleQualifyingQuestionsModal(token);
5249            } else if (event === 'cancel') this._setExpirationLsItem(7200000); // 2 hours
5250        }
5251    }
5252    /**
5253   * Set expiration local storage item for google one tap
5254   * @param {number} ms
5255   */ _setExpirationLsItem(ms) {
5256        const expiration = new Date().getTime() + ms;
5257        this.window.localStorage.setItem('googleOneTapExpiration', expiration);
5258    }
5259    /**
5260   * Check if google one tap is expired
5261   * @return {boolean}
5262   */ _isGoogleOneTapOnCooldown() {
5263        const expirationTime = this.window.localStorage.getItem('googleOneTapExpiration');
5264        return Number(expirationTime) > new Date().getTime();
5265    }
5266    /**
5267   * Convert google sign in buttons
5268   * @param {HTMLElement} el
5269   */ _convertGoogleSignIn(el) {
5270        this._replaceWithIframe('googleSignIn', el);
5271    }
5272    /**
5273   * Convert google sign in buttons
5274   * @param {HTMLElement} el
5275   */ _convertFacebookSignIn(el) {
5276        this._replaceWithIframe('facebookSignIn', el);
5277    }
5278    /**
5279   * Convert google sign in buttons
5280   * @param {'googleSignIn' | 'facebookSignIn'} provider
5281   * @param {HTMLElement} el
5282   */ _replaceWithIframe(provider, el) {
5283        this._attachSuccessCallback(el);
5284        const iframe = this.document.createElement('iframe');
5285        iframe.src = this._buildUrlAndCopyAttributes(el, iframe, provider);
5286        iframe.dataset.isSocialOauthButton = true;
5287        el.replaceWith(iframe);
5288    }
5289    /**
5290   * Listening for messages from BSS iframes
5291   * @param {Event} e
5292   */ _listenToMessages(e) {
5293        const { buyerSellerServiceUrl: buyerSellerServiceUrl } = this.config;
5294        // eslint-disable-next-line sonarjs/no-collapsible-if
5295        if (e.origin === buyerSellerServiceUrl) {
5296            if (e.data.event === 'success') {
5297                const event = new Event($0d25a3fa2e0f4f92$var$EVENT_NAME);
5298                this.window.dispatchEvent(event);
5299                // Registration / social sign-in is a lead event — credit the conversion.
5300                (0, $3ec2bf3965f87ecc$export$e70565180c0e6950)(this.window, this.document);
5301                this.successListeners.forEach((callback)=>{
5302                    if (this.window[callback]) this.window[callback](event);
5303                    else // eslint-disable-next-line no-console
5304                    console.error(`Callback function ${callback} not found on window object`);
5305                });
5306                this.document.documentElement.classList.add('is-login-success');
5307            }
5308        }
5309    }
5310    /**
5311   * Attach callback to iframe
5312   * @param {HTMLElement} el
5313   */ _attachSuccessCallback(el) {
5314        this.window.addEventListener('message', this._listenToMessages);
5315        const callbackFunction = el.dataset.onSuccessFunctionName;
5316        if (callbackFunction) this.successListeners.push(callbackFunction);
5317    }
5318    /**
5319   * Build Iframe URL
5320   * @param {HTMLElement} source
5321   * @param {HTMLElement} target
5322   * @param {string} provider
5323   * @return {string}
5324   */ _buildUrlAndCopyAttributes(source, target, provider) {
5325        const { buyerSellerServiceUrl: buyerSellerServiceUrl, companyId: companyId, websiteId: websiteId, pageId: pageId, pageMeta: pageMeta } = this.config;
5326        const { location: location } = this.window;
5327        const sourceUrl = location.origin + location.pathname;
5328        const destination = new URL(`${buyerSellerServiceUrl}/buttons/${provider}`);
5329        const utm = this.window.localStorage.getItem('utm_vars');
5330        const referrer = this.window.localStorage.getItem('referrer');
5331        destination.searchParams.append('companyId', companyId);
5332        destination.searchParams.append('websiteId', websiteId);
5333        destination.searchParams.append('pageId', pageId);
5334        destination.searchParams.append('sourceUrl', sourceUrl);
5335        destination.searchParams.append('pageMeta', JSON.stringify(pageMeta));
5336        if (utm) destination.searchParams.append('utm', utm);
5337        if (referrer) destination.searchParams.append('referrer', referrer);
5338        // Google and Facebook Attributes used to style the social button
5339        const RESERVED_ATTRIBUTES = [
5340            'data-size',
5341            'data-width',
5342            'data-text',
5343            'data-button-type',
5344            'data-shape',
5345            'data-layout',
5346            'data-max-rows',
5347            'data-use-continue-as',
5348            'data-type',
5349            'data-theme',
5350            'data-logo_alignment',
5351            'data-locale'
5352        ];
5353        Array.from(source.attributes).forEach((attribute)=>{
5354            if (RESERVED_ATTRIBUTES.includes(attribute.nodeName)) destination.searchParams.append(attribute.nodeName, attribute.nodeValue);
5355            else target.setAttribute(attribute.nodeName === 'id' ? 'data-id' : attribute.nodeName, attribute.nodeValue);
5356        });
5357        return destination.toString();
5358    }
5359    /**
5360   * Decode a JWT token to extract payload information
5361   * @param {string} token - The JWT token to decode
5362   * @return {Object|null} The decoded payload object or null if decoding fails
5363   */ _decodeToken(token) {
5364        try {
5365            const parts = token.split('.');
5366            const payload = parts[1];
5367            const base64 = payload.replace(/-/g, '+').replace(/_/g, '/');
5368            const padding = 4 - base64.length % 4;
5369            const padded = padding === 4 ? base64 : base64 + '='.repeat(padding);
5370            return JSON.parse(atob(padded));
5371        } catch (error) {
5372            return null;
5373        }
5374    }
5375    /**
5376   * Handle qualifying questions modal showing for Google Sign On
5377   * Decodes the JWT token to extract user email and shows the modal if available
5378   * @param {string} token - The JWT token containing user information
5379   */ _handleQualifyingQuestionsModal(token) {
5380        if (token && this.window.luxuryPresence && this.window.luxuryPresence.qualifyingQuestionsModal) {
5381            // Decoding only for lead attribution, fine to skip signature verification
5382            const decoded = this._decodeToken(token);
5383            if (decoded && decoded.email) this.window.luxuryPresence.qualifyingQuestionsModal.showModal(decoded.email, 'Google Sign On');
5384        }
5385    }
5386}
5387
5388
5389/* eslint-disable import/prefer-default-export */ 
5390class $dcf72769f009ff26$export$b900d6fe921fd49c extends (0, $7c391e2f7931d60d$export$3b5bd9381a52554c) {
5391    /**
5392   * Initialize Qualifying Questions Modal Controller at build time
5393   * @param { ConfigController } config
5394   * @param {Window} window
5395   * @param {Document} document
5396   */ constructor(config, window, document){
5397        super(config, window, document);
5398        this.showModal = this.showModal.bind(this);
5399        this.hasModalBeenSubmitted = this.hasModalBeenSubmitted.bind(this);
5400        this.modalId = 'qualifying-questions-modal';
5401        this.cookieKey = 'qualifyingQuestionsModalSubmitted';
5402        this.qualifyingQuestionsModalEnabled = true;
5403        // Store references for cleanup
5404        this.eventListeners = [];
5405        this.timeouts = [];
5406    }
5407    initialize(options = {}) {
5408        this.qualifyingQuestionsModalEnabled = options.qualifyingQuestionsModalEnabled ?? this.qualifyingQuestionsModalEnabled;
5409        if (!this.qualifyingQuestionsModalEnabled) return;
5410        this.attachModalCloseListeners();
5411    }
5412    destroy() {
5413        // Remove all stored event listeners
5414        this.eventListeners.forEach(({ element: element, event: event, handler: handler })=>{
5415            if (element && element.removeEventListener) element.removeEventListener(event, handler);
5416        });
5417        this.timeouts.forEach((timeoutId)=>{
5418            clearTimeout(timeoutId);
5419        });
5420        this.restoreBodyScroll();
5421        this.eventListeners = [];
5422        this.timeouts = [];
5423    }
5424    /**
5425   * Check if modal has been submitted using cookie-based deduplication
5426   * @return {boolean}
5427   */ hasModalBeenSubmitted() {
5428        const cookieValue = this.getCookie(this.cookieKey);
5429        return cookieValue === 'true';
5430    }
5431    /**
5432   * Set cookie to prevent modal from showing again
5433   */ setModalSubmittedCookie() {
5434        this.setCookie(this.cookieKey, 'true', 365); // 1 year
5435    }
5436    showModal(email, triggerSource) {
5437        if (!this.qualifyingQuestionsModalEnabled || this.hasModalBeenSubmitted()) return;
5438        this.updateEmailValue(email);
5439        this.updateTriggerSourceValue(triggerSource);
5440        this.showModalElement();
5441    }
5442    /**
5443   * Get modal element with error handling
5444   * @return {Element|null}
5445   */ getModalElement() {
5446        const modal = this.document.getElementById(this.modalId);
5447        if (!modal) console.error('Modal element not found:', this.modalId);
5448        return modal;
5449    }
5450    updateEmailValue(email) {
5451        const modal = this.getModalElement();
5452        if (!modal) return;
5453        const emailInput = modal.querySelector('input[name="email"]');
5454        if (emailInput && typeof email === 'string') emailInput.value = email;
5455    }
5456    updateTriggerSourceValue(triggerSource) {
5457        const modal = this.getModalElement();
5458        if (!modal) return;
5459        const triggerSourceInput = modal.querySelector(`#${this.modalId}-triggerSource`);
5460        if (triggerSourceInput && typeof triggerSource === 'string') triggerSourceInput.value = triggerSource;
5461    }
5462    showModalElement() {
5463        const modal = this.getModalElement();
5464        if (!modal) return;
5465        modal.style.display = 'flex';
5466        this.blockBodyScroll();
5467    }
5468    /**
5469   * Helper method to get cookie value
5470   * @param {string} name
5471   * @return {string|null}
5472   */ getCookie(name) {
5473        const value = `; ${this.document.cookie}`;
5474        const parts = value.split(`; ${name}=`);
5475        if (parts.length === 2) return decodeURIComponent(parts.pop().split(';').shift());
5476        return null;
5477    }
5478    /**
5479   * Helper method to set cookie
5480   * @param {string} name
5481   * @param {string} value
5482   * @param {number} days
5483   */ setCookie(name, value, days) {
5484        let expires = '';
5485        if (days) {
5486            const date = new Date();
5487            date.setTime(date.getTime() + days * 86400000);
5488            expires = `; expires=${date.toUTCString()}`;
5489        }
5490        let attrs = '; path=/; SameSite=Lax';
5491        if (this.window && this.window.location && this.window.location.protocol === 'https:') attrs += '; Secure';
5492        this.document.cookie = `${name}=${encodeURIComponent(value || '')}${expires}${attrs}`;
5493    }
5494    blockBodyScroll() {
5495        this._prevOverflow = this.document.body.style.overflow;
5496        this.document.body.style.overflow = 'hidden';
5497    }
5498    restoreBodyScroll() {
5499        this.document.body.style.overflow = this._prevOverflow || '';
5500        this._prevOverflow = null;
5501    }
5502    attachModalCloseListeners() {
5503        const modal = this.getModalElement();
5504        if (!modal) return;
5505        // Listen for form submission success (when modal closes automatically)
5506        const form = this.document.getElementById(`${this.modalId}-form`);
5507        if (form) {
5508            const formSubmittedHandler = ()=>{
5509                // Set cookie to prevent showing again and hide modal
5510                this.setModalSubmittedCookie();
5511                const timeoutId = setTimeout(()=>{
5512                    modal.style.display = 'none';
5513                    this.restoreBodyScroll();
5514                }, 100);
5515                this.timeouts.push(timeoutId);
5516            };
5517            form.addEventListener('formsubmitted', formSubmittedHandler);
5518            this.eventListeners.push({
5519                element: form,
5520                event: 'formsubmitted',
5521                handler: formSubmittedHandler
5522            });
5523        }
5524        // Listen for close button clicks
5525        const closeButton = modal.querySelector('[data-dismiss="modal"]');
5526        if (closeButton) {
5527            const closeButtonHandler = ()=>{
5528                modal.style.display = 'none';
5529                this.restoreBodyScroll();
5530            };
5531            closeButton.addEventListener('click', closeButtonHandler);
5532            this.eventListeners.push({
5533                element: closeButton,
5534                event: 'click',
5535                handler: closeButtonHandler
5536            });
5537        }
5538        // Listen for backdrop clicks
5539        const backdropClickHandler = (e)=>{
5540            // Check if click is on the modal backdrop (not on the modal content)
5541            if (e.target === modal || e.target.id === this.modalId) {
5542                modal.style.display = 'none';
5543                this.restoreBodyScroll();
5544            }
5545        };
5546        modal.addEventListener('click', backdropClickHandler);
5547        this.eventListeners.push({
5548            element: modal,
5549            event: 'click',
5550            handler: backdropClickHandler
5551        });
5552    }
5553}
5554
5555
5556/* eslint-disable import/prefer-default-export */ 
5557class $50eefeef8d1f2372$export$8a2bf06fbae4dde extends (0, $7c391e2f7931d60d$export$3b5bd9381a52554c) {
5558    constructor(configController, window, document){
5559        super(configController, window, document);
5560        this.isValidating = false;
5561        this.lastValidationResult = null;
5562        this.lastValidationTime = null;
5563        this.validationCacheDuration = 300000; // 5 minutes
5564    }
5565    /**
5566   * Destroy
5567   */ destroy() {
5568        this.isValidating = false;
5569        this.lastValidationResult = null;
5570        this.lastValidationTime = null;
5571    }
5572    /**
5573   * Validate user session using GraphQL validSession query
5574   * @param {Object} options - Options for session validation
5575   * @param {boolean} options.useCache - Whether to use cached validation result
5576   * @returns {Promise<boolean>} - true if session is valid, false otherwise
5577   */ async validateSession(options = {}) {
5578        const { useCache: useCache = true } = options;
5579        if (useCache && this.lastValidationResult !== null && this.lastValidationTime) {
5580            const timeSinceLastValidation = Date.now() - this.lastValidationTime;
5581            if (timeSinceLastValidation < this.validationCacheDuration) return this.lastValidationResult;
5582        }
5583        if (this.isValidating) return this.lastValidationResult !== null ? this.lastValidationResult : false;
5584        this.isValidating = true;
5585        const query = `
5586      query {
5587        validSession {
5588          success
5589        }
5590      }
5591    `;
5592        try {
5593            // query from same domain as the website
5594            const response = await this.window.fetch(`/graphql`, {
5595                method: 'POST',
5596                headers: {
5597                    'Content-Type': 'application/json'
5598                },
5599                credentials: 'include',
5600                body: JSON.stringify({
5601                    query: query
5602                })
5603            });
5604            if (!response.ok) {
5605                // eslint-disable-next-line no-console
5606                console.error('SessionController: HTTP error during session validation', response.status);
5607                this.lastValidationResult = false;
5608                this.lastValidationTime = Date.now();
5609                return false;
5610            }
5611            const data = await response.json();
5612            if (data.errors) {
5613                this.lastValidationResult = false;
5614                this.lastValidationTime = Date.now();
5615                return false;
5616            }
5617            const isValid = data.data?.validSession?.success === true;
5618            this.lastValidationResult = isValid;
5619            this.lastValidationTime = Date.now();
5620            return isValid;
5621        } catch (error) {
5622            // eslint-disable-next-line no-console
5623            console.error('SessionController: Error validating session', error);
5624            this.lastValidationResult = false;
5625            this.lastValidationTime = Date.now();
5626            return false;
5627        } finally{
5628            this.isValidating = false;
5629        }
5630    }
5631    /**
5632   * Clear validation cache
5633   */ clearCache() {
5634        this.lastValidationResult = null;
5635        this.lastValidationTime = null;
5636    }
5637}
5638
5639
5640/* eslint-disable import/prefer-default-export */ 
5641function $396d9f0ca7465335$export$48d5542b9e3ba39(document) {
5642    const match = document.cookie.match(/cookieyes-consent=([^;]+)/);
5643    if (!match) return false;
5644    try {
5645        const cookieValue = decodeURIComponent(match[1]);
5646        if (cookieValue.includes(',')) {
5647            const segments = cookieValue.split(',').map((c)=>c.trim());
5648            if (segments.some((s)=>s.includes(':'))) return segments.some((s)=>s === 'analytics:yes');
5649            return segments.includes('analytics');
5650        }
5651        return cookieValue.includes('analytics');
5652    } catch (error) {
5653        return false;
5654    }
5655}
5656/**
5657 * Consent providers. Each entry isolates the only things that differ between
5658 * integrations: the change-event name, how to read the *initial* analytics
5659 * consent, and how to interpret a change event's detail. Everything else
5660 * (loading/removing trackers, lifecycle) is shared by the controller.
5661 */ const $396d9f0ca7465335$var$PROVIDERS = {
5662    // Third-party CookieYes banner.
5663    cookieyes: {
5664        eventName: 'cookieyes_consent_update',
5665        hasAnalyticsConsent: (document)=>$396d9f0ca7465335$export$48d5542b9e3ba39(document),
5666        isAnalyticsAccepted: (detail)=>Array.isArray(detail?.accepted) && detail.accepted.includes('analytics')
5667    },
5668    // LP in-house consent widget (lp-consent-widget). It exposes resolved state on
5669    // window.__lpConsent and emits `lp_consent_update` with detail.choices.
5670    'lp-consent': {
5671        eventName: 'lp_consent_update',
5672        hasAnalyticsConsent: (_document, window)=>!!window.__lpConsent?.state?.c?.analytics,
5673        isAnalyticsAccepted: (detail)=>!!detail?.choices?.analytics
5674    }
5675};
5676class $396d9f0ca7465335$export$bb018224876724b9 extends (0, $7c391e2f7931d60d$export$3b5bd9381a52554c) {
5677    constructor(config, window, document){
5678        super(config, window, document);
5679        this.consentListener = null;
5680        this.eventName = null;
5681    }
5682    /**
5683   * Destroy and cleanup event listeners
5684   */ destroy() {
5685        if (this.consentListener && this.eventName) {
5686            this.document.removeEventListener(this.eventName, this.consentListener);
5687            this.consentListener = null;
5688        }
5689    }
5690    /**
5691   * Load PostHog and Divolte scripts (idempotent — guarded by element id).
5692   */ loadScript() {
5693        if (!this.document.getElementById('posthog-script')) this.window.luxuryPresence.eventBus.initialize({
5694            enabled: this.config.eventBus?.enabled
5695        });
5696        if (!this.document.getElementById('divolte-script')) this.window.luxuryPresence.divolte.initialize({});
5697    }
5698    /**
5699   * Remove PostHog and Divolte scripts (used on consent withdrawal).
5700   */ removeScripts() {
5701        this.window.luxuryPresence?.eventBus?.destroy?.();
5702        this.window.luxuryPresence?.divolte?.destroy?.();
5703        this.document.getElementById('posthog-script')?.remove();
5704        this.document.getElementById('divolte-script')?.remove();
5705    }
5706    /**
5707   * Initialize the consent controller for a given provider.
5708   * @param {{ provider: 'cookieyes' | 'lp-consent' }} options
5709   */ async initialize(options = {}) {
5710        const provider = $396d9f0ca7465335$var$PROVIDERS[options.provider];
5711        if (!provider) return;
5712        this.eventName = provider.eventName;
5713        const isAuthenticated = await this.window.luxuryPresence.session.validateSession();
5714        if (provider.hasAnalyticsConsent(this.document, this.window) || isAuthenticated) this.loadScript();
5715        if (!this.consentListener) {
5716            this.consentListener = (eventData)=>{
5717                if (provider.isAnalyticsAccepted(eventData.detail)) this.loadScript();
5718                else this.removeScripts();
5719            };
5720            this.document.addEventListener(provider.eventName, this.consentListener);
5721        }
5722    }
5723}
5724
5725
5726/* global window */ /* eslint-disable import/prefer-default-export */ /**
5727 * Checks if the current site should redirect homeowner valuation submissions to HST.
5728 * Returns true and performs the redirect if all three gate conditions are met.
5729 * Returns false if the redirect did not fire (caller should continue with existing flow).
5730 *
5731 * @param {string} address - The human-readable address string from the form
5732 * @returns {boolean}
5733 */ function $0ae243a777665fd3$var$checkHstRedirect(address) {
5734    const { config: config } = window.luxuryPresence;
5735    if (config.hstValuationRedirectEnabled && config.mlsEnabled && config.myhomeDashboardEnabled) {
5736        window.location.href = `/home-search/home-valuation?address=${encodeURIComponent(address)}`;
5737        return true;
5738    }
5739    return false;
5740}
5741const $0ae243a777665fd3$export$4225ff17959c7313 = {
5742    checkHstRedirect: $0ae243a777665fd3$var$checkHstRedirect,
5743    destroy () {}
5744};
5745
5746
5747const $fa0280e505379701$export$1fd2b467a3644d37 = new (0, $dc851cf3939b6ef5$export$ff0712c26d5458f7)({});
5748const $fa0280e505379701$export$e12694e911a05f40 = new (0, $0ead03fdb95fa9ce$export$d507f25e63650365)($fa0280e505379701$export$1fd2b467a3644d37, window, document);
5749const $fa0280e505379701$export$3de614e59a842917 = new (0, $d48f9f944810f613$export$ca3218b7861b9cb0)($fa0280e505379701$export$1fd2b467a3644d37, window, document);
5750const $fa0280e505379701$export$fb9b298fdbf31455 = new (0, $68a2d4aa500c7a05$export$61ec8f2b6291ec31)($fa0280e505379701$export$1fd2b467a3644d37, window, document);
5751const $fa0280e505379701$export$178cc3119b453c2a = new (0, $e10bd00497be8876$export$3c5380623cf51249)($fa0280e505379701$export$1fd2b467a3644d37, window, document);
5752const $fa0280e505379701$export$9376af1a01686f2 = new (0, $ea6901fdf47e0ec1$export$3c19195edca3fa5c)($fa0280e505379701$export$1fd2b467a3644d37, window, document);
5753const $fa0280e505379701$export$94d36f806562393e = new (0, $0a0ad49f13c0b8fd$export$ba9afeb75f20f616)($fa0280e505379701$export$1fd2b467a3644d37, window, document);
5754const $fa0280e505379701$export$89e66d1faf94651e = new (0, $2b1790aa32f109d1$export$43e435c053a109f6)($fa0280e505379701$export$1fd2b467a3644d37, window, document);
5755const $fa0280e505379701$export$7743b07270cd6d6c = new (0, $4f184d9bd3037f15$export$7a6215890afba974)($fa0280e505379701$export$1fd2b467a3644d37, window, document);
5756const $fa0280e505379701$export$40a7039551318c37 = new (0, $102039871668a1df$export$e22e4b1be0bb6c61)($fa0280e505379701$export$1fd2b467a3644d37, window, document);
5757const $fa0280e505379701$export$8a0bbf7e7652fcfc = new (0, $0d25a3fa2e0f4f92$export$b718a981691eae5c)($fa0280e505379701$export$1fd2b467a3644d37, window, document);
5758const $fa0280e505379701$export$b313b3f6544c97a3 = new (0, $dcf72769f009ff26$export$b900d6fe921fd49c)($fa0280e505379701$export$1fd2b467a3644d37, window, document);
5759const $fa0280e505379701$export$b526bc4ac03268ef = new (0, $50eefeef8d1f2372$export$8a2bf06fbae4dde)($fa0280e505379701$export$1fd2b467a3644d37, window, document);
5760const $fa0280e505379701$export$c0affdb0a7a2ef6 = new (0, $396d9f0ca7465335$export$bb018224876724b9)($fa0280e505379701$export$1fd2b467a3644d37, window, document);
5761
5762
5763/**
5764 * Attach controller to window for usage
5765 * @param {string} key
5766 * @param {any} controller
5767 */ function $89a8a84b77163415$var$attachController(key, controller) {
5768    if (window.luxuryPresence[key]) try {
5769        // New version of sdk, destroy previous
5770        window.luxuryPresence[key].destroy();
5771    } catch (e) {
5772        // eslint-disable-next-line no-console
5773        console.log(e);
5774    }
5775    window.luxuryPresence[key] = controller;
5776}
5777$89a8a84b77163415$var$attachController('config', (0, $fa0280e505379701$export$1fd2b467a3644d37));
5778$89a8a84b77163415$var$attachController('modals', (0, $fa0280e505379701$export$e12694e911a05f40));
5779$89a8a84b77163415$var$attachController('buttons', (0, $fa0280e505379701$export$3de614e59a842917));
5780$89a8a84b77163415$var$attachController('validation', (0, $fa0280e505379701$export$fb9b298fdbf31455));
5781$89a8a84b77163415$var$attachController('contactForms', (0, $fa0280e505379701$export$178cc3119b453c2a));
5782$89a8a84b77163415$var$attachController('mapApiLoader', (0, $fa0280e505379701$export$9376af1a01686f2));
5783$89a8a84b77163415$var$attachController('pagination', (0, $fa0280e505379701$export$94d36f806562393e));
5784$89a8a84b77163415$var$attachController('expandSliders', (0, $fa0280e505379701$export$89e66d1faf94651e));
5785$89a8a84b77163415$var$attachController('divolte', (0, $fa0280e505379701$export$7743b07270cd6d6c));
5786$89a8a84b77163415$var$attachController('eventBus', (0, $fa0280e505379701$export$40a7039551318c37));
5787$89a8a84b77163415$var$attachController('oauth', (0, $fa0280e505379701$export$8a0bbf7e7652fcfc));
5788$89a8a84b77163415$var$attachController('qualifyingQuestionsModal', (0, $fa0280e505379701$export$b313b3f6544c97a3));
5789$89a8a84b77163415$var$attachController('session', (0, $fa0280e505379701$export$b526bc4ac03268ef));
5790$89a8a84b77163415$var$attachController('consent', (0, $fa0280e505379701$export$c0affdb0a7a2ef6));
5791$89a8a84b77163415$var$attachController('redirects', (0, $0ae243a777665fd3$export$4225ff17959c7313));
5792// methods for existing elements (can be removed later after elements updated)
5793window.luxuryPresence.formatSliderPriceRange = (0, $fa0280e505379701$export$94d36f806562393e).formatSliderPriceRange.bind((0, $fa0280e505379701$export$94d36f806562393e));
5794window.luxuryPresence.formatSliderAreaRange = (0, $fa0280e505379701$export$94d36f806562393e).formatSliderAreaRange.bind((0, $fa0280e505379701$export$94d36f806562393e));
5795// method below doesn't use 'this', but just to be safe in case of further method updates
5796window.luxuryPresence.getSearchFormValues = (0, $fa0280e505379701$export$94d36f806562393e).getSearchFormValues.bind((0, $fa0280e505379701$export$94d36f806562393e));
5797window.luxuryPresence.handlebarsHelpersFactory = function(handlebarsInstance) {
5798    return (0, (/*@__PURE__*/$parcel$interopDefault($53de3c160faf5a81$exports
5798)))(handlebarsInstance, {
5799        isEqual (a, b) {
5800            // eslint-disable-next-line
5801            return a == b;
5802        }
5803    });
5804};
5805
5806
5807
5808})();
5809//# sourceMappingURL=lp-sdk.js.map
5810
5811    </script>
5811
5812
5813    
5813<script>
5814        var lpGlobalInitialized = false;
5815
5816        function lpGlobalInit () {
5817          if (lpGlobalInitialized) {
5818            return;
5819          }
5820            lpGlobalInitialized = true;
5821            // Initialize wow animation plugin only according to turbolinks
5822            var wow;
5823            if (window.WOW) {
5824                wow = new WOW({
5825                    animateClass: 'animated',
5826                    offset: wowOffset,
5827                    live: false,
5828                    callback: function(box) {}
5829                });
5830            }
5831            // Initialize handlebar helpers only once
5832            function handlebarsInit() {
5833              if (!window.Handlebars) {
5834                return;
5835              }
5836              HandlebarsIntl.registerWith(Handlebars);
5837              Handlebars.registerHelper(window.luxuryPresence.handlebarsHelpersFactory(Handlebars));
5838            }
5839
5840            handlebarsInit();
5841
5842              var modalContentUrl = "/modals.html";
5843                const modalsContainer = document.getElementById('modals');
5844                if (modalsContainer) {
5845                  fetch(modalContentUrl).then(function(res) {
5846                    if (!res.ok) {
5847                      throw new Error(`HTTP error! Status: ${res.status}`);
5848                    }
5849                    return res.text();
5850                  }).then(function(resultText) {
5851                    modalsContainer.innerHTML = resultText;
5852
5853                    // now we need to execute all script elements
5854                    Array.from(modalsContainer.getElementsByTagName('script')).forEach(function (s) {
5855                      const script  = document.createElement("script");
5856                      script.text = s.innerHTML;
5857                      Array.from(s.attributes).forEach(function (a) {
5858                        script.setAttribute(a.name, a.value);
5859                      })
5860                      s.parentNode.replaceChild(script, s);
5861                    });
5862
5863                    try {
5864                      window.luxuryPresence.modals.initialize(window.luxuryPresence._modalIncludes);
5865                      window.luxuryPresence.contactForms.initialize({ selector: '#modals' });
5866                      window.luxuryPresence.validation.initialize({ selector: '#modals' });
5867                      window.luxuryPresence.oauth.initialize({
5868                        googleSignOnEnabled: false,
5869                        iframe: false });
5870                    } catch (e) {
5871                      console.log(e);
5872                    }
5873                    document.querySelectorAll('.modals > .modal .close').forEach(closeModalBtn => {
5874                      closeModalBtn.addEventListener('click', function() {
5875                        window.lpUI.hideClosestModal(closeModalBtn);
5876                      });
5877                    });
5878                  }).catch((e) => console.log(e));
5879                }
5880            /* Initialize Luxury Presence SDK */
5881            try {
5882                window.luxuryPresence.config.setCompany("2c02232f-2988-4a2c-a284-887b44b8c4fc", {});
5883                window.luxuryPresence.config.setWebsite("47a83415-cce5-4158-a944-4eb949b3b156", {
5884                    myhomeDashboardEnabled: false,
5885                    mlsEnabled: true,
5886                    hstValuationRedirectEnabled: true
5887                });
5888                const url = new URL(window.location.href);
5889                const shareId = url.searchParams.get('shareId');
5890                window.luxuryPresence.config.setPage("e6c68775-b811-4906-b042-f13e4ef1b35d", {
5891                    sourceResource: "",
5892                    pageElementId: "",
5893                    pageQueryVariables: {},
5894                    shareId: "",
5895                });
5896                window.luxuryPresence.config.setWebsiteApiGatewayUrl("https://wgw.luxurypresence.com", {});
5897                window.luxuryPresence.config.setBuyerSellerServiceUrl("https://bss.luxurypresence.com", {});
5898                    window.luxuryPresence.config.setDivolteServiceUrl("https://t.luxurypresence.com", {});
5899                  window.luxuryPresence.config.setEventBusUrl("https://cdn.luxurypresence.com/scripts/event-bus-js", {});
5900                  window.luxuryPresence.config.setEventBus({
5901                    enabled: true,
5902                    apiKey: "phc_PMYT31xlmXBaTCwpIRx1v6RrpLVZIuP47N3mOT6KLnr",
5903                    url: "https://p.luxurypresence.com",
5904                  });
5905                window.luxuryPresence.config.setTemplateId("e3960201-1a19-4660-a991-8658653d81e9", {});
5906                window.luxuryPresence.config.setLeadIngesterUrl("https://leads.luxurypresence.com", {});
5907                window.luxuryPresence.buttons.initialize({});
5908                    window.luxuryPresence.eventBus.initialize({});
5909                window.luxuryPresence.contactForms.initialize({});
5910                window.luxuryPresence.validation.initialize({});
5911                window.luxuryPresence.expandSliders.initialize({});
5912                window.luxuryPresence.oauth.initialize({ googleSignOnEnabled: false, iframe: false });
5913                window.luxuryPresence.qualifyingQuestionsModal.initialize({ qualifyingQuestionsModalEnabled: true });
5914                      window.luxuryPresence.divolte.initialize({});
5915            } catch (e) {
5916                console.log(e);
5917            }
5918
5919            /* Inject Section Specific Javascript */
5920                try {
5921(function init(sectionDomId) {
5922  let address = $('#' + sectionDomId + " .company_address").text().trim();
5923  $('#' + sectionDomId + " .company_address").text(address);
5924  function setHttp(link) {
5925    if (link.search(/^http[s]?\:\/\/|\//) == -1) {
5926      link = 'http://' + link;
5927    }
5928    return link;
5929  }
5930  $(`#${sectionDomId} .contact-form__form`).on('reset', () => {
5931    const redirectLink = $('#' + sectionDomId + ' .redirect-link');
5932    if (redirectLink.length) {
5933      const rawHref = redirectLink.attr('href');
5934      redirectLink.attr('href', setHttp(rawHref));
5935      redirectLink[0].click();
5936    }
5937  });
5938})('modal-global-contact-us');
5939} catch(e) {
5940console.log(e);
5941}
5942                
5943                try {
5944(function init(sectionDomId) {
5945  const mediaQuery = window.matchMedia('(hover: hover) and (pointer: fine)');
5946  var $subNavTrigger = $('.header .sub-nav-container a');
5947  var $subNavContainer = $('.header .sub-nav-container');
5948  if (mediaQuery.matches) {
5949    $subNavTrigger.off('click');
5950    $subNavContainer.mouseout(function () {
5951      var self = $(this);
5952      self.removeClass('active').find('.sub-nav').removeClass('visible');
5953    }).mouseover(function () {
5954      $(this).siblings('.sub-nav-container').removeClass('active').find('.sub-nav').removeClass('visible');
5955      $(this).addClass('active').find('.sub-nav').addClass('visible');
5956    }).mouseup(function () {
5957      var self = $(this);
5958      self.toggleClass('active');
5959    });
5960  }
5961  function isSectionLight(sect) {
5962    if (!sect || !sect.style) {
5963      return true;
5964    }
5965    if (sect.style.backgroundImage) {
5966      return false;
5967    }
5968    if ($(sect).children('.video-wrapper').length) {
5969      return false;
5970    }
5971    return sect.classList.contains('is-background-color-light');
5972  }
5973  const $header = $(`#${sectionDomId} > .header`);
5974  if ($header.hasClass('theme-auto')) {
5975    if (isSectionLight($('body > section')[0])) {
5976      $header.removeClass('theme-light');
5977    } else {
5978      $header.addClass('theme-light');
5979    }
5980  }
5981})('global-navbar');
5982} catch(e) {
5983console.log(e);
5984}
5985                try {
5986(function init(sectionDomId, options) {
5987  var elementSelector = options.elementSelector || 'nav';
5988  var element = document.querySelector(elementSelector);
5989  var sections = document.querySelectorAll('body > section');
5990  var subNavContainers = element.querySelectorAll('.sub-nav');
5991  var initialBackgroundColor = options.initialBackgroundColor || element.style.backgroundColor;
5992  var backgroundColorScroll = options.backgroundColorScroll || '#191919';
5993  var fontColor = options.fontColor || '#fff';
5994  var fontColorScroll = options.fontColorScroll || '#000';
5995  var didScroll = false;
5996  var lastScrollTop = 0;
5997  var delta = 5;
5998
5999  // eslint-disable-next-line sonarjs/no-collapsible-if
6000  if (wow) {
6001    // Wowjs might not trigger for position fixed elements
6002    if (window.scrollY > 0) {
6003      element.querySelectorAll('.wow').forEach(el => wow.show(el));
6004    }
6005  }
6006  function adjustNavPinState() {
6007    // Remove 'visible' class from all subNavContainers
6008    for (let i = 0; i < subNavContainers.length; i++) {
6009      subNavContainers[i].classList.remove('visible');
6010    }
6011    if (window.scrollY > 0) {
6012      element.style.backgroundColor = backgroundColorScroll;
6013      element.style.color = fontColorScroll;
6014      element.classList.add('scroll');
6015    } else {
6016      element.style.backgroundColor = initialBackgroundColor;
6017      element.style.color = fontColor;
6018      element.classList.remove('scroll');
6019    }
6020  }
6021  adjustNavPinState();
6022  function onScroll() {
6023    didScroll = true;
6024  }
6025  window.addEventListener('scroll', onScroll);
6026
6027  // eslint-disable-next-line
6028  var debounceInterval = setInterval(() => {
6029    if (didScroll) {
6030      // eslint-disable-next-line
6031      hasScrolled();
6032      didScroll = false;
6033    }
6034  }, 250);
6035  function hasScrolled() {
6036    adjustNavPinState();
6037    // eslint-disable-next-line
6038    var navbarHeight = element.offsetHeight;
6039    // eslint-disable-next-line
6040    var st = window.scrollY;
6041
6042    // Make sure they scroll more than delta
6043    if (Math.abs(lastScrollTop - st) <= delta) {
6044      return;
6045    }
6046    if (st > lastScrollTop && st > navbarHeight) {
6047      // Scroll Down
6048      element.style.transform = `translateY(-${navbarHeight}px) scaleY(0)`;
6049      document.documentElement.style.setProperty('--global-header-height', '0px');
6050
6051      // Some sections "follow" the navbar with class sticky (i.e. Producer search)
6052      sections.forEach(section => {
6053        if (section.classList.contains('sticky')) {
6054          section.style.top = '0px';
6055        }
6056      });
6057    } else {
6058      // Scroll Up
6059      // eslint-disable-next-line
6060      if (st + window.innerHeight < document.documentElement.scrollHeight) {
6061        element.style.transform = `translateY(0) scaleY(1)`;
6062        document.documentElement.style.setProperty('--global-header-height', `${navbarHeight}px`);
6063        sections.forEach(section => {
6064          if (section.classList.contains('sticky')) {
6065            section.style.top = `${navbarHeight}px`;
6066          }
6067        });
6068      }
6069    }
6070    lastScrollTop = st;
6071  }
6072})('NAVBAR', JSON.parse("{\"fontColor\":\"#ffffff\",\"elementSelector\":\"nav\",\"fontColorScroll\":\"#000000\",\"backgroundColorScroll\":\"#ffffff\",\"initialBackgroundColor\":\"rgba(0,0,0,0)\"}"));
6073} catch(e) {
6074console.log(e);
6075}
6076                try {
6077(function init(sectionDomId) {
6078  sectionDomId = "global-sidemenu";
6079  var $sidemenu = $('#' + sectionDomId);
6080  const subNavItems = $('body > div.sidemenu .sub-nav-container .sub-nav__item');
6081  const hideSubNavItems = () => {
6082    subNavItems.removeClass('fadeInUp');
6083  };
6084  const showSubNavItems = subnav => {
6085    if ($(subnav).find('.arrow').hasClass('active')) {
6086      $(".sidemenu").find('.arrow').removeClass('active');
6087    } else {
6088      $(".sidemenu").find('.arrow').removeClass('active');
6089      $(subnav).find('.arrow').addClass('active');
6090    }
6091    let i = 0;
6092    subnav.find('.sub-nav__item').each((idx, item) => {
6093      i++;
6094      var timeout;
6095      clearTimeout(timeout);
6096      timeout = setTimeout(() => {
6097        $(item).addClass('fadeInUp');
6098      }, 100 + i * 50);
6099    });
6100  };
6101  $(document).on("click", function (e) {
6102    if ($(e.target).closest(".navigation").length < 1) {
6103      hideSubNavItems();
6104    }
6105  });
6106  $('body > div.sidemenu .sub-nav-container > a').click(function (e) {
6107    const subnavContainer = $(this).closest('.sub-nav-container');
6108    hideSubNavItems();
6109    showSubNavItems(subnavContainer);
6110  });
6111  const hideSideMenu = () => {
6112    $('body > div.sidemenu').removeClass('visible');
6113  };
6114  $('body > div.sidemenu .navigation .navigation__item:not(.sub-nav-container) .navigation__link').on('click', function (e) {
6115    onHide();
6116    hideSideMenu();
6117  });
6118  $('body > div.sidemenu .sub-nav-container .sub-nav__link').on('click', function (e) {
6119    onHide();
6120    setTimeout(() => {
6121      hideSideMenu();
6122    }, 1601);
6123  });
6124  var shown = false;
6125  function onShow() {
6126    if (shown) {
6127      return;
6128    }
6129    shown = true;
6130    window.lpUI.requestScrollLock(sectionDomId);
6131    $('#' + sectionDomId + ' .navigation__link').removeClass('fade-in');
6132    $('#' + sectionDomId + ' .lp-socials__link').removeClass('fade-in');
6133    let i = 0;
6134    $('#' + sectionDomId + ' .navigation__link').each(function () {
6135      i++;
6136      setTimeout(() => {
6137        $(this).addClass('fade-in');
6138      }, 900 + i * 50);
6139    });
6140    $('#' + sectionDomId + ' .lp-socials__link').each(function () {
6141      i++;
6142      setTimeout(() => {
6143        $(this).addClass('fade-in');
6144      }, 900 + i * 50);
6145    });
6146  }
6147  function onHide() {
6148    hideSubNavItems();
6149    if (!shown) {
6150      return;
6151    }
6152    $('#' + sectionDomId + ' .lp-socials__link').removeClass('fade-in');
6153    let i = 0;
6154    $($('#' + sectionDomId + ' .navigation__link').get().reverse()).each(function () {
6155      i++;
6156      setTimeout(() => {
6157        $(this).removeClass('fade-in');
6158      }, i * 50);
6159    });
6160    shown = false;
6161    setTimeout(() => {
6162      window.lpUI.releaseScrollLock(sectionDomId);
6163    }, 1600);
6164  }
6165  $sidemenu.on('lpui-show', onShow);
6166  $sidemenu.on('lpui-hide', onHide);
6167})('global-sidemenu');
6168} catch(e) {
6169console.log(e);
6170}
6171                
6172                try {
6173(function init(sectionDomId) {
6174  function setHttp(link) {
6175    if (link.search(/^http[s]?\:\/\/|\//) == -1) {
6176      link = 'http://' + link;
6177    }
6178    return link;
6179  }
6180  $(`#${sectionDomId} form`).on("reset", function () {
6181    const redirectLink = $('#' + sectionDomId + ' .redirect-link');
6182    if (redirectLink.length) {
6183      const rawHref = redirectLink.attr('href');
6184      redirectLink.attr('href', setHttp(rawHref));
6185      redirectLink[0].click();
6186    }
6187  });
6188})('global-footer');
6189} catch(e) {
6190console.log(e);
6191}
6192                
6193                try {
6194(function init(sectionDomId) {
6195  var _section = $('#' + sectionDomId);
6196  var _footer = document.getElementById('global-footer');
6197  const emailInput = _section.find('.js-email-input');
6198  const emailRegex = /[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~\-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)+/;
6199  emailInput.on('input', function () {
6200    if (emailRegex.test(this.value)) {
6201      this.setCustomValidity('');
6202    } else {
6203      this.setCustomValidity('Please enter a valid email address.');
6204    }
6205    this.reportValidity();
6206  });
6207  _section.find('input[name="name"]').on("keyup", function () {
6208    if (this.value.replaceAll(/\d/g, "").trim().split(" ").length < 2 || this.value.replaceAll(/\d/g, "").trim() === "") {
6209      this.setCustomValidity("Please input your first name and last name.");
6210    } else {
6211      this.setCustomValidity("");
6212    }
6213  });
6214  _section.find('form').on("reset", function () {
6215    $(this).addClass("show-success");
6216  });
6217  $(window).scroll(function () {
6218    if ($(this).scrollTop() >= 150) _section.find('.btn-holder').addClass('visible');else _section.find('.btn-holder').removeClass('visible');
6219  });
6220  _section.find('.close-btn, .connect-btn').click(function () {
6221    _section.find('.pop-up').toggle();
6222    _section.find('.btn-holder').toggle();
6223  });
6224  if (!_footer) return;
6225  const observer = new IntersectionObserver(entries => {
6226    entries.forEach(entry => {
6227      if (entry.isIntersecting) _section.hide();else _section.show();
6228    });
6229  }, {
6230    threshold: 0.1
6231  });
6232  observer.observe(_footer);
6233  function selectToDropdown(selectItem) {
6234    let customDropdown = `
6235        <div class="custom-select" role="presentation">
6236        <button class="custom-select-toggle is-placeholder" type="button" aria-haspopup="true" aria-expanded="false"></button>
6237        <div class="custom-select-menu" style="display: none;max-height: none;">
6238        <div class="custom-select-content">
6239        </div>
6240        </div>
6241        </div>`;
6242    $(customDropdown).insertAfter(selectItem);
6243    let $dropdown = $($(selectItem).next());
6244    let $dropdownToggle = $dropdown.find(".custom-select-toggle");
6245    let $dropdownMenu = $dropdown.find(".custom-select-menu");
6246    let $dropdownContent = $dropdown.find(".custom-select-content");
6247    $dropdownToggle.addClass($(selectItem).attr("class")).removeClass("dropdown-select");
6248    $dropdownToggle.attr("id", $(selectItem).attr("id") + "custom");
6249    $dropdownMenu.attr("aria-labelledby", $dropdownToggle.attr("id"));
6250    appendOptionButtons(selectItem, $dropdownContent);
6251    $(selectItem).removeClass().addClass("sr-only");
6252    var toggleText = $(selectItem).find(":selected").first().text() || $(selectItem).children().first().text();
6253    $dropdownToggle.html(toggleText);
6254    $dropdown.on("click", ".custom-select-item", function (e) {
6255      if ($(this).hasClass("is-disabled")) return;
6256      let elementNumber = $(this).index();
6257      let $originalSelect = $(this).closest(".custom-select").siblings("select");
6258      let $linkedOption = $originalSelect.find("option").eq(elementNumber);
6259      if (!$linkedOption.prop("selected")) {
6260        $linkedOption.prop("selected", true);
6261        $originalSelect.change();
6262        $(this).addClass("is-selected").siblings(".custom-select-item").removeClass("is-selected");
6263        $dropdownToggle.html($(this).html());
6264        closeSelectMenu($(this).closest(".custom-select-menu"));
6265      }
6266      $dropdownToggle.removeClass("is-placeholder");
6267    });
6268    function convertOptionToButton(option) {
6269      var optionText = $(option).text();
6270      var optionValue = $(option).attr("value") || $(option).text();
6271      var optionIsDisabled = $(option).prop("disabled");
6272      var outputButton = `<button value="${optionValue}" class="custom-select-item" type="button" ${optionIsDisabled ? "disabled" : ""}>${optionText}</button>`;
6273      return outputButton;
6274    }
6275    function appendOptionButtons(selectItem, appendTarget) {
6276      $(selectItem).find("option").each(function () {
6277        let currentButton = convertOptionToButton(this);
6278        $(appendTarget).append(currentButton);
6279      });
6280    }
6281    function showSelectMenu(selectMenu) {
6282      var customSelect = $(selectMenu).closest(".custom-select")[0];
6283      $(customSelect).addClass("open");
6284      $(selectMenu).slideDown();
6285    }
6286    function closeSelectMenu(selectMenu) {
6287      var customSelect = $(selectMenu).closest(".custom-select")[0];
6288      $(customSelect).removeClass("open");
6289      $(selectMenu).slideUp();
6290    }
6291    $dropdown.on("click", ".custom-select-toggle", function (e) {
6292      var $customSelect = $(this).closest(".custom-select");
6293      var selectMenu = $customSelect.find(".custom-select-menu")[0];
6294      if ($customSelect.hasClass("open")) {
6295        closeSelectMenu(selectMenu);
6296      } else {
6297        showSelectMenu(selectMenu);
6298      }
6299    });
6300    $(document).on("click", function (e) {
6301      if ($(e.target).closest(".custom-select").length < 1 && $(".custom-select").hasClass("open")) {
6302        $(".custom-select.open").each(function () {
6303          var selectMenu = $(this).find(".custom-select-menu")[0];
6304          closeSelectMenu(selectMenu);
6305        });
6306      }
6307    });
6308  }
6309  $(".pop-up select[name='interest']").each(function () {
6310    selectToDropdown(this);
6311  });
6312})('global-mobile-contact');
6313} catch(e) {
6314console.log(e);
6315}
6316                
6317                try {
6318(function init(sectionDomId) {
6319  const $section = $('#' + sectionDomId);
6320  const $videoWrap = $section.find('.full-screen-video-component > .video-wrapper');
6321  const $playButton = $section.find('.js-play-btn');
6322  if ($videoWrap.length) {
6323    const $video = $videoWrap.find('video');
6324    $video.each(function () {
6325      var v = this;
6326      if (v.readyState > 0) {
6327        $videoWrap.addClass('playing');
6328        var promise = v.play();
6329        if (promise !== undefined) {
6330          promise.catch(error => {
6331            $playButton.addClass('visible');
6332          }).then(() => {});
6333        }
6334      } else {
6335        v.addEventListener('canplay', function () {
6336          $videoWrap.addClass('playing');
6337        }, {
6338          once: true
6339        });
6340      }
6341    });
6342  }
6343  $playButton.on('click', function () {
6344    const $video = $videoWrap.find('video');
6345    this.classList.remove('visible');
6346    if ($video[0].currentTime === 0) {
6347      $video[0].load();
6348      $video[0].play();
6349    }
6350  });
6351  window.luxuryPresence.mapApiLoader.load().then(() => {
6352    const $searchWrapper = $section.find('.search-wrapper');
6353    if (!$searchWrapper.length) {
6354      return;
6355    }
6356    const searchMls = $searchWrapper[0].dataset.searchMls === 'true';
6357    const searchProperties = $searchWrapper[0].dataset.searchProperties === 'true';
6358    const searchPlaces = searchMls;
6359    const showNeighborhoods = searchMls;
6360    const searchNearEnabled = searchMls;
6361    const $searchInput = $section.find('.search-input');
6362    const $searchResults = $section.find('.search-results');
6363    const $resultsContainer = $section.find('.results-container');
6364    const $loader = $section.find('.search-in-progress');
6365    const $predefined = $section.find('.predefined-links');
6366    const $searchBtn = $section.find('.search-button');
6367    const $leaseFalseButton = $section.find('.jsLeaseFalse');
6368    const $leaseTrueButton = $section.find('.jsLeaseTrue');
6369    const $nextSection = $section.next();
6370    const fixZIndex = $nextSection.length && parseInt($nextSection.css('z-index')) || 1;
6371    const searchDelay = 300;
6372    const maxPlaces = 3;
6373    const maxMls = 5;
6374    const leaseFilter = $leaseFalseButton.length > 0 && $leaseTrueButton.length > 0;
6375    const service = new google.maps.places.AutocompleteService();
6376    const geocoder = new google.maps.Geocoder();
6377    var keyword;
6378    var leasePropertyState = false;
6379    var leasePropertySearched;
6380    var searchActive = false;
6381    var isLoading = false;
6382    function showSearchResults() {
6383      searchActive = true;
6384      updateSearchDisplay();
6385    }
6386    function hideSearchResults() {
6387      searchActive = false;
6388      updateSearchDisplay();
6389    }
6390    function showLoading() {
6391      isLoading = true;
6392      updateSearchDisplay();
6393    }
6394    function hideLoading() {
6395      isLoading = false;
6396      updateSearchDisplay();
6397    }
6398    function updateSearchDisplay() {
6399      if (leaseFilter) {
6400        if (leasePropertyState) {
6401          $leaseTrueButton.addClass('active');
6402          $leaseFalseButton.removeClass('active');
6403        } else {
6404          $leaseFalseButton.addClass('active');
6405          $leaseTrueButton.removeClass('active');
6406        }
6407      }
6408      if (!searchActive) {
6409        $searchResults.removeClass('show');
6410        $searchResults.css('height', '0');
6411        return;
6412      }
6413      var hasResults = !!$resultsContainer.html();
6414      var hasPredefined = $predefined.find('a:not(.not-processed)').length > 0;
6415      if (hasResults) {
6416        $predefined.addClass('not-visible');
6417        $loader.addClass('not-visible');
6418        $resultsContainer.removeClass('not-visible');
6419      } else if (isLoading) {
6420        $resultsContainer.addClass('not-visible');
6421        $predefined.addClass('not-visible');
6422        $loader.removeClass('not-visible');
6423      } else if (hasPredefined) {
6424        $resultsContainer.addClass('not-visible');
6425        $loader.addClass('not-visible');
6426        $predefined.removeClass('not-visible');
6427      } else {
6428        $resultsContainer.addClass('not-visible');
6429        $loader.addClass('not-visible');
6430        $predefined.addClass('not-visible');
6431      }
6432      var height = 0;
6433      height += $predefined[0].getBoundingClientRect().height;
6434      height += $resultsContainer[0].getBoundingClientRect().height;
6435      height += $loader[0].getBoundingClientRect().height;
6436      if (height > 0) {
6437        $searchResults.addClass('show');
6438      } else {
6439        $searchResults.removeClass('show');
6440      }
6441      $searchResults.css('height', height + 'px');
6442    }
6443    function clearSelection() {
6444      $searchResults.find('.selected-link').removeClass('selected-link');
6445    }
6446    function moveSelection(up) {
6447      var $cont = $resultsContainer.html() ? $resultsContainer : $predefined;
6448      var $links = $cont.find('.results-link');
6449      if (!$links.length) {
6450        return;
6451      }
6452      var idx = -1;
6453      $links.each(function (i) {
6454        if (idx === -1 && $(this).is('.selected-link')) {
6455          idx = i;
6456        }
6457      });
6458      var newIdx;
6459      if (up) {
6460        newIdx = idx - 1;
6461        if (newIdx < 0) {
6462          newIdx = $links.length - 1;
6463        }
6464      } else {
6465        newIdx = idx + 1;
6466        if (newIdx > $links.length - 1) {
6467          newIdx = 0;
6468        }
6469      }
6470      if (newIdx !== idx) {
6471        $searchResults.find('.selected-link').removeClass('selected-link');
6472        $($links.get(newIdx)).addClass('selected-link');
6473      }
6474    }
6475    var newSearchTimer;
6476    function inputChanged(ev) {
6477      if (ev.which === 38) {
6478        ev.preventDefault();
6479        moveSelection(true);
6480        return false;
6481      }
6482      if (ev.which === 40) {
6483        ev.preventDefault();
6484        moveSelection();
6485        return false;
6486      }
6487      if (ev.which === 13) {
6488        $lnk = $searchResults.find('.selected-link');
6489        if ($lnk.length) {
6490          $lnk[0].click();
6491          hideSearchResults();
6492        } else {
6493          $searchBtn.click();
6494        }
6495      }
6496      window.clearTimeout(newSearchTimer);
6497      newSearchTimer = window.setTimeout(startSearch, searchDelay);
6498    }
6499    function startSearch() {
6500      const term = $searchInput.val();
6501      if (term === keyword && leasePropertySearched === leasePropertyState) {
6502        return;
6503      }
6504      leasePropertySearched = leasePropertyState;
6505      keyword = term;
6506      if (term) {
6507        doSearch(term, leasePropertySearched);
6508      } else {
6509        setResults(null);
6510      }
6511    }
6512    function mlsSearch(term, leaseProperty) {
6513      var query = {
6514        keyword_search: term,
6515        limit: maxMls
6516      };
6517      if (leaseFilter && leaseProperty) {
6518        query.lease_property = true;
6519      }
6520      return superagent.get(window.location.protocol + '//' + window.location.host + '/home-search/listings.json').query(query).then(function (res) {
6521        if (!Array.isArray(res.body)) {
6522          return [];
6523        }
6524        return res.body.map(function (item) {
6525          return {
6526            id: item.id,
6527            display_address: [item.address_1, item.city, [item.state, item.postal_code].filter(function (i) {
6528              return i;
6529            }).join(' ')].filter(function (i) {
6530              return i;
6531            }).join(', ')
6532          };
6533        });
6534      }, function (e) {
6535        console.log(e);
6536        return [];
6537      });
6538    }
6539    function resolveGeoBounds(placeId, description, terms) {
6540      return new Promise(function (resolve, reject) {
6541        geocoder.geocode({
6542          'placeId': placeId
6543        }, function (results, status) {
6544          if (status != 'OK') {
6545            return resolve(null);
6546          }
6547          var result = results[0];
6548          var bounds = new google.maps.LatLngBounds();
6549          bounds.extend(result.geometry.viewport.getSouthWest());
6550          bounds.extend(result.geometry.viewport.getNorthEast());
6551          result.geometry.bounds = bounds.toJSON();
6552          var placeUrl = window.luxuryPresence.makeMlsLink(result);
6553          return resolve({
6554            placeUrl: placeUrl,
6555            description: description,
6556            cityName: terms[0].value,
6557            stateName: terms[1].value
6558          });
6559        });
6560      });
6561    }
6562    function resolveAutocomplete(term, deeper) {
6563      var request = {
6564        input: term,
6565        componentRestrictions: {
6566          country: 'us'
6567        },
6568        types: deeper ? ['geocode'] : ['(regions)'],
6569        limit: 1
6570      };
6571      return new Promise(function (resolve, reject) {
6572        service.getPlacePredictions(request, function (results, status) {
6573          if (status !== google.maps.places.PlacesServiceStatus.OK) {
6574            resolve(null);
6575            return;
6576          }
6577          if (!Array.isArray(results)) {
6578            resolve(null);
6579            return;
6580          }
6581          if (deeper) {
6582            var allowedTypes = {
6583              'neighborhood': true,
6584              'administrative_area_level_3': true,
6585              'administrative_area_level_4': true,
6586              'administrative_area_level_5': true,
6587              'sublocality_level_1': true,
6588              'sublocality_level_2': true,
6589              'sublocality_level_3': true
6590            };
6591            results = results.filter(function (res) {
6592              return res.types.find(t => allowedTypes[t]);
6593            });
6594          }
6595          if (!results.length) {
6596            resolve(null);
6597            return;
6598          }
6599          resolve(results);
6600        });
6601      });
6602    }
6603    var placesResult = {};
6604    function placesSearch(term, ignoreInput) {
6605      if (placesResult.term !== term) {
6606        placesResult = {
6607          term: term,
6608          result: resolveAutocomplete(term).then(function (results) {
6609            if (!ignoreInput && term !== keyword) {
6610              return null;
6611            }
6612            if (ignoreInput && !results) {
6613              return resolveAutocomplete(term, true);
6614            }
6615            return results;
6616          }).then(function (results) {
6617            if (!ignoreInput && term !== keyword) {
6618              return [];
6619            }
6620            if (!results) {
6621              return [];
6622            }
6623            var geoResultPromises = results.map(function (result) {
6624              return resolveGeoBounds(result.place_id, result.description, result.terms);
6625            });
6626            return Promise.all(geoResultPromises).then(function (geoLinks) {
6627              return geoLinks.filter(function (i) {
6628                return i;
6629              }).slice(0, maxPlaces);
6630            });
6631          })
6632        };
6633      }
6634      return placesResult.result;
6635    }
6636    function propertiesSearch(term, leaseProperty) {
6637      var payload = {
6638        companyId: window.luxuryPresence.defaults.companyId,
6639        search: term,
6640        offset: 0,
6641        limit: 6,
6642        statusIds: ["5f528253-abb7-484e-95c3-330269ac1105", "959c11cf-8655-4f91-874c-292b0ab7ea6b", "a0012964-4f51-4430-abf8-6547c5ab6441", "df04ccbe-4621-4140-a504-ee1a17430bb7", "88b4ace6-f39b-4b25-a051-8f6dba976833", "96031d77-bbe5-4de3-90d8-1e4e70de8ca8"]
6643      };
6644      if (leaseFilter) {
6645        payload.leaseProperty = !!leaseProperty;
6646      }
6647      return superagent.post(window.luxuryPresence.defaults.apiGatewayUrl + '/graphql').send({
6648        query: window.luxuryPresence.defaults.gql.properties,
6649        variables: payload
6650      }).then(function (res) {
6651        return (res.body.data || {}).properties || [];
6652      }, function (err) {
6653        return [];
6654      });
6655    }
6656    function doSearch(term, leaseProperty) {
6657      showLoading();
6658      Promise.all([searchMls ? mlsSearch(term, leaseProperty) : [], searchPlaces ? placesSearch(term) : [], searchProperties ? propertiesSearch(term, leaseProperty) : []]).then(function (res) {
6659        if (term !== keyword) {
6660          return;
6661        }
6662        setResults(res[0], res[1], res[2], leaseProperty);
6663      });
6664    }
6665    function makeResultsBlockHtml(title, links) {
6666      if (!links || !links.length) {
6667        return '';
6668      }
6669      var html = '<div class="results-block">';
6670      html += '<div class="results-block-title">';
6671      if (searchNearEnabled) {
6672        html += '<div class="search-near-container"><a class="search-near lp-link lp-link--light">Search Near Me</a></div>';
6673      }
6674      html += '<div class="results-title-label">' + title + '</div></div>';
6675      html += links.join('') + '</div>';
6676      return html;
6677    }
6678    function setResults(mlsResults, placesResults, propertiesResults, leaseProperty) {
6679      clearSelection();
6680      hideLoading();
6681      if (!mlsResults) {
6682        $resultsContainer.html('');
6683        updateSearchDisplay();
6684        return;
6685      }
6686      if (!mlsResults.length && !placesResults.length && !propertiesResults.length) {
6687        $resultsContainer.html('<div class="nothing-found">No results found</div>');
6688        updateSearchDisplay();
6689        return;
6690      }
6691      var propertiesHtml = makeResultsBlockHtml('Featured Properties', propertiesResults.map(function (result) {
6692        return `<a href="/properties/${result.slug}" class="results-link">${result.privateAddress ? result.name : result.fullAddress}</a>`;
6693      }));
6694      var placesHtml = makeResultsBlockHtml('Locations', placesResults.map(function (result) {
6695        return `<a class="results-link" href="${result.placeUrl}${leaseProperty ? '&lease_property=true' : ''}&cityName=${result.cityName}&stateName=${result.stateName}">${result.description}</a>`;
6696      }));
6697      var mlsHtml = makeResultsBlockHtml('Address', mlsResults.map(function (result) {
6698        return `<a href="/home-search/listings/${result.id}" class="results-link">${result.display_address}</a>`;
6699      }));
6700      $resultsContainer.html(propertiesHtml + placesHtml + mlsHtml);
6701      updateSearchDisplay();
6702    }
6703    function searchBtnClicked() {
6704      var resultsBlockHref = $("#" + sectionDomId + " .results-block .results-link").attr("href");
6705      const term = $searchInput.val();
6706      if (!term) {
6707        return;
6708      }
6709      if (searchMls) {
6710        window.location.href = resultsBlockHref;
6711        return;
6712      }
6713      if (searchProperties) {
6714        window.location.href = "/properties/sale";
6715      }
6716    }
6717    var neighborhoods = null;
6718    function fetchNeighborhoods() {
6719      var url = window.luxuryPresence.defaults.apiGatewayUrl;
6720      var gqlQuery = 'query ($companyId: String, $offset: Int, $limit: Int) {' + 'neighborhoods (companyId: $companyId, offset: $offset, limit: $limit) {id, name, mlsLink, googlePlaceData}}';
6721      var payload = {};
6722      payload.offset = 0;
6723      payload.limit = 100;
6724      payload.companyId = window.luxuryPresence.defaults.companyId;
6725      return superagent.post(url + '/graphql').withCredentials().send({
6726        query: gqlQuery,
6727        variables: payload
6728      }).then(function (res) {
6729        neighborhoods = res.body.data && res.body.data.neighborhoods;
6730        if (neighborhoods && !neighborhoods.length) {
6731          neighborhoods = null;
6732        }
6733      });
6734    }
6735    function setPredefinedNeighborhoods() {
6736      return fetchNeighborhoods().then(function () {
6737        if (!neighborhoods) {
6738          return;
6739        }
6740        var leaseProperty = leaseFilter && leasePropertyState;
6741        var placesHtml = makeResultsBlockHtml('Locations', neighborhoods.map(function (item) {
6742          return `<a class="results-link" href="${item.mlsLink}${leaseProperty ? '&lease_property=true' : ''}">${item.googlePlaceData && item.googlePlaceData.formatted_address || item.name}</a>`;
6743        }));
6744        $predefined.html(placesHtml);
6745        updateSearchDisplay();
6746      });
6747    }
6748    if (showNeighborhoods) {
6749      setPredefinedNeighborhoods();
6750    }
6751    $searchInput.on('focus', showSearchResults);
6752    $searchInput.on('keyup focus', inputChanged);
6753    $searchResults.on('mouseenter', '.results-link', function (ev) {
6754      clearSelection();
6755    });
6756    $searchBtn.on('click', searchBtnClicked);
6757    $leaseFalseButton.on('click', function () {
6758      if (leasePropertyState) {
6759        leasePropertyState = false;
6760        if (showNeighborhoods) {
6761          setPredefinedNeighborhoods();
6762        }
6763        updateSearchDisplay();
6764        setResults(null);
6765        startSearch();
6766      }
6767    });
6768    $leaseTrueButton.on('click', function () {
6769      if (!leasePropertyState) {
6770        leasePropertyState = true;
6771        if (showNeighborhoods) {
6772          setPredefinedNeighborhoods();
6773        }
6774        updateSearchDisplay();
6775        setResults(null);
6776        startSearch();
6777      }
6778    });
6779    function createPolygonUrl(center, radius, n) {
6780      var step = Math.PI * 2 / n;
6781      var angle = 0 - step / 2;
6782      var points = [];
6783      var kx = 1.0 / Math.cos(center[1] * Math.PI / 180);
6784      for (var i = 0; i < n; i++) {
6785        points.push('[' + (center[0] + radius * Math.sin(angle) * kx).toFixed(5) + ',' + (center[1] - radius * Math.cos(angle)).toFixed(5) + ']');
6786        angle += step;
6787      }
6788      points.push(points[0]);
6789      var str = '[[' + points.join(',') + ']]';
6790      return '&polygon=' + encodeURIComponent(str);
6791    }
6792    function makeNearMeUrl(center, leaseProperty) {
6793      var url = '/home-search/listings?search_type=envelope';
6794      if (leaseProperty) {
6795        url += '&lease_property=true';
6796      }
6797      var distance = 0.11;
6798      var lat = center[1];
6799      var lng = center[0];
6800      url += '&south=' + (lat - distance);
6801      url += '&north=' + (lat + distance);
6802      url += '&west=' + (lng - distance);
6803      url += '&east=' + (lng + distance);
6804      url += createPolygonUrl(center, distance, 54);
6805      return url;
6806    }
6807    var $locMsg = null;
6808    $section.on('click', '.search-near', function () {
6809      showLoading();
6810      navigator.geolocation.getCurrentPosition(function (position) {
6811        hideLoading();
6812        hideSearchResults();
6813        if (!position || !position.coords || !position.coords.latitude || !position.coords.longitude) {
6814          showLocationMessage('Unknown Location', '<p>Getting position of your device failed.</p><p>
6814You can type your address manually in the search field</p>');
6815          return;
6816        }
6817        var url = makeNearMeUrl([position.coords.longitude, position.coords.latitude], leaseFilter && leasePropertyState);
6818        var link = document.createElement('a');
6819        link.href = url;
6820        link.class = 'lp-visually-hidden';
6821        $section[0].appendChild(link);
6822        link.click();
6823        setTimeout(function () {
6824          $section[0].removeChild(link);
6825        }, 100);
6826      }, function (geoError) {
6827        hideLoading();
6828        hideSearchResults();
6829        var title = 'Unknown Location';
6830        var msg;
6831        if (geoError.code === 1) {
6832          msg = '<p>To be able to search near you we need to know your current location.</p><p>If you don\'t want to give access to your device\'s location, you can type your address in the search field</p>';
6833        } else {
6834          msg = '<p>Getting position of your device failed.</p><p>You can type your address manually in the search field</p>';
6835        }
6836        showLocationMessage(title, msg);
6837      });
6838    });
6839    var locHideTimer = null;
6840    function showLocationMessage(title, message) {
6841      clearTimeout(locHideTimer);
6842      if (!$locMsg) {
6843        var html = `<div class="loc-msg-backdrop">
6844          <div class="loc-msg-wrap">
6845            <div class="loc-msg-modal">
6846              <div class="loc-msg-close"></div>
6847              <h4 class="loc-msg-title lp-h4"></h4>
6848              <div class="loc-msg-container"></div>
6849            </div>
6850          </div>
6851        </div>
6852        `;
6853        $locMsg = $(html);
6854        $locMsg.on('click', hideLocationMessage);
6855        $section.append($locMsg);
6856      }
6857      $locMsg.find('.loc-msg-container').html(message);
6858      $locMsg.find('.loc-msg-title').html(title);
6859      setTimeout(function () {
6860        if ($locMsg) {
6861          $section.addClass('visible-loc-msg');
6862        }
6863      });
6864    }
6865    function hideLocationMessage() {
6866      $section.removeClass('visible-loc-msg');
6867      locHideTimer = setTimeout(function () {
6868        $locMsg.remove();
6869        $locMsg = null;
6870      }, 400);
6871    }
6872    function outsideClickHandler(e) {
6873      if ($searchWrapper.find($(e.target)).length > 0) {
6874        return;
6875      }
6876      hideSearchResults();
6877    }
6878    $(document).on('click', outsideClickHandler);
6879    if ('geolocation' in navigator) {
6880      $searchWrapper.removeClass('search-near-hidden');
6881    }
6882    updateSearchDisplay();
6883  });
6884})('section-28f45f08-c7d4-49ae-b152-9a02d549e538', 'undefined');
6885} catch(e) {
6886console.log(e);
6887}
6888                try {
6889(function init(sectionDomId, options) {
6890  let section = null;
6891  switch (sectionDomId) {
6892    case 'NAVBAR':
6893      section = document.querySelector('body > nav, #global-navbar');
6894      break;
6895    case 'FOOTER':
6896      section = document.querySelector('body > footer, #global-footer');
6897      break;
6898    case 'SIDEMENU':
6899      section = document.querySelector('body > div.sidemenu, #global-sidemenu');
6900      break;
6901    case 'CONTACT':
6902      section = document.querySelector('#modal-global-contact-us');
6903      break;
6904    case 'MOBILE_CONTACT':
6905      section = document.querySelector('body > div.mobile-contact-wrapper, #global-mobile-contact');
6906      break;
6907    case 'SUBSCRIBE':
6908      // Subscribe Not Implemented
6909      section = null;
6910      break;
6911    case 'ACCOUNT':
6912      // Account Not Implemented
6913      section = null;
6914      break;
6915    default:
6916      section = document.querySelector('#' + sectionDomId);
6917  }
6918  if (!section) {
6919    return;
6920  }
6921
6922  // Where content / items are rendered
6923  const dataContainer = section.querySelector('.data-container');
6924  if (!dataContainer) {
6925    // no place to render items = no need to query server or do anything else
6926    return;
6927  }
6928  let variables = options.variables || {};
6929
6930  // Some variables in options may not have been injected - remove
6931  Object.keys(variables).forEach(function (variableName) {
6932    if (typeof variables[variableName] === 'string' && variables[variableName].match(/^{{.*}}$/)) {
6933      delete variables[variableName];
6934    }
6935  });
6936
6937  // Merge page query variables
6938  if (options.usePageResource) {
6939    variables = {
6940      ...variables,
6941      ...window.luxuryPresence.config.pageMeta.pageQueryVariables[options.resource]
6942    };
6943  }
6944
6945  // Pagination Executes on a Numbered Pagination Container
6946  //  Or via a load more button
6947  let mode = 'BUTTONLESS_PAGINATION';
6948  const container = section.querySelector('.pagination-container');
6949  const loadMoreButton = section.querySelector(options?.loadMoreSelector);
6950  if (container) {
6951    mode = 'NUMBERED_PAGINATION';
6952  }
6953  if (loadMoreButton) {
6954    mode = 'LOAD_MORE_BUTTON';
6955  }
6956  let searchContainer = section.querySelector('.search-container');
6957  const hidePaginationOnFirstPage = options.hidePaginationOnFirstPage || false;
6958  const eventPrefix = '__pagination-';
6959  const searchFormParams = options.searchFormParams || (options.resource === 'properties' ? [{
6960    param: 'neighborhoodId',
6961    urlKey: 'neighborhood'
6962  }, {
6963    param: 'search',
6964    urlKey: 'search'
6965  }, {
6966    param: 'salesPriceGTE',
6967    urlKey: 'pricemin',
6968    formKey: 'priceMin',
6969    type: 'int'
6970  }, {
6971    param: 'salesPriceLTE',
6972    urlKey: 'pricemax',
6973    formKey: 'priceMax',
6974    type: 'int'
6975  }, {
6976    param: 'livingSpaceSizeGTE',
6977    urlKey: 'areamin',
6978    formKey: 'areaMin',
6979    type: 'int'
6980  }, {
6981    param: 'livingSpaceSizeLTE',
6982    urlKey: 'areamax',
6983    formKey: 'areaMax',
6984    type: 'int'
6985  }] : []);
6986
6987  // Total entries - initialized in first render
6988  let totalNumber = 0;
6989  const DefaultSearchParams = {
6990    page: 1
6991  };
6992  searchFormParams.forEach(function (formParam) {
6993    DefaultSearchParams[formParam.formKey || formParam.param] = null;
6994  });
6995  let searchParams = {
6996    ...DefaultSearchParams
6997  };
6998  const offset = options.variables?.offset || 0;
6999  let scrollTarget = options.scrollTargetSelector ? section.querySelector(options.scrollTargetSelector) || section : section;
7000  let scrollOffset = (parseInt(options.scrollOffset, 10) || 0) ?? 100;
7001
7002  // entries of per page
7003  // when query variables for a given section would't be filled options.pageSize can store
7004  // template string, ex: "{{variables.limit}}", below code handles that case and set 9 as a default value
7005  let pageSize = parseInt(options.pageSize, 10) || 9;
7006
7007  // Adding mobile pageRange support
7008  var NARROW_BREAKPOINT = 600;
7009  var mobileBreakpoint = options.mobileBreakpoint > 0 ? options.mobileBreakpoint : NARROW_BREAKPOINT;
7010  var paginationMql = window.matchMedia(`(max-width: ${mobileBreakpoint}px)`);
7011
7012  // Page range (pages on both sides of the current page)
7013  var mobilePageRange = options.mobilePageRange > 0 ? options.mobilePageRange : 0;
7014  var desktopPageRange = options.pageRange >= 0 ? options.pageRange : 2;
7015  var pageRange = paginationMql.matches ? mobilePageRange : desktopPageRange;
7016
7017  // Whether to display the 'Previous' button
7018  var showPrevious = true;
7019
7020  // Whether to display the 'Next' button
7021  var showNext = true;
7022
7023  // Whether to display the page buttons
7024  var showPageNumbers = true;
7025
7026  // 'Previous' text
7027  var prevText = options.prevText || '&laquo;';
7028
7029  // 'Next' text
7030  var nextText = options.nextText || '&raquo;';
7031
7032  // Ellipsis text
7033  var ellipsisText = '&hellip;';
7034  var classPrefix = 'paginationjs';
7035
7036  // Default active class
7037  var activeClassName = 'active';
7038
7039  // Default disable class
7040  var disableClassName = 'disabled';
7041
7042  // Pagination element's position in the container
7043  var position = 'bottom';
7044
7045  // Whether to trigger pagination at initialization
7046  var triggerPagingOnInit = !options.skipInitialLoad;
7047  var showFirstOnEllipsisShow = true;
7048  var showLastOnEllipsisShow = true;
7049
7050  // Instantiated in init()
7051  var el = null;
7052
7053  // Controls scrollTop logic
7054  var firstRender = true;
7055  var renderBySearch = false;
7056  var disabled = false;
7057
7058  // Pagination script class selector
7059  var paginationScriptSelector = options.paginationPartialName ? `.${options.paginationPartialName}` : '.pagination-script';
7060
7061  // Property Specific Image Override if No Image
7062  var propertyPlaceholderImage = window.luxuryPresence.defaults.propertyPlaceholderImage;
7063
7064  // Construct template
7065  var templateHTML = section.querySelector(`script${paginationScriptSelector}`)?.innerHTML || '';
7066  var template = Handlebars.compile(templateHTML);
7067
7068  // Initialize
7069  init();
7070  function init() {
7071    Object.assign(searchParams, window.luxuryPresence.pagination.deserializeParams(searchFormParams, sectionDomId));
7072
7073    // Append/prepend pagination element to the pagination container
7074    if (mode === 'NUMBERED_PAGINATION') {
7075      el = document.createElement('div');
7076      el.className = 'paginationjs';
7077      container[position === 'bottom' ? 'append' : 'prepend'](el);
7078    }
7079    if (searchContainer) {
7080      initSearchContainer({
7081        fetchNeighborhoods: searchContainer.dataset.fetchNeighborhoods === 'true',
7082        fetchPostCategories: searchContainer.dataset.fetchPostCategories === 'true',
7083        fetchOffices: searchContainer.dataset.fetchOffices === 'true',
7084        fetchRentalRates: searchContainer.dataset.fetchRentalRates === 'true'
7085      }, function () {
7086        syncSearchFormState(searchParams);
7087      });
7088    }
7089
7090    // Bind events
7091    observer();
7092  }
7093  function syncSearchFormState(params) {
7094    searchContainer.dispatchEvent(new CustomEvent('sync', {
7095      detail: params
7096    }));
7097  }
7098  function initSearchContainer(options, done) {
7099    var promises = [];
7100    if (options.fetchNeighborhoods) {
7101      promises.push(fetchAllNeighborhoods(function (neighborhoods) {
7102        searchContainer.dispatchEvent(new CustomEvent('neighborhoods-data', {
7103          detail: {
7104            data: neighborhoods.map(function (item) {
7105              return {
7106                value: item.id,
7107                label: item.name
7108              };
7109            })
7110          }
7111        }));
7112      }));
7113    }
7114    if (options.fetchPostCategories) {
7115      promises.push(fetchPostCategories(function (categories) {
7116        searchContainer.dispatchEvent(new CustomEvent('post-categories-data', {
7117          detail: {
7118            data: categories
7119          }
7120        }));
7121      }));
7122    }
7123    if (options.fetchOffices) {
7124      promises.push(fetchOffices(function (offices) {
7125        searchContainer.dispatchEvent(new CustomEvent('offices-data', {
7126          detail: {
7127            data: offices
7128          }
7129        }));
7130      }));
7131    }
7132    if (options.fetchRentalRates) {
7133      promises.push(fetchAllRentalRates(function (rentalRates) {
7134        searchContainer.dispatchEvent(new CustomEvent('rental-rates-data', {
7135          detail: {
7136            data: rentalRates
7137          }
7138        }));
7139      }));
7140    }
7141    if (promises.length > 0) {
7142      Promise.all(promises).then(function () {
7143        done();
7144      });
7145    } else {
7146      // element's custom code is not executed yet, so we're scheduling callback to after element's code
7147      setTimeout(done);
7148    }
7149  }
7150  function fetchAllNeighborhoods(done) {
7151    var url = options.url || window.luxuryPresence.defaults.apiGatewayUrl;
7152    var gqlQuery = 'query ($companyId: String, $withProperties: NeighborhoodPropertiesFilter, $withBlogPosts: NeighborhoodBlogPostsFilter, $offset: Int, $limit: Int) {' + 'neighborhoods (companyId: $companyId, withProperties: $withProperties, withBlogPosts: $withBlogPosts, offset: $offset, limit: $limit) {id, name}}';
7153    var payload = {};
7154    payload.offset = 0;
7155    payload.limit = 100;
7156    payload.companyId = variables.companyId;
7157    if (options.resource === 'properties') {
7158      payload.withProperties = {
7159        active: true
7160      };
7161      ['agentIds', 'tag', 'propertyTypeId', 'statusIds', 'architectureStyle', 'lifestyle', 'salesPriceGTE', 'salesPriceLTE', 'leasePriceGTE', 'leasePriceLTE', 'livingSpaceSizeGTE', 'livingSpaceSizeLTE', 'bathCountGTE', 'bathCountLTE', 'bedroomCountGTE', 'bedroomCountLTE', 'bathCountGTE', 'bathCountLTE', 'bedroomCountGTE', 'bedroomCountLTE', 'featuredListing', 'leaseProperty', 'neighborhoodId', 'developmentId', 'openHouse'].forEach(function (field) {
7162        if (variables[field] !== undefined && variables[field] !== null) {
7163          payload.withProperties[field] = variables[field];
7164        }
7165      });
7166    }
7167    if (options.resource === 'posts') {
7168      payload.withBlogPosts = {
7169        active: true
7170      };
7171      ['search', 'postStatusId', 'featured', 'categoryId', 'categoryIds', 'neighborhoodId', 'slug'].forEach(function (field) {
7172        if (variables[field] !== undefined && variables[field] !== null) {
7173          payload.withBlogPosts[field] = variables[field];
7174        }
7175      });
7176    }
7177    superagent.post(url + '/graphql').withCredentials().send({
7178      query: gqlQuery,
7179      variables: payload
7180    }).then(function (res) {
7181      var items = res.body.data && res.body.data.neighborhoods || [];
7182      done(items, items.length);
7183    });
7184  }
7185  function fetchPostCategories(done) {
7186    var url = options.url || window.luxuryPresence.defaults.apiGatewayUrl;
7187    var featured = options.resource === 'posts' && !!variables.featured;
7188    var gqlQuery = 'query ($companyId: String, $offset: Int, $limit: Int) {' + 'postCategories (companyId: $companyId, offset: $offset, limit: $limit ' + (featured ? ' withFeaturedPublishedOnly: true' : ' withPublishedOnly: true') + ') {id, name, publishedCount, featuredPublishedCount}}';
7189    var payload = {};
7190    payload.offset = 0;
7191    payload.limit = 100;
7192    payload.companyId = variables.companyId;
7193    superagent.post(url + '/graphql').withCredentials().send({
7194      query: gqlQuery,
7195      variables: payload
7196    }).then(function (res) {
7197      var items = res.body.data && res.body.data.postCategories || [];
7198      done(items.map(function (item) {
7199        item.count = featured ? item.featuredPublishedCount : item.publishedCount;
7200        return item;
7201      }), items.length);
7202    });
7203  }
7204  function fetchOffices(done) {
7205    var url = options.url || window.luxuryPresence.defaults.apiGatewayUrl;
7206    var gqlQuery = 'query ($companyId: String, $offset: Int, $limit: Int) {' + 'offices (companyId: $companyId, offset: $offset, limit: $limit) {' + 'id, name, tags}}';
7207    var payload = {
7208      offset: 0,
7209      limit: 100,
7210      companyId: variables.companyId
7211    };
7212    superagent.post(url + '/graphql').withCredentials().send({
7213      query: gqlQuery,
7214      variables: payload
7215    }).then(function (res) {
7216      var items = res.body.data && res.body.data.offices || [];
7217      done(items, items.length);
7218    });
7219  }
7220  function fetchAllRentalRates(done) {
7221    var url = options.url || window.luxuryPresence.defaults.apiGatewayUrl;
7222    var gqlQuery = 'query ($companyId: String, $offset: Int, $limit: Int) {' + 'rentalRates (companyId: $companyId, offset: $offset, limit: $limit) {rentalRateId, label}}';
7223    var payload = {
7224      offset: 0,
7225      limit: 100,
7226      companyId: variables.companyId
7227    };
7228    superagent.post(url + '/graphql').withCredentials().send({
7229      query: gqlQuery,
7230      variables: payload
7231    }).then(function (res) {
7232      var items = res.body.data && res.body.data.rentalRates || [];
7233      done(items, items.length);
7234    }).catch(function (err) {
7235      console.error('Error fetching rental rates:', err);
7236      done([], 0);
7237    });
7238  }
7239  function fetchData(params, done) {
7240    var url = options.url || window.luxuryPresence.defaults.apiGatewayUrl;
7241    var resource = options.resource;
7242    var gqlQuery = options.query || window.luxuryPresence.defaults.gql[resource];
7243    var payload = {};
7244    try {
7245      payload = JSON.parse(JSON.stringify(variables));
7246    } catch (e) {
7247      Object.keys(variables).forEach(function (variableName) {
7248        payload[variableName] = variables[variableName];
7249      });
7250    }
7251    payload.offset = (params.page - 1) * pageSize + offset;
7252    payload.limit = pageSize;
7253    payload.companyId = options.companyId;
7254    searchFormParams.forEach(function (formParam) {
7255      var val = params[formParam.formKey || formParam.param];
7256      if (val !== null && val !== undefined) {
7257        objSet(payload, formParam.param, val);
7258      }
7259    });
7260
7261    // TODO: Disabled loading due to jarring effect
7262    // dataContainer.html('Loading...');
7263    superagent.post(url + '/graphql').withCredentials().send({
7264      query: gqlQuery,
7265      variables: payload
7266    }).then(function (res) {
7267      if (res.body.errors) {
7268        done(res.body.errors);
7269        return;
7270      }
7271      var data = res.body.data || {};
7272      var resources = data[resource] || [];
7273      var resourceCount = data[resource + 'Count'] && data[resource + 'Count'].count ? data[resource + 'Count'].count : 0;
7274      if (resource === 'properties' && propertyPlaceholderImage?.id) {
7275        resources = resources.map(resource => {
7276          if (resource.media?.length === 0) {
7277            return Object.assign(resource, {
7278              media: [propertyPlaceholderImage]
7279            });
7280          }
7281          return resource;
7282        });
7283      }
7284      done(null, resources, resourceCount);
7285    });
7286  }
7287  function getTotalPage() {
7288    return Math.ceil(totalNumber / pageSize);
7289  }
7290  function renderPaginationList() {
7291    var totalPages = getTotalPage();
7292    var rangeStart = searchParams.page - pageRange;
7293    var rangeEnd = searchParams.page + pageRange;
7294    if (rangeEnd > totalPages) {
7295      rangeEnd = totalPages;
7296      rangeStart = totalPages - pageRange * 2;
7297      rangeStart = rangeStart < 1 ? 1 : rangeStart;
7298    }
7299    if (rangeStart <= 1) {
7300      rangeStart = 1;
7301      rangeEnd = Math.min(pageRange * 2 + 1, totalPages);
7302    }
7303
7304    // Making sure that 1 more page button is shown in edge positions
7305    if (pageRange === 0) {
7306      if (searchParams.page === totalPages) {
7307        rangeStart = totalPages <= 1 ? 1 : totalPages - 1;
7308      }
7309      if (searchParams.page === 1) {
7310        rangeEnd = Math.min(2, totalPages);
7311      }
7312    }
7313
7314    // Render pagination list
7315    if (mode === 'NUMBERED_PAGINATION') {
7316      el.innerHTML = generateHTML({
7317        currentPage: searchParams.page,
7318        pageRange: pageRange,
7319        rangeStart: rangeStart,
7320        rangeEnd: rangeEnd
7321      });
7322      if (totalPages < 2 && hidePaginationOnFirstPage) {
7323        container.style.display = 'none';
7324      } else {
7325        container.style.display = '';
7326      }
7327    } else if (mode === 'LOAD_MORE_BUTTON') {
7328      if (searchParams.page >= totalPages) {
7329        loadMoreButton.style.display = 'none';
7330      } else {
7331        loadMoreButton.style.display = '';
7332      }
7333    }
7334  }
7335  function render(data) {
7336    renderPaginationList();
7337
7338    // Render new content with handlebars
7339    var html = '';
7340    if (mode === 'LOAD_MORE_BUTTON' && searchParams.page > 1) {
7341      // If using load more, append search results to existing results
7342      html = dataContainer.innerHTML;
7343    }
7344    for (var i = 0; i < data.length; i++) {
7345      var itemData = recursivelyParse(data[i]);
7346      itemData.sectionIndex = options.sectionIndex;
7347      itemData.renderOptions = options.renderOptions;
7348      html += template(itemData);
7349    }
7350    dataContainer.innerHTML = html;
7351
7352    // Scroll Top
7353    if (!firstRender && mode === 'NUMBERED_PAGINATION' && (!renderBySearch || !options.skipScrollOnSearch)) {
7354      // Only animate to the top if we replace dataContainer (numbered pagination)
7355      setTimeout(() => {
7356        const scrollTargetOffsetTop = scrollTarget.getBoundingClientRect().top + window.scrollY - scrollOffset;
7357        window.scrollTo({
7358          top: scrollTargetOffsetTop,
7359          behavior: 'smooth'
7360        });
7361      }, 250);
7362    }
7363    return true;
7364  }
7365  function generateHTML(args) {
7366    const totalPages = getTotalPage();
7367    const {
7368      rangeStart,
7369      rangeEnd
7370    } = args;
7371    const makeLnk = page =>
7371 window.luxuryPresence.pagination.serializeParams(searchFormParams, sectionDomId, {
7372      ...searchParams,
7373      page
7374    });
7375    let html = '';
7376    if (showPrevious || showPageNumbers || showNext) {
7377      html += '<div class="paginationjs-pages"><ul>';
7378
7379      // Previous button
7380      if (showPrevious) {
7381        if (searchParams.page <= 1) {
7382          html += `<li class="${classPrefix}-prev ${disableClassName}"><a>${prevText}</a></li>`;
7383        } else {
7384          html += `<li class="${classPrefix}-prev J-paginationjs-previous" data-num="${searchParams.page - 1}" title="Previous page"><a href="${makeLnk(searchParams.page - 1)}">${prevText}</a></li>`;
7385        }
7386      }
7387
7388      // Pages
7389      if (showPageNumbers) {
7390        if (rangeStart <= 3) {
7391          for (let i = 1; i < rangeStart; i++) {
7392            html += `<li class="${classPrefix}-page J-paginationjs-page ${i === searchParams.page ? activeClassName : ''}" data-num="${i}"><a ${i === searchParams.page ? '' : `href="${makeLnk(i)}"`}>${i}</a></li>`;
7393          }
7394        } else {
7395          if (showFirstOnEllipsisShow) {
7396            html += `<li class="${classPrefix}-page ${classPrefix}-first J-paginationjs-page" data-num="1"><a href="${makeLnk(1)}">1</a></li>`;
7397          }
7398          html += `<li class="${classPrefix}-ellipsis ${disableClassName}"><a>${ellipsisText}</a></li>`;
7399        }
7400        for (let i = rangeStart; i <= rangeEnd; i++) {
7401          html += `<li class="${classPrefix}-page J-paginationjs-page ${i === searchParams.page ? activeClassName : ''}" data-num="${i}"><a ${i === searchParams.page ? '' : `href="${makeLnk(i)}"`}>${i}</a></li>`;
7402        }
7403        if (rangeEnd < totalPages - 2) {
7404          html += `<li class="${classPrefix}-ellipsis ${disableClassName}"><a>${ellipsisText}</a></li>`;
7405          if (showLastOnEllipsisShow) {
7406            html += `<li class="${classPrefix}-page ${classPrefix}-last J-paginationjs-page" data-num="${totalPages}"><a href="${makeLnk(totalPages)}">${totalPages}</a></li>`;
7407          }
7408        } else {
7409          for (let i = rangeEnd + 1; i <= totalPages; i++) {
7410            html += `<li class="${classPrefix}-page J-paginationjs-page" data-num="${i}"><a href="${makeLnk(i)}">${i}</a></li>`;
7411          }
7412        }
7413      }
7414
7415      // Next button
7416      if (showNext) {
7417        if (searchParams.page >= totalPages) {
7418          html += `<li class="${classPrefix}-next ${disableClassName}"><a>${nextText}</a></li>`;
7419        } else {
7420          html += `<li class="${classPrefix}-next J-paginationjs-next" data-num="${searchParams.page + 1}" title="Next page"><a href="${makeLnk(searchParams.page + 1)}">${nextText}</a></li>`;
7421        }
7422      }
7423      html += '</ul></div>';
7424    }
7425    return html;
7426  }
7427  function go(newSearchParams, callback, restorationVisit) {
7428    if (disabled) return;
7429    var goToPageNumber = newSearchParams.page;
7430
7431    // Page number is out of bounds
7432    if (!goToPageNumber || goToPageNumber < 1) return;
7433    var totalPage = getTotalPage();
7434
7435    // Page number is out of bounds
7436    if (!restorationVisit && totalNumber > 0) {
7437      if (goToPageNumber > totalPage) return;
7438    }
7439    if (!options.skipSerialization && (mode === 'NUMBERED_PAGINATION' || searchContainer)) {
7440      var newURL = window.luxuryPresence.pagination.serializeParams(searchFormParams, sectionDomId, {
7441        ...newSearchParams,
7442        page: goToPageNumber !== 1 && mode === 'NUMBERED_PAGINATION' ? newSearchParams.page : null
7443      });
7444      if (!areQueryParamsEqual(newSearchParams, searchParams) && !restorationVisit) {
7445        window.history.pushState({}, '', window.luxuryPresence.getPath(newURL, {
7446          queryString: true
7447        }));
7448      }
7449    }
7450
7451    // Fetch and update page
7452    fetchData(newSearchParams, renderWithData);
7453    disabled = true;
7454    function renderWithData(err, data, count) {
7455      if (err) {
7456        dataContainer.dispatchEvent(new Event('error'));
7457      } else {
7458        searchParams = {
7459          ...newSearchParams
7460        };
7461        totalNumber = count - offset;
7462        if (data.length === 0) {
7463          dataContainer.dispatchEvent(new Event('no-data'));
7464        } else {
7465          dataContainer.dispatchEvent(new Event('data'));
7466        }
7467        render(data);
7468        firstRender = false;
7469      }
7470      disabled = false;
7471      renderBySearch = false;
7472    }
7473  }
7474  function areQueryParamsEqual(first, second) {
7475    var differ = Object.keys(first).find(function (key) {
7476      return first[key] !== undefined && first[key] !== null && first[key] !== second[key];
7477    });
7478    if (differ) {
7479      return false;
7480    }
7481    differ = Object.keys(second).find(function (key) {
7482      return second[key] !== undefined && second[key] !== null && second[key] !== first[key];
7483    });
7484    return !differ;
7485  }
7486  function next(callback) {
7487    go({
7488      ...searchParams,
7489      page: searchParams.page + 1
7490    }, callback);
7491  }
7492  function previous(callback) {
7493    go({
7494      ...searchParams,
7495      page: searchParams.page - 1
7496    }, callback);
7497  }
7498  function refresh(callback) {
7499    go(searchParams, callback);
7500  }
7501  function update(params, callback) {
7502    renderBySearch = true;
7503    go(params, callback);
7504  }
7505  function observer() {
7506    if (searchContainer) {
7507      searchContainer.addEventListener('search', function (event, newSearchParams) {
7508        newSearchParams = event.detail || newSearchParams;
7509        update({
7510          ...searchParams,
7511          ...newSearchParams,
7512          page: 1
7513        });
7514      });
7515      searchContainer.addEventListener('clear-search', function () {
7516        const defaultSearchParams = {
7517          ...DefaultSearchParams
7518        };
7519        const isCurrentSearchFormStateDefault = areQueryParamsEqual({
7520          ...defaultSearchParams,
7521          page: null
7522        }, {
7523          ...searchParams,
7524          page: null
7525        });
7526
7527        // if mode is LOAD_MORE_BUTTON we should't make anything on clear
7528        // when search form have default state
7529        if (isCurrentSearchFormStateDefault && mode !== 'NUMBERED_PAGINATION') {
7530          return;
7531        }
7532
7533        // if someone initially go to some page and click 'Clear' on search from
7534        // we should't navigate to first page. We should preserve page value
7535        if (isCurrentSearchFormStateDefault) {
7536          defaultSearchParams.page = searchParams.page;
7537        }
7538        syncSearchFormState(defaultSearchParams);
7539        update(defaultSearchParams);
7540      });
7541    }
7542    if (mode === 'LOAD_MORE_BUTTON') {
7543      loadMoreButton.addEventListener('click', function (event) {
7544        go({
7545          ...searchParams,
7546          page: searchParams.page + 1
7547        });
7548        return false;
7549      });
7550    }
7551    if (mode === 'LOAD_MORE_BUTTON' || mode === 'BUTTONLESS_PAGINATION') {
7552      // Do initial render
7553      go(Object.assign({}, searchParams, {
7554        page: 1
7555      }));
7556      return;
7557    }
7558    if (mode === 'NUMBERED_PAGINATION') {
7559      // Go to specified page number
7560      container.addEventListener(eventPrefix + 'go', function (event) {
7561        let {
7562          pageNumber,
7563          done
7564        } = event.detail || {};
7565        pageNumber = parseInt(pageNumber, 10);
7566        if (!pageNumber) {
7567          return;
7568        }
7569        go({
7570          ...searchParams,
7571          page: pageNumber
7572        }, done);
7573      });
7574
7575      // Page number button click
7576      el.addEventListener('click', function (event) {
7577        let clickTarget = event.target;
7578        let current = clickTarget.closest('.J-paginationjs-page, .J-paginationjs-previous, .J-paginationjs-next');
7579        let pageNumber = current?.getAttribute('data-num');
7580        if (!pageNumber || current.classList.contains(disableClassName) || current.classList.contains(activeClassName)) {
7581          return;
7582        } else {
7583          go({
7584            ...searchParams,
7585            page: parseInt(pageNumber, 10)
7586          });
7587        }
7588        event.preventDefault();
7589      });
7590
7591      // Whether to load the default page
7592      var defaultPageNumber = searchParams.page;
7593      if (triggerPagingOnInit) {
7594        container.dispatchEvent(new CustomEvent(eventPrefix + 'go', {
7595          detail: {
7596            pageNumber: defaultPageNumber
7597          }
7598        }));
7599      }
7600    }
7601    window.addEventListener('popstate', function (event) {
7602      var newParams = Object.assign({}, DefaultSearchParams, window.luxuryPresence.pagination.deserializeParams(searchFormParams, sectionDomId));
7603      if (!areQueryParamsEqual(newParams, searchParams)) {
7604        go(newParams, null, true);
7605        if (searchContainer) {
7606          syncSearchFormState(newParams);
7607        }
7608      }
7609    });
7610  }
7611  function replaceVariables(template, variables) {
7612    var formattedString;
7613    for (var key in variables) {
7614      var value = variables[key];
7615      var regexp = new RegExp('<%=\\s*' + key + '\\s*%>', 'img');
7616      formattedString = (formattedString || template).replace(regexp, value);
7617    }
7618    return formattedString;
7619  }
7620  function isTextEditorValue(obj) {
7621    return 'raw' in obj || 'gjs' in obj;
7622  }
7623  function getTextEditorValue(obj) {
7624    if (!obj.html) {
7625      return '';
7626    }
7627    var data = obj.html;
7628    var css = (obj.raw || obj.gjs || {}).css;
7629    if (css) {
7630      data = data + '<style>' + css + '</style>';
7631    }
7632    return data;
7633  }
7634
7635  /**
7636   * check rendered resources for html and raw properties that could indicate if resource is from an advanced text editor.
7637   * strips out raw proprties and returns only HTML if it exists.
7638   * @param {Object} resources a collection retrieved from the database
7639   * @return {Object} the newly modified object.
7640   */
7641  function recursivelyParse(resources) {
7642    forEach(resources, function (value, key) {
7643      if (!value) {
7644        return;
7645      }
7646      if (value instanceof Object) {
7647        if (isTextEditorValue(value)) {
7648          resources[key] = getTextEditorValue(value);
7649          return;
7650        } else {
7651          return recursivelyParse(value);
7652        }
7653      }
7654      try {
7655        var parsedData = JSON.parse(value);
7656        if (isTextEditorValue(parsedData)) {
7657          resources[key] = getTextEditorValue(parsedData);
7658        }
7659      } catch (e) {
7660        // do nothing if we failed to parse value as JSON
7661      }
7662    });
7663    return resources;
7664  }
7665  function forEach(collection, iteratee) {
7666    var func = Array.isArray(collection) ? arrayEach : baseFor;
7667    return func(collection, iteratee);
7668  }
7669  function baseFor(object, iteratee) {
7670    if (!object) {
7671      return;
7672    }
7673    var iterable = Object(object);
7674    var props = Object.keys(object);
7675    var length = props.length;
7676    var index = -1;
7677    while (length--) {
7678      var key = props[++index];
7679      if (iteratee(iterable[key], key, iterable) === false) {
7680        break;
7681      }
7682    }
7683    return object;
7684  }
7685  function objSet(obj, path, value) {
7686    const pathArray = Array.isArray(path) ? path : path.match(/([^[.\]])+/g);
7687    pathArray.reduce((acc, key, i) => {
7688      if (acc[key] === undefined) acc[key] = {};
7689      if (i === pathArray.length - 1) acc[key] = value;
7690      return acc[key];
7691    }, obj);
7692  }
7693  function arrayEach(array, iteratee) {
7694    var index = -1;
7695    var length = array.length;
7696    while (++index < length) {
7697      if (iteratee(array[index], index, array) === false) {
7698        break;
7699      }
7700    }
7701    return array;
7702  }
7703  function selectPageRangeMode(e) {
7704    pageRange = e.matches ? mobilePageRange : desktopPageRange;
7705    renderPaginationList();
7706  }
7707  paginationMql.addEventListener('change', selectPageRangeMode);
7708})('section-3087e602-065d-462f-8f31-f4819d6fc3cd', JSON.parse("{\"pageSize\":\"9\",\"resource\":\"posts\",\"pageRange\":1,\"variables\":{\"limit\":9,\"offset\":0,\"sortDir\":\"DESC\",\"companyId\":\"2c02232f-2988-4a2c-a284-887b44b8c4fc\",\"categoryId\":\"{{pageElement.categoryId}}\",\"order\":\"publishedAt\"},\"hidePaginationOnFirstPage\":true,\"companyId\":\"2c02232f-2988-4a2c-a284-887b44b8c4fc\",\"usePageResource\":false,\"sectionIndex\":2}"));
7709} catch(e) {
7710console.log(e);
7711}
7712                try {
7713(function init(sectionDomId) {})('section-3087e602-065d-462f-8f31-f4819d6fc3cd', 'undefined');
7714} catch(e) {
7715console.log(e);
7716}
7717                try {
7718(function init(sectionDomId, options) {
7719  let section = null;
7720  switch (sectionDomId) {
7721    case 'NAVBAR':
7722      section = document.querySelector('body > nav, #global-navbar');
7723      break;
7724    case 'FOOTER':
7725      section = document.querySelector('body > footer, #global-footer');
7726      break;
7727    case 'SIDEMENU':
7728      section = document.querySelector('body > div.sidemenu, #global-sidemenu');
7729      break;
7730    case 'CONTACT':
7731      section = document.querySelector('#modal-global-contact-us');
7732      break;
7733    case 'MOBILE_CONTACT':
7734      section = document.querySelector('body > div.mobile-contact-wrapper, #global-mobile-contact');
7735      break;
7736    case 'SUBSCRIBE':
7737      // Subscribe Not Implemented
7738      section = null;
7739      break;
7740    case 'ACCOUNT':
7741      // Account Not Implemented
7742      section = null;
7743      break;
7744    default:
7745      section = document.querySelector('#' + sectionDomId);
7746  }
7747  if (!section) {
7748    return;
7749  }
7750
7751  // Where content / items are rendered
7752  const dataContainer = section.querySelector('.data-container');
7753  if (!dataContainer) {
7754    // no place to render items = no need to query server or do anything else
7755    return;
7756  }
7757  let variables = options.variables || {};
7758
7759  // Some variables in options may not have been injected - remove
7760  Object.keys(variables).forEach(function (variableName) {
7761    if (typeof variables[variableName] === 'string' && variables[variableName].match(/^{{.*}}$/)) {
7762      delete variables[variableName];
7763    }
7764  });
7765
7766  // Merge page query variables
7767  if (options.usePageResource) {
7768    variables = {
7769      ...variables,
7770      ...window.luxuryPresence.config.pageMeta.pageQueryVariables[options.resource]
7771    };
7772  }
7773
7774  // Pagination Executes on a Numbered Pagination Container
7775  //  Or via a load more button
7776  let mode = 'BUTTONLESS_PAGINATION';
7777  const container = section.querySelector('.pagination-container');
7778  const loadMoreButton = section.querySelector(options?.loadMoreSelector);
7779  if (container) {
7780    mode = 'NUMBERED_PAGINATION';
7781  }
7782  if (loadMoreButton) {
7783    mode = 'LOAD_MORE_BUTTON';
7784  }
7785  let searchContainer = section.querySelector('.search-container');
7786  const hidePaginationOnFirstPage = options.hidePaginationOnFirstPage || false;
7787  const eventPrefix = '__pagination-';
7788  const searchFormParams = options.searchFormParams || (options.resource === 'properties' ? [{
7789    param: 'neighborhoodId',
7790    urlKey: 'neighborhood'
7791  }, {
7792    param: 'search',
7793    urlKey: 'search'
7794  }, {
7795    param: 'salesPriceGTE',
7796    urlKey: 'pricemin',
7797    formKey: 'priceMin',
7798    type: 'int'
7799  }, {
7800    param: 'salesPriceLTE',
7801    urlKey: 'pricemax',
7802    formKey: 'priceMax',
7803    type: 'int'
7804  }, {
7805    param: 'livingSpaceSizeGTE',
7806    urlKey: 'areamin',
7807    formKey: 'areaMin',
7808    type: 'int'
7809  }, {
7810    param: 'livingSpaceSizeLTE',
7811    urlKey: 'areamax',
7812    formKey: 'areaMax',
7813    type: 'int'
7814  }] : []);
7815
7816  // Total entries - initialized in first render
7817  let totalNumber = 0;
7818  const DefaultSearchParams = {
7819    page: 1
7820  };
7821  searchFormParams.forEach(function (formParam) {
7822    DefaultSearchParams[formParam.formKey || formParam.param] = null;
7823  });
7824  let searchParams = {
7825    ...DefaultSearchParams
7826  };
7827  const offset = options.variables?.offset || 0;
7828  let scrollTarget = options.scrollTargetSelector ? section.querySelector(options.scrollTargetSelector) || section : section;
7829  let scrollOffset = (parseInt(options.scrollOffset, 10) || 0) ?? 100;
7830
7831  // entries of per page
7832  // when query variables for a given section would't be filled options.pageSize can store
7833  // template string, ex: "{{variables.limit}}", below code handles that case and set 9 as a default value
7834  let pageSize = parseInt(options.pageSize, 10) || 9;
7835
7836  // Adding mobile pageRange support
7837  var NARROW_BREAKPOINT = 600;
7838  var mobileBreakpoint = options.mobileBreakpoint > 0 ? options.mobileBreakpoint : NARROW_BREAKPOINT;
7839  var paginationMql = window.matchMedia(`(max-width: ${mobileBreakpoint}px)`);
7840
7841  // Page range (pages on both sides of the current page)
7842  var mobilePageRange = options.mobilePageRange > 0 ? options.mobilePageRange : 0;
7843  var desktopPageRange = options.pageRange >= 0 ? options.pageRange : 2;
7844  var pageRange = paginationMql.matches ? mobilePageRange : desktopPageRange;
7845
7846  // Whether to display the 'Previous' button
7847  var showPrevious = true;
7848
7849  // Whether to display the 'Next' button
7850  var showNext = true;
7851
7852  // Whether to display the page buttons
7853  var showPageNumbers = true;
7854
7855  // 'Previous' text
7856  var prevText = options.prevText || '&laquo;';
7857
7858  // 'Next' text
7859  var nextText = options.nextText || '&raquo;';
7860
7861  // Ellipsis text
7862  var ellipsisText = '&hellip;';
7863  var classPrefix = 'paginationjs';
7864
7865  // Default active class
7866  var activeClassName = 'active';
7867
7868  // Default disable class
7869  var disableClassName = 'disabled';
7870
7871  // Pagination element's position in the container
7872  var position = 'bottom';
7873
7874  // Whether to trigger pagination at initialization
7875  var triggerPagingOnInit = !options.skipInitialLoad;
7876  var showFirstOnEllipsisShow = true;
7877  var showLastOnEllipsisShow = true;
7878
7879  // Instantiated in init()
7880  var el = null;
7881
7882  // Controls scrollTop logic
7883  var firstRender = true;
7884  var renderBySearch = false;
7885  var disabled = false;
7886
7887  // Pagination script class selector
7888  var paginationScriptSelector = options.paginationPartialName ? `.${options.paginationPartialName}` : '.pagination-script';
7889
7890  // Property Specific Image Override if No Image
7891  var propertyPlaceholderImage = window.luxuryPresence.defaults.propertyPlaceholderImage;
7892
7893  // Construct template
7894  var templateHTML = section.querySelector(`script${paginationScriptSelector}`)?.innerHTML || '';
7895  var template = Handlebars.compile(templateHTML);
7896
7897  // Initialize
7898  init();
7899  function init() {
7900    Object.assign(searchParams, window.luxuryPresence.pagination.deserializeParams(searchFormParams, sectionDomId));
7901
7902    // Append/prepend pagination element to the pagination container
7903    if (mode === 'NUMBERED_PAGINATION') {
7904      el = document.createElement('div');
7905      el.className = 'paginationjs';
7906      container[position === 'bottom' ? 'append' : 'prepend'](el);
7907    }
7908    if (searchContainer) {
7909      initSearchContainer({
7910        fetchNeighborhoods: searchContainer.dataset.fetchNeighborhoods === 'true',
7911        fetchPostCategories: searchContainer.dataset.fetchPostCategories === 'true',
7912        fetchOffices: searchContainer.dataset.fetchOffices === 'true',
7913        fetchRentalRates: searchContainer.dataset.fetchRentalRates === 'true'
7914      }, function () {
7915        syncSearchFormState(searchParams);
7916      });
7917    }
7918
7919    // Bind events
7920    observer();
7921  }
7922  function syncSearchFormState(params) {
7923    searchContainer.dispatchEvent(new CustomEvent('sync', {
7924      detail: params
7925    }));
7926  }
7927  function initSearchContainer(options, done) {
7928    var promises = [];
7929    if (options.fetchNeighborhoods) {
7930      promises.push(fetchAllNeighborhoods(function (neighborhoods) {
7931        searchContainer.dispatchEvent(new CustomEvent('neighborhoods-data', {
7932          detail: {
7933            data: neighborhoods.map(function (item) {
7934              return {
7935                value: item.id,
7936                label: item.name
7937              };
7938            })
7939          }
7940        }));
7941      }));
7942    }
7943    if (options.fetchPostCategories) {
7944      promises.push(fetchPostCategories(function (categories) {
7945        searchContainer.dispatchEvent(new CustomEvent('post-categories-data', {
7946          detail: {
7947            data: categories
7948          }
7949        }));
7950      }));
7951    }
7952    if (options.fetchOffices) {
7953      promises.push(fetchOffices(function (offices) {
7954        searchContainer.dispatchEvent(new CustomEvent('offices-data', {
7955          detail: {
7956            data: offices
7957          }
7958        }));
7959      }));
7960    }
7961    if (options.fetchRentalRates) {
7962      promises.push(fetchAllRentalRates(function (rentalRates) {
7963        searchContainer.dispatchEvent(new CustomEvent('rental-rates-data', {
7964          detail: {
7965            data: rentalRates
7966          }
7967        }));
7968      }));
7969    }
7970    if (promises.length > 0) {
7971      Promise.all(promises).then(function () {
7972        done();
7973      });
7974    } else {
7975      // element's custom code is not executed yet, so we're scheduling callback to after element's code
7976      setTimeout(done);
7977    }
7978  }
7979  function fetchAllNeighborhoods(done) {
7980    var url = options.url || window.luxuryPresence.defaults.apiGatewayUrl;
7981    var gqlQuery = 'query ($companyId: String, $withProperties: NeighborhoodPropertiesFilter, $withBlogPosts: NeighborhoodBlogPostsFilter, $offset: Int, $limit: Int) {' + 'neighborhoods (companyId: $companyId, withProperties: $withProperties, withBlogPosts: $withBlogPosts, offset: $offset, limit: $limit) {id, name}}';
7982    var payload = {};
7983    payload.offset = 0;
7984    payload.limit = 100;
7985    payload.companyId = variables.companyId;
7986    if (options.resource === 'properties') {
7987      payload.withProperties = {
7988        active: true
7989      };
7990      ['agentIds', 'tag', 'propertyTypeId', 'statusIds', 'architectureStyle', 'lifestyle', 'salesPriceGTE', 'salesPriceLTE', 'leasePriceGTE', 'leasePriceLTE', 'livingSpaceSizeGTE', 'livingSpaceSizeLTE', 'bathCountGTE', 'bathCountLTE', 'bedroomCountGTE', 'bedroomCountLTE', 'bathCountGTE', 'bathCountLTE', 'bedroomCountGTE', 'bedroomCountLTE', 'featuredListing', 'leaseProperty', 'neighborhoodId', 'developmentId', 'openHouse'].forEach(function (field) {
7991        if (variables[field] !== undefined && variables[field] !== null) {
7992          payload.withProperties[field] = variables[field];
7993        }
7994      });
7995    }
7996    if (options.resource === 'posts') {
7997      payload.withBlogPosts = {
7998        active: true
7999      };
8000      ['search', 'postStatusId', 'featured', 'categoryId', 'categoryIds', 'neighborhoodId', 'slug'].forEach(function (field) {
8001        if (variables[field] !== undefined && variables[field] !== null) {
8002          payload.withBlogPosts[field] = variables[field];
8003        }
8004      });
8005    }
8006    superagent.post(url + '/graphql').withCredentials().send({
8007      query: gqlQuery,
8008      variables: payload
8009    }).then(function (res) {
8010      var items = res.body.data && res.body.data.neighborhoods || [];
8011      done(items, items.length);
8012    });
8013  }
8014  function fetchPostCategories(done) {
8015    var url = options.url || window.luxuryPresence.defaults.apiGatewayUrl;
8016    var featured = options.resource === 'posts' && !!variables.featured;
8017    var gqlQuery = 'query ($companyId: String, $offset: Int, $limit: Int) {' + 'postCategories (companyId: $companyId, offset: $offset, limit: $limit ' + (featured ? ' withFeaturedPublishedOnly: true' : ' withPublishedOnly: true') + ') {id, name, publishedCount, featuredPublishedCount}}';
8018    var payload = {};
8019    payload.offset = 0;
8020    payload.limit = 100;
8021    payload.companyId = variables.companyId;
8022    superagent.post(url + '/graphql').withCredentials().send({
8023      query: gqlQuery,
8024      variables: payload
8025    }).then(function (res) {
8026      var items = res.body.data && res.body.data.postCategories || [];
8027      done(items.map(function (item) {
8028        item.count = featured ? item.featuredPublishedCount : item.publishedCount;
8029        return item;
8030      }), items.length);
8031    });
8032  }
8033  function fetchOffices(done) {
8034    var url = options.url || window.luxuryPresence.defaults.apiGatewayUrl;
8035    var gqlQuery = 'query ($companyId: String, $offset: Int, $limit: Int) {' + 'offices (companyId: $companyId, offset: $offset, limit: $limit) {' + 'id, name, tags}}';
8036    var payload = {
8037      offset: 0,
8038      limit: 100,
8039      companyId: variables.companyId
8040    };
8041    superagent.post(url + '/graphql').withCredentials().send({
8042      query: gqlQuery,
8043      variables: payload
8044    }).then(function (res) {
8045      var items = res.body.data && res.body.data.offices || [];
8046      done(items, items.length);
8047    });
8048  }
8049  function fetchAllRentalRates(done) {
8050    var url = options.url || window.luxuryPresence.defaults.apiGatewayUrl;
8051    var gqlQuery = 'query ($companyId: String, $offset: Int, $limit: Int) {' + 'rentalRates (companyId: $companyId, offset: $offset, limit: $limit) {rentalRateId, label}}';
8052    var payload = {
8053      offset: 0,
8054      limit: 100,
8055      companyId: variables.companyId
8056    };
8057    superagent.post(url + '/graphql').withCredentials().send({
8058      query: gqlQuery,
8059      variables: payload
8060    }).then(function (res) {
8061      var items = res.body.data && res.body.data.rentalRates || [];
8062      done(items, items.length);
8063    }).catch(function (err) {
8064      console.error('Error fetching rental rates:', err);
8065      done([], 0);
8066    });
8067  }
8068  function fetchData(params, done) {
8069    var url = options.url || window.luxuryPresence.defaults.apiGatewayUrl;
8070    var resource = options.resource;
8071    var gqlQuery = options.query || window.luxuryPresence.defaults.gql[resource];
8072    var payload = {};
8073    try {
8074      payload = JSON.parse(JSON.stringify(variables));
8075    } catch (e) {
8076      Object.keys(variables).forEach(function (variableName) {
8077        payload[variableName] = variables[variableName];
8078      });
8079    }
8080    payload.offset = (params.page - 1) * pageSize + offset;
8081    payload.limit = pageSize;
8082    payload.companyId = options.companyId;
8083    searchFormParams.forEach(function (formParam) {
8084      var val = params[formParam.formKey || formParam.param];
8085      if (val !== null && val !== undefined) {
8086        objSet(payload, formParam.param, val);
8087      }
8088    });
8089
8090    // TODO: Disabled loading due to jarring effect
8091    // dataContainer.html('Loading...');
8092    superagent.post(url + '/graphql').withCredentials().send({
8093      query: gqlQuery,
8094      variables: payload
8095    }).then(function (res) {
8096      if (res.body.errors) {
8097        done(res.body.errors);
8098        return;
8099      }
8100      var data = res.body.data || {};
8101      var resources = data[resource] || [];
8102      var resourceCount = data[resource + 'Count'] && data[resource + 'Count'].count ? data[resource + 'Count'].count : 0;
8103      if (resource === 'properties' && propertyPlaceholderImage?.id) {
8104        resources = resources.map(resource => {
8105          if (resource.media?.length === 0) {
8106            return Object.assign(resource, {
8107              media: [propertyPlaceholderImage]
8108            });
8109          }
8110          return resource;
8111        });
8112      }
8113      done(null, resources, resourceCount);
8114    });
8115  }
8116  function getTotalPage() {
8117    return Math.ceil(totalNumber / pageSize);
8118  }
8119  function renderPaginationList() {
8120    var totalPages = getTotalPage();
8121    var rangeStart = searchParams.page - pageRange;
8122    var rangeEnd = searchParams.page + pageRange;
8123    if (rangeEnd > totalPages) {
8124      rangeEnd = totalPages;
8125      rangeStart = totalPages - pageRange * 2;
8126      rangeStart = rangeStart < 1 ? 1 : rangeStart;
8127    }
8128    if (rangeStart <= 1) {
8129      rangeStart = 1;
8130      rangeEnd = Math.min(pageRange * 2 + 1, totalPages);
8131    }
8132
8133    // Making sure that 1 more page button is shown in edge positions
8134    if (pageRange === 0) {
8135      if (searchParams.page === totalPages) {
8136        rangeStart = totalPages <= 1 ? 1 : totalPages - 1;
8137      }
8138      if (searchParams.page === 1) {
8139        rangeEnd = Math.min(2, totalPages);
8140      }
8141    }
8142
8143    // Render pagination list
8144    if (mode === 'NUMBERED_PAGINATION') {
8145      el.innerHTML = generateHTML({
8146        currentPage: searchParams.page,
8147        pageRange: pageRange,
8148        rangeStart: rangeStart,
8149        rangeEnd: rangeEnd
8150      });
8151      if (totalPages < 2 && hidePaginationOnFirstPage) {
8152        container.style.display = 'none';
8153      } else {
8154        container.style.display = '';
8155      }
8156    } else if (mode === 'LOAD_MORE_BUTTON') {
8157      if (searchParams.page >= totalPages) {
8158        loadMoreButton.style.display = 'none';
8159      } else {
8160        loadMoreButton.style.display = '';
8161      }
8162    }
8163  }
8164  function render(data) {
8165    renderPaginationList();
8166
8167    // Render new content with handlebars
8168    var html = '';
8169    if (mode === 'LOAD_MORE_BUTTON' && searchParams.page > 1) {
8170      // If using load more, append search results to existing results
8171      html = dataContainer.innerHTML;
8172    }
8173    for (var i = 0; i < data.length; i++) {
8174      var itemData = recursivelyParse(data[i]);
8175      itemData.sectionIndex = options.sectionIndex;
8176      itemData.renderOptions = options.renderOptions;
8177      html += template(itemData);
8178    }
8179    dataContainer.innerHTML = html;
8180
8181    // Scroll Top
8182    if (!firstRender && mode === 'NUMBERED_PAGINATION' && (!renderBySearch || !options.skipScrollOnSearch)) {
8183      // Only animate to the top if we replace dataContainer (numbered pagination)
8184      setTimeout(() => {
8185        const scrollTargetOffsetTop = scrollTarget.getBoundingClientRect().top + window.scrollY - scrollOffset;
8186        window.scrollTo({
8187          top: scrollTargetOffsetTop,
8188          behavior: 'smooth'
8189        });
8190      }, 250);
8191    }
8192    return true;
8193  }
8194  function generateHTML(args) {
8195    const totalPages = getTotalPage();
8196    const {
8197      rangeStart,
8198      rangeEnd
8199    } = args;
8200    const makeLnk = page =>
8200 window.luxuryPresence.pagination.serializeParams(searchFormParams, sectionDomId, {
8201      ...searchParams,
8202      page
8203    });
8204    let html = '';
8205    if (showPrevious || showPageNumbers || showNext) {
8206      html += '<div class="paginationjs-pages"><ul>';
8207
8208      // Previous button
8209      if (showPrevious) {
8210        if (searchParams.page <= 1) {
8211          html += `<li class="${classPrefix}-prev ${disableClassName}"><a>${prevText}</a></li>`;
8212        } else {
8213          html += `<li class="${classPrefix}-prev J-paginationjs-previous" data-num="${searchParams.page - 1}" title="Previous page"><a href="${makeLnk(searchParams.page - 1)}">${prevText}</a></li>`;
8214        }
8215      }
8216
8217      // Pages
8218      if (showPageNumbers) {
8219        if (rangeStart <= 3) {
8220          for (let i = 1; i < rangeStart; i++) {
8221            html += `<li class="${classPrefix}-page J-paginationjs-page ${i === searchParams.page ? activeClassName : ''}" data-num="${i}"><a ${i === searchParams.page ? '' : `href="${makeLnk(i)}"`}>${i}</a></li>`;
8222          }
8223        } else {
8224          if (showFirstOnEllipsisShow) {
8225            html += `<li class="${classPrefix}-page ${classPrefix}-first J-paginationjs-page" data-num="1"><a href="${makeLnk(1)}">1</a></li>`;
8226          }
8227          html += `<li class="${classPrefix}-ellipsis ${disableClassName}"><a>${ellipsisText}</a></li>`;
8228        }
8229        for (let i = rangeStart; i <= rangeEnd; i++) {
8230          html += `<li class="${classPrefix}-page J-paginationjs-page ${i === searchParams.page ? activeClassName : ''}" data-num="${i}"><a ${i === searchParams.page ? '' : `href="${makeLnk(i)}"`}>${i}</a></li>`;
8231        }
8232        if (rangeEnd < totalPages - 2) {
8233          html += `<li class="${classPrefix}-ellipsis ${disableClassName}"><a>${ellipsisText}</a></li>`;
8234          if (showLastOnEllipsisShow) {
8235            html += `<li class="${classPrefix}-page ${classPrefix}-last J-paginationjs-page" data-num="${totalPages}"><a href="${makeLnk(totalPages)}">${totalPages}</a></li>`;
8236          }
8237        } else {
8238          for (let i = rangeEnd + 1; i <= totalPages; i++) {
8239            html += `<li class="${classPrefix}-page J-paginationjs-page" data-num="${i}"><a href="${makeLnk(i)}">${i}</a></li>`;
8240          }
8241        }
8242      }
8243
8244      // Next button
8245      if (showNext) {
8246        if (searchParams.page >= totalPages) {
8247          html += `<li class="${classPrefix}-next ${disableClassName}"><a>${nextText}</a></li>`;
8248        } else {
8249          html += `<li class="${classPrefix}-next J-paginationjs-next" data-num="${searchParams.page + 1}" title="Next page"><a href="${makeLnk(searchParams.page + 1)}">${nextText}</a></li>`;
8250        }
8251      }
8252      html += '</ul></div>';
8253    }
8254    return html;
8255  }
8256  function go(newSearchParams, callback, restorationVisit) {
8257    if (disabled) return;
8258    var goToPageNumber = newSearchParams.page;
8259
8260    // Page number is out of bounds
8261    if (!goToPageNumber || goToPageNumber < 1) return;
8262    var totalPage = getTotalPage();
8263
8264    // Page number is out of bounds
8265    if (!restorationVisit && totalNumber > 0) {
8266      if (goToPageNumber > totalPage) return;
8267    }
8268    if (!options.skipSerialization && (mode === 'NUMBERED_PAGINATION' || searchContainer)) {
8269      var newURL = window.luxuryPresence.pagination.serializeParams(searchFormParams, sectionDomId, {
8270        ...newSearchParams,
8271        page: goToPageNumber !== 1 && mode === 'NUMBERED_PAGINATION' ? newSearchParams.page : null
8272      });
8273      if (!areQueryParamsEqual(newSearchParams, searchParams) && !restorationVisit) {
8274        window.history.pushState({}, '', window.luxuryPresence.getPath(newURL, {
8275          queryString: true
8276        }));
8277      }
8278    }
8279
8280    // Fetch and update page
8281    fetchData(newSearchParams, renderWithData);
8282    disabled = true;
8283    function renderWithData(err, data, count) {
8284      if (err) {
8285        dataContainer.dispatchEvent(new Event('error'));
8286      } else {
8287        searchParams = {
8288          ...newSearchParams
8289        };
8290        totalNumber = count - offset;
8291        if (data.length === 0) {
8292          dataContainer.dispatchEvent(new Event('no-data'));
8293        } else {
8294          dataContainer.dispatchEvent(new Event('data'));
8295        }
8296        render(data);
8297        firstRender = false;
8298      }
8299      disabled = false;
8300      renderBySearch = false;
8301    }
8302  }
8303  function areQueryParamsEqual(first, second) {
8304    var differ = Object.keys(first).find(function (key) {
8305      return first[key] !== undefined && first[key] !== null && first[key] !== second[key];
8306    });
8307    if (differ) {
8308      return false;
8309    }
8310    differ = Object.keys(second).find(function (key) {
8311      return second[key] !== undefined && second[key] !== null && second[key] !== first[key];
8312    });
8313    return !differ;
8314  }
8315  function next(callback) {
8316    go({
8317      ...searchParams,
8318      page: searchParams.page + 1
8319    }, callback);
8320  }
8321  function previous(callback) {
8322    go({
8323      ...searchParams,
8324      page: searchParams.page - 1
8325    }, callback);
8326  }
8327  function refresh(callback) {
8328    go(searchParams, callback);
8329  }
8330  function update(params, callback) {
8331    renderBySearch = true;
8332    go(params, callback);
8333  }
8334  function observer() {
8335    if (searchContainer) {
8336      searchContainer.addEventListener('search', function (event, newSearchParams) {
8337        newSearchParams = event.detail || newSearchParams;
8338        update({
8339          ...searchParams,
8340          ...newSearchParams,
8341          page: 1
8342        });
8343      });
8344      searchContainer.addEventListener('clear-search', function () {
8345        const defaultSearchParams = {
8346          ...DefaultSearchParams
8347        };
8348        const isCurrentSearchFormStateDefault = areQueryParamsEqual({
8349          ...defaultSearchParams,
8350          page: null
8351        }, {
8352          ...searchParams,
8353          page: null
8354        });
8355
8356        // if mode is LOAD_MORE_BUTTON we should't make anything on clear
8357        // when search form have default state
8358        if (isCurrentSearchFormStateDefault && mode !== 'NUMBERED_PAGINATION') {
8359          return;
8360        }
8361
8362        // if someone initially go to some page and click 'Clear' on search from
8363        // we should't navigate to first page. We should preserve page value
8364        if (isCurrentSearchFormStateDefault) {
8365          defaultSearchParams.page = searchParams.page;
8366        }
8367        syncSearchFormState(defaultSearchParams);
8368        update(defaultSearchParams);
8369      });
8370    }
8371    if (mode === 'LOAD_MORE_BUTTON') {
8372      loadMoreButton.addEventListener('click', function (event) {
8373        go({
8374          ...searchParams,
8375          page: searchParams.page + 1
8376        });
8377        return false;
8378      });
8379    }
8380    if (mode === 'LOAD_MORE_BUTTON' || mode === 'BUTTONLESS_PAGINATION') {
8381      // Do initial render
8382      go(Object.assign({}, searchParams, {
8383        page: 1
8384      }));
8385      return;
8386    }
8387    if (mode === 'NUMBERED_PAGINATION') {
8388      // Go to specified page number
8389      container.addEventListener(eventPrefix + 'go', function (event) {
8390        let {
8391          pageNumber,
8392          done
8393        } = event.detail || {};
8394        pageNumber = parseInt(pageNumber, 10);
8395        if (!pageNumber) {
8396          return;
8397        }
8398        go({
8399          ...searchParams,
8400          page: pageNumber
8401        }, done);
8402      });
8403
8404      // Page number button click
8405      el.addEventListener('click', function (event) {
8406        let clickTarget = event.target;
8407        let current = clickTarget.closest('.J-paginationjs-page, .J-paginationjs-previous, .J-paginationjs-next');
8408        let pageNumber = current?.getAttribute('data-num');
8409        if (!pageNumber || current.classList.contains(disableClassName) || current.classList.contains(activeClassName)) {
8410          return;
8411        } else {
8412          go({
8413            ...searchParams,
8414            page: parseInt(pageNumber, 10)
8415          });
8416        }
8417        event.preventDefault();
8418      });
8419
8420      // Whether to load the default page
8421      var defaultPageNumber = searchParams.page;
8422      if (triggerPagingOnInit) {
8423        container.dispatchEvent(new CustomEvent(eventPrefix + 'go', {
8424          detail: {
8425            pageNumber: defaultPageNumber
8426          }
8427        }));
8428      }
8429    }
8430    window.addEventListener('popstate', function (event) {
8431      var newParams = Object.assign({}, DefaultSearchParams, window.luxuryPresence.pagination.deserializeParams(searchFormParams, sectionDomId));
8432      if (!areQueryParamsEqual(newParams, searchParams)) {
8433        go(newParams, null, true);
8434        if (searchContainer) {
8435          syncSearchFormState(newParams);
8436        }
8437      }
8438    });
8439  }
8440  function replaceVariables(template, variables) {
8441    var formattedString;
8442    for (var key in variables) {
8443      var value = variables[key];
8444      var regexp = new RegExp('<%=\\s*' + key + '\\s*%>', 'img');
8445      formattedString = (formattedString || template).replace(regexp, value);
8446    }
8447    return formattedString;
8448  }
8449  function isTextEditorValue(obj) {
8450    return 'raw' in obj || 'gjs' in obj;
8451  }
8452  function getTextEditorValue(obj) {
8453    if (!obj.html) {
8454      return '';
8455    }
8456    var data = obj.html;
8457    var css = (obj.raw || obj.gjs || {}).css;
8458    if (css) {
8459      data = data + '<style>' + css + '</style>';
8460    }
8461    return data;
8462  }
8463
8464  /**
8465   * check rendered resources for html and raw properties that could indicate if resource is from an advanced text editor.
8466   * strips out raw proprties and returns only HTML if it exists.
8467   * @param {Object} resources a collection retrieved from the database
8468   * @return {Object} the newly modified object.
8469   */
8470  function recursivelyParse(resources) {
8471    forEach(resources, function (value, key) {
8472      if (!value) {
8473        return;
8474      }
8475      if (value instanceof Object) {
8476        if (isTextEditorValue(value)) {
8477          resources[key] = getTextEditorValue(value);
8478          return;
8479        } else {
8480          return recursivelyParse(value);
8481        }
8482      }
8483      try {
8484        var parsedData = JSON.parse(value);
8485        if (isTextEditorValue(parsedData)) {
8486          resources[key] = getTextEditorValue(parsedData);
8487        }
8488      } catch (e) {
8489        // do nothing if we failed to parse value as JSON
8490      }
8491    });
8492    return resources;
8493  }
8494  function forEach(collection, iteratee) {
8495    var func = Array.isArray(collection) ? arrayEach : baseFor;
8496    return func(collection, iteratee);
8497  }
8498  function baseFor(object, iteratee) {
8499    if (!object) {
8500      return;
8501    }
8502    var iterable = Object(object);
8503    var props = Object.keys(object);
8504    var length = props.length;
8505    var index = -1;
8506    while (length--) {
8507      var key = props[++index];
8508      if (iteratee(iterable[key], key, iterable) === false) {
8509        break;
8510      }
8511    }
8512    return object;
8513  }
8514  function objSet(obj, path, value) {
8515    const pathArray = Array.isArray(path) ? path : path.match(/([^[.\]])+/g);
8516    pathArray.reduce((acc, key, i) => {
8517      if (acc[key] === undefined) acc[key] = {};
8518      if (i === pathArray.length - 1) acc[key] = value;
8519      return acc[key];
8520    }, obj);
8521  }
8522  function arrayEach(array, iteratee) {
8523    var index = -1;
8524    var length = array.length;
8525    while (++index < length) {
8526      if (iteratee(array[index], index, array) === false) {
8527        break;
8528      }
8529    }
8530    return array;
8531  }
8532  function selectPageRangeMode(e) {
8533    pageRange = e.matches ? mobilePageRange : desktopPageRange;
8534    renderPaginationList();
8535  }
8536  paginationMql.addEventListener('change', selectPageRangeMode);
8537})('section-5d01005b-e93f-48f9-92b7-4822576c8b85', JSON.parse("{\"pageSize\":\"9\",\"resource\":\"posts\",\"pageRange\":1,\"variables\":{\"limit\":9,\"offset\":0,\"sortDir\":\"DESC\",\"companyId\":\"2c02232f-2988-4a2c-a284-887b44b8c4fc\",\"categoryId\":\"{{pageElement.categoryId}}\",\"order\":\"publishedAt\"},\"hidePaginationOnFirstPage\":true,\"companyId\":\"2c02232f-2988-4a2c-a284-887b44b8c4fc\",\"usePageResource\":false,\"sectionIndex\":3}"));
8538} catch(e) {
8539console.log(e);
8540}
8541                try {
8542(function init(sectionDomId) {})('section-5d01005b-e93f-48f9-92b7-4822576c8b85', 'undefined');
8543} catch(e) {
8544console.log(e);
8545}
8546                try {
8547(function init(sectionDomId, options) {
8548  let section = null;
8549  switch (sectionDomId) {
8550    case 'NAVBAR':
8551      section = document.querySelector('body > nav, #global-navbar');
8552      break;
8553    case 'FOOTER':
8554      section = document.querySelector('body > footer, #global-footer');
8555      break;
8556    case 'SIDEMENU':
8557      section = document.querySelector('body > div.sidemenu, #global-sidemenu');
8558      break;
8559    case 'CONTACT':
8560      section = document.querySelector('#modal-global-contact-us');
8561      break;
8562    case 'MOBILE_CONTACT':
8563      section = document.querySelector('body > div.mobile-contact-wrapper, #global-mobile-contact');
8564      break;
8565    case 'SUBSCRIBE':
8566      // Subscribe Not Implemented
8567      section = null;
8568      break;
8569    case 'ACCOUNT':
8570      // Account Not Implemented
8571      section = null;
8572      break;
8573    default:
8574      section = document.querySelector('#' + sectionDomId);
8575  }
8576  if (!section) {
8577    return;
8578  }
8579
8580  // Where content / items are rendered
8581  const dataContainer = section.querySelector('.data-container');
8582  if (!dataContainer) {
8583    // no place to render items = no need to query server or do anything else
8584    return;
8585  }
8586  let variables = options.variables || {};
8587
8588  // Some variables in options may not have been injected - remove
8589  Object.keys(variables).forEach(function (variableName) {
8590    if (typeof variables[variableName] === 'string' && variables[variableName].match(/^{{.*}}$/)) {
8591      delete variables[variableName];
8592    }
8593  });
8594
8595  // Merge page query variables
8596  if (options.usePageResource) {
8597    variables = {
8598      ...variables,
8599      ...window.luxuryPresence.config.pageMeta.pageQueryVariables[options.resource]
8600    };
8601  }
8602
8603  // Pagination Executes on a Numbered Pagination Container
8604  //  Or via a load more button
8605  let mode = 'BUTTONLESS_PAGINATION';
8606  const container = section.querySelector('.pagination-container');
8607  const loadMoreButton = section.querySelector(options?.loadMoreSelector);
8608  if (container) {
8609    mode = 'NUMBERED_PAGINATION';
8610  }
8611  if (loadMoreButton) {
8612    mode = 'LOAD_MORE_BUTTON';
8613  }
8614  let searchContainer = section.querySelector('.search-container');
8615  const hidePaginationOnFirstPage = options.hidePaginationOnFirstPage || false;
8616  const eventPrefix = '__pagination-';
8617  const searchFormParams = options.searchFormParams || (options.resource === 'properties' ? [{
8618    param: 'neighborhoodId',
8619    urlKey: 'neighborhood'
8620  }, {
8621    param: 'search',
8622    urlKey: 'search'
8623  }, {
8624    param: 'salesPriceGTE',
8625    urlKey: 'pricemin',
8626    formKey: 'priceMin',
8627    type: 'int'
8628  }, {
8629    param: 'salesPriceLTE',
8630    urlKey: 'pricemax',
8631    formKey: 'priceMax',
8632    type: 'int'
8633  }, {
8634    param: 'livingSpaceSizeGTE',
8635    urlKey: 'areamin',
8636    formKey: 'areaMin',
8637    type: 'int'
8638  }, {
8639    param: 'livingSpaceSizeLTE',
8640    urlKey: 'areamax',
8641    formKey: 'areaMax',
8642    type: 'int'
8643  }] : []);
8644
8645  // Total entries - initialized in first render
8646  let totalNumber = 0;
8647  const DefaultSearchParams = {
8648    page: 1
8649  };
8650  searchFormParams.forEach(function (formParam) {
8651    DefaultSearchParams[formParam.formKey || formParam.param] = null;
8652  });
8653  let searchParams = {
8654    ...DefaultSearchParams
8655  };
8656  const offset = options.variables?.offset || 0;
8657  let scrollTarget = options.scrollTargetSelector ? section.querySelector(options.scrollTargetSelector) || section : section;
8658  let scrollOffset = (parseInt(options.scrollOffset, 10) || 0) ?? 100;
8659
8660  // entries of per page
8661  // when query variables for a given section would't be filled options.pageSize can store
8662  // template string, ex: "{{variables.limit}}", below code handles that case and set 9 as a default value
8663  let pageSize = parseInt(options.pageSize, 10) || 9;
8664
8665  // Adding mobile pageRange support
8666  var NARROW_BREAKPOINT = 600;
8667  var mobileBreakpoint = options.mobileBreakpoint > 0 ? options.mobileBreakpoint : NARROW_BREAKPOINT;
8668  var paginationMql = window.matchMedia(`(max-width: ${mobileBreakpoint}px)`);
8669
8670  // Page range (pages on both sides of the current page)
8671  var mobilePageRange = options.mobilePageRange > 0 ? options.mobilePageRange : 0;
8672  var desktopPageRange = options.pageRange >= 0 ? options.pageRange : 2;
8673  var pageRange = paginationMql.matches ? mobilePageRange : desktopPageRange;
8674
8675  // Whether to display the 'Previous' button
8676  var showPrevious = true;
8677
8678  // Whether to display the 'Next' button
8679  var showNext = true;
8680
8681  // Whether to display the page buttons
8682  var showPageNumbers = true;
8683
8684  // 'Previous' text
8685  var prevText = options.prevText || '&laquo;';
8686
8687  // 'Next' text
8688  var nextText = options.nextText || '&raquo;';
8689
8690  // Ellipsis text
8691  var ellipsisText = '&hellip;';
8692  var classPrefix = 'paginationjs';
8693
8694  // Default active class
8695  var activeClassName = 'active';
8696
8697  // Default disable class
8698  var disableClassName = 'disabled';
8699
8700  // Pagination element's position in the container
8701  var position = 'bottom';
8702
8703  // Whether to trigger pagination at initialization
8704  var triggerPagingOnInit = !options.skipInitialLoad;
8705  var showFirstOnEllipsisShow = true;
8706  var showLastOnEllipsisShow = true;
8707
8708  // Instantiated in init()
8709  var el = null;
8710
8711  // Controls scrollTop logic
8712  var firstRender = true;
8713  var renderBySearch = false;
8714  var disabled = false;
8715
8716  // Pagination script class selector
8717  var paginationScriptSelector = options.paginationPartialName ? `.${options.paginationPartialName}` : '.pagination-script';
8718
8719  // Property Specific Image Override if No Image
8720  var propertyPlaceholderImage = window.luxuryPresence.defaults.propertyPlaceholderImage;
8721
8722  // Construct template
8723  var templateHTML = section.querySelector(`script${paginationScriptSelector}`)?.innerHTML || '';
8724  var template = Handlebars.compile(templateHTML);
8725
8726  // Initialize
8727  init();
8728  function init() {
8729    Object.assign(searchParams, window.luxuryPresence.pagination.deserializeParams(searchFormParams, sectionDomId));
8730
8731    // Append/prepend pagination element to the pagination container
8732    if (mode === 'NUMBERED_PAGINATION') {
8733      el = document.createElement('div');
8734      el.className = 'paginationjs';
8735      container[position === 'bottom' ? 'append' : 'prepend'](el);
8736    }
8737    if (searchContainer) {
8738      initSearchContainer({
8739        fetchNeighborhoods: searchContainer.dataset.fetchNeighborhoods === 'true',
8740        fetchPostCategories: searchContainer.dataset.fetchPostCategories === 'true',
8741        fetchOffices: searchContainer.dataset.fetchOffices === 'true',
8742        fetchRentalRates: searchContainer.dataset.fetchRentalRates === 'true'
8743      }, function () {
8744        syncSearchFormState(searchParams);
8745      });
8746    }
8747
8748    // Bind events
8749    observer();
8750  }
8751  function syncSearchFormState(params) {
8752    searchContainer.dispatchEvent(new CustomEvent('sync', {
8753      detail: params
8754    }));
8755  }
8756  function initSearchContainer(options, done) {
8757    var promises = [];
8758    if (options.fetchNeighborhoods) {
8759      promises.push(fetchAllNeighborhoods(function (neighborhoods) {
8760        searchContainer.dispatchEvent(new CustomEvent('neighborhoods-data', {
8761          detail: {
8762            data: neighborhoods.map(function (item) {
8763              return {
8764                value: item.id,
8765                label: item.name
8766              };
8767            })
8768          }
8769        }));
8770      }));
8771    }
8772    if (options.fetchPostCategories) {
8773      promises.push(fetchPostCategories(function (categories) {
8774        searchContainer.dispatchEvent(new CustomEvent('post-categories-data', {
8775          detail: {
8776            data: categories
8777          }
8778        }));
8779      }));
8780    }
8781    if (options.fetchOffices) {
8782      promises.push(fetchOffices(function (offices) {
8783        searchContainer.dispatchEvent(new CustomEvent('offices-data', {
8784          detail: {
8785            data: offices
8786          }
8787        }));
8788      }));
8789    }
8790    if (options.fetchRentalRates) {
8791      promises.push(fetchAllRentalRates(function (rentalRates) {
8792        searchContainer.dispatchEvent(new CustomEvent('rental-rates-data', {
8793          detail: {
8794            data: rentalRates
8795          }
8796        }));
8797      }));
8798    }
8799    if (promises.length > 0) {
8800      Promise.all(promises).then(function () {
8801        done();
8802      });
8803    } else {
8804      // element's custom code is not executed yet, so we're scheduling callback to after element's code
8805      setTimeout(done);
8806    }
8807  }
8808  function fetchAllNeighborhoods(done) {
8809    var url = options.url || window.luxuryPresence.defaults.apiGatewayUrl;
8810    var gqlQuery = 'query ($companyId: String, $withProperties: NeighborhoodPropertiesFilter, $withBlogPosts: NeighborhoodBlogPostsFilter, $offset: Int, $limit: Int) {' + 'neighborhoods (companyId: $companyId, withProperties: $withProperties, withBlogPosts: $withBlogPosts, offset: $offset, limit: $limit) {id, name}}';
8811    var payload = {};
8812    payload.offset = 0;
8813    payload.limit = 100;
8814    payload.companyId = variables.companyId;
8815    if (options.resource === 'properties') {
8816      payload.withProperties = {
8817        active: true
8818      };
8819      ['agentIds', 'tag', 'propertyTypeId', 'statusIds', 'architectureStyle', 'lifestyle', 'salesPriceGTE', 'salesPriceLTE', 'leasePriceGTE', 'leasePriceLTE', 'livingSpaceSizeGTE', 'livingSpaceSizeLTE', 'bathCountGTE', 'bathCountLTE', 'bedroomCountGTE', 'bedroomCountLTE', 'bathCountGTE', 'bathCountLTE', 'bedroomCountGTE', 'bedroomCountLTE', 'featuredListing', 'leaseProperty', 'neighborhoodId', 'developmentId', 'openHouse'].forEach(function (field) {
8820        if (variables[field] !== undefined && variables[field] !== null) {
8821          payload.withProperties[field] = variables[field];
8822        }
8823      });
8824    }
8825    if (options.resource === 'posts') {
8826      payload.withBlogPosts = {
8827        active: true
8828      };
8829      ['search', 'postStatusId', 'featured', 'categoryId', 'categoryIds', 'neighborhoodId', 'slug'].forEach(function (field) {
8830        if (variables[field] !== undefined && variables[field] !== null) {
8831          payload.withBlogPosts[field] = variables[field];
8832        }
8833      });
8834    }
8835    superagent.post(url + '/graphql').withCredentials().send({
8836      query: gqlQuery,
8837      variables: payload
8838    }).then(function (res) {
8839      var items = res.body.data && res.body.data.neighborhoods || [];
8840      done(items, items.length);
8841    });
8842  }
8843  function fetchPostCategories(done) {
8844    var url = options.url || window.luxuryPresence.defaults.apiGatewayUrl;
8845    var featured = options.resource === 'posts' && !!variables.featured;
8846    var gqlQuery = 'query ($companyId: String, $offset: Int, $limit: Int) {' + 'postCategories (companyId: $companyId, offset: $offset, limit: $limit ' + (featured ? ' withFeaturedPublishedOnly: true' : ' withPublishedOnly: true') + ') {id, name, publishedCount, featuredPublishedCount}}';
8847    var payload = {};
8848    payload.offset = 0;
8849    payload.limit = 100;
8850    payload.companyId = variables.companyId;
8851    superagent.post(url + '/graphql').withCredentials().send({
8852      query: gqlQuery,
8853      variables: payload
8854    }).then(function (res) {
8855      var items = res.body.data && res.body.data.postCategories || [];
8856      done(items.map(function (item) {
8857        item.count = featured ? item.featuredPublishedCount : item.publishedCount;
8858        return item;
8859      }), items.length);
8860    });
8861  }
8862  function fetchOffices(done) {
8863    var url = options.url || window.luxuryPresence.defaults.apiGatewayUrl;
8864    var gqlQuery = 'query ($companyId: String, $offset: Int, $limit: Int) {' + 'offices (companyId: $companyId, offset: $offset, limit: $limit) {' + 'id, name, tags}}';
8865    var payload = {
8866      offset: 0,
8867      limit: 100,
8868      companyId: variables.companyId
8869    };
8870    superagent.post(url + '/graphql').withCredentials().send({
8871      query: gqlQuery,
8872      variables: payload
8873    }).then(function (res) {
8874      var items = res.body.data && res.body.data.offices || [];
8875      done(items, items.length);
8876    });
8877  }
8878  function fetchAllRentalRates(done) {
8879    var url = options.url || window.luxuryPresence.defaults.apiGatewayUrl;
8880    var gqlQuery = 'query ($companyId: String, $offset: Int, $limit: Int) {' + 'rentalRates (companyId: $companyId, offset: $offset, limit: $limit) {rentalRateId, label}}';
8881    var payload = {
8882      offset: 0,
8883      limit: 100,
8884      companyId: variables.companyId
8885    };
8886    superagent.post(url + '/graphql').withCredentials().send({
8887      query: gqlQuery,
8888      variables: payload
8889    }).then(function (res) {
8890      var items = res.body.data && res.body.data.rentalRates || [];
8891      done(items, items.length);
8892    }).catch(function (err) {
8893      console.error('Error fetching rental rates:', err);
8894      done([], 0);
8895    });
8896  }
8897  function fetchData(params, done) {
8898    var url = options.url || window.luxuryPresence.defaults.apiGatewayUrl;
8899    var resource = options.resource;
8900    var gqlQuery = options.query || window.luxuryPresence.defaults.gql[resource];
8901    var payload = {};
8902    try {
8903      payload = JSON.parse(JSON.stringify(variables));
8904    } catch (e) {
8905      Object.keys(variables).forEach(function (variableName) {
8906        payload[variableName] = variables[variableName];
8907      });
8908    }
8909    payload.offset = (params.page - 1) * pageSize + offset;
8910    payload.limit = pageSize;
8911    payload.companyId = options.companyId;
8912    searchFormParams.forEach(function (formParam) {
8913      var val = params[formParam.formKey || formParam.param];
8914      if (val !== null && val !== undefined) {
8915        objSet(payload, formParam.param, val);
8916      }
8917    });
8918
8919    // TODO: Disabled loading due to jarring effect
8920    // dataContainer.html('Loading...');
8921    superagent.post(url + '/graphql').withCredentials().send({
8922      query: gqlQuery,
8923      variables: payload
8924    }).then(function (res) {
8925      if (res.body.errors) {
8926        done(res.body.errors);
8927        return;
8928      }
8929      var data = res.body.data || {};
8930      var resources = data[resource] || [];
8931      var resourceCount = data[resource + 'Count'] && data[resource + 'Count'].count ? data[resource + 'Count'].count : 0;
8932      if (resource === 'properties' && propertyPlaceholderImage?.id) {
8933        resources = resources.map(resource => {
8934          if (resource.media?.length === 0) {
8935            return Object.assign(resource, {
8936              media: [propertyPlaceholderImage]
8937            });
8938          }
8939          return resource;
8940        });
8941      }
8942      done(null, resources, resourceCount);
8943    });
8944  }
8945  function getTotalPage() {
8946    return Math.ceil(totalNumber / pageSize);
8947  }
8948  function renderPaginationList() {
8949    var totalPages = getTotalPage();
8950    var rangeStart = searchParams.page - pageRange;
8951    var rangeEnd = searchParams.page + pageRange;
8952    if (rangeEnd > totalPages) {
8953      rangeEnd = totalPages;
8954      rangeStart = totalPages - pageRange * 2;
8955      rangeStart = rangeStart < 1 ? 1 : rangeStart;
8956    }
8957    if (rangeStart <= 1) {
8958      rangeStart = 1;
8959      rangeEnd = Math.min(pageRange * 2 + 1, totalPages);
8960    }
8961
8962    // Making sure that 1 more page button is shown in edge positions
8963    if (pageRange === 0) {
8964      if (searchParams.page === totalPages) {
8965        rangeStart = totalPages <= 1 ? 1 : totalPages - 1;
8966      }
8967      if (searchParams.page === 1) {
8968        rangeEnd = Math.min(2, totalPages);
8969      }
8970    }
8971
8972    // Render pagination list
8973    if (mode === 'NUMBERED_PAGINATION') {
8974      el.innerHTML = generateHTML({
8975        currentPage: searchParams.page,
8976        pageRange: pageRange,
8977        rangeStart: rangeStart,
8978        rangeEnd: rangeEnd
8979      });
8980      if (totalPages < 2 && hidePaginationOnFirstPage) {
8981        container.style.display = 'none';
8982      } else {
8983        container.style.display = '';
8984      }
8985    } else if (mode === 'LOAD_MORE_BUTTON') {
8986      if (searchParams.page >= totalPages) {
8987        loadMoreButton.style.display = 'none';
8988      } else {
8989        loadMoreButton.style.display = '';
8990      }
8991    }
8992  }
8993  function render(data) {
8994    renderPaginationList();
8995
8996    // Render new content with handlebars
8997    var html = '';
8998    if (mode === 'LOAD_MORE_BUTTON' && searchParams.page > 1) {
8999      // If using load more, append search results to existing results
9000      html = dataContainer.innerHTML;
9001    }
9002    for (var i = 0; i < data.length; i++) {
9003      var itemData = recursivelyParse(data[i]);
9004      itemData.sectionIndex = options.sectionIndex;
9005      itemData.renderOptions = options.renderOptions;
9006      html += template(itemData);
9007    }
9008    dataContainer.innerHTML = html;
9009
9010    // Scroll Top
9011    if (!firstRender && mode === 'NUMBERED_PAGINATION' && (!renderBySearch || !options.skipScrollOnSearch)) {
9012      // Only animate to the top if we replace dataContainer (numbered pagination)
9013      setTimeout(() => {
9014        const scrollTargetOffsetTop = scrollTarget.getBoundingClientRect().top + window.scrollY - scrollOffset;
9015        window.scrollTo({
9016          top: scrollTargetOffsetTop,
9017          behavior: 'smooth'
9018        });
9019      }, 250);
9020    }
9021    return true;
9022  }
9023  function generateHTML(args) {
9024    const totalPages = getTotalPage();
9025    const {
9026      rangeStart,
9027      rangeEnd
9028    } = args;
9029    const makeLnk = page =>
9029 window.luxuryPresence.pagination.serializeParams(searchFormParams, sectionDomId, {
9030      ...searchParams,
9031      page
9032    });
9033    let html = '';
9034    if (showPrevious || showPageNumbers || showNext) {
9035      html += '<div class="paginationjs-pages"><ul>';
9036
9037      // Previous button
9038      if (showPrevious) {
9039        if (searchParams.page <= 1) {
9040          html += `<li class="${classPrefix}-prev ${disableClassName}"><a>${prevText}</a></li>`;
9041        } else {
9042          html += `<li class="${classPrefix}-prev J-paginationjs-previous" data-num="${searchParams.page - 1}" title="Previous page"><a href="${makeLnk(searchParams.page - 1)}">${prevText}</a></li>`;
9043        }
9044      }
9045
9046      // Pages
9047      if (showPageNumbers) {
9048        if (rangeStart <= 3) {
9049          for (let i = 1; i < rangeStart; i++) {
9050            html += `<li class="${classPrefix}-page J-paginationjs-page ${i === searchParams.page ? activeClassName : ''}" data-num="${i}"><a ${i === searchParams.page ? '' : `href="${makeLnk(i)}"`}>${i}</a></li>`;
9051          }
9052        } else {
9053          if (showFirstOnEllipsisShow) {
9054            html += `<li class="${classPrefix}-page ${classPrefix}-first J-paginationjs-page" data-num="1"><a href="${makeLnk(1)}">1</a></li>`;
9055          }
9056          html += `<li class="${classPrefix}-ellipsis ${disableClassName}"><a>${ellipsisText}</a></li>`;
9057        }
9058        for (let i = rangeStart; i <= rangeEnd; i++) {
9059          html += `<li class="${classPrefix}-page J-paginationjs-page ${i === searchParams.page ? activeClassName : ''}" data-num="${i}"><a ${i === searchParams.page ? '' : `href="${makeLnk(i)}"`}>${i}</a></li>`;
9060        }
9061        if (rangeEnd < totalPages - 2) {
9062          html += `<li class="${classPrefix}-ellipsis ${disableClassName}"><a>${ellipsisText}</a></li>`;
9063          if (showLastOnEllipsisShow) {
9064            html += `<li class="${classPrefix}-page ${classPrefix}-last J-paginationjs-page" data-num="${totalPages}"><a href="${makeLnk(totalPages)}">${totalPages}</a></li>`;
9065          }
9066        } else {
9067          for (let i = rangeEnd + 1; i <= totalPages; i++) {
9068            html += `<li class="${classPrefix}-page J-paginationjs-page" data-num="${i}"><a href="${makeLnk(i)}">${i}</a></li>`;
9069          }
9070        }
9071      }
9072
9073      // Next button
9074      if (showNext) {
9075        if (searchParams.page >= totalPages) {
9076          html += `<li class="${classPrefix}-next ${disableClassName}"><a>${nextText}</a></li>`;
9077        } else {
9078          html += `<li class="${classPrefix}-next J-paginationjs-next" data-num="${searchParams.page + 1}" title="Next page"><a href="${makeLnk(searchParams.page + 1)}">${nextText}</a></li>`;
9079        }
9080      }
9081      html += '</ul></div>';
9082    }
9083    return html;
9084  }
9085  function go(newSearchParams, callback, restorationVisit) {
9086    if (disabled) return;
9087    var goToPageNumber = newSearchParams.page;
9088
9089    // Page number is out of bounds
9090    if (!goToPageNumber || goToPageNumber < 1) return;
9091    var totalPage = getTotalPage();
9092
9093    // Page number is out of bounds
9094    if (!restorationVisit && totalNumber > 0) {
9095      if (goToPageNumber > totalPage) return;
9096    }
9097    if (!options.skipSerialization && (mode === 'NUMBERED_PAGINATION' || searchContainer)) {
9098      var newURL = window.luxuryPresence.pagination.serializeParams(searchFormParams, sectionDomId, {
9099        ...newSearchParams,
9100        page: goToPageNumber !== 1 && mode === 'NUMBERED_PAGINATION' ? newSearchParams.page : null
9101      });
9102      if (!areQueryParamsEqual(newSearchParams, searchParams) && !restorationVisit) {
9103        window.history.pushState({}, '', window.luxuryPresence.getPath(newURL, {
9104          queryString: true
9105        }));
9106      }
9107    }
9108
9109    // Fetch and update page
9110    fetchData(newSearchParams, renderWithData);
9111    disabled = true;
9112    function renderWithData(err, data, count) {
9113      if (err) {
9114        dataContainer.dispatchEvent(new Event('error'));
9115      } else {
9116        searchParams = {
9117          ...newSearchParams
9118        };
9119        totalNumber = count - offset;
9120        if (data.length === 0) {
9121          dataContainer.dispatchEvent(new Event('no-data'));
9122        } else {
9123          dataContainer.dispatchEvent(new Event('data'));
9124        }
9125        render(data);
9126        firstRender = false;
9127      }
9128      disabled = false;
9129      renderBySearch = false;
9130    }
9131  }
9132  function areQueryParamsEqual(first, second) {
9133    var differ = Object.keys(first).find(function (key) {
9134      return first[key] !== undefined && first[key] !== null && first[key] !== second[key];
9135    });
9136    if (differ) {
9137      return false;
9138    }
9139    differ = Object.keys(second).find(function (key) {
9140      return second[key] !== undefined && second[key] !== null && second[key] !== first[key];
9141    });
9142    return !differ;
9143  }
9144  function next(callback) {
9145    go({
9146      ...searchParams,
9147      page: searchParams.page + 1
9148    }, callback);
9149  }
9150  function previous(callback) {
9151    go({
9152      ...searchParams,
9153      page: searchParams.page - 1
9154    }, callback);
9155  }
9156  function refresh(callback) {
9157    go(searchParams, callback);
9158  }
9159  function update(params, callback) {
9160    renderBySearch = true;
9161    go(params, callback);
9162  }
9163  function observer() {
9164    if (searchContainer) {
9165      searchContainer.addEventListener('search', function (event, newSearchParams) {
9166        newSearchParams = event.detail || newSearchParams;
9167        update({
9168          ...searchParams,
9169          ...newSearchParams,
9170          page: 1
9171        });
9172      });
9173      searchContainer.addEventListener('clear-search', function () {
9174        const defaultSearchParams = {
9175          ...DefaultSearchParams
9176        };
9177        const isCurrentSearchFormStateDefault = areQueryParamsEqual({
9178          ...defaultSearchParams,
9179          page: null
9180        }, {
9181          ...searchParams,
9182          page: null
9183        });
9184
9185        // if mode is LOAD_MORE_BUTTON we should't make anything on clear
9186        // when search form have default state
9187        if (isCurrentSearchFormStateDefault && mode !== 'NUMBERED_PAGINATION') {
9188          return;
9189        }
9190
9191        // if someone initially go to some page and click 'Clear' on search from
9192        // we should't navigate to first page. We should preserve page value
9193        if (isCurrentSearchFormStateDefault) {
9194          defaultSearchParams.page = searchParams.page;
9195        }
9196        syncSearchFormState(defaultSearchParams);
9197        update(defaultSearchParams);
9198      });
9199    }
9200    if (mode === 'LOAD_MORE_BUTTON') {
9201      loadMoreButton.addEventListener('click', function (event) {
9202        go({
9203          ...searchParams,
9204          page: searchParams.page + 1
9205        });
9206        return false;
9207      });
9208    }
9209    if (mode === 'LOAD_MORE_BUTTON' || mode === 'BUTTONLESS_PAGINATION') {
9210      // Do initial render
9211      go(Object.assign({}, searchParams, {
9212        page: 1
9213      }));
9214      return;
9215    }
9216    if (mode === 'NUMBERED_PAGINATION') {
9217      // Go to specified page number
9218      container.addEventListener(eventPrefix + 'go', function (event) {
9219        let {
9220          pageNumber,
9221          done
9222        } = event.detail || {};
9223        pageNumber = parseInt(pageNumber, 10);
9224        if (!pageNumber) {
9225          return;
9226        }
9227        go({
9228          ...searchParams,
9229          page: pageNumber
9230        }, done);
9231      });
9232
9233      // Page number button click
9234      el.addEventListener('click', function (event) {
9235        let clickTarget = event.target;
9236        let current = clickTarget.closest('.J-paginationjs-page, .J-paginationjs-previous, .J-paginationjs-next');
9237        let pageNumber = current?.getAttribute('data-num');
9238        if (!pageNumber || current.classList.contains(disableClassName) || current.classList.contains(activeClassName)) {
9239          return;
9240        } else {
9241          go({
9242            ...searchParams,
9243            page: parseInt(pageNumber, 10)
9244          });
9245        }
9246        event.preventDefault();
9247      });
9248
9249      // Whether to load the default page
9250      var defaultPageNumber = searchParams.page;
9251      if (triggerPagingOnInit) {
9252        container.dispatchEvent(new CustomEvent(eventPrefix + 'go', {
9253          detail: {
9254            pageNumber: defaultPageNumber
9255          }
9256        }));
9257      }
9258    }
9259    window.addEventListener('popstate', function (event) {
9260      var newParams = Object.assign({}, DefaultSearchParams, window.luxuryPresence.pagination.deserializeParams(searchFormParams, sectionDomId));
9261      if (!areQueryParamsEqual(newParams, searchParams)) {
9262        go(newParams, null, true);
9263        if (searchContainer) {
9264          syncSearchFormState(newParams);
9265        }
9266      }
9267    });
9268  }
9269  function replaceVariables(template, variables) {
9270    var formattedString;
9271    for (var key in variables) {
9272      var value = variables[key];
9273      var regexp = new RegExp('<%=\\s*' + key + '\\s*%>', 'img');
9274      formattedString = (formattedString || template).replace(regexp, value);
9275    }
9276    return formattedString;
9277  }
9278  function isTextEditorValue(obj) {
9279    return 'raw' in obj || 'gjs' in obj;
9280  }
9281  function getTextEditorValue(obj) {
9282    if (!obj.html) {
9283      return '';
9284    }
9285    var data = obj.html;
9286    var css = (obj.raw || obj.gjs || {}).css;
9287    if (css) {
9288      data = data + '<style>' + css + '</style>';
9289    }
9290    return data;
9291  }
9292
9293  /**
9294   * check rendered resources for html and raw properties that could indicate if resource is from an advanced text editor.
9295   * strips out raw proprties and returns only HTML if it exists.
9296   * @param {Object} resources a collection retrieved from the database
9297   * @return {Object} the newly modified object.
9298   */
9299  function recursivelyParse(resources) {
9300    forEach(resources, function (value, key) {
9301      if (!value) {
9302        return;
9303      }
9304      if (value instanceof Object) {
9305        if (isTextEditorValue(value)) {
9306          resources[key] = getTextEditorValue(value);
9307          return;
9308        } else {
9309          return recursivelyParse(value);
9310        }
9311      }
9312      try {
9313        var parsedData = JSON.parse(value);
9314        if (isTextEditorValue(parsedData)) {
9315          resources[key] = getTextEditorValue(parsedData);
9316        }
9317      } catch (e) {
9318        // do nothing if we failed to parse value as JSON
9319      }
9320    });
9321    return resources;
9322  }
9323  function forEach(collection, iteratee) {
9324    var func = Array.isArray(collection) ? arrayEach : baseFor;
9325    return func(collection, iteratee);
9326  }
9327  function baseFor(object, iteratee) {
9328    if (!object) {
9329      return;
9330    }
9331    var iterable = Object(object);
9332    var props = Object.keys(object);
9333    var length = props.length;
9334    var index = -1;
9335    while (length--) {
9336      var key = props[++index];
9337      if (iteratee(iterable[key], key, iterable) === false) {
9338        break;
9339      }
9340    }
9341    return object;
9342  }
9343  function objSet(obj, path, value) {
9344    const pathArray = Array.isArray(path) ? path : path.match(/([^[.\]])+/g);
9345    pathArray.reduce((acc, key, i) => {
9346      if (acc[key] === undefined) acc[key] = {};
9347      if (i === pathArray.length - 1) acc[key] = value;
9348      return acc[key];
9349    }, obj);
9350  }
9351  function arrayEach(array, iteratee) {
9352    var index = -1;
9353    var length = array.length;
9354    while (++index < length) {
9355      if (iteratee(array[index], index, array) === false) {
9356        break;
9357      }
9358    }
9359    return array;
9360  }
9361  function selectPageRangeMode(e) {
9362    pageRange = e.matches ? mobilePageRange : desktopPageRange;
9363    renderPaginationList();
9364  }
9365  paginationMql.addEventListener('change', selectPageRangeMode);
9366})('section-c0d58c8d-bb8c-453f-9168-aa08a1cecdda', JSON.parse("{\"pageSize\":\"9\",\"resource\":\"posts\",\"pageRange\":1,\"variables\":{\"limit\":9,\"offset\":0,\"sortDir\":\"DESC\",\"companyId\":\"2c02232f-2988-4a2c-a284-887b44b8c4fc\",\"categoryId\":\"{{pageElement.categoryId}}\",\"order\":\"publishedAt\"},\"hidePaginationOnFirstPage\":true,\"companyId\":\"2c02232f-2988-4a2c-a284-887b44b8c4fc\",\"usePageResource\":false,\"sectionIndex\":4}"));
9367} catch(e) {
9368console.log(e);
9369}
9370                try {
9371(function init(sectionDomId) {})('section-c0d58c8d-bb8c-453f-9168-aa08a1cecdda', 'undefined');
9372} catch(e) {
9373console.log(e);
9374}
9375                try {
9376(function init(sectionDomId) {
9377  const $section = $('#' + sectionDomId);
9378  if ($section.find('.parallax').length) $section.addClass('parallax-enabled');
9379  if ($section.find('.video-wrapper').length) $section.addClass('video');
9380})('section-42ff6c98-9b79-4ecf-b1d4-503fd5a6e14d', 'undefined');
9381} catch(e) {
9382console.log(e);
9383}
9384                try {
9385(function init(sectionDomId, options) {
9386  let section = null;
9387  switch (sectionDomId) {
9388    case 'NAVBAR':
9389      section = document.querySelector('body > nav, #global-navbar');
9390      break;
9391    case 'FOOTER':
9392      section = document.querySelector('body > footer, #global-footer');
9393      break;
9394    case 'SIDEMENU':
9395      section = document.querySelector('body > div.sidemenu, #global-sidemenu');
9396      break;
9397    case 'CONTACT':
9398      section = document.querySelector('#modal-global-contact-us');
9399      break;
9400    case 'MOBILE_CONTACT':
9401      section = document.querySelector('body > div.mobile-contact-wrapper, #global-mobile-contact');
9402      break;
9403    case 'SUBSCRIBE':
9404      // Subscribe Not Implemented
9405      section = null;
9406      break;
9407    case 'ACCOUNT':
9408      // Account Not Implemented
9409      section = null;
9410      break;
9411    default:
9412      section = document.querySelector('#' + sectionDomId);
9413  }
9414  if (!section) {
9415    return;
9416  }
9417  var url = window.luxuryPresence.defaults.routerUrl;
9418  var companyId = window.luxuryPresence.defaults.companyId;
9419  var limit = options.limit || 8;
9420  if (typeof limit === 'string') {
9421    limit = parseInt(limit, 10) || 8; // this NaN protection also filters out 0 - this is expected
9422  }
9423  var templateSelector = options.templateSelector || '.jsIGTemplate';
9424  var containerSelector = options.containerSelector || '.jsIGContainer';
9425  var hasDataClass = options.hasDataClass || 'has-data';
9426  var hideActivateMessage = options.hasDataClass || false;
9427  var payload = {
9428    companyId: companyId,
9429    limit: limit
9430  };
9431  if (options.resourceId && typeof options.resourceId === 'string' && !
9431options.resourceId.match(/^{{.*}}$/)) {
9432    payload.resourceId = options.resourceId;
9433    // Federated enum values are uppercase (AGENT/TEAM); element configs carry lowercase
9434    payload.resource = String(options.resource || 'agent').toUpperCase();
9435    payload.fallbackToNoResource = options.fallbackToNoResource === 'true' || options.fallbackToNoResource === true;
9436  }
9437  var query = 'query InstagramFeed (\n' + '  $companyId: ID!\n' + '  $instagramAuthorizationId: ID\n' + '  $username: String\n' + (payload.resourceId ? '$resource: InstagramContentAuthResourceEnum\n $resourceId: ID\n $fallbackToNoResource: Boolean' : '') + '  $limit: Int\n' + ') {\n' + '  instagramContentFeed (\n' + '  companyId: $companyId\n' + '  instagramAuthorizationId: $instagramAuthorizationId\n' + '  username: $username\n' + (payload.resourceId ? 'resource: $resource\n resourceId: $resourceId\n fallbackToNoResource: $fallbackToNoResource' : '') + '  limit: $limit\n' + '  ) {\n' + '    active\n' + '    feedUrl\n' + '    username\n' + '    items {\n' + '      id\n' + '      caption\n' + '      commentsCount\n' + '      likeCount\n' + '      mediaType\n' + '      mediaUrl\n' + '      permalink\n' + '      shortcode\n' + '      thumbnailUrl\n' + '      timestamp\n' + '      username\n' + '    }\n' + '  }\n' + '}\n';
9438  var templateHTML = section.querySelector(templateSelector)?.innerHTML || '';
9439  var template = Handlebars.compile(templateHTML);
9440  var container = section.querySelector(containerSelector);
9441  if (options.variables) {
9442    Object.keys(options.variables).forEach(function (key) {
9443      if (options.variables.hasOwnProperty(key) && (typeof options.variables[key] !== 'string' || !options.variables[key].match(/^{{.*}}$/))) {
9444        payload[key] = options.variables[key];
9445      }
9446    });
9447  }
9448  function getData() {
9449    var feed = {
9450      error: true
9451    };
9452    if (payload.companyId == null || payload.companyId === '') {
9453      // instagramContentFeed requires companyId (ID!) — nothing to fetch without it.
9454      // Checked after the options.variables merge, which may override the default.
9455      // Deferred so element listeners (attached after this template runs) still receive it.
9456      setTimeout(function () {
9457        section.dispatchEvent(new CustomEvent('ig-data', {
9458          detail: feed
9459        }));
9460      }, 0);
9461      return;
9462    }
9463    superagent.post(url + '/graphql').send({
9464      query: query,
9465      variables: payload
9466    }).then(res => {
9467      try {
9468        if (!res.body.errors) {
9469          feed = res.body.data.instagramContentFeed;
9470          if (!feed.active) {
9471            if (!hideActivateMessage && sectionDomId === 'section-temp' && container) {
9472              if (payload.resourceId) {
9473                container.innerHTML = '<div style="text-align: center">Instagram account is not connected to selected ' + payload.resource + '.<br /> Connect it on the ' + payload.resource + ' page</div>';
9474              } else {
9475                container.innerHTML = '<div style="text-align: center">Instagram account is not connected.<br /> Connect it on <a href="/profile">Profile page</a></div>';
9476              }
9477            }
9478          } else {
9479            if (feed.items.length) {
9480              if (hasDataClass) {
9481                section.classList.add(hasDataClass);
9482              }
9483              const feedName = feed.username;
9484              section.querySelectorAll('.jsIGLink').forEach(link => link.setAttribute('href', feed.feedUrl));
9485              section.querySelectorAll('.jsIGName').forEach(name => {
9486                name.textContent = '@' + feedName;
9487                name.setAttribute('title', '@' + feedName);
9488              });
9489              if (container && template) {
9490                container.innerHTML = template(feed);
9491              }
9492            }
9493          }
9494        }
9495      } catch (e) {}
9496      section.dispatchEvent(new CustomEvent('ig-data', {
9497        detail: feed
9498      }));
9499    }).catch(e => {
9500      console.log('err', e);
9501      section.dispatchEvent(new CustomEvent('ig-data', {
9502        detail: feed
9503      }));
9504    });
9505  }
9506  getData();
9507})('section-dc35c8ba-2e7a-45c2-9887-4d2125099be8', JSON.parse("{\"companyId\":\"2c02232f-2988-4a2c-a284-887b44b8c4fc\",\"sectionIndex\":6}"));
9508} catch(e) {
9509console.log(e);
9510}
9511                try {
9512(function init(sectionDomId) {
9513  $("#" + sectionDomId).on("ig-data", function () {
9514    let title = $("#" + sectionDomId + " .js-slider-holder").data("title");
9515    if (title) {
9516      $("#" + sectionDomId + " .js-h3").text(title);
9517    }
9518    if (window.matchMedia("(max-width: 768px)").matches) {
9519      $("#" + sectionDomId + " .js-slider-holder").before($("#" + sectionDomId + " .js-title-group").clone());
9520    }
9521    $("#" + sectionDomId + " .js-collection .js-title-group").remove();
9522    function buildSlick() {
9523      $('#' + sectionDomId + ' .js-collection').slick({
9524        autoplay: true,
9525        arrows: false,
9526        speed: 0,
9527        autoplaySpeed: 6000,
9528        dots: false,
9529        infinite: true,
9530        slidesToShow: 4,
9531        slidesToScroll: 4,
9532        cssEase: 'linear',
9533        variableWidth: true,
9534        centerMode: false,
9535        swipe: false,
9536        responsive: [{
9537          breakpoint: 1024,
9538          settings: {
9539            slidesToShow: 2,
9540            slidesToScroll: 2
9541          }
9542        }, {
9543          breakpoint: 768,
9544          settings: {
9545            slidesToShow: 4,
9546            slidesToScroll: 4
9547          }
9548        }]
9549      });
9550    }
9551    if ($("#" + sectionDomId + " .js-collection").length) {
9552      if ($("#" + sectionDomId + " .js-collection").hasClass('slick-initialized')) {
9553        $("#" + sectionDomId + " .js-collection").slick('unslick');
9554        buildSlick();
9555      } else {
9556        buildSlick();
9557      }
9558    }
9559  });
9560})('section-dc35c8ba-2e7a-45c2-9887-4d2125099be8', 'undefined');
9561} catch(e) {
9562console.log(e);
9563}
9564
9565            var { body } = document;
9566            var globalNav = body.querySelector(':scope > nav');
9567            var globalSideMenu = body.querySelector(':scope > div.sidemenu');
9568
9569            document.querySelectorAll('body > .modal .close').forEach(modalCloseBtn => {
9570                modalCloseBtn.addEventListener('click', function() {
9571                window.lpUI.hideClosestModal(modalCloseBtn);
9572              });
9573            });
9574
9575            window.addEventListener('click', function() {
9576                document.querySelectorAll('.share-popup').forEach(sharedPopup => {
9577                    sharedPopup.style.display = 'none' ;
9578                });
9579            });
9580
9581            /* Misc Partials / Addons */
9582            function initWOW() {
9583                if (wow) {
9584                    wow.init();
9585                    wow.scrollHandler();
9586                    setTimeout(function () {
9587                        const wowHideStyle = document.getElementById('wow-hide-elements');
9588                        if(wowHideStyle) {
9589                            wowHideStyle.disabled = true;
9590                        }
9591                    }, 1);
9592                }
9593            }
9594
9595            const wowHideElements =  document.getElementById('wow-hide-elements');
9596            if (wowHideElements) {
9597               wowHideElements.disabled = false;
9598            }
9599
9600                initWOW();
9601
9602            /* Generic Navbar Handling */
9603            globalNav?.querySelectorAll('.hamburger-component').forEach(hamburgerComponent => {
9604                hamburgerComponent.addEventListener('click', function() {
9605                window.lpUI.sideMenuToggle();
9606              });
9607            });
9608            globalSideMenu?.querySelectorAll('.toggle').forEach(toggleEl => {
9609                toggleEl.addEventListener('click', function() {
9610                window.lpUI.sideMenuToggle();
9611              });
9612            });
9613
9614            document.querySelectorAll('body > nav .sub-nav-container > a, body > div.sidemenu .sub-nav-container > a').forEach(linkEl => {
9615                linkEl.addEventListener('click', function(e) {
9616                  e.preventDefault();
9617                  e.stopPropagation();
9618                  var subNav = linkEl.parentElement.querySelector(':scope > .sub-nav');
9619                  if (subNav && subNav.classList.contains('visible')){
9620                    subNav.classList.remove('visible');
9621                  } else {
9622                    globalNav?.querySelectorAll('.sub-nav-container .sub-nav').forEach(globalSubNav => {
9623                      globalSubNav.classList.remove('visible');
9624                    });
9625                    globalSideMenu?.querySelectorAll('.sub-nav').forEach(sideMenuSubNav => {
9626                        sideMenuSubNav.classList.remove('visible');
9627                    });
9628                    subNav?.classList.add('visible');
9629                  }
9630                });
9631            });
9632            window.addEventListener('click', function() {
9633                document.querySelectorAll('nav .sub-nav.visible, .sidemenu .sub-nav.visible').forEach(subNavEl => {
9634                    subNavEl.classList.remove('visible');
9635                });
9636            });
9637
9638        }
9639
9640        document.addEventListener('DOMContentLoaded', lpGlobalInit);
9641
9642    </script>
9642
9643
9644    
9644<script type="module">
9645    function selectorExists(selector) {
9646        return document.querySelector(selector) !== null;
9647    }
9648
9649    // Function to initialize the third-party library
9650    function initParoller(selector = '.my-paroller') {
9651        var $parollerElements = $(selector);
9652        if ($parollerElements.length > 0 && typeof $parollerElements.paroller === 'function') {
9653            $parollerElements.paroller();
9654        }
9655    }
9656
9657    const parollerSelector = '.my-paroller';
9658
9659    if (selectorExists(parollerSelector)) {
9660        window.luxuryPresence.libs.loadJs(window.luxuryPresence.libs.jsLibsMap.paroller.jsSrc, function() {
9661            initParoller(parollerSelector);
9662            window.luxuryPresence.libs.jsLibsMap.paroller.isLoaded = true;
9663        });
9664    }
9665    </script>
9665
9666
9667            <!-- Google Tag Manager (noscript) -->
vendor: 80 bytes, lines 9667-9668
9667
9668            <noscript><iframe src="https://www.googletagmanager.com/ns.html?id=
9668GTM-5P9WP78
vendor: 107 bytes, lines 9668-9670
9668"
9669            height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
9670            
9670<!-- End Google Tag Manager -->
9671            <!-- Google Tag Manager (noscript) -->
vendor: 80 bytes, lines 9671-9672
9671
9672            <noscript><iframe src="https://www.googletagmanager.com/ns.html?id=
9672GTM-T9SFQGHZ
vendor: 107 bytes, lines 9672-9674
9672"
9673            height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
9674            
9674<!-- End Google Tag Manager -->
9675        
9676<script>(function(){function c(){var b=a.contentDocument||(a.contentWindow&&a.contentWindow.document);if(b){var d=b.createElement('script');d.innerHTML="window.__CF$cv$params={r:'a4816c15ff5532f4',t:'MTc5MTU5MTIzOA=='};var a=document.createElement('script');a.src='/cdn-cgi/challenge-platform/scripts/jsd/main.js';document.getElementsByTagName('head')[0].appendChild(a);";b.getElementsByTagName('head')[0].appendChild(d)}}if(document.body){var a=document.createElement('iframe');a.height=1;a.width=1;a.style.position='absolute';a.style.top=0;a.style.left=0;a.style.border='none';a.style.visibility='hidden';document.body.appendChild(a);if('loading'!==document.readyState)c();else if(window.addEventListener)document.addEventListener('DOMContentLoaded',c);else{var e=document.onreadystatechange||function(){};document.onreadystatechange=function(b){e(b);'loading'!==document.readyState&&(document.onreadystatechange=e,c())}}}})();</script>
9676<script type="module" src="https://static.cloudflareinsights.com/beacon.min.js/v4bc70e2c01a94c73b74392e4234840661791215815920" integrity="sha512-L0ha0OXavK/8okipN9F8BtP84dg9DUhPERbBXzwI6dgTA55d2+yweo3pn5CSFYs45/r8md2+xvUPtTdvTNRfjA==" data-cf-beacon='{"version":"2024.11.0","token":"d2a8f4b3d65944edb8fcd6ffce49ee5e","spa":2}' crossorigin="anonymous"></script>
9676
9677</body>
9678</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.