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>Luxury Homes for Sale in Kauai | Danette Andrews Team</title> 10 <meta property="og:title" content="Luxury Homes for Sale in Kauai | Danette Andrews Team"> 11 <meta name="twitter:title" content="Luxury Homes for Sale in Kauai | Danette Andrews Team"> 12 <meta name="description" content="Explore luxury properties for sale in Kauai with the Andrews Collection. Browse estates in Kilauea, Kalaheo, and Lihue starting from $5.7M. Contact us today."> 13 <meta property="og:description" content="Explore luxury properties for sale in Kauai with the Andrews Collection. Browse estates in Kilauea, Kalaheo, and Lihue starting from $5.7M. Contact us today."> 14 <meta name="twitter:description" content="Explore luxury properties for sale in Kauai with the Andrews Collection. Browse estates in Kilauea, Kalaheo, and Lihue starting from $5.7M. Contact us today."> 15 <meta property="og:image" content="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/b241e1c5-b423-466b-87dd-a79fea252714"> 16 <meta name="twitter:image" content="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/b241e1c5-b423-466b-87dd-a79fea252714"> 17 <meta property="og:url" content="https://andrewskauai.com/properties/sale"> 18 <link rel="canonical" href="https://andrewskauai.com/properties/sale"> 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 <style>@font-face {font-family: 'CompassSerif';src: url('https://s3-us-west-2.amazonaws.com/static-lp/fonts/compass/CompassSerif/CompassSerif-Regular.woff2') format('woff2'),url('https://s3-us-west-2.amazonaws.com/static-lp/fonts/compass/CompassSerif/CompassSerif-Regular.woff') format('woff');font-weight: 400;font-style: normal;}@font-face {font-family: 'CompassSerif';src: url('https://s3-us-west-2.amazonaws.com/static-lp/fonts/compass/CompassSerif/CompassSerif-Italic.woff2') format('woff2'),url('https://s3-us-west-2.amazonaws.com/static-lp/fonts/compass/CompassSerif/CompassSerif-Italic.woff') format('woff');font-weight: 400;font-style: italic;}@font-face {font-family: 'CompassSerif';src: url('https://s3-us-west-2.amazonaws.com/static-lp/fonts/compass/CompassSerif/CompassSerif-SemiBold.woff2') format('woff2'),url('https://s3-us-west-2.amazonaws.com/static-lp/fonts/compass/CompassSerif/CompassSerif-SemiBold.woff') format('woff');font-weight: 600;font-style: normal;}@font-face {font-family: 'CompassSerif';src: url('https://s3-us-west-2.amazonaws.com/static-lp/fonts/compass/CompassSerif/CompassSerif-SemiBoldItalic.woff2') format('woff2'),url('https://s3-us-west-2.amazonaws.com/static-lp/fonts/compass/CompassSerif/CompassSerif-SemiBoldItalic.woff') format('woff');font-weight: 600;font-style: italic;}@font-face {font-family: 'CompassSerif';src: url('https://s3-us-west-2.amazonaws.com/static-lp/fonts/compass/CompassSerif/CompassSerif-Bold.woff2') format('woff2'),url('https://s3-us-west-2.amazonaws.com/static-lp/fonts/compass/CompassSerif/CompassSerif-Bold.woff') format('woff');font-weight: 700;font-style: normal;}@font-face {font-family: 'CompassSerif';src: url('https://s3-us-west-2.amazonaws.com/static-lp/fonts/compass/CompassSerif/CompassSerif-BoldItalic.woff2') format('woff2'),url('https://s3-us-west-2.amazonaws.com/static-lp/fonts/compass/CompassSerif/CompassSerif-BoldItalic.woff') format('woff');font-weight: 700;font-style: italic;}@font-face {font-family: 'CompassSerif';src: url('https://s3-us-west-2.amazonaws.com/static-lp/fonts/compass/CompassSerif/CompassSerif-SemiBold.woff2') format('woff2'),url('https://s3-us-west-2.amazonaws.com/static-lp/fonts/compass/CompassSerif/CompassSerif-SemiBold.woff') format('woff');font-weight: 500;font-style: normal;}@font-face {font-family: 'CompassSerif';src: url('https://s3-us-west-2.amazonaws.com/static-lp/fonts/compass/CompassSerif/CompassSerif-SemiBoldItalic.woff2') format('woff2'),url('https://s3-us-west-2.amazonaws.com/static-lp/fonts/compass/CompassSerif/CompassSerif-SemiBoldItalic.woff') format('woff');font-weight: 500;font-style: italic;}</style><style>@font-face {font-family: 'CompassSans';src: url('https://s3-us-west-2.amazonaws.com/static-lp/fonts/compass/CompassSans/CompassSans-Regular.woff2') format('woff2'),url('https://s3-us-west-2.amazonaws.com/static-lp/fonts/compass/CompassSans/CompassSans-Regular.woff') format('woff');font-weight: 400;font-style: normal;}@font-face {font-family: 'CompassSans';src: url('https://s3-us-west-2.amazonaws.com/static-lp/fonts/compass/CompassSans/CompassSans-Italic.woff2') format('woff2'),url('https://s3-us-west-2.amazonaws.com/static-lp/fonts/compass/CompassSans/CompassSans-Italic.woff') format('woff');font-weight: 400;font-style: italic;}@font-face {font-family: 'CompassSans';src: url('https://s3-us-west-2.amazonaws.com/static-lp/fonts/compass/CompassSans/CompassSans-Medium.woff2') format('woff2'),url('https://s3-us-west-2.amazonaws.com/static-lp/fonts/compass/CompassSans/CompassSans-Medium.woff') format('woff');font-weight: 500;font-style: normal;}@font-face {font-family: 'CompassSans';src: url('https://s3-us-west-2.amazonaws.com/static-lp/fonts/compass/CompassSans/CompassSans-MediumItalic.woff2') format('woff2'),url('https://s3-us-west-2.amazonaws.com/static-lp/fonts/compass/CompassSans/CompassSans-MediumItalic.woff') format('woff');font-weight: 500;font-style: italic;}@font-face {font-family: 'CompassSans';src: url('https://s3-us-west-2.amazonaws.com/static-lp/fonts/compass/CompassSans/CompassSans-Bold.woff2') format('woff2'),url('https://s3-us-west-2.amazonaws.com/static-lp/fonts/compass/CompassSans/CompassSans-Bold.woff') format('woff');font-weight: 700;font-style: normal;}@font-face {font-family: 'CompassSans';src: url('https://s3-us-west-2.amazonaws.com/static-lp/fonts/compass/CompassSans/CompassSans-BoldItalic.woff2') format('woff2'),url('https://s3-us-west-2.amazonaws.com/static-lp/fonts/compass/CompassSans/CompassSans-BoldItalic.woff') format('woff');font-weight: 700;font-style: italic;}@font-face {font-family: 'CompassSans';src: url('https://s3-us-west-2.amazonaws.com/static-lp/fonts/compass/CompassSans/CompassSans-Medium.woff2') format('woff2'),url('https://s3-us-west-2.amazonaws.com/static-lp/fonts/compass/CompassSans/CompassSans-Medium.woff') format('woff');font-weight: 600;font-style: normal;}@font-face {font-family: 'CompassSans';src: url('https://s3-us-west-2.amazonaws.com/static-lp/fonts/compass/CompassSans/CompassSans-MediumItalic.woff2') format('woff2'),url('https://s3-us-west-2.amazonaws.com/static-lp/fonts/compass/CompassSans/CompassSans-MediumItalic.woff') format('woff');font-weight: 600;font-style: italic;}</style> 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:CompassSerif,serif;--global-primary-font-family-short:CompassSerif;--global-secondary-font-family:CompassSans,sans-serif;--global-secondary-font-family-short:CompassSans;--global-body-padding:0px;--global-background-color:#fff;--global-body-font-size:16px;--global-h1-font-size:49px;--global-h2-font-size:37px;
29--global-h3-font-size:30px;--global-h4-font-size:24px;--global-h5-font-size:12px;--global-h6-font-size:32px;--global-section-padding:96px;}@media (max-width: 768px){:root{--global-section-padding:64px;}}body{padding:0px;background-color:#fff;font-family:CompassSans,sans-serif;font-size:16px;}@media (min-width: 768px){body{padding:0px 0px 0px 0px;}}h1,h2,h3,h4,h5,h6,button{font-family:CompassSerif,serif;}h1{font-size:49px;}h2{font-size:37px;}h3{font-size:30px;}h4{font-size:24px;}h5{font-size:12px;}h6{font-size:32px;}</style> 30 <link rel="stylesheet" type="text/css" href="https://styles.luxurypresence.com/visionary/index.css" /> 31 <style id="website-css">:root{--lp-color-primary-accent:#000000;--primary:#000000;--secondary:#000000;--accent:#000000;--blocking:#f1f1f1;--text-input:#f3f3f3;--header:#000000;--black:#000;--white:#FFF;--light-gray:#CCC;--dark-gray:#999;--lp-color-error:#F00;--hover:#D8DDE3;}:root{--global-h4-font-size:32px;--global-h5-font-size:24px;--global-h6-font-size:20px;}.lp-h1,.lp-h2,.lp-h3{font-variation-settings:'opsz' 44,'GRAD' 0,'slnt' 0,'XTRA' 510,'XOPQ' 96,'YOPQ' 40,'YTLC' 540,'YTUC' 712,'YTAS' 750,'YTDE' -220,'YTFI' 738;}.watermark{font-variation-settings:'GRAD' 0,'slnt' 0,'XTRA' 511,'XOPQ' 96,'YOPQ' 50,'YTLC' 537,'YTUC' 712,'YTAS' 750,'YTDE' -221,'YTFI' 738,'opsz' 44;}h1{text-transform:uppercase!important;}.lp-h1{text-transform:uppercase!important;}h2{text-transform:uppercase!important;}.lp-h2{text-transform:uppercase!important;}h3{text-transform:uppercase!important;}.lp-h3{text-transform:uppercase!important;}div#global-sidemenu.sidemenu a,nav#global-navbar a{text-transform:uppercase;}div#global-sidemenu.sidemenu button,nav#global-navbar button{text-transform:uppercase;}@media only screen and (max-width:768px){.contact-form-modal__close:after{height:25px;width:20px;--iconColor:#000;}}@media only screen and (min-width:769px){.contact-form-modal__close:after{height:30px;width:40px;}}.contact-form-modal label.lp-label{text-transform:uppercase!important;}@media only screen and (min-width:769px){body.page-sellers .hoverable-section{padding-bottom:0;padding-top:0;}}@media only screen and (max-width:768px){body.page-sellers .hoverable-section{padding-bottom:80px;padding-top:80px;}}@media only screen and (min-width:769px){body.page-buyers .hoverable-section{padding-bottom:0;padding-top:0;}}@media only screen and (max-width:768px){body.page-buyers .hoverable-section{padding-bottom:80px;padding-top:80px;}}.header-container{height:60px!important;}@media only screen and (max-width: 768px){.header-container{height:60px!important;}}.header-logo{height:100%;max-width:200px!important;}@media only screen and (max-width: 768px){.header-logo{height:100%;max-width:180px!important;}}.header:is(.scroll){background:var(--header)!important;color:var(--white)!important;}.header:is(.scroll) .header-logo__img--light{display:block!important;}.header:is(.scroll) .header-logo__img--dark{display:none!important;}.header:is(.scroll) .header-navigation__link:before,.header:is(.scroll) .header-navigation__link:after{background-color:var(--white);}.header:is(.scroll) .header-hamburger-btn{border-color:var(--white);background:transparent;}.header:is(.scroll) .header-hamburger-btn:empty:before,.header:is(.scroll) .header-hamburger-btn:empty:after{background:var(--white);}.header:is(.scroll) .header-hamburger-btn:hover:not(:disabled){border-color:var(--white);background:var(--white);}.header:is(.scroll) .header-hamburger-btn:hover:not(:disabled):empty:before,.header:is(.scroll) .header-hamburger-btn:hover:not(:disabled):empty:after{background:var(--primary);}.header:is(.scroll) .header-navigation__sub-nav{padding:0px;background:var(--header);min-width:150px;}.header:is(.scroll) .header-navigation__sub-nav-link{padding:12px 16px;color:var(--white);}.header:is(.scroll) .header-navigation__sub-nav-link:hover{background-color:var(--white);color:var(--primary);}.header:not(.scroll){background:rgba(0, 0, 0, .0)!important;}.header:not(.scroll) .header-logo__img--light{display:block!important;}.header:not(.scroll) .header-logo__img--dark{display:none!important;}.header:not(.scroll) .header-hamburger-btn{border-color:var(--white);background:transparent;}.header:not(.scroll) .header-hamburger-btn:empty:before,.header:not(.scroll) .header-hamburger-btn:empty:after{background:var(--white);}.header:not(.scroll) .header-hamburger-btn:hover:not(:disabled){border-color:var(--white);background:var(--white);}.header:not(.scroll) .header-hamburger-btn:hover:not(:disabled):empty:before,.header:not(.scroll) .header-hamburger-btn:hover:not(:disabled):empty:after{background:var(--accent);}.header:not(.scroll) .header-navigation__link:before,.header:not(.scroll) .header-navigation__link:after{background-color:var(--white);}.header:not(.scroll) .header-navigation__sub-nav{padding:0px;background:var(--white);min-width:150px;}.header:not(.scroll) .header-navigation__sub-nav-link{padding:12px 16px;color:var(--black);}.header:not(.scroll) .header-navigation__sub-nav-link:hover{background-color:var(--primary);color:var(--white);}.contact-form-modal-consultation-link{color:#fff!important;position:relative!important;font-size:14px;}.contact-form-modal-consultation-link:before,.contact-form-modal-consultation-link:after{-webkit-transition:0.4s;transition:0.4s;-webkit-text-decoration:none!important;text-decoration:none!important;line-height:1;content:"";height:1px;position:absolute!important;bottom:-2px;left:0;}.contact-form-modal-consultation-link:before{width:100%!important;background-color:rgba(250, 250, 250, 0.8)!important;}.contact-form-modal-consultation-link:after{width:0%!important;background-color:var(--primary)!important;}.contact-form-modal-consultation-link:hover:after{width:100%!important;}@media (min-width: 769px){.sidemenu{width:auto;}}.sidemenu-wrapper{min-height:-webkit-fit-content;min-height:-moz-fit-content;min-height:fit-content;max-height:100%;}@media (min-width: 1025px){.sidemenu-nav-holder:has(> .sidemenu-navigation:nth-child(1):last-child){-ms-grid-columns:auto;grid-template-columns:auto;}.sidemenu-nav-holder:has(> .sidemenu-navigation:nth-child(2):last-child){-ms-grid-columns:auto auto;grid-template-columns:auto auto;}.sidemenu-nav-holder:has(> .sidemenu-navigation:nth-child(3):last-child){-ms-grid-columns:auto auto auto;grid-template-columns:auto auto auto;}.sidemenu-nav-holder:has(> .sidemenu-navigation:nth-child(4):last-child){-ms-grid-columns:auto auto auto auto;grid-template-columns:auto auto auto auto;}}@media (max-width: 768px){.sidemenu-wrapper{width:100%;}}@media (min-width: 769px){.sidemenu-footer:before{width:100%;}}@media (max-width: 768px){.sidemenu-socials-block:before{width:100%;}}@media (max-width: 768px){#global-sidemenu{padding-top:128px;padding-bottom:48px;}}@media (min-width: 1025px){.sidemenu-footer{padding-top:70px;}}@media (max-width: 768px){.sidemenu-footer{padding-top:70px;padding-bottom:0px;}}.sidemenu__col-description{white-space:pre-line;}@media (max-width: 768px){.sidemenu-close{top:16px;right:16px;}}.sidemenu-close{border-color:var(--primary);background:var(--primary);}
31.sidemenu-close:after{background:var(--white);}.sidemenu-close:hover:not(:disabled){border-color:var(--primary);background:transparent;}.sidemenu-close:hover:not(:disabled):after{background:var(--primary);}.sidemenu-navigation__link:hover{color:var(--primary);}.sidemenu__col-phone,.sidemenu__col-email,.sidemenu-navigation-sub-nav__link{-webkit-transition:0.25s;transition:0.25s;max-width:-webkit-fit-content;max-width:-moz-fit-content;max-width:fit-content;text-decoration-color:var(--light-gray)!important;}.sidemenu__col-phone:hover,.sidemenu__col-phone:focus,.sidemenu__col-email:hover,.sidemenu__col-email:focus,.sidemenu-navigation-sub-nav__link:hover,.sidemenu-navigation-sub-nav__link:focus{text-decoration-color:var(--primary)!important;}.sidemenu__col-phone:active,.sidemenu__col-email:active,.sidemenu-navigation-sub-nav__link:active{--lp-color-primary-accent-dark:var(--primary);}.sidemenu-footer:before,.sidemenu-socials-block:before{background:var(--primary);opacity:1;}@media only screen and (max-width: 768px){.sidemenu-navigation{gap:16px;}.sidemenu-footer{padding-top:0;}}#global-sidemenu .sidemenu-navigation__link{display:block;white-space:normal;overflow:visible;}.sidemenu__col-content:first-of-type{width:64%;}.sidemenu__section-content .sidemenu__col-content:first-child a{-webkit-text-decoration:none;text-decoration:none;cursor:default;}.sidemenu__col-content strong{font-weight:500;font-size:12px;}@media (min-width: 1025px){.sidemenu{width:auto!important;padding-right:60px!important;}}@media (min-width: 1025px){.sidemenu-nav-holder{display:-ms-grid;display:grid;-ms-grid-columns:1fr 1fr!important;grid-template-columns:1fr 1fr!important;-webkit-align-items:start;-webkit-box-align:start;-ms-flex-align:start;align-items:start;}}.contact-form-modal-details__open a{color:#fff;-webkit-text-decoration:underline;text-decoration:underline;text-underline-offset:2px;text-decoration-color:#999;-webkit-transition:0.3s;transition:0.3s;}.contact-form-modal-details__open a:hover{color:#fff!important;text-decoration-color:#fff!important;}.contact-form-modal__bg-image{content:url('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/4ca8986e-60ee-4424-8ea0-d08fe8a3c7a9');}.contact-form-modal-details__title{max-width:100%;}
31.contact-form-modal-agent{opacity:1;}.contact-form-modal-agent__link{-webkit-transition:0.25s;transition:0.25s;--lp-color-secondary-gray-600:var(--light-gray);}.contact-form-modal-agent__link:hover,.contact-form-modal-agent__link:focus{color:var(--white);--lp-color-primary-accent:var(--light);}.contact-form-modal-agent__link:active{--lp-color-primary-accent-dark:var(--primary);}.custom-form__form-row .lp-input,.modal-content .custom-select-toggle.is-placeholder{color:#000!important;}.modal-content .custom-select .custom-select-item{color:#000;background:#fff;}.modal-content .custom-select .custom-select-item:hover{color:#fff;background:var(--primary)!important;}.contact-form-modal__close-container{top:0px;right:0px;}.email-sign-up-modal .email-sign-up-modal__form .email-sign-up-modal__close{opacity:1!important;}.contact-form-modal__close{top:16px!important;right:48px!important;padding:0px;}.contact-form-modal__close:after{background:var(--white);}.contact-form-modal-agent__contact{max-width:100%;}@media only screen and (max-width: 768px){.contact-form-modal-form__title{text-align:center;}}.contact-form-modal-form__group .lp-input{background-color:var(--text-input);}.custom-intro__content-box{background-color:transparent;}.custom-intro__pre-title{color:var(--white);}.custom-intro__title{color:var(--white);}.custom-intro__description{color:var(--white);}.custom-intro__scroll-btn,.neighborhood-intro__scroll-btn,.blog-post-intro__scroll-btn,.agent-intro__scroll-btn{border-color:var(--white);background:var(--white);}.custom-intro__scroll-btn:after,.neighborhood-intro__scroll-btn:after,.blog-post-intro__scroll-btn:after,.agent-intro__scroll-btn:after{background:var(--primary);}.custom-intro__scroll-btn:hover,.neighborhood-intro__scroll-btn:hover,.blog-post-intro__scroll-btn:hover,.agent-intro__scroll-btn:hover{border-color:var(--white);background:transparent;}.custom-intro__scroll-btn:hover:after,.neighborhood-intro__scroll-btn:hover:after,.blog-post-intro__scroll-btn:hover:after,.agent-intro__scroll-btn:hover:after{background:var(--white);}.lp-title-group{max-width:1400px;}.lp-lightbox__close{border-color:var(--white)!important;background:var(--white)!important;color:var(--primary)!important;-webkit-transition:all 0.3s ease;transition:all 0.3s ease;}.lp-lightbox__close:hover{color:var(--white)!important;background:transparent!important;}.lp-lightbox__close:hover:after,.lp-lightbox__close:hover:before{background-color:var(--white);}.lp-lightbox.show .lp-lightbox-arrow{border-color:var(--white);background:var(--white)!important;}.lp-lightbox.show .lp-lightbox-arrow:before{border-color:var(--primary)!important;}.lp-lightbox.show .lp-lightbox-arrow:hover{background-color:transparent!important;}.lp-lightbox.show .lp-lightbox-arrow:hover:before{border-color:var(--white)!important;}li[class^="paginationjs"]{--lp-color-primary-2:#fff;}div#global-mobile-contact .floating-contact-button-pop-up{background:var(--primary);padding:26px 40px;}div#global-mobile-contact .floating-contact-button__btn-connect:hover{background:#fff!important;color:var(--black)!important;}div#global-mobile-contact .floating-contact-button-pop-up__close{scale:0.8;}div#global-mobile-contact .floating-contact-button-pop-up__close:before{color:var(--black);}div#global-mobile-contact .floating-contact-button-pop-up__close:hover:before{color:var(--primary);}div#global-mobile-contact .lp-input{font-size:14px;color:var(--black);background-color:#FFF;}div#global-mobile-contact .lp-input:focus{border-color:var(--text-dark);}div#global-mobile-contact .floating-contact-button-pop-up__input-group.is-placeholder,div#global-mobile-contact .floating-contact-button-pop-up__input-group.custom-select-toggle{text-transform:uppercase;}div#global-mobile-contact .floating-contact-button-pop-up__input-group.is-placeholder:after,div#global-mobile-contact .floating-contact-button-pop-up__input-group.custom-select-toggle:after{background:var(--accent);}div#global-mobile-contact .custom-select .custom-select-item{text-transform:uppercase;}div#global-mobile-contact .custom-select .custom-select-item:hover{background:var(--accent);color:var(--white);}div#global-mobile-contact .custom-select .custom-select-item.is-selected{background:var(--accent);color:var(--white);}div#global-mobile-contact .contact-form__inputs-container a:hover{color:var(--primary);}div#global-mobile-contact .pop-up .lp-container,div#global-mobile-contact .contact-form{padding:0;}div#global-mobile-contact .contact-form__container{-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px);padding:60px;border:none;}@media only screen and (max-width: 768px){div#global-mobile-contact .contact-form__container{padding:24px 24px 0 24px;}}@media (max-width:768px){.floating-contact-button-pop-up{padding:20px!important;}.floating-contact-button-pop-up h3.floating-contact-button-pop-up__title{font-size:27px;margin-bottom:12px;}.floating-contact-button-pop-up .lp-input{font-size:12px!important;}.floating-contact-button-pop-up .lp-disclaimer{font-size:10px;}.floating-contact-button-pop-up .floating-contact-button-pop-up__close{margin:6px auto 0;height:24px;scale:0.85;}}@media (min-width:1000px) and (max-height:750px){.floating-contact-button-pop-up{scale:0.85;left:0;bottom:-44px;}}footer#global-footer a:not(.lp-socials__link){color:var(--dark);-webkit-transition:0.4s;transition:0.4s;--lp-color-secondary-gray-600:var(--light-gray);}footer#global-footer a:not(.lp-socials__link):hover,footer#global-footer a:not(.lp-socials__link):focus{color:var(--dark);
31--lp-color-primary-accent:var(--primary);}.footer-navigation__item+.footer-navigation__item{border-left:1px solid #fff;}.footer-navigation__item{text-transform:uppercase;}.footer-info{border-right:1px solid #fff;}.footer-contact-row{border-bottom:1px solid #fff;}@media (max-width: 768px){.footer-bottom-row{-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;gap:16px;}}@media (max-width: 768px){.footer-copyright{width:100%;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;gap:16px;}.footer-copyright__powered,.footer-copyright__privacy{-webkit-flex-basis:calc((100% / 2) - 16px + (16px / 2));-ms-flex-preferred-size:calc((100% / 2) - 16px + (16px / 2));flex-basis:calc((100% / 2) - 16px + (16px / 2));}}@media (max-width: 768px){.footer-copyright__powered,.footer-copyright__privacy{-webkit-flex-basis:calc((100% / 2) - 16px + (16px / 2));-ms-flex-preferred-size:calc((100% / 2) - 16px + (16px / 2));flex-basis:calc((100% / 2) - 16px + (16px / 2));}}.footer-logos-row .footer-logo{max-height:100px;}@media (max-width: 768px){.footer-logos-row .footer-logo{max-width:280px;}}.footer-logo{max-width:350px;}@media (min-width: 768px){.footer__col-description p{min-width:230px!important;}}@media (max-width: 768px){.footer__col-content{min-width:100%!important;}.footer__section-content{display:-webkit-box!important;display:-webkit-flex!important;display:-ms-flexbox!important;display:flex!important;-webkit-flex-direction:column!important;-ms-flex-direction:column!important;flex-direction:column!important;}}.footer__col-content{max-width:300px;}.footer-disclaimer a{-webkit-text-decoration:underline;text-decoration:underline;text-decoration-color:#6c6c6c;}.footer-disclaimer a:hover{text-decoration-color:var(--primary);}@media only screen and (max-width: 768px){.footer__section-content{-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;gap:30px;}.footer-navigation{gap:10px;}}.footer__col-description{max-width:unset!important;}.footer-navigation__link:hover{cursor:pointer;}@media (max-width:768px){.footer-navigation__item+.footer-navigation__item,.footer-info,.footer-copyright__privacy{border:none!important;}@media (max-width:768px){.footer-navigation__item+.footer-navigation__item,.footer-info,.footer-copyright__privacy{border:none!important;}.lp-socials{-webkit-box-pack:center!important;-ms-flex-pack:center!important;-webkit-justify-content:center!important;justify-content:center!important;}.sidemenu__col-content:first-of-type{width:92%;}}}div#global-mobile-contact .lp-input::-webkit-input-placeholder{text-transform:uppercase;}div#global-mobile-contact .lp-input::-moz-placeholder{text-transform:uppercase;}div#global-mobile-contact .lp-input:-ms-input-placeholder{text-transform:uppercase;}div#global-mobile-contact .lp-input::placeholder{text-transform:uppercase;}</style> 32 <style id="wow-hide-elements">.wow{visibility:hidden!important}</style> 33 <style id="page-css"> 34 #section-771ca4c0-dfe5-4a13-818a-e283d65c7e1f{color:#fff;--fontColor:#fff;--fontColor_H:0;--fontColor_S:0%;--fontColor_L:100%;--fontColor_A:1;--fontColor_darkenDir:-1;--bgColor:#ffffff;--bgColor_H:0;--bgColor_S:0%;--bgColor_L:100%;--bgColor_A:1;--bgColor_darkenDir:-1;background-color:#ffffff;--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/b241e1c5-b423-466b-87dd-a79fea252714');background-repeat:no-repeat;-webkit-background-position:center;background-position:center;-webkit-background-size:cover;background-size:cover;}@media (min-width: 960px) and (orientation: landscape){#section-771ca4c0-dfe5-4a13-818a-e283d65c7e1f{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/b241e1c5-b423-466b-87dd-a79fea252714');}}@media (min-width: 1280px) and (orientation: landscape){#section-771ca4c0-dfe5-4a13-818a-e283d65c7e1f{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/b241e1c5-b423-466b-87dd-a79fea252714');}}@media (min-width: 1920px) and (orientation: landscape){#section-771ca4c0-dfe5-4a13-818a-e283d65c7e1f{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=2560/https://media-production.lp-cdn.com/media/b241e1c5-b423-466b-87dd-a79fea252714');}}@media (min-width: 2560px) and (orientation: landscape){#section-771ca4c0-dfe5-4a13-818a-e283d65c7e1f{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=3456/https://media-production.lp-cdn.com/media/b241e1c5-b423-466b-87dd-a79fea252714');}}#section-055f7306-112d-4d27-8914-cafe3745ec53{color:#1A1A1A;--fontColor:#1A1A1A;--fontColor_H:0;--fontColor_S:0%;--fontColor_L:10%;--fontColor_A:1;--fontColor_darkenDir:1;--bgColor:#ffffff;--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(4 / 4 * var(--global-section-padding));background-color:#ffffff;}#section-055f7306-112d-4d27-8914-cafe3745ec53 .properties-list-item{-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;text-transform:uppercase;}#section-055f7306-112d-4d27-8914-cafe3745ec53 .properties-list__input,#section-055f7306-112d-4d27-8914-cafe3745ec53 .properties-list__dropdown-select{background-color:var(--accent);color:#fff!important;}#section-055f7306-112d-4d27-8914-cafe3745ec53 .lp-input-icon--search:after,#section-055f7306-112d-4d27-8914-cafe3745ec53 .properties-list__dropdown-select:after{background-color:var(--accent);}#section-055f7306-112d-4d27-8914-cafe3745ec53 .custom-select-item:hover{background-color:transparent;}#section-055f7306-112d-4d27-8914-cafe3745ec53 .properties-list__show-btn{background-color:transparent;border-color:var(--accent);color:#000;}#section-055f7306-112d-4d27-8914-cafe3745ec53 .properties-list__show-btn:hover{background-color:transparent;color:var(--accent);border-color:var(--accent);}#section-055f7306-112d-4d27-8914-cafe3745ec53 .properties-list__hide-btn{border-color:var(--accent);}#section-055f7306-112d-4d27-8914-cafe3745ec53 .properties-list-item__tag{background-color:var(--accent);font-size:13px;text-transform:uppercase;letter-spacing:1px;padding:8px 20px;}#section-055f7306-112d-4d27-8914-cafe3745ec53 .properties-list-item__icon-tag{background-color:var(--accent);color:#fff;margin-bottom:16px;}#section-055f7306-112d-4d27-8914-cafe3745ec53 .paginationjs-next a:hover:after,#section-055f7306-112d-4d27-8914-cafe3745ec53 .paginationjs-prev a:hover:after{background-color:var(--primary);}#section-055f7306-112d-4d27-8914-cafe3745ec53>div:last-child{padding-top:calc(4 / 4 * var(--global-section-padding))!important;padding-bottom:calc(4 / 4 * var(--global-section-padding))!important;}#section-4510a72a-a320-4493-886b-c8947b75a60f{color:#fff;--fontColor:#fff;--fontColor_H:0;--fontColor_S:0%;--fontColor_L:100%;--fontColor_A:1;--fontColor_darkenDir:-1;--bgColor:#ffffff;--bgColor_H:0;--bgColor_S:0%;--bgColor_L:100%;--bgColor_A:1;--bgColor_darkenDir:-1;background-color:#ffffff;--gradient-color:var(--overlay-color, rgba(0, 0, 0, 0.30));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/5ce52d10-5ee6-490f-84d6-a38f8d53e5f3');background-repeat:no-repeat;-webkit-background-position:center;background-position:center;-webkit-background-size:cover;background-size:cover;}#section-4510a72a-a320-4493-886b-c8947b75a60f .lp-input-icon:after{background:#042D49;}#section-4510a72a-a320-4493-886b-c8947b75a60f .newsletter-contact-cta__word-divide:after,#section-4510a72a-a320-4493-886b-c8947b75a60f .newsletter-contact-cta__word-divide:before{background:#fff;}#section-4510a72a-a320-4493-886b-c8947b75a60f .lp-input,#section-4510a72a-a320-4493-886b-c8947b75a60f .lp-input--light:-webkit-autofill,#section-4510a72a-a320-4493-886b-c8947b75a60f .lp-input--light:-webkit-autofill:focus{color:#000!important;background:#fff;-webkit-text-fill-color:#000!important;-webkit-box-shadow:0 0 0px 1000px transparent inset!important;}#section-4510a72a-a320-4493-886b-c8947b75a60f .newsletter-contact-cta__description{opacity:1;}#section-4510a72a-a320-4493-886b-c8947b75a60f .lp-vertical-paddings:not([class*=pb-]){padding-top:96px;padding-bottom:96px;}@media(max-width:768px){#section-4510a72a-a320-4493-886b-c8947b75a60f .lp-vertical-paddings:not([class*=pb-]){padding-top:64px;padding-bottom:64px;}}#section-4510a72a-a320-4493-886b-c8947b75a60f .work-with-us__title--with-pretitle{position:relative;padding-top:10px;}#section-4510a72a-a320-4493-886b-c8947b75a60f .work-with-us__title--with-pretitle:before{border-top-style:solid;border-top-width:2px;content:"";display:inline-block;left:50%;position:absolute;top:0;-webkit-transform:translateX(-50%);-moz-transform:translateX(-50%);-ms-transform:translateX(-50%);transform:translateX(-50%);width:104px;}@media (min-width: 960px) and (orientation: landscape){#section-4510a72a-a320-4493-886b-c8947b75a60f{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/5ce52d10-5ee6-490f-84d6-a38f8d53e5f3');}}@media (min-width: 1280px) and (orientation: landscape){#section-4510a72a-a320-4493-886b-c8947b75a60f{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/5ce52d10-5ee6-490f-84d6-a38f8d53e5f3');}}@media (min-width: 1920px) and (orientation: landscape){#section-4510a72a-a320-4493-886b-c8947b75a60f{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=2560/https://media-production.lp-cdn.com/media/5ce52d10-5ee6-490f-84d6-a38f8d53e5f3');}}@media (min-width: 2560px) and (orientation: landscape){#section-4510a72a-a320-4493-886b-c8947b75a60f{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=3456/https://media-production.lp-cdn.com/media/5ce52d10-5ee6-490f-84d6-a38f8d53e5f3');}}
34#section-f6b2e0c9-5dd7-43a4-8086-a51ab775df71{color:#1a1a1a;--fontColor:#1a1a1a;--fontColor_H:0;--fontColor_S:0%;--fontColor_L:10%;--fontColor_A:1;--fontColor_darkenDir:1;--bgColor:#ffffff;--bgColor_H:0;--bgColor_S:0%;--bgColor_L:100%;--bgColor_A:1;--bgColor_darkenDir:-1;background-color:#ffffff;}body>div.sidemenu{background-color:rgba(255, 255, 255, 1);color:rgba(0, 0, 0, 1);--fontColor:rgba(0, 0, 0, 1);--fontColor_H:0;--fontColor_S:0%;--fontColor_L:0%;--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;}footer{background-color:rgba(255, 255, 255, 1);color:rgba(26, 26, 26, 1);--fontColor:rgba(26, 26, 26, 1);--fontColor_H:0;--fontColor_S:0%;--fontColor_L:10%;--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;} 35 </style> 36 <style id="custom-style-css">.social_icons-style-1 a{border-color:#000000!important;background-color:#000000!important;color:rgba(255, 255, 255, 1)!important;}.social_icons-style-1 a:hover{border-color:#000000!important;background-color:rgba(0, 0, 0, 0)!important;color:#000000!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;}.pagination-style-1 li a{color:rgba(255, 255, 255, 1)!important;background-color:#000000!important;border-color:#000000!important;}.pagination-style-1 li a:hover{color:#000000!important;background-color:rgba(0, 0, 0, 0)!important;border-color:#000000!important;}.pagination-style-1 li.active a{color:#000000!important;background-color:rgba(0, 0, 0, 0)!important;border-color:#000000!important;}.button-style-1{color:rgba(255, 255, 255, 1)!important;background-color:#000000!important;border-color:#000000!important;}.button-style-1:hover{color:#000000!important;background-color:rgba(0, 0, 0, 0)!important;border-color:#000000!important;}.hyperlink-style-1{color:#000000!important;}.hyperlink-style-1:hover{color:#000000!important;}.button-style-2{color:#000000!important;background-color:#FFFFFF!important;border-color:#FFFFFF!important;}.button-style-2:hover{color:rgba(255, 255, 255, 1)!important;background-color:rgba(0, 0, 0, 0)!important;border-color:#FFFFFF!important;}.hyperlink-style-2{color:rgba(255, 255, 255, 1)!important;}.hyperlink-style-2:hover{color:#FFFFFF!important;}.social_icons-style-2 a{border-color:#FFFFFF!important;background-color:#FFFFFF!important;color:#000000!important;}.social_icons-style-2 a:hover{border-color:#FFFFFF!important;background-color:rgba(0, 0, 0, 0)!important;color:#FFFFFF!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:#000000!important;background-color:rgba(0, 0, 0, 0)!important;border-color:rgba(177, 132, 99, 0)!important;}.pagination-style-2 li a:hover{color:rgba(255, 255, 255, 1)!important;background-color:#000000!important;border-color:#000000!important;}.pagination-style-2 li.active a{color:rgba(255, 255, 255, 1)!important;background-color:#000000!important;border-color:#000000!important;}.hyperlink-style-3{color:rgba(177, 132, 99, 1)!important;}.hyperlink-style-3:hover{color:rgba(145, 102, 72, 1)!important;}.button-style-3{color:#FFFFFF!important;background-color:rgba(0, 0, 0, 0)!important;border-color:rgba(255, 255, 255, 1)!important;}.button-style-3:hover{color:#000000!important;background-color:#FFFFFF!important;border-color:#FFFFFF!important;}.button-style-4{color:#000000!important;background-color:rgba(0, 0, 0, 0)!important;border-color:#000000!important;}.button-style-4:hover{color:#FFFFFF!important;background-color:#000000!important;border-color:#000000!important;}</style> 37 <!-- LP Consent bootstrap: blocking; resolves consent state, pushes Consent Mode 38 defaults, and dynamically loads the locale + main (and banner if needed). --> 39
39<script src="https://cdn.luxurypresence.com/scripts/lp-consent/latest/lp-consent-boot.js" data-website-id="e8034653-cea9-43db-b10d-f8cf56e2295a"></script>
39 40 41 42
42<script> 43 (function utmParse() { 44 const url = new URL(window.location.href); 45 if (url.search) { 46 const utm = url.search.split(/\?|&/g).reduce((acc, current) => { 47 const matched = current.match(/utm_(content|campaign|medium|source|term|id)|gclid/g); 48 if (matched) { 49 acc[matched[0]] = current.replace(`${matched[0]}=`, ''); 50 } 51 return acc; 52 }, {}); 53 if (Object.keys(utm).length) { 54 window.localStorage.setItem('utm_vars', JSON.stringify(utm)); 55 } else { 56 // Remove old utm vars 57 window.localStorage.removeItem('utm_vars'); 58 } 59 } 60 // Set referrer in local storage 61 // This is meant to be stored once to avoid self-referrals and to have the first referrer only. 62 if (!window.localStorage.getItem('referrer')) { 63 // Capture the Referrer URL 64 const referrer = document.referrer; 65 if (referrer) { 66 // Only store the referrer if it comes from outside the current domain (to avoid self-referrals) 67 const currentDomain = window.location.hostname; 68 const referrerDomain = new URL(referrer).hostname; 69 70 if (referrerDomain !== currentDomain) { 71 // Store it in localStorage 72 localStorage.setItem('referrer', referrer); 73 } 74 } 75 } 76 })(); 77 </script>
77 78 79 <!-- GOOGLE TRANSLATE STYLES are moved to external CSS --> 80</head> 81<body> 82 <div id="google_translate_element" style="display: none"></div> 83 84 <nav id="global-navbar" data-el-id="3242b8f0-253e-46f7-b814-162ccf958ec2"> 85 86<header class="header js-header" style="--textColor: rgba(255, 255, 255, 1); --backgroundColor: rgba(26, 26, 26, 1);"> 87 <div class="header-container "> 88 89 <a href="/" class="header-logo"> 90 <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/4e1b582c-2b13-446e-a510-aa4c06c0cac9" srcset="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/4e1b582c-2b13-446e-a510-aa4c06c0cac9 320w, 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/4e1b582c-2b13-446e-a510-aa4c06c0cac9 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/4e1b582c-2b13-446e-a510-aa4c06c0cac9 1280w, 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/4e1b582c-2b13-446e-a510-aa4c06c0cac9 1920w, https://media-production.lp-cdn.com/cdn-cgi/image/format=auto,quality=85,fit=scale-down,width=2560/https://media-production.lp-cdn.com/media/4e1b582c-2b13-446e-a510-aa4c06c0cac9 2560w, https://media-production.lp-cdn.com/cdn-cgi/image/format=auto,quality=85,fit=scale-down,width=3456/https://media-production.lp-cdn.com/media/4e1b582c-2b13-446e-a510-aa4c06c0cac9 3456w" sizes="350px" alt="Compass" class="header-logo__img header-logo__img--dark"> 91 <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/6073f18c-11fd-4db2-a174-06657bfe96c9" srcset="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/6073f18c-11fd-4db2-a174-06657bfe96c9 320w, 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/6073f18c-11fd-4db2-a174-06657bfe96c9 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/6073f18c-11fd-4db2-a174-06657bfe96c9 1280w, 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/6073f18c-11fd-4db2-a174-06657bfe96c9 1920w, https://media-production.lp-cdn.com/cdn-cgi/image/format=auto,quality=85,fit=scale-down,width=2560/https://media-production.lp-cdn.com/media/6073f18c-11fd-4db2-a174-06657bfe96c9 2560w, https://media-production.lp-cdn.com/cdn-cgi/image/format=auto,quality=85,fit=scale-down,width=3456/https://media-production.lp-cdn.com/media/6073f18c-11fd-4db2-a174-06657bfe96c9 3456w" sizes="350px" alt="Compass" class="header-logo__img header-logo__img--light"> 92 </a> 93 94 <ul class="header-navigation"> 95 <li class="header-navigation__item header-navigation__item--sub-nav"> 96 97 <a class="header-navigation__link js-subnav-opener" style="--delay: 0s">Properties</a> 98 99 <ul class="header-navigation__sub-nav"> 100 <li class="header-navigation__sub-nav-item"> 101 <a class="header-navigation__sub-nav-link" href="/properties/sale" >Featured Listings</a> 102 </li> 103 <li class="header-navigation__sub-nav-item"> 104 <a class="header-navigation__sub-nav-link" href="/properties/sold" >Past Transactions</a> 105 </li> 106 </ul> 107 </li> 108 <li class="header-navigation__item "> 109 110 <a class="header-navigation__link " href="/neighborhoods" style="--delay: 0.1s">Neighborhoods</a> 111 </li> 112 <li class="header-navigation__item "> 113 114 <a class="header-navigation__link " href="/home-search/listings" style="--delay: 0.2s">Search Homes</a> 115 </li> 116 <li class="header-navigation__item "> 117 118 <a class="header-navigation__link " href="/home-valuation" style="--delay: 0.30000000000000004s">Home Valuation</a> 119 </li> 120 </ul> 121 122 123 <div class="header-buttons-wrapper"> 124 <a 125 role="button" 126 data-type="CONTACT_US" 127 class="header-contact-btn lp-btn button-style-2" 128 129 130 131 132 133 > 134 Contact Us 135 </a> 136 137 138 139 <button type="button" class="header-hamburger-btn lp-btn hamburger-component hamburger js-sidemenu-opener" 140 title="Toggle Sidemenu"></button> 141 </div> 142 </div> 143 144</header> 145 146 </nav> 147 <div id="global-sidemenu" class="sidemenu" data-el-id="033c3235-a8bd-45bf-a4a8-96977e33190d"> 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164<button class="sidemenu-close toggle close lp-btn lp-icon link-icon--plus"></button> 165 166 167<div class="sidemenu-wrapper sidemenu-wrapper--small" style="--navItemNumberColor: rgba(177, 132, 99, 1);"> 168 <div class="sidemenu-nav-holder "> 169 <ul class="sidemenu-navigation "> 170 <li class="sidemenu-navigation__item js-idemenu-navigation-item "> 171 <a 172 href="/" 173 class="sidemenu-navigation__link">Home</a> 174 175 </li> 176 177 <li class="sidemenu-navigation__item js-idemenu-navigation-item sidemenu-navigation__item--sub-nav">
178 <span class="sidemenu-navigation__link sidemenu-navigation__link--sub-nav sidemenu-navigation__link--sub-nav-active js-sub-nav-opener lp-icon"> 179 ABOUT 180 </span> 181 182 <ul class="sidemenu-navigation-sub-nav lp-a"> 183 <li class="sidemenu-navigation-sub-nav__item"><a href="/team" class="sidemenu-navigation-sub-nav__link">Meet the Team</a></li> 184 <li class="sidemenu-navigation-sub-nav__item"><a href="/testimonials" class="sidemenu-navigation-sub-nav__link">Testimonials</a></li> 185 </ul> 186 </li> 187 188 <li class="sidemenu-navigation__item js-idemenu-navigation-item sidemenu-navigation__item--sub-nav"> 189 <span class="sidemenu-navigation__link sidemenu-navigation__link--sub-nav sidemenu-navigation__link--sub-nav-active js-sub-nav-opener lp-icon"> 190 PROPERTIES 191 </span> 192 193 <ul class="sidemenu-navigation-sub-nav lp-a"> 194 <li class="sidemenu-navigation-sub-nav__item"><a href="/properties/sale" class="sidemenu-navigation-sub-nav__link">Featured Listings</a></li> 195 <li class="sidemenu-navigation-sub-nav__item"><a href="/properties/sold" class="sidemenu-navigation-sub-nav__link">Past Transactions</a></li> 196 </ul> 197 </li> 198 199 </ul> 200 201 <ul class="sidemenu-navigation "> 202 <li class="sidemenu-navigation__item js-idemenu-navigation-item "> 203 <a 204 href="/home-search" 205 class="sidemenu-navigation__link">Home Search</a> 206 207 </li> 208 209 <li class="sidemenu-navigation__item js-idemenu-navigation-item "> 210 <a 211 href="/home-valuation" 212 class="sidemenu-navigation__link">Home Valuation</a> 213 214 </li> 215 216 <li class="sidemenu-navigation__item js-idemenu-navigation-item "> 217 <a 218 href="/neighborhoods" 219 class="sidemenu-navigation__link">Neighborhoods</a> 220 221 </li> 222 223 </ul> 224 225 <ul class="sidemenu-navigation "> 226 <li class="sidemenu-navigation__item js-idemenu-navigation-item "> 227 <a 228 href="/compass-concierge" 229 class="sidemenu-navigation__link">Compass Concierge</a> 230 231 </li> 232 233 <li class="sidemenu-navigation__item js-idemenu-navigation-item "> 234 <a 235 href="/blog" 236 class="sidemenu-navigation__link">Blog</a> 237 238 </li> 239 240 <li class="sidemenu-navigation__item js-idemenu-navigation-item "> 241 <a 242 href="/contact" 243 class="sidemenu-navigation__link">Contact Us</a> 244 245 </li> 246 247 </ul> 248 249 <ul class="sidemenu-navigation "> 250 <li class="sidemenu-navigation__item js-idemenu-navigation-item "> 251 <a 252 href="/home-search/auth/sign_in" 253 class="sidemenu-navigation__link">My Search Portal</a> 254 255 </li> 256 257 </ul> 258 </div> 259 260 <div class="sidemenu-footer"> 261 <div class="sidemenu__info-group sidemenu__col"> 262 <div class="sidemenu__section-content"> 263 <div class="sidemenu__col-content"> 264 <p class="sidemenu__col-title">Address</p><div class="sidemenu__col-description lp-a"> 265 <p class="sidemenu__col-agent-name"></p> 266 <a href="tel:2555802" class="sidemenu__col-phone">2555 Ala Namahana Pkwy Unit 802 </a> 267 <a href="/cdn-cgi/l/email-protection#90b0dbf9fcf1e5f5f1bcb0
267d8d9b0a9a6a7a5a4" class="sidemenu__col-email"> Kilauea, HI 96754</a> 268 </div> 269 </div> 270 <div class="sidemenu__col-content"> 271 <div class="sidemenu__col-description lp-a sidemenu__col-description--pre-line"><p><strong>DANETTE ANDREWS</strong></p> 272 <p><a href="tel:(808)%20635-7019">(808) 635-7019</a></p> 273 <p><a href="/cdn-cgi/l/email-protection#ee8a8f808b9a9a8bae8f808a9c8b999d858f9b8f87c08d8183"><span class="__cf_email__" data-cfemail="c0a4a1aea5b4b4a580a1aea4b2a5b7b3aba1b5a1a9eea3afad">[email protected]</span></a></p> 274 <p> </p> 275 <p><strong>CODY ANDREWS</strong></p> 276 <p><a href="tel:(808) 635-2604">(808) 635-2604</a></p> 277 <p><a href="/cdn-cgi/l/email-protection#93f0fcf7ead3f2fdf7e1f6e4e0f8f2e6f2fabdf0fcfe"><span class="__cf_email__" data-cfemail="492a262d300928272d3b2c3e3a22283c2820672a2624">[email protected]</span></a></p></div> 278 279 </div> 280 </div> 281 282 </div> 283 284 <div class="sidemenu-socials-block"> 285 <p class="sidemenu__col-title">Follow Us</p> 286 <ul class="lp-socials social_icons-style-1"> 287 288 <li> 289 <a 290 href="https://www.facebook.com/danetteandrewskauai/" 291 class="lp-socials__link" 292 data-wow-delay="0s" 293 target="_blank" 294 aria-label="FACEBOOK" 295 > 296 <span class="lp-i lp-i--facebook" aria-hidden="true"></span> 297 </a> 298 </li> 299 <li> 300 <a 301 href="https://www.instagram.com/danetteandrewsrealestate/" 302 class="lp-socials__link" 303 data-wow-delay="0.1s" 304 target="_blank" 305 aria-label="INSTAGRAM" 306 > 307 <span class="lp-i lp-i--instagram" aria-hidden="true"></span> 308 </a> 309 </li> 310 <li> 311 <a 312 href="https://www.linkedin.com/in/danetteandrews/" 313 class="lp-socials__link" 314 data-wow-delay="0.2s" 315 target="_blank" 316 aria-label="LINKEDIN" 317 > 318 <span class="lp-i lp-i--linkedin" aria-hidden="true"></span> 319 </a> 320 </li> 321 </ul> </div> 322 </div> 323</div> 324 </div> 325 <div id="global-mobile-contact" class="mobile-contact-wrapper" data-el-id="4c08210d-8fa1-4e4b-ad13-3209994c2ceb"> 326 <div class="floating-contact-button"> 327 <div class="floating-contact-button__btn-holder js-btn-holder" 328 style="--backgroundColor: rgba(0, 0, 0, 1); --textColor: rgba(255, 255, 255, 1); --pillTextColor: rgba(255, 255, 255, 1); --pillBackgroundColor: rgba(0, 0, 0, 1);"> 329 <button type="button" class="floating-contact-button__btn-connect js-btn-connect lp-icon lp-ico-arrow-top">CONTACT US</button> 330 </div> 331 332 <div class="floating-contact-button-pop-up js-pop-up" style="--backgroundColor: rgba(0, 0, 0, 1); --textColor: rgba(255, 255, 255, 1);"> 333 <form class="floating-contact-button-pop-up__form js-form" data-type="contact-form"> 334 <h3 class="floating-contact-button-pop-up__title">Leave a Message</h3> 335 336 <div class="floating-contact-button-pop-up__input-group lp-input-group"> 337 <input id="__FullName" type="text" name="name"
338 class="lp-input js-input-name lp-input--light" 339 required placeholder="Full Name"> 340 </div> 341 342 <div class="floating-contact-button-pop-up__input-group lp-input-group"> 343 <input id="__Email" type="email" name="email" 344 class="lp-input js-email-input " 345 required placeholder="Email"> 346 </div> 347 348 <div class="floating-contact-button-pop-up__input-group lp-input-group"> 349 <input class="lp-input " type="tel" placeholder="Phone" id="__Phone" 350 name="phone" required> 351 </div> 352 353 <select name="interest" id="-field-interest" 354 class="floating-contact-button-pop-up__input-group lp-input js-select " required> 355 <option value="" selected disabled data-label="Interest">Interested in...</option> 356 <option value="Selling & Buying">Selling & Buying</option> 357 <option value="Selling">Selling</option> 358 <option value="Buying">Buying</option> 359 <option value="Renting">Renting</option> 360 <option value="Other">Other</option> 361 <label for="-field-interest" class="lp-label sr-only">Interest</label> 362 </select> 363 364 <div class="floating-contact-button-pop-up__input-group lp-input-group"> 365 <textarea name="message" rows="4" id="__Message" class="lp-input " 366 placeholder="Message" required></textarea> 367 </div> 368 369 <div class="lp-disclaimer"> <label style='display: none;' for='-termsAccepted'>Opt In/Disclaimer Consent:</label> 370 <label class='lp-tcr-content'> 371 <span class='lp-tcr-checkbox'> 372 <input 373 type='checkbox' 374 id='-termsAccepted' 375 name='termsAccepted' 376 oninvalid="this.setCustomValidity('Please accept the terms and conditions')" 377 oninput="this.setCustomValidity('')" 378 required 379 /></span> 380 <span class='lp-tcr-message'> 381 382 I agree to be contacted by 383 Andrews Collection 384 via call, email, and text for real estate services. To opt out, you can reply 'stop' at any time or reply 'help' for assistance. 385 You can also click the unsubscribe link in the emails. Message and data rates may apply. Message frequency may vary. 386 <a href='/terms-and-conditions' target='_blank'>Privacy Policy</a>. 387 </span> 388 </label> 389 390</div> 391 392 <button type="submit" class="floating-contact-button-pop-up__btn-submit lp-btn lp-btn--mob-full-width button-style-2">Submit</button> 393 394 <div class="lp-h-pot"> 395 <input id="__newsSignMiddleName" name="middleName" value="" autocomplete="off" 396 tabindex="-1"> 397 </div> 398 <input style="display: none;" type="text" name="source" value="CONTACT_INQUIRY" /> 399 <input type="hidden" name="button_text" value="CONTACT US"> 400 </form> 401 402 <div class="floating-contact-button-pop-up__success js-success"> 403 <h3 class="floating-contact-button-pop-up__title">Thank you for your message. We will be in touch with you shortly.</h3> 404 405 <a 406 href="/properties/sale" 407 408 class="lp-btn floating-contact-button-pop-up__success-btn button-style-2" 409 410 411 412 413 414 > 415 Explore Our Properties 416 </a> 417 </div> 418 <button type="button" class="floating-contact-button-pop-up__close js-close-btn lp-icon"></button> 419 </div> 420 421</div> 422 423 </div> 424 <section class="image-section is-font-color-light is-background-color-light" id="section-771ca4c0-dfe5-4a13-818a-e283d65c7e1f" data-el-id="d1637c2a-e69e-42d9-8d39-7fe5c68c7ee9"> 425 <div class="custom-intro js-scroll-section custom-intro__horizon-center" 426 style=" 427 --titleColor: rgba(177, 132, 99, 1); 428 --boxBackColor: rgba(26, 26, 26, 1); 429 --backOverlayColor: rgba(255, 255, 255, 1); 430 " 431 > 432 <div class="custom-intro__container"> 433 <div class="custom-intro__content-wrapper"> 434 <div class="custom-intro__content-box"> 435 <div class="custom-intro__pre-title lp-text--pretitle">Current</div> 436 <h1 class="custom-intro__title custom-intro__title--with-pretitle">Featured Properties</h1> 437 <div class="custom-intro__scroll-btn jsScrollBtn"></div> 438 </div> 439 </div> 440 </div> 441</div> 442 443</section> 444<section id="section-055f7306-112d-4d27-8914-cafe3745ec53" class="solid-section is-font-color-dark is-background-color-light" data-el-id="194f7b4b-fe39-4449-93f2-7e4994a1baa6">
vendor: 111 bytes, lines 444-445
444 445 <script data-cfasync="false" src="/cdn-cgi/scripts/5c5dd728/cloudflare-static/email-decode.min.js"></script>
445<script src="https://cdnjs.cloudflare.com/ajax/libs/noUiSlider/15.8.1/nouislider.min.js" integrity="sha512-g/feAizmeiVKSwvfW0Xk3ZHZqv5Zs8PEXEBKzL15pM0SevEvoX8eJ4yFWbqakvRj7vtw1Q97bLzEpG2IVWX0Mg==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
445 446<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/noUiSlider/15.8.1/nouislider.css" integrity="sha512-MKxcSu/LDtbIYHBNAWUQwfB3iVoG9xeMCm32QV5hZ/9lFaQZJVaXfz9aFa0IZExWzCpm7OWvp9zq9gVip/nLMg==" crossorigin="anonymous" referrerpolicy="no-referrer" /> 447 448
449<script type="text/x-handlebars-template" class="propertyItem pagination-script"> <a href="{{#if fromMLS}}/home-search/listings/{{id}}{{else}}/properties/{{slug}}{{/if}}" class="properties-list-item"> 450 <div class="properties-list-item__image-container lp_animation-img-zoom"> 451 <span class="properties-list-item__tag lp-tag">{{formatPropertyStatus status false (hbFormatDate soldDate)}}</span> 452 {{#if openHouseHours}} 453 <span class="properties-list-item__open-houses lp-tag">Open House: {{openHouseHours}}</span> 454 {{/if}} 455 {{{mediaImage media.[0] alt=name width="400" height="270" class="properties-list-item__image"}}} 456 </div> 457 458 <div class="properties-list-item__info"> 459 460 <div class="properties-list-item__top-block"> 461 <p class="properties-list-item__address">{{#if privateAddress}}Private Address{{else}}{{fullAddress}}{{/if}}</p> 462 <h4 class="properties-list-item__price">{{formatPropertyPrice this}}</h4> 463 464 {{#if (or bedroomCount livingSpaceSize bathCount fullBathCount halfBathCount threeQuarterBathCount)}} 465 <div class="properties-list-item__icons-row"> 466 {{#if bedroomCount}} 467 <div class="properties-list-item__icon-tag lp-tag lp-icon icon-bed">{{bedroomCount}} Bed{{#numCompare bedroomCount 1 ">"}}s{{/numCompare}}</div> 468 {{/if}} 469 470 {{#if bathCount}} 471 <div class="properties-list-item__icon-tag lp-tag lp-icon icon-bath">{{bathCount}} Bath{{#numCompare bathCount 1 ">"}}s{{/numCompare}}</div> 472 {{/if}} 473 474 {{#if livingSpaceSize}} 475 <div class="properties-list-item__icon-tag lp-tag lp-icon icon-sqft">{{lpFormatNumber livingSpaceSize}} {{formatAreaUnit livingSpaceUnits}}</div> 476 {{/if}} 477 </div> 478 {{/if}} 479 </div> 480 481 <div class="properties-list-item__bottom-block"> 482 {{#if description}} 483 <p class="properties-list-item__bottom-label">Property description</p> 484 <p class="properties-list-item__description">{{{truncate (striptags description) 200 '...'}}}</p> 485 {{/if}} 486 <span class="properties-list-item__btn lp-btn button-style-1">Property Details</span> 487 </div> 488 489 </div> 490 </a> 491</script>
491 492 493 <div class="properties-list lp-vertical-paddings" style="--titleColor: rgba(0, 0, 0, 1);"> 494 495 496 497 <span class="properties-list__show-btn show-btn lp-btn js-show-filter"><span>Show Filters <span class="properties-list__selected-filters js-selected-filters">0</span></span> <span class="properties-list__btn-icon lp-icon lp-icon-arrow"></span></span> 498 <span class="properties-list__hide-btn hide-btn lp-btn js-hide-filter">Hide Filters <span class="properties-list__btn-icon lp-icon lp-icon-arrow"></span></span> 499 500 <div class="properties-list__filters filters search-container" data-fetch-neighborhoods="true" data-fetch-rental-rates="true" aria-labelledby="filtersTitle"> 501 <input name="companyId" type="hidden" value="c1908ce5-efe4-423f-a0b8-f9e844db2413" /> 502 503 <div class="properties-list__input-row"> 504 <div class="properties-list__input-group properties-list__input-group--search lp-input-group lp-input-group--search lp-input--with-icon"> 505 <input type="text" class="properties-list__input lp-input" placeholder="Search by address" id="section-055f7306-112d-4d27-8914-cafe3745ec53-search-input" name="search-input"> 506 <span class="properties-list__input-icon lp-icon lp-input-icon lp-input-icon--search"></span> 507 </div> 508 509 <div class="properties-list__input-group properties-list__input-group--neighborhood lp-input-group js-neighborhoods-select-holder"> 510 <select id="section-055f7306-112d-4d27-8914-cafe3745ec53-neighborhood" name="neighborhood-select" class="properties-list__dropdown-select lp-input dropdown-select js-neighborhoods-select"> 511 <option value="" selected disabled hidden data-label="Select neighborhood">Select neighborhood</option> 512 </select> 513 <label class="properties-list__label lp-label" for="section-055f7306-112d-4d27-8914-cafe3745ec53-neighborhood" style="display: none">Select neighborhood</label> 514 </div> 515 516 <div class="properties-list__input-group properties-list__input-group--rental-rates lp-input-group js-rental-rates-select-holder"> 517 <select id="section-055f7306-112d-4d27-8914-cafe3745ec53-seasonal-price" name="seasonal-price" class="properties-list__dropdown-select lp-input dropdown-select js-rental-rates-select"> 518 <option value="" selected disabled hidden data-label="Rental availability">Rental availability</option> 519 </select> 520 <label class="properties-list__label lp-label" for="section-055f7306-112d-4d27-8914-cafe3745ec53-seasonal-price" style="display: none">Rental availability</label> 521 </div> 522 </div> 523 524 <div class="properties-list-range__row"> 525 526 <div class="properties-list-range__slider-group"> 527 <div class="properties-list-range__block"> 528 <span class="properties-list-range__label">Sales Price</span> 529 <div class="properties-list-range__range"> 530 <span class="js-price-slider-min properties-list-range__min"></span> 531 <span class="js-price-slider-max properties-list-range__max"></span> 532 <div class="js-price-slider" data-min="1000000" data-max="25000000" data-step="100000"></div> 533 </div> 534 </div> 535 <div class="properties-list-range__block"> 536 <span class="properties-list-range__label paragraph--14">Sq. Ft.</span> 537 <div class="properties-list-range__range"> 538 <span class="js-area-slider-min properties-list-range__min"></span> 539 <span class="js-area-slider-max properties-list-range__max"></span> 540 <div class="js-area-slider" data-min="500" data-max="10000" data-step="500"></div> 541 </div> 542 </div> 543 </div> 544 545 <div> 546 <button type="button" class="properties-list-range__reset js-reset" aria-label="Clear search">Clear <span class="lp-icon"></span></button> 547 </div> 548 </div> 549 </div> 550 551 <div class="properties-list__collection data-container"> 552 <a href="/properties/2838-kapoli-st-kealia-hi-us-96751-731952" class="properties-list-item"> 553 <div class="properties-list-item__image-container lp_animation-img-zoom">
554 <span class="properties-list-item__tag lp-tag">For Sale</span> 555 <img src="https://dlajgvw9htjpb.cloudfront.net/cms/c1908ce5-efe4-423f-a0b8-f9e844db2413/731952/27822266011115116.jpg" class="properties-list-item__image" height="270" width="400" alt="Modern coastal home with a swimming pool and expansive lawn overlooking a sandy beach and ocean." loading="lazy"> 556 </div> 557 558 <div class="properties-list-item__info"> 559 560 <div class="properties-list-item__top-block"> 561 <p class="properties-list-item__address">2838 KAPOLI ST, Kealia, HI 96751</p> 562 <h4 class="properties-list-item__price">$21,000,000</h4> 563 564 <div class="properties-list-item__icons-row"> 565 <div class="properties-list-item__icon-tag lp-tag lp-icon icon-bed">4 Beds</div> 566 567 <div class="properties-list-item__icon-tag lp-tag lp-icon icon-bath">6 Baths</div> 568 569 <div class="properties-list-item__icon-tag lp-tag lp-icon icon-sqft">6,003 Sq.Ft.</div> 570 </div> 571 </div> 572 573 <div class="properties-list-item__bottom-block"> 574 <p class="properties-list-item__bottom-label">Property description</p> 575 <p class="properties-list-item__description">Experience the pinnacle of luxury living at 2838 Kapoli St in the exclusive Kealia Kai subdivision. This brand-new, nearly oceanfront estate showcases unmatched craftsmanship, custom designer furni...</p> 576 <span class="properties-list-item__btn lp-btn button-style-1">Property Details</span> 577 </div> 578 579 </div> 580 </a> 581 <a href="/properties/4114-waha-rd-j-kalaheo-hi-us-96741-727977" class="properties-list-item"> 582 <div class="properties-list-item__image-container lp_animation-img-zoom"> 583 <span class="properties-list-item__tag lp-tag">For Sale</span> 584 <img src="https://dlajgvw9htjpb.cloudfront.net/cms/c1908ce5-efe4-423f-a0b8-f9e844db2413/727977/1187153561396382705.jpg" class="properties-list-item__image" height="270" width="400" alt="Large red-tile-roof home on a manicured lawn amid tropical greenery, with the ocean on the horizon." loading="lazy"> 585 </div> 586 587 <div class="properties-list-item__info"> 588 589 <div class="properties-list-item__top-block"> 590 <p class="properties-list-item__address">4114 WAHA RD J, Kalaheo, HI 96741</p> 591 <h4 class="properties-list-item__price">$7,395,000</h4> 592 593 <div class="properties-list-item__icons-row"> 594 <div class="properties-list-item__icon-tag lp-tag lp-icon icon-bed">6 Beds</div> 595 596 <div class="properties-list-item__icon-tag lp-tag lp-icon icon-bath">5 Baths</div> 597 598 <div class="properties-list-item__icon-tag lp-tag lp-icon icon-sqft">7,601 Sq.Ft.</div> 599 </div> 600 </div> 601 602 <div class="properties-list-item__bottom-block"> 603 <p class="properties-list-item__bottom-label">Property description</p> 604 <p class="properties-list-item__description">Set high above the verdant Lawai Valley and embraced on three sides by the renowned National Tropical Botanical Garden, Hale o ka Lani is an extraordinary 5.57-acre estate offering sweeping ocean a...</p> 605 <span class="properties-list-item__btn lp-btn button-style-1">Property Details</span> 606 </div> 607 608 </div> 609 </a> 610 <a href="/properties/7465-c-koolau-road-kilauea-hi-us-96754-715966" class="properties-list-item"> 611 <div class="properties-list-item__image-container lp_animation-img-zoom"> 612 <span class="properties-list-item__tag lp-tag">For Sale</span> 613 <img src="https://dlajgvw9htjpb.cloudfront.net/cms/c1908ce5-efe4-423f-a0b8-f9e844db2413/715966/-8789901732529132721.jpg" class="properties-list-item__image" height="270" width="400" alt="Aerial view of a sprawling home and pool on green grounds overlooking the ocean." loading="lazy"> 614 </div> 615 616 <div class="properties-list-item__info"> 617 618 <div class="properties-list-item__top-block"> 619 <p class="properties-list-item__address">7465-C Koolau Road, Kilauea, HI 96754</p> 620 <h4 class="properties-list-item__price">$5,600,000</h4> 621 622 <div class="properties-list-item__icons-row"> 623 <div class="properties-list-item__icon-tag lp-tag lp-icon icon-bed">4 Beds</div> 624 625 <div class="properties-list-item__icon-tag lp-tag lp-icon icon-bath">4 Baths</div> 626 627 <div class="properties-list-item__icon-tag lp-tag lp-icon icon-sqft">2,192 Sq.Ft.</div> 628 </div> 629 </div> 630 631 <div class="properties-list-item__bottom-block"> 632 <p class="properties-list-item__bottom-label">Property description</p> 633 <p class="properties-list-item__description">Designed by Santo Giorgio and built in 2017, this stunning home is a masterpiece of Hawaii's contemporary plantation-style architecture. Situated on nearly 3 acres and bordering 500 acres of ranch ...</p>
634 <span class="properties-list-item__btn lp-btn button-style-1">Property Details</span> 635 </div> 636 637 </div> 638 </a> 639 </div> 640 641 <div class="pagination-container pagination-style-1"></div> 642 </div> 643 644 645 646</section> 647<section class="image-section is-font-color-light is-background-color-light" id="section-4510a72a-a320-4493-886b-c8947b75a60f" data-el-id="1ed7f92a-2189-48c5-889c-3838656da504"> 648 <div class="newsletter-contact-cta lp-vertical-paddings" 649 style=" 650 --titleColorFirst: rgba(0, 0, 0, 1); 651 --newsletterBack: rgba(255, 255, 255, 0.9); 652 --titleColorSecond: rgba(255, 255, 255, 1); 653 --workWithBack: rgba(0, 0, 0, 0.9); 654 --newsletterTextColor: rgba(0, 0, 0, 1); 655 --rightBack: rgba(255, 255, 255, 0); 656 " 657> 658 <div class="newsletter-contact-cta__right-back"></div> 659 <div class="newsletter-contact-cta__container lp-container"> 660 <div class="newsletter-contact-cta__wrapper"> 661 <div class="newsletter-contact-cta__block newsletter-contact-cta__block--newsletter"> 662 <div class="newsletter-contact-cta__heading"> 663 <div class="newsletter-contact-cta__pre-title newsletter-contact-cta__pre-title--newsletter lp-text--pretitle">Market Trends & Tips</div> 664 <h2 class="newsletter-contact-cta__title newsletter-contact-cta__title--newsletter newsletter-contact-cta__title--with-pretitle">Newsletter</h2> 665 <div class="newsletter-contact-cta__description"><p data-start="852" data-end="1126">Sign up to receive the latest market updates, listings, and advice from the Andrews Collection to make informed decisions.</p></div> 666 </div> 667 <form data-type="contact-form" class="newsletter-contact-cta__form"> 668 <div class="newsletter-contact-cta__form-wrapper"> 669 <div class="newsletter-contact-cta__input-group lp-input-group"> 670 <div class="h-pot"> 671 <label for="section-4510a72a-a320-4493-886b-c8947b75a60f-middleName">Middle Name</label> 672 <input 673 id="section-4510a72a-a320-4493-886b-c8947b75a60f-middleName" 674 name="middleName" 675 value="" 676 autocomplete="off" 677 tabindex="-1" 678 /> 679 </div> 680 <label for="section-4510a72a-a320-4493-886b-c8947b75a60f__wwu-email" class="newsletter-contact-cta__label lp-label">Enter Your Email Address</label> 681 <input 682 id="section-4510a72a-a320-4493-886b-c8947b75a60f__wwu-email" 683 name="email" 684 type="email" 685 class="newsletter-contact-cta__text-input lp-input" 686 required 687 placeholder="Enter Your Email Address" 688 pattern="[a-zA-Z0-9.!#$%&â*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)+" 689 /> 690 <div class="lp-icon lp-input-icon lp-input-icon--mail"></div> 691 </div> 692 <div class="newsletter-contact-cta__disclaimer lp-disclaimer"> <label style='display: none;' for='section-4510a72a-a320-4493-886b-c8947b75a60f-termsAccepted'>Opt In/Disclaimer Consent:</label> 693 <label class='lp-tcr-content'> 694 <span class='lp-tcr-checkbox'> 695 <input 696 type='checkbox' 697 id='section-4510a72a-a320-4493-886b-c8947b75a60f-termsAccepted' 698 name='termsAccepted' 699 oninvalid="this.setCustomValidity('Please accept the terms and conditions')"
700 oninput="this.setCustomValidity('')" 701 required 702 /></span> 703 <span class='lp-tcr-message'> 704 705 I agree to be contacted by 706 Andrews Collection 707 via call, email, and text for real estate services. To opt out, you can reply 'stop' at any time or reply 'help' for assistance. 708 You can also click the unsubscribe link in the emails. Message and data rates may apply. Message frequency may vary. 709 <a href='/terms-and-conditions' target='_blank'>Privacy Policy</a>. 710 </span> 711 </label> 712 713</div> 714 <input style="display: none;" type="text" name="source" value="NEWSLETTER_SIGNUP" /> 715 <button type="submit" class="newsletter-contact-cta__btn lp-btn lp-btn--mob-full-width lp-icon button-style-1"> 716 <span class="lp-btn__content">Subscribe</span> 717 </button> 718 </div> 719 </form> 720 </div> 721 <div class="newsletter-contact-cta__block newsletter-contact-cta__block--touch"> 722 <div class="newsletter-contact-cta__heading"> 723 <div class="newsletter-contact-cta__pre-title newsletter-contact-cta__pre-title--touch lp-text--pretitle">Partner with Local Experts</div> 724 <h2 class="newsletter-contact-cta__title newsletter-contact-cta__title--touch newsletter-contact-cta__title--with-pretitle">Work With Us</h2> 725 <div class="newsletter-contact-cta__description"><p>Whether you’re buying your dream home or selling a Kilauea property, our team combines deep local knowledge, professional service, and proven results to make your real estate journey seamless and successful.</p></div> 726 </div> 727 <div class="newsletter-contact-cta__btn-wrap"> 728 <a 729 role="button" 730 data-type="CONTACT_US" 731 class="newsletter-contact-cta__btn lp-btn button-style-2" 732 733 734 735 736 737 > 738 <span class="lp-btn__content">Contact Us</span> 739 </a> 740 </div> 741 <div class="newsletter-contact-cta__word-divide"><span class="newsletter-contact-cta__word-word">or</span></div> 742 <div class="newsletter-contact-cta__call-cell"> 743 <span class="newsletter-contact-cta__prefix-cell">Call us at</span> 744 <a 745 href="tel:8086357019" 746 class="newsletter-contact-cta__link lp-a lp-link hyperlink-style-2" 747 > 748 <span class="newsletter-contact-cta__phone-wrapper lp-icon link-icon--phone"></span> 749 (808) 635-7019 750 </a> 751 </div> 752 </div> 753 </div> 754 </div> 755</div> 756</section> 757<section id="section-f6b2e0c9-5dd7-43a4-8086-a51ab775df71" class="solid-section is-font-color-dark is-background-color-light" data-el-id="85dc9e17-a4c7-449c-8890-869fdc11b485"> 758 <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@splidejs/[email protected]/dist/css/splide-core.min.css"/>
759<script src="https://cdn.jsdelivr.net/npm/@splidejs/[email protected]/dist/js/splide.min.js"></script>
vendor: 1 bytes, line 759
759
760<script type="text/x-handlebars-template" class="jsIGTemplate"> 761 {{#each items}} 762 <a href="{{permalink}}" target="_blank" class="instagram-feed__item lp_animation-img-zoom splide__slide insta-item insta-type-{{mediaType}}"> 763 <img class="instagram-feed__image" src="{{#ifEquals mediaType 'VIDEO'}}{{thumbnailUrl}}{{else}}{{mediaUrl}}{{/ifEquals}}" alt="Instagram post by @{{username}}"> 764 </a> 765 {{/each}} 766</script>
766 767 768<div class="instagram-feed lp-vertical-paddings"> 769 <div class="instagram-feed__container" style="--titleColor: #B18463; --boxColor: rgba(238, 237, 233, 1);"> 770 <div class="instagram-feed__title-group lp-title-group"> 771 <div class="instagram-feed__icon lp-icon"></div> 772 <p class="instagram-feed__pretitle">Follow Us On Instagram</p> 773 <h2 class="instagram-feed__title instagram-feed__title--with-pretitle"><a href="#" target="_blank" class="instagram-feed__link jsIGLink jsIGName"></a></h2> 774 </div> 775 776 <div class="instagram-feed__collection splide js-slider"> 777 <div class="splide__track"> 778 <ul class="splide__list jsIGContainer"> 779 </ul> 780 </div> 781 </div> 782 </div> 783</div> 784 785 786 787 788</section> 789 790 <div id="modals" class="modals"></div> 791 <footer id="global-footer" class="is-font-color-dark is-background-color-light" data-el-id="b8c9ffd0-3b1f-4577-96fc-828efdac86e7"> 792 793 794<div class="footer"> 795 <div class="footer-logos-row"> 796 <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/fe02419d-7253-4ccc-8bd2-78b2e27ca10b" srcset="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/fe02419d-7253-4ccc-8bd2-78b2e27ca10b 320w, 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/fe02419d-7253-4ccc-8bd2-78b2e27ca10b 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/fe02419d-7253-4ccc-8bd2-78b2e27ca10b 1280w, 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/fe02419d-7253-4ccc-8bd2-78b2e27ca10b 1920w, https://media-production.lp-cdn.com/cdn-cgi/image/format=auto,quality=85,fit=scale-down,width=2560/https://media-production.lp-cdn.com/media/fe02419d-7253-4ccc-8bd2-78b2e27ca10b 2560w, https://media-production.lp-cdn.com/cdn-cgi/image/format=auto,quality=85,fit=scale-down,width=3456/https://media-production.lp-cdn.com/media/fe02419d-7253-4ccc-8bd2-78b2e27ca10b 3456w" class="footer-logo" sizes="350px" alt="Danette Andrews and Compass"> 797 798 </div> 799 <div class="footer-contact-row"> 800 <div class="footer-info footer-info--two-agents"> 801 <div class="footer__col"> 802 <h5 class="footer__section-title">DANETTE ANDREWS</h5> 803 <div class="footer__section-content"> 804 <div class="footer__col-content"> 805 <p class="footer__col-title">Contact</p> <div class="footer__col-description lp-a lp-pre-line"><div><a href="tel:(808) 635-7019">(808) 635-7019</a><br><a href="/cdn-cgi/l/email-protection#1c787d72796868795c7d72786e796b6f777d697d75327f7371"><span class="__cf_email__" data-cfemail="0c686d62697878694c6d62687e697b7f676d796d65226f6361">[email protected]</span></a></div></div> 806 </div> 807 808 <div class="footer__col-content"> 809 <p class="footer__col-title">Office</p> <div class="footer__col-description lp-a lp-pre-line"><p>2555 Ala Namahana Pkwy Unit 802 <br>Kilauea, HI 96754</p></div> 810 </div> 811 </div> 812 </div> 813 814 815 816 <div class="footer__col"> 817 <h5 class="footer__section-title">CODY ANDREWS</h5> 818 <div class="footer__section-content"> 819 <div class="footer__col-content"> 820 <p class="footer__col-title">CONTACT</p>
820 <div class="footer__col-description lp-a lp-pre-line"><div><a class="hyperlink-style-1" href="tel:(808) 635-2604">(808) 635-2604</a></div> 821 <div><a href="/cdn-cgi/l/email-protection#53303c372a13323d3721362420383226323a7d303c3e"><span class="__cf_email__" data-cfemail="04676b607d44656a60766173776f6571656d2a676b69">[email protected]</span></a></div> 822 <div> </div></div> 823 </div> 824 825 </div> 826 </div> 827 </div> 828 829 <ul class="lp-socials social_icons-style-1 footer-socials"> 830 831 <li> 832 <a 833 href="https://www.facebook.com/danetteandrewskauai/" 834 class="lp-socials__link socials__link" 835 data-wow-delay="0s" 836 target="_blank" 837 aria-label="FACEBOOK" 838 > 839 <span class="lp-i lp-i--facebook" aria-hidden="true"></span> 840 </a> 841 </li> 842 <li> 843 <a 844 href="https://www.instagram.com/danetteandrewsrealestate/" 845 class="lp-socials__link socials__link" 846 data-wow-delay="0.1s" 847 target="_blank" 848 aria-label="INSTAGRAM" 849 > 850 <span class="lp-i lp-i--instagram" aria-hidden="true"></span> 851 </a> 852 </li> 853 <li> 854 <a 855 href="https://www.linkedin.com/in/danetteandrews/" 856 class="lp-socials__link socials__link" 857 data-wow-delay="0.2s" 858 target="_blank" 859 aria-label="LINKEDIN" 860 > 861 <span class="lp-i lp-i--linkedin" aria-hidden="true"></span> 862 </a> 863 </li> 864 </ul> </div> 865 866 867 <div class="footer-navigation-row"> 868 <p class="footer-navigation-title">navigation</p> 869 870 <ul class="footer-navigation lp-a"> 871 <li class="footer-navigation__item"> 872 <a href="/properties/sale" class="footer-navigation__link ">Featured Properties</a> 873 874 </li> 875 <li class="footer-navigation__item"> 876 <a href="/neighborhoods" class="footer-navigation__link ">Neighborhoods</a> 877 878 </li> 879 <li class="footer-navigation__item"> 880 <a href="/home-valuation" class="footer-navigation__link ">Home Valuation</a> 881 882 </li> 883 <li class="footer-navigation__item"> 884 <a href="/contact" class="footer-navigation__link ">Contact Us</a> 885 886 </li> 887 </ul> 888 </div> 889 890 891 892 <div class="footer-disclaimer-row"> 893 <div class="footer-disclaimer"><p style="font-size: 12px;">Andrews Collection is a team of real estate licensees affiliated with Compass, is a licensed real estate broker and abides by equal housing opportunity laws. All material presented herein is intended for informational purposes only. Information is compiled from sources deemed reliable but is subject to errors, omissions, changes in price, condition, sale, or withdrawal without notice. No statement is made as to accuracy of any description. All measurements and square footages are approximate. This is not intended to solicit property already listed. Nothing herein shall be construed as legal, accounting or other professional advice outside the realm of real estate brokerage.<br><img style="margin-top: 10px;" src="https://res.cloudinary.com/luxuryp/images/f_auto,q_auto/g5qzbyky8ifp5w0ex0ik/realtor-eho-logo-07232021-update-dark" width="100px;"></p></div> 894 895 896 </div> 897 898 899 <div class="footer-bottom-row"> 900 <img src="https://media-production.lp-cdn.com/cdn-cgi/image/format=auto,quality=85/https://media-production.lp-cdn.com/media/jnymuan6tigs629jigsz" srcset="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/jnymuan6tigs629jigsz 320w, https://media-production.lp-cdn.com/cdn-cgi/image/format=auto,quality=85/https://media-production.lp-cdn.com/media/jnymuan6tigs629jigsz 390w" class="footer-logo" sizes="350px" alt=""> 901 902 <div class="footer-copyright lp-a"> 903 <div class="footer-copyright__powered"> 904 Powered by <a href="https://www.luxurypresence.com/" class="" target="_blank">Luxury Presence</a> 905 </div> 906 907 <div class="footer-copyright__privacy">
908 <span>Copyright © <span class="auto-year-update">2026</span></span> 909 910 911 <a href="/terms-and-conditions" class="footer-copyright__privacy-policy">Privacy Policy</a> 912 </div> 913 </div> 914 </div> 915 916</div> 917 918 </footer> 919 920 <div id="modal-global-contact-us" class="modal " 921 data-el-id="" 922 style="background-color: ;" 923 > 924 <div class="modal-content"> 925 926 927 <div class="contact-form-modal lp-vertical-paddings" style="--leftPanelBgColor: rgba(0, 0, 0, 1); --textColor:rgba(255, 255, 255, 1); --formBgColor: rgba(255, 255, 255, 1); --formTextColor: rgba(0, 0, 0, 1)"> 928 <div class="contact-form-modal__bg"> 929 <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/5517869e-0fc4-45b3-bc3c-173b72c39dec" srcset="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/5517869e-0fc4-45b3-bc3c-173b72c39dec 320w, 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/5517869e-0fc4-45b3-bc3c-173b72c39dec 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/5517869e-0fc4-45b3-bc3c-173b72c39dec 1280w, 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/5517869e-0fc4-45b3-bc3c-173b72c39dec 1920w, https://media-production.lp-cdn.com/cdn-cgi/image/format=auto,quality=85,fit=scale-down,width=2560/https://media-production.lp-cdn.com/media/5517869e-0fc4-45b3-bc3c-173b72c39dec 2560w, https://media-production.lp-cdn.com/cdn-cgi/image/format=auto,quality=85,fit=scale-down,width=3456/https://media-production.lp-cdn.com/media/5517869e-0fc4-45b3-bc3c-173b72c39dec 3456w" sizes="(min-width: 1981px) 12.2222vw, (min-width: 1025px) 424px, 100vw" class="contact-form-modal__bg-image portrait" alt=""> 930 </div> 931 <div class="contact-form-modal__close-container"> 932 <button class="contact-form-modal__close toggle close lp-btn lp-icon link-icon--plus"></button> 933 </div> 934 <div class="contact-form-modal__container"> 935 <div class="contact-form-modal-details only-desktop"> 936 <h2 class="contact-form-modal-details__title only-desktop js-contact-title">Get in Touch</h2> 937 938 <div class="contact-form-modal-details__open"><div><strong>DANETTE ANDREWS</strong></div> 939 <div><a href="tel:(808)%20635-7019">(808) 635-7019</a></div> 940 <div><a href="/cdn-cgi/l/email-protection#8aeeebe4effefeefcaebe4eef8effdf9e1ebffebe3a4e9e5e7"><span class="__cf_email__" data-cfemail="e581848b80919180a5848b81978092968e8490848ccb868a88">[email protected]</span></a></div> 941 <p> </p> 942 <div><strong>CODY ANDREWS</strong></div> 943 <div><a href="tel:(808) 635-2604">(808) 635-2604</a></div> 944 <div><a href="/cdn-cgi/l/email-protection#a2c1cdc6dbe2c3ccc6d0c7d5d1c9c3d7c3cb8cc1cdcf"><span class="__cf_email__" data-cfemail="45262a213c05242b21372032362e2430242c6b262a28">[email protected]</span></a></div> 945 <p> </p> 946 <p>2555 Ala Namahana Pkwy Unit 802 <br>Kilauea, HI 96754</p></div> 947 948 949 <div class="contact-form-modal-details__socials"> 950 <ul class="lp-socials social_icons-style-2 contact-form-modal-details__socials-list lp-socials"> 951 952 <li> 953 <a 954 href="https://www.facebook.com/danetteandrewskauai/" 955 class="lp-socials__link contact-form-modal-details__socials-l
955ink" 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/danetteandrewsrealestate/" 966 class="lp-socials__link contact-form-modal-details__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.linkedin.com/in/danetteandrews/" 977 class="lp-socials__link contact-form-modal-details__socials-link" 978 data-wow-delay="0.2s" 979 target="_blank" 980 aria-label="LINKEDIN" 981 > 982 <span class="lp-i lp-i--linkedin" aria-hidden="true"></span> 983 </a> 984 </li> 985 </ul> </div> 986 </div> 987 <div class="contact-form-modal-form"> 988 <h2 class="contact-form-modal-form__title only-mobile js-contact-title">Get in Touch</h2> 989 <form action="" class="contact-form-modal-form__form js-form" data-type="contact-form"> 990 <div class="lp-h-pot"> 991 <label for="-if-middleName">Middle Name</label> 992 <input id="-if-middleName" name="middleName" value="" autocomplete="off" tabindex="-1"> 993 </div> 994 <div class="contact-form-modal-form__group"> 995 <div class="contact-form-modal-form__group-container lp-input-group"> 996 <input required id="-name" name="name" type="text" class="lp-input js-input-name" placeholder="Enter your full name"> 997 <label for="-name" class="lp-label contact-form-modal-form__label">Name</label> 998 </div> 999 <div class="contact-form-modal-form__group-container lp-input-group"> 1000 <input required id="-phone" name="phone" type="tel" class="lp-input" placeholder="Your phone"> 1001 <label for="-phone" class="lp-label contact-form-modal-form__label">Phone</label> 1002 </div> 1003 </div> 1004 <div class="contact-form-modal-form__group lp-input-group"> 1005 <div class="contact-form-modal-form__input-container"> 1006 <input required id="-email" name="email" type="email" class="lp-input js-email-input" placeholder="@"> 1007 <div class="contact-form-modal-form__error error">Enter a valid email</div> 1008 </div> 1009 1010 <label for="-email" class="contact-form-modal-form__label lp-label">Email</label> 1011 </div> 1012 <div class="contact-form-modal-form__group lp-input-group"> 1013 <textarea id="-message" name="message" class="contact-form-modal-form__textarea lp-input" placeholder="Type your message"></textarea> 1014 <label for="-message" class="contact-form-modal-form__label lp-label">Your Message</label> 1015 </div> 1016 1017 <div class="contact-form-modal-form__disclaimer lp-disclaimer"> <label style='display: none;' for='-termsAccepted'>Opt In/Disclaimer Consent:</label> 1018 <label class='lp-tcr-content'>
1019 <span class='lp-tcr-checkbox'> 1020 <input 1021 type='checkbox' 1022 id='-termsAccepted' 1023 name='termsAccepted' 1024 oninvalid="this.setCustomValidity('Please accept the terms and conditions')" 1025 oninput="this.setCustomValidity('')" 1026 required 1027 /></span> 1028 <span class='lp-tcr-message'> 1029 1030 I agree to be contacted by 1031 Danette Andrews 1032 via call, email, and text for real estate services. To opt out, you can reply 'stop' at any time or reply 'help' for assistance. 1033 You can also click the unsubscribe link in the emails. Message and data rates may apply. Message frequency may vary. 1034 <a href='/terms-and-conditions' target='_blank'>Privacy Policy</a>. 1035 </span> 1036 </label> 1037 1038 </div> 1039 1040 <button type="submit" class="contact-form-modal-submit lp-btn lp-icon button-style-1"> 1041 <div class="contact-form-modal-submit__default"> 1042 <span class="contact-form-modal-submit__content lp-btn__content">Send Message</span> 1043 </div> 1044 <div class="contact-form-modal-submit__loading"> 1045 <span class="contact-form-modal-submit__content lp-btn__content">Sending</span> 1046 </div> 1047 <div class="contact-form-modal-submit__success"> 1048 <span class="contact-form-modal-submit__content lp-btn__content">Message Sent!</span> 1049 </div> 1050 </button> 1051 </form> 1052 </div> 1053 1054 <div class="contact-form-modal-details only-mobile"> 1055 <h2 class="contact-form-modal-details__title only-desktop js-contact-title">Get in Touch</h2> 1056 1057 <div class="contact-form-modal-details__open"><div><strong>DANETTE ANDREWS</strong></div> 1058 <div><a href="tel:(808)%20635-7019">(808) 635-7019</a></div> 1059 <div><a href="/cdn-cgi/l/email-protection#5b3f3a353e2f2f3e1b3a353f293e2c28303a2e3a3275383436"><span class="__cf_email__" data-cfemail="d8bcb9b6bdacacbd98b9b6bcaabdafabb3b9adb9b1f6bbb7b5">[email protected]</span></a></div> 1060 <p> </p> 1061 <div><strong>CODY ANDREWS</strong></div> 1062 <div><a href="tel:(808) 635-2604">(808) 635-2604</a></div> 1063 <div><a href="/cdn-cgi/l/email-protection#7a19151e033a1b141e081f0d09111b0f1b1354191517"><span class="__cf_email__" data-cfemail="d0b3bfb4a990b1beb4a2b5a7a3bbb1a5b1b9feb3bfbd">[email protected]</span></a></div> 1064 <p> </p> 1065 <p>2555 Ala Namahana Pkwy Unit 802 <br>Kilauea, HI 96754</p></div> 1066 1067 1068 <div class="contact-form-modal-details__socials"> 1069 <ul class="lp-socials social_icons-style-2 contact-form-modal-details__socials-list lp-socials"> 1070 1071 <li> 1072 <a 1073 href="https://www.facebook.com/danetteandrewskauai/" 1074 class="lp-socials__link contact-form-modal-details__socials-link" 1075 data-wow-delay="0s" 1076 target="_blank" 1077 aria-label="FACEBOOK" 1078 > 1079 <span class="lp-i lp-i--facebook" aria-hidden="true"></span> 1080 </a> 1081 </li> 1082 <li> 1083 <a 1084 href="https://www.instagram.com/danetteandrewsrealestate/" 1085 class="lp-socials__link contact-form-modal-details__socials-l
1085ink" 1086 data-wow-delay="0.1s" 1087 target="_blank" 1088 aria-label="INSTAGRAM" 1089 > 1090 <span class="lp-i lp-i--instagram" aria-hidden="true"></span> 1091 </a> 1092 </li> 1093 <li> 1094 <a 1095 href="https://www.linkedin.com/in/danetteandrews/" 1096 class="lp-socials__link contact-form-modal-details__socials-link" 1097 data-wow-delay="0.2s" 1098 target="_blank" 1099 aria-label="LINKEDIN" 1100 > 1101 <span class="lp-i lp-i--linkedin" aria-hidden="true"></span> 1102 </a> 1103 </li> 1104 </ul> </div> 1105 </div> 1106 </div> 1107 </div> 1108 1109 </div> 1110 <button class="close lp-close" type="button" aria-label="close modal"> 1111 <span class="lp-close-icon" aria-hidden="true"></span> 1112 </button> 1113 </div> 1114 <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;"> 1115 <style> 1116 #qualifying-questions-modal .custom-select-toggle { 1117 border: 1px solid #848484; 1118 border-radius: 8px; 1119 padding: 12px 16px; 1120 } 1121 1122 #qualifying-questions-modal .custom-select-toggle.is-placeholder { 1123 color: #848484; 1124 } 1125 1126 #qualifying-questions-modal #qualifying-questions-modal-phoneNumber::placeholder { 1127 color: #848484; 1128 opacity: 1; 1129 } 1130 1131 #qualifying-questions-modal .disclaimer-more { 1132 display: none; 1133 } 1134 1135 #qualifying-questions-modal #qualifying-questions-modal-disclaimer-text:not(.collapsed) .disclaimer-more { 1136 display: inline; 1137 } 1138 1139 #qualifying-questions-modal #qualifying-questions-modal-disclaimer-text:not(.collapsed) .disclaimer-ellipsis { 1140 display: none; 1141 } 1142 </style>
vendor: 119 bytes, lines 1142-1143
1142 1143 <script data-cfasync="false" src="/cdn-cgi/scripts/5c5dd728/cloudflare-static/email-decode.min.js"></script>
1143<script> 1144 function toggleDisclaimerQualifyingQuestionsModal() { 1145 const disclaimerText = document.getElementById('qualifying-questions-modal-disclaimer-text'); 1146 const toggleButton = document.getElementById('qualifying-questions-modal-toggle-disclaimer'); 1147 1148 if (disclaimerText.classList.contains('collapsed')) { 1149 disclaimerText.classList.remove('collapsed'); 1150 toggleButton.textContent = 'Read less'; 1151 toggleButton.setAttribute('aria-expanded', 'true'); 1152 } else { 1153 disclaimerText.classList.add('collapsed'); 1154 toggleButton.textContent = 'Read more'; 1155 toggleButton.setAttribute('aria-expanded', 'false'); 1156 } 1157 } 1158 </script>
1158 1159 <div style="max-width: 400px; width: 95%; margin: 0 auto;"> 1160 <div style="background: #fff; border: none; border-radius: 16px; color: black; box-shadow: none; position: relative;"> 1161 <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;"> 1162 <span aria-hidden="true">×</span> 1163 </button> 1164 <div style="padding: 40px 30px 32px;"> 1165 <div style="text-align: left; margin-bottom: 32px;"> 1166 <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;"> 1167 Thanks, please provide more information to help serve you 1168 </h2> 1169 </div> 1170 <form id="qualifying-questions-modal-form" data-type="contact-form"> 1171 <input type="hidden" name="source" value="PROFILE_UPDATE" /> 1172 <input type="hidden" name="email" value="" id="qualifying-questions-modal-email" /> 1173 <input type="hidden" name="triggerSource" id="qualifying-questions-modal-triggerSource" value="" /> 1174 <label for="qualifying-questions-modal-email" style="display:none;"> 1175 Email 1176 </label> 1177 <label for="qualifying-questions-modal-triggerSource" style="display:none;"> 1178 Trigger Source 1179 </label> 1180 1181 <div style="margin-bottom: 20px;"> 1182 <label for="qualifying-questions-modal-phoneNumber" style="display:none;"> 1183 Phone Number 1184 </label> 1185 <input 1186 type="tel" 1187 id="qualifying-questions-modal-phoneNumber" 1188 name="phoneNumber" 1189 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;" 1190 pattern="^\+?1?[-.\s]?\(?[0-9]{3}\)?[-.\s]?[0-9]{3}[-.\s]?[0-9]{4}$" 1191 required 1192 placeholder="Phone" 1193 aria-label="Phone Number" 1194 inputmode="tel" 1195 autocomplete="tel" 1196 onfocus="this.style.borderColor='black';" 1197 onblur="this.style.borderColor='#848484';" 1198 /> 1199 </div> 1200 1201 <div style="margin-bottom: 20px;"> 1202 <label for="qualifying-questions-modal-interest" style="display:none;"> 1203 Interest 1204 </label> 1205 <select 1206 id="qualifying-questions-modal-interest" 1207 name="interest" 1208 required 1209 data-label="Interest" 1210 aria-label="Interest" 1211 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;" 1212 onfocus="this.style.borderColor='black'; this.style.color='black';" 1213 onblur="this.style.borderColor='#848484'; if(this.value === '') this.style.color='#848484'; else this.style.color='black';" 1214 > 1215 <option value="" style="background: #fff; color: #848484;" disabled selected>Interested in...</option> 1216 <option value="Selling & Buying" style="background: #fff; color: black;">Selling & Buying</option> 1217 <option value="Selling" style="background: #fff; color: black;">Selling</option> 1218 <option value="Buying" style="background: #fff; color: black;">Buying</option> 1219 <option value="Renting" style="background: #fff; color: black;">Renting</option> 1220 <option value="Other" style="background: #fff; color: black;">Other</option> 1221 </select> 1222 </div> 1223 1224 <div style="margin-bottom: 32px; font-size: 12px; line-height: 1.2;"> 1225 <label style='display: none;' for='qualifying-questions-modal-qualifying-questions-termsAccepted'>Opt In/Disclaimer Consent:</label> 1226 <label class='lp-tcr-content'>
1227 <span class='lp-tcr-checkbox'> 1228 <input 1229 type='checkbox' 1230 id='qualifying-questions-modal-qualifying-questions-termsAccepted' 1231 name='termsAccepted' 1232 aria-describedby='qualifying-questions-modal-disclaimer-text' 1233 oninvalid="this.setCustomValidity('Please accept the terms and conditions')" 1234 oninput="this.setCustomValidity('')" 1235 required 1236 /></span> 1237 <span class='lp-tcr-message'> 1238 <div id="qualifying-questions-modal-disclaimer-text" class="collapsed" style="color: #848484;"> 1239 1240 I agree to be contacted by 1241 <strong>Danette Andrews</strong> 1242 via call, email, and text <span class="disclaimer-more">for real estate services. 1243 To opt out, you can reply 'stop' at any time or reply 'help' for assistance. 1244 You can also click the unsubscribe link in the emails. 1245 Message and data rates may apply. Message frequency may vary.</span> 1246 <span class="disclaimer-ellipsis">...</span> 1247 <a href='/terms-and-conditions' target='_blank' rel='noopener noreferrer' style='text-decoration: underline;'>Privacy Policy</a>. 1248 </div> 1249 <button 1250 id="qualifying-questions-modal-toggle-disclaimer" 1251 type="button" 1252 style="background: none; border: none; color: #848484; font-size: inherit; font-weight: bold; padding: 0; margin-top: 4px; cursor: pointer;" 1253 aria-expanded="false" 1254 onclick="toggleDisclaimerQualifyingQuestionsModal()" 1255 > 1256 Read more 1257 </button> 1258 </span> 1259 </label> 1260 </div> 1261 1262 <div> 1263 <button 1264 type="submit" 1265 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;" 1266 onmouseover="this.style.background='transparent'; this.style.color='black';" 1267 onmouseout="this.style.background='black'; this.style.color='white';" 1268 > 1269 Submit 1270 </button> 1271 </div> 1272 </form> 1273 </div> 1274 </div> 1275 </div> 1276 </div> 1277 1278
1278<script> 1279 (function() { 1280 var lazyVideos = [].slice.call(document.querySelectorAll("video.lazy")); 1281 1282 if ("IntersectionObserver" in window && lazyVideos.length > 0) { 1283 var lazyVideoObserver = new IntersectionObserver(function(entries, observer) { 1284 entries.forEach(function(video) { 1285 if (video.isIntersecting) { 1286 for (var source in video.target.children) { 1287 var videoSource = video.target.children[source]; 1288 if (typeof videoSource.tagName === "string" && videoSource.tagName === "SOURCE") { 1289 videoSource.src = videoSource.dataset.src; 1290 } 1291 } 1292 1293 video.target.load(); 1294 video.target.classList.remove("lazy"); 1295 lazyVideoObserver.unobserve(video.target); 1296 } 1297 }); 1298 }); 1299 1300 lazyVideos.forEach(function(lazyVideo) { 1301 lazyVideoObserver.observe(lazyVideo); 1302 }); 1303 } 1304 })(); 1305 </script>
1305 1306 1307 <!-- Global site tag (gtag.js) - Google Analytics --> 1308
1308<script defer src="https://www.googletagmanager.com/gtag/js"></script>
1308 1309 1310 <!-- Google Tag Manager --> 1311
1311<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start': 1312 new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0], 1313 j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.defer=true;j.async=false;j.src= 1314 'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f); 1315 })(window,document,'script','dataLayer','GTM-T9SFQGHZ');</script>
1315 1316 <!-- End Google Tag Manager --> 1317 1318 1319 <!-- LP Tracker (divolte.js) - LP Divolte --> 1320
1320<script>window.divolteLp=window.divolteLp||function(){(divolteLp.q=divolteLp.q||[]).push(arguments)}</script>
1320 1321 <!-- LP Tracker (eventBus) - LP EventBus --> 1322
1322<script>window.eventBusLp=window.eventBusLp||function(){(eventBusLp.q=eventBusLp.q||[]).push(arguments)}</script>
1322 1323 1324
1324<script> 1325 window.dataLayer = window.dataLayer || []; 1326 document.sendGoogleTagManagerEvent = function() { 1327 /* Honor GPC-enabled browsers and prevent GTM event if GPC is enabled. More details: https://global-privacy-control.glitch.me/ */ 1328 if (window.navigator.globalPrivacyControl) { 1329 return; 1330 } 1331 1332 dataLayer.push(arguments); 1333 } 1334 1335 document.sendGoogleTagManagerEvent('js', new Date()); 1336 document.sendGoogleTagManagerEvent('config', 'G-P6G3GETC0J', { page: location.pathname, location: location.href }); 1337 document.sendGoogleAnalyticsEvent = function(googleEvent) { 1338 document.sendGoogleTagManagerEvent('event', googleEvent.eventAction || googleEvent.hitType, { 1339 event_category: googleEvent.eventCategory, 1340 event_label: googleEvent.eventLabel, 1341 value: googleEvent.eventValue, 1342 page: googleEvent.page, 1343 location: googleEvent.location 1344 }) 1345 }; 1346 1347 document.addEventListener("DOMContentLoaded", function() { 1348 (function() { 1349 //If the page has an element with ID of auto-year-update the element will be populated with the current year. 1350 var date = new Date(); 1351 var elements = document.getElementsByClassName('auto-year-update'); 1352 var i; 1353 for (i = 0; i < elements.length; i++) { 1354 elements[i].innerText = date.getFullYear(); 1355 } 1356 })(); 1357 if (window.divolteLp) { 1358 window.divolteLp('sendLpPageView', {}); 1359 } 1360 if (window.eventBusLp) { 1361 window.eventBusLp('sendLpPageView', {}); 1362 } 1363 }); 1364 </script>
1364 1365 1366 1367
1367<script> 1368 // Function to dynamically load a script 1369 function loadScript(url, callback) { 1370 var script = document.createElement('script'); 1371 script.type = 'text/javascript'; 1372 script.src = url; 1373 script.defer = true; 1374 script.async = true; 1375 script.onload = callback; 1376 document.head.appendChild(script); 1377 } 1378 1379 // Function to dynamically load CSS file 1380 function loadCSS(url) { 1381 var link = document.createElement("link"); 1382 link.rel = "stylesheet"; 1383 link.href = url; 1384 document.head.appendChild(link); 1385 } 1386 1387 // Global methods / variables that can be accessed by element js 1388 window.luxuryPresence = { 1389 libs: { 1390 loadJs: loadScript, 1391 loadCss: loadCSS, 1392 jsLibsMap: { 1393 paroller: { 1394 jsSrc: 'https://d1e1jt2fj4r8r.cloudfront.net/javascript/jquery.paroller.min.js', 1395 isLoaded: false, 1396 }, 1397 ionRangeSlider: { 1398 jsSrc: 'https://cdnjs.cloudflare.com/ajax/libs/ion-rangeslider/2.3.1/js/ion.rangeSlider.min.js', 1399 cssSrc: 'https://cdnjs.cloudflare.com/ajax/libs/ion-rangeslider/2.3.1/css/ion.rangeSlider.min.css', 1400 isLoaded: false, 1401 requires: ['jquery'], 1402 }, 1403 splide: { 1404 jsSrc: 'https://cdnjs.cloudflare.com/ajax/libs/splidejs/4.1.4/js/splide.min.js', 1405 cssSrc: 'https://cdnjs.cloudflare.com/ajax/libs/splidejs/4.1.4/css/splide-core.min.css', 1406 isLoaded: false, 1407 }, 1408 wow: { 1409 jsSrc: 'https://cdnjs.cloudflare.com/ajax/libs/wow/1.1.2/wow.min.js', 1410 isLoaded: false, 1411 }, 1412 jquery: { 1413 jsSrc: 'https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js', 1414 isLoaded: false, 1415 }, 1416 slick: { 1417 jsSrc: 'https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.8.1/slick.min.js', 1418 isLoaded: false, 1419 requires: ['jquery'], 1420 }, 1421 libphonenumber: { 1422 jsSrc: 'https://cdnjs.cloudflare.com/ajax/libs/libphonenumber-js/1.11.8/libphonenumber-js.min.js', 1423 isLoaded: false, 1424 }, 1425 }, 1426 }, 1427 }; 1428 </script>
1428 1429
1429<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>
1429 1430
1430<script defer src="https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/4.7.8/handlebars.min.js"></script>
1430 1431
1431<script defer src="https://cdn.jsdelivr.net/npm/[email protected]/dist/handlebars-intl.min.js"></script>
1431 1432
1432<script defer src="https://cdnjs.cloudflare.com/ajax/libs/superagent/4.1.0/superagent.min.js"></script>
1432 1433
1433<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>
1433 1434
1434<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>
1434 1435
1435<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>
1435 1436 1437 <!-- GOOGLE TRANSLATE SCRIPT --> 1438
1438<script> 1439 function googleTranslateElementInit() { 1440 // list of languages can be overridden by setting window.customLanguages in the head JS. example `window.customLanguages = 'en,de,fr,ro,sk,pl'` 1441 // Language codes can be taken from here https://cloud.google.com/translate/docs/languages 1442 const DEFAULT_LANGUAGES = 'en,es,zh-CN,zh-TW,tl,vi,ar,ko,ru,de,fr,hi,pt'; 1443 document.querySelectorAll('[data-type="TRANSLATE"]').forEach(function(translate){ 1444 translate.innerText = ''; 1445 new google.translate.TranslateElement({ 1446 pageLanguage: 'en', 1447 layout: google.translate.TranslateElement.InlineLayout.SIMPLE, 1448 includedLanguages: window.customLanguages || DEFAULT_LANGUAGES, 1449 }, translate); 1450 }); 1451 } 1452 </script>
1452 1453
1453<script defer src="//translate.google.com/translate_a/element.js?cb=googleTranslateElementInit"></script>
1453 1454
1454<script defer src="https://accounts.google.com/gsi/intermediate"></script>
1454 1455 1456 <!-- GOOGLE TRANSLATE SCRIPT END--> 1457
1457<script> 1458 1459 // UI helpers 1460 (function () { 1461 1462 function getSideMenu () { 1463 return document.querySelector('body > div.sidemenu'); 1464 } 1465 1466 function sideMenuHide (instant) { 1467 var sideMenu = getSideMenu(); 1468 if (!sideMenu || !sideMenu.classList.contains('visible')) { 1469 return; 1470 } 1471 sideMenu.classList.remove('visible'); 1472 sideMenu.dispatchEvent(new CustomEvent('lpui-hide', { detail: { instant: !!instant } })); 1473 window.dispatchEvent(new CustomEvent('lpui-sidemenu-hide', { detail: {instant: !!instant} })); 1474 } 1475 1476 function sideMenuShow () { 1477 var sideMenu = getSideMenu(); 1478 if (!sideMenu || sideMenu.classList.contains('visible')) { 1479 return; 1480 } 1481 sideMenu.classList.add('visible'); 1482 sideMenu.dispatchEvent(new Event('lpui-show')); 1483 window.dispatchEvent(new Event('lpui-sidemenu-show')); 1484 } 1485 1486 function sideMenuToggle () { 1487 var sideMenu = getSideMenu(); 1488 if (!sideMenu) { 1489 return; 1490 } 1491 var isSideMenuVisible = sideMenu.classList.contains('visible'); 1492 if (isSideMenuVisible) { 1493 sideMenuHide(); 1494 } else { 1495 sideMenuShow(); 1496 } 1497 } 1498 1499 var scrollLockRequests = {}; 1500 window.__debug_scrollLockRequests = scrollLockRequests; 1501 var hideScrollStyles = ''+ 1502 'body {'+ 1503 'overflow: hidden;' + 1504 '}'; 1505 var hideScrollId = 'hide-body-scroll-style'; 1506 1507 function scrollLock () { 1508 var style = document.createElement('style'); 1509 style.id = hideScrollId; 1510 style.textContent = hideScrollStyles; 1511 document.head.appendChild(style); 1512 window.dispatchEvent(new Event('lpui-scroll-locked')); 1513 } 1514 1515 function scrollUnlock () { 1516 document.getElementById(hideScrollId)?.remove(); 1517 window.dispatchEvent(new Event('lpui-scroll-unlocked')); 1518 } 1519 1520 function requestScrollLock (lockId) { 1521 var wasLocked = Object.keys(scrollLockRequests).length > 0; 1522 scrollLockRequests[lockId || '__anonymous_lock'] = true; 1523 if (!wasLocked) { 1524 scrollLock(); 1525 } 1526 } 1527 1528 function releaseScrollLock (lockId) { 1529 if (lockId) { 1530 delete scrollLockRequests[lockId]; 1531 if (!Object.keys(scrollLockRequests).length) { 1532 scrollUnlock(); 1533 } 1534 } else { 1535 scrollLockRequests = {}; 1536 window.__debug_scrollLockRequests = scrollLockRequests; 1537 scrollUnlock(); 1538 } 1539 } 1540 1541 function showModal (modalId, options) { 1542 var modal = document.getElementById(modalId); 1543 if (!modal) { 1544 return; 1545 } 1546 1547 if (!modal.classList.contains('visible')) { 1548 modal.classList.add('visible'); 1549 if (options && options.scrollLock) { 1550 window.lpUI.requestScrollLock(modalId); 1551 } 1552 modal.dispatchEvent(new Event('lpui-show')); 1553 window.dispatchEvent(new CustomEvent('lpui-modal-show', { detail: { id: modalId } })); 1554 } 1555 1556 const visibleModals = document.querySelectorAll('.modal.visible'); 1557 1558 if (visibleModals.length > 1) { 1559 1560 const maxZIndex = Array.from(visibleModals).reduce((maxZIndex, modal) => { 1561 const zIndex = window.getComputedStyle(modal).zIndex; 1562 const parsedZIndex = zIndex !== 'auto' ? parseInt(zIndex) : 0; 1563 return Math.max(maxZIndex, parsedZIndex); 1564 }, 0); 1565 1566 modal.style.zIndex = maxZIndex + 1; 1567 } 1568 1569 } 1570 1571 function _hideModal (modalEl) { 1572 if (!modalEl) { 1573 return; 1574 } 1575 if (!modalEl.classList.contains('visible')) { 1576 return; 1577 } 1578 modalEl.classList.remove('visible'); 1579 modalEl.style.zIndex = '';
1580 modalEl.dispatchEvent(new Event('lpui-hide')); 1581 var modalId = modalEl.getAttribute('id'); 1582 if (modalId) { 1583 window.lpUI.releaseScrollLock(modalId); 1584 window.dispatchEvent(new CustomEvent('lpui-modal-hide', { detail: { id: modalId } })); 1585 } 1586 } 1587 1588 function hideModal (modalId) { 1589 _hideModal(document.getElementById(modalId)); 1590 } 1591 1592 function hideClosestModal (el) { 1593 const modal = el?.closest('.modal'); 1594 if (!modal) { 1595 return; 1596 } 1597 if (modal.classList) { 1598 _hideModal(modal); 1599 return; 1600 } 1601 if (modal.length && modal[0].classList) { 1602 _hideModal(modal[0]); 1603 } 1604 } 1605 1606 window.lpUI = { 1607 sideMenuHide: sideMenuHide, 1608 sideMenuShow: sideMenuShow, 1609 sideMenuToggle: sideMenuToggle, 1610 requestScrollLock: requestScrollLock, 1611 releaseScrollLock: releaseScrollLock, 1612 showModal: showModal, 1613 hideModal: hideModal, 1614 hideClosestModal: hideClosestModal 1615 } 1616 })(); 1617 1618 var stringifyPrimitive = function(v) { 1619 switch (typeof v) { 1620 case 'string': 1621 return v; 1622 1623 case 'boolean': 1624 return v ? 'true' : 'false'; 1625 1626 case 'number': 1627 return isFinite(v) ? v : ''; 1628 1629 default: 1630 return ''; 1631 } 1632 }; 1633 1634 function objectToQuerystring(obj, sep, eq, name) { 1635 // https://github.com/Gozala/querystring/blob/master/encode.js 1636 sep = sep || '&'; 1637 eq = eq || '='; 1638 if (obj === null) { 1639 obj = undefined; 1640 } 1641 1642 if (typeof obj === 'object') { 1643 return Object.keys(obj).map(function(k) { 1644 var ks = encodeURIComponent(stringifyPrimitive(k)) + eq; 1645 if (Array.isArray(obj[k])) { 1646 return obj[k].map(function(v) { 1647 return ks + encodeURIComponent(stringifyPrimitive(v)); 1648 }).join(sep); 1649 } else { 1650 return ks + encodeURIComponent(stringifyPrimitive(obj[k])); 1651 } 1652 }).filter(Boolean).join(sep); 1653 1654 } 1655 1656 if (!name) return ''; 1657 return encodeURIComponent(stringifyPrimitive(name)) + eq + 1658 encodeURIComponent(stringifyPrimitive(obj)); 1659 } 1660 1661 function getPath(url, options) { 1662 var parser = document.createElement('a'); 1663 parser.href = url || ''; 1664 var path = parser.pathname || ''; 1665 if (path[0] !== '/') { 1666 // IE does not return path starting with a slash 1667 path = '/' + path; 1668 } 1669 1670 if (options && options.queryString) { 1671 path += parser.search; 1672 } 1673 1674 return path; 1675 } 1676 1677 function getMLSAutocomplete(keyword) { 1678 var searchURL = window.location.protocol + '//' + window.location.hostname + '/home-search/auto_complete'; 1679 var query = { 1680 kind: 'listings', 1681 query: keyword 1682 }; 1683 1684 return superagent 1685 .get(searchURL) 1686 .query(query) 1687 .then(function(res) { 1688 var data = res.body || []; 1689 // Array of listing_auto_complete documents: id, display_address, city, state, 1690 // price, sold_price, status, status_modified_at, photo_urls (array of URLs). 1691 1692 return data; 1693 }); 1694 } 1695 1696 function getMLSAutocompleteWithFilters(keyword, filters = {}) { 1697 var searchURL = window.location.protocol + '//' + window.location.hostname + '/home-search/auto_complete'; 1698 1699 return superagent 1700 .get(searchURL) 1701 .query({ kind: 'listings', query: keyword, ...filters }) 1702 .then(function(res) { 1703 // Same response shape as getMLSAutocomplete. 1704 return res.body || []; 1705 }); 1706 } 1707 1708 function makeMlsLink(data) { 1709 // Code Dupe from utils/googlePlace 1710 // mapping of google data type to mls data type 1711 var mapping = { 1712 neighborhood: 'neighborhood', 1713 locality: 'place', 1714 administrative_area_level_2: 'county', 1715 administrative_area_level_1: 'state', 1716 postal_code: 'postalcode', 1717 }; 1718 1719 function _filterTypes(types) { 1720 return types.filter(function(type) { return type !== 'political' }); 1721 } 1722 1723 if (!data || !Object.keys(data).length) { 1724 return '/home-search/listings'; 1725 } 1726 1727 var newData = {};
1728 _filterTypes(data.types).forEach(function(type) { 1729 if (mapping[type]) { 1730 newData.search_type = mapping[type]; 1731 } 1732 }); 1733 newData.omnibox = data.formatted_address; 1734 data.address_components.forEach(function(component) { 1735 _filterTypes(component.types).forEach(function(type) { 1736 if (mapping[type]) { 1737 newData[mapping[type]] = component.long_name; 1738 } 1739 }); 1740 }); 1741 var bounds = data.geometry.bounds; 1742 var convertedData = Object.assign(bounds, newData); 1743 1744 return '/home-search/listings?' + objectToQuerystring(convertedData); 1745 } 1746 1747 function debounce(func, wait) { 1748 let timeout; 1749 return function(...args) { 1750 const context = this; 1751 clearTimeout(timeout); 1752 timeout = setTimeout(() => func.apply(context, args), wait) 1753 } 1754 } 1755 1756 // Global methods / variables that can be accessed by element js 1757 window.luxuryPresence = { 1758 ...window.luxuryPresence, 1759 defaults: { 1760 companyId: 'c1908ce5-efe4-423f-a0b8-f9e844db2413', 1761 apiGatewayUrl: '/api-gw', 1762 routerUrl: '/api-nv', 1763 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\
1763n }\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 $companyId: ID\n $pressReleaseIds: [ID!]\n $offset: Int\n $limit: Int\n $sort: String\n $sortDir: String\n $search: String\n $categories: [String!]\n $propertyId: [ID!]\n $developmentId: [ID!]\n $agentId: [ID!]\n $teamId: [ID!]\n $year: [Int!]\n ) {\n pressReleases (\n companyId: $companyId\n pressReleaseIds: $pressReleaseIds\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 year: $year\n ) {\n items {\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 altTagText\n }\n publishedAt\n categories\n }\n total\n }\n }\n","posts":"\n query Posts (\n $companyId: String\n $postId: [ID!]\n $slug: String\n $offset: Int\n $limit: Int\n $sort: String\n $sortDir: String\n $search: String\n $featured: Boolean\n $categoryId: [String!]\n $neighborhoodId: [String!]\n ) {\n posts (\n companyId: $companyId\n postId: $postId\n slug: $slug\n offset: $offset\n limit: $limit\n sort: $sort\n sortDir: $sortDir\n search: $search\n featured: $featured\n postStatusId: \"5f528253-abb7-484e-95c3-330269ac1102\"\n categoryId: $categoryId\n neighborhoodId: $neighborhoodId\n ) {\n items {\n id\n postId\n title\n subtitle\n description\n status: postStatus\n featured\n slug\n categories {\n id\n name\n }\n createdAt\n publishedAt\n updatedAt\n scheduledAt\n createdBy {\n ... on Agent {\n firstName\n lastName\n }\n }\n customAuthor\n media {\n smallUrl\n mediumUrl\n largeUrl\n xLargeUrl\n xxLargeUrl\n height\n width\n altTagText\n }\n seoTitle\n seoDescription\n }\n total\n }\n }\n","testimonials":"\n query Testimonials (\n $companyId: String\n $agentId: ID\n $teamId: ID\n $testimonialIds: [ID!]\n $offset: Int\n $limit: Int\n $sort: String\n $sortDir: String\n $search: String\n ) {\n testimonials (\n companyId: $companyId\n agentId: $agentId\n teamId: $teamId\n testimonialIds: $testimonialIds\n offset: $offset\n limit: $limit\n sort: $sort\n sortDir: $sortDir\n search: $search\n ) {\n items {\n id\n testimonialId\n body\n author\n position\n media {\n smallUrl\n mediumUrl\n largeUrl\n xLargeUrl\n xxLargeUrl\n height\n width\n altTagText\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 total\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 $companyId: ID!\n $developmentIds: [ID!]\n $agentId: String\n $slug: String\n $search: String\n $tag: [String!]\n $offset: Int\n $limit: Int\n $sort: String\n $sortDir: SortDirection\n $neighborhoodId: ID\n $neighborhoodIds: [ID!]\n ) {\n developments (\n companyId: $companyId\n developmentIds: $developmentIds\n agentId: $agentId\n slug: $slug\n search: $search\n tag: $tag\n offset: $offset\n limit: $limit\n sort: $sort\n sortDir: $sortDir\n neighborhoodId: $neighborhoodId\n neighborhoodIds: $neighborhoodIds\n ) {\n items {\n id\n name\n description\n descriptionShort\n slug\n createdAt\n updatedAt\n media {\n smallUrl\n mediumUrl\n largeUrl\n xLargeUrl\n xxLargeUrl\n height\n width\n altTagText\n }\n logoMedia {\n smallUrl\n mediumUrl\n largeUrl\n xLargeUrl\n xxLargeUrl\n height\n width\n altTagText\n }\n websiteUrl\n videoUrl\n googlePlaceData\n coordinates\n mlsLink\n seoTitle\n seoDescription\n featuresAndAmenities {\n featureIds\n features {\n featureId\n name\n }\n description\n }\n latitude\n longitude\n addressLine1\n addressLine2\n city\n state\n zipCode\n country\n yearCompleted\n residences\n availability\n neighborhoodId\n developer\n architect\n interiorDesigner\n stories\n buildingHeight\n buildingHeightUnit\n bedMin\n bedMax\n bathMin\n bathMax\n livingSpaceMin\n livingSpaceMa
1763x\n livingSpaceUnit\n lotSizeMin\n lotSizeMax\n lotSizeUnit\n priceMin\n priceMax\n priceCurrency\n tags\n }\n total\n }\n }\n","pois":"\n query PointsOfInterest (\n $regionId: UUID!\n $radius: Int\n $offset: Int\n $limit: Int\n $categories: [AreasOfInterestCategories!]\n $sortBy: AreasOfInterestSorting\n ) {\n pois: areasOfInterest (\n input: {\n regionId: $regionId\n radius: $radius\n offset: $offset\n limit: $limit\n categories: $categories\n sortBy: $sortBy\n }\n ) {\n items {\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 total\n }\n }\n","offices":"\n query Offices (\n $companyId: ID!\n $officeIds: [ID!]\n $officeMlsIds: [String!]\n $externalIds: [String!]\n $externalSource: String\n $agentId: ID\n $archived: Boolean\n $tags: [String!]\n $slug: String\n $search: String\n $sort: String\n $sortDir: SortDirection\n $offset: Int\n $limit: Int\n ) {\n offices (\n companyId: $companyId\n officeIds: $officeIds\n officeMlsIds: $officeMlsIds\n externalIds: $externalIds\n externalSource: $externalSource\n agentId: $agentId\n archived: $archived\n tags: $tags\n slug: $slug\n search: $search\n sort: $sort\n sortDir: $sortDir\n offset: $offset\n limit: $limit\n ) {\n items {\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 tags\n media {\n id\n originalUrl\n thumbnailUrl\n smallUrl\n mediumUrl\n largeUrl\n xLargeUrl\n xxLargeUrl\n }\n }\n total\n }\n }\n","teams":"\n query Teams (\n $companyId: ID\n $teamIds: [ID!]\n $agentId: ID\n $externalIds: [String!]\n $externalSource: String\n $slug: String\n $search: String\n $sort: String\n $sortDir: String\n $offset: Int\n $limit: Int\n ) {\n teams (\n companyId: $companyId\n teamIds: $teamIds\n agentId: $agentId\n externalIds: $externalIds\n externalSource: $externalSource\n slug: $slug\n search: $search\n sort: $sort\n sortDir: $sortDir\n offset: $offset\n limit: $limit\n ) {\n items {\n id\n companyId\n name\n email\n shortBio\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 total\n }\n }\n"}, 1764 propertyPlaceholderImage: {"id":"113e7e98-f220-417e-97bb-1288b860cdbc","alt":null,"bytes":21894,"width":1920,"format":"png","height":1200,"pngUrl":null,"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/73452989-4e67-4e38-93f8-dd48c0196724","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/73452989-4e67-4e38-93f8-dd48c0196724","authorUrl":null,"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/73452989-4e67-4e38-93f8-dd48c0196724","sourceUrl":null,"xLargeUrl":"https://media-production.lp-cdn.com/cdn-cgi/image/format=auto,quality=85/https://media-production.lp-cdn.com/media/73452989-4e67-4e38-93f8-dd48c0196724","__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/73452989-4e67-4e38-93f8-dd48c0196724","description":null,"displayName":"property_placeholder-compass-logo","originalUrl":"https://media-production.lp-cdn.com/cdn-cgi/image/format=auto,quality=85/https://media-production.lp-cdn.com/media/73452989-4e67-4e38-93f8-dd48c0196724","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/73452989-4e67-4e38-93f8-dd48c0196724","originalFileName":"Property_placeholder-Compass-logo","cloudinaryPublicId":"73452989-4e67-4e38-93f8-dd48c0196724"} 1765 }, 1766 objectToQuerystring: objectToQuerystring, 1767 getPath: getPath, 1768 getMLSAutocomplete: getMLSAutocomplete, 1769 getMLSAutocompleteWithFilters: getMLSAutocompleteWithFilters, 1770 makeMlsLink: makeMlsLink, 1771 debounce: debounce, 1772 }; 1773 1774 var wowOffset = 100; 1775 </script>
1775 1776
1776<script> 1777 (()=>{function e(e){return e&&e.__esModule?e.default:e}var t=globalThis,r={},i={},s=t.parcelRequired4f7;null==s&&((s=function(e){if(e in r)return r[e].exports;if(e in i){var t=i[e];delete i[e];var s={id:e,exports:{}};return r[e]=s,t.call(s.exports,s,s.exports),s.exports}var o=Error("Cannot find module '"+e+"'");throw o.code="MODULE_NOT_FOUND",o}).register=function(e,t){i[e]=t},t.parcelRequired4f7=s);var o=s.register;o("ikl6F",function(e,t){"use strict";Object.defineProperty(e.exports,"__esModule",{value:!0}),e.exports.formatMoney=e.exports.convertAmount=e.exports.fetchExchangeRates=e.exports.toSupportedToCurrency=e.exports.toSupportedFromCurrency=e.exports.SUPPORTED_TO_CURRENCIES=e.exports.SUPPORTED_FROM_CURRENCIES=e.exports.DISPLAY_CURRENCIES=e.exports.writeCurrencyCookie=e.exports.readValidCurrencyCookie=e.exports.readCurrencyCookie=e.exports.clearCurrencyCookie=e.exports.CURRENCY_COOKIE_SAME_SITE=e.exports.CURRENCY_COOKIE_PATH=e.exports.CURRENCY_COOKIE_NAME=e.exports.CURRENCY_COOKIE_MAX_AGE_SECONDS=void 0;var r=s("65bUu");Object.defineProperty(e.exports,"CURRENCY_COOKIE_MAX_AGE_SECONDS",{enumerable:!0,get:function(){return r.CURRENCY_COOKIE_MAX_AGE_SECONDS}}),Object.defineProperty(e.exports,"CURRENCY_COOKIE_NAME",{enumerable:!0,get:function(){return r.CURRENCY_COOKIE_NAME}}),Object.defineProperty(e.exports,"CURRENCY_COOKIE_PATH",{enumerable:!0,get:function(){return r.CURRENCY_COOKIE_PATH}}),Object.defineProperty(e.exports,"CURRENCY_COOKIE_SAME_SITE",{enumerable:!0,get:function(){return r.CURRENCY_COOKIE_SAME_SITE}}),Object.defineProperty(e.exports,"clearCurrencyCookie",{enumerable:!0,get:function(){return r.clearCurrencyCookie}}),Object.defineProperty(e.exports,"readCurrencyCookie",{enumerable:!0,get:function(){return r.readCurrencyCookie}}),Object.defineProperty(e.exports,"readValidCurrencyCookie",{enumerable:!0,get:function(){return r.readValidCurrencyCookie}}),Object.defineProperty(e.exports,"writeCurrencyCookie",{enumerable:!0,get:function(){return r.writeCurrencyCookie}});var i=s("gUuHZ");Object.defineProperty(e.exports,"DISPLAY_CURRENCIES",{enumerable:!0,get:function(){return i.DISPLAY_CURRENCIES}}),Object.defineProperty(e.exports,"SUPPORTED_FROM_CURRENCIES",{enumerable:!0,get:function(){return i.SUPPORTED_FROM_CURRENCIES}}),Object.defineProperty(e.exports,"SUPPORTED_TO_CURRENCIES",{enumerable:!0,get:function(){return i.SUPPORTED_TO_CURRENCIES}}),Object.defineProperty(e.exports,"toSupportedFromCurrency",{enumerable:!0,get:function(){return i.toSupportedFromCurrency}}),Object.defineProperty(e.exports,"toSupportedToCurrency",{enumerable:!0,get:function(){return i.toSupportedToCurrency}});var o=s("jCxYG");Object.defineProperty(e.exports,"fetchExchangeRates",{enumerable:!0,get:function(){return o.fetchExchangeRates}});var n=s("igUcG");Object.defineProperty(e.exports,"convertAmount",{enumerable:!0,get:function(){return n.convertAmount}}),Object.defineProperty(e.exports,"formatMoney",{enumerable:!0,get:function(){return n.formatMoney}})}),o("65bUu",function(e,t){"use strict";Object.defineProperty(e.exports,"__esModule",{value:!0}),e.exports.readValidCurrencyCookie=e.exports.clearCurrencyCookie=e.exports.writeCurrencyCookie=e.exports.readCurrencyCookie=e.exports.CURRENCY_COOKIE_PATH=e.exports.CURRENCY_COOKIE_SAME_SITE=e.exports.CURRENCY_COOKIE_MAX_AGE_SECONDS=e.exports.CURRENCY_COOKIE_NAME=void 0;var r=s("gUuHZ");e.exports.CURRENCY_COOKIE_NAME="lp-currency",e.exports.CURRENCY_COOKIE_MAX_AGE_SECONDS=31536e3,e.exports.CURRENCY_COOKIE_SAME_SITE="Lax",e.exports.CURRENCY_COOKIE_PATH="/";let i=e=>e?.trim().toLowerCase().replace(/^\.+/,"")||void 0,o=e=>"undefined"!=typeof DOMException&&e instanceof DOMException,n=({document:t})=>{let r=`${e.exports.CURRENCY_COOKIE_NAME}=`;return t.cookie.split(";").map(e=>e.trim()).filter(e=>e.startsWith(r)).map(e=>e.slice(r.length))},a=e=>{try{return decodeURIComponent(e)}catch{return}};e.exports.readCurrencyCookie=e=>{let t=(e=>{try{return n(e)[0]}catch(e){if(!o(e))throw e;return}})(e);return void 0===t?void 0:a(t)};let l=(t,r,i,s)=>{var o;let n,a;t.document.cookie=`${e.exports.CURRENCY_COOKIE_NAME}=${r}${o=t.location,n="https:"===o.protocol?"; Secure":"",a=s?`; Domain=${s}`:"",`; Path=${e.exports.CURRENCY_COOKIE_PATH}; Max-Age=${i}; SameSite=${e.exports.CURRENCY_COOKIE_SAME_SITE}${n}${a}`}`};e.exports.writeCurrencyCookie=(t,s)=>{let a,d=(0,r.toSupportedToCurrency)(s);if(!d)return!1;let c=i(t.domain);try{if(a=n(t)[0],c&&l(t,"",0,void 0),l(t,encodeURIComponent(d),e.exports.CURRENCY_COOKIE_MAX_AGE_SECONDS,c),(0,e.exports.readCurrencyCookie)(t)===d)return!0}catch(e){if(!o(e))throw e}return c&&void 0!==a&&((t,r)=>{try{if(n(t).includes(r))return;l(t,r,e.exports.CURRENCY_COOKIE_MAX_AGE_SECONDS,void 0)}catch(e){if(!o(e))throw e}})(t,a),!1},e.exports.clearCurrencyCookie=e=>{let t=i(e.domain);try{t&&l(e,"",0,void 0),l(e,"",0,t)}catch(e){if(!o(e))throw e}},e.exports.readValidCurrencyCookie=(t,{enabled:s,enabledCurrencies:d})=>{if(!s)return;let c=(e=>{try{let t=n(e);if(!i(e.domain)||t.length<2)return t[0];return l(e,"",0,void 0),n(e)[0]}catch(e){if(!o(e))throw e;return}})(t);if(void 0===c)return;let u=new Set(d.map(r.toSupportedToCurrency).filter(e=>!!e)),h=(0,r.toSupportedToCurrency)(a(c));
1777if(h&&u.has(h))return h;(0,e.exports.clearCurrencyCookie)(t)}}),o("gUuHZ",function(e,t){"use strict";Object.defineProperty(e.exports,"__esModule",{value:!0}),e.exports.toSupportedToCurrency=e.exports.SUPPORTED_TO_CURRENCIES=e.exports.DISPLAY_CURRENCIES=e.exports.toSupportedFromCurrency=e.exports.SUPPORTED_FROM_CURRENCIES=void 0,e.exports.SUPPORTED_FROM_CURRENCIES=["usd","cad","eur","gbp"];let r=(e,t)=>{if("string"!=typeof e)return;let r=e.toLowerCase();return t.includes(r)?r:void 0};e.exports.toSupportedFromCurrency=t=>r(t,e.exports.SUPPORTED_FROM_CURRENCIES),e.exports.DISPLAY_CURRENCIES=[{code:"usd",name:"US dollar"},{code:"eur",name:"Euro"},{code:"gbp",name:"Pound sterling"},{code:"cad",name:"Canadian dollar"},{code:"chf",name:"Swiss franc"},{code:"brl",name:"Brazilian real"},{code:"mxn",name:"Mexican peso"},{code:"sek",name:"Swedish krona"},{code:"nok",name:"Norwegian krone"},{code:"dkk",name:"Danish krone"},{code:"ars",name:"Argentine peso"},{code:"cop",name:"Colombian peso"},{code:"clp",name:"Chilean peso"},{code:"pen",name:"Peruvian sol"},{code:"dop",name:"Dominican peso"},{code:"gtq",name:"Guatemalan quetzal"},{code:"crc",name:"Costa Rican colón"},{code:"bob",name:"Bolivian boliviano"},{code:"pyg",name:"Paraguayan guaranÃ"},{code:"kyd",name:"Cayman Islands dollar"}],e.exports.SUPPORTED_TO_CURRENCIES=e.exports.DISPLAY_CURRENCIES.map(e=>e.code),e.exports.toSupportedToCurrency=t=>r(t,e.exports.SUPPORTED_TO_CURRENCIES)}),o("jCxYG",function(e,t){"use strict";Object.defineProperty(e.exports,"__esModule",{value:!0}),e.exports.fetchExchangeRates=void 0;var r=s("gUuHZ");let i=async(e,{baseUrl:t,signal:i,fetch:s,onError:o})=>{let n=(0,r.toSupportedFromCurrency)(e);if(!n)return{};let a=`${t.replace(/\/$/,"")}/api/v1/exchange-rates?from=${encodeURIComponent(n)}`;try{let e=await (s??fetch)(a,{credentials:"omit",signal:i});if(!e.ok)throw Error(`Exchange rates HTTP ${e.status}`);var l=await e.json();let t=l?.rates;if("object"!=typeof t||null===t)return{};let o={};return Object.entries(t).forEach(([e,t])=>{let i=(0,r.toSupportedToCurrency)(e);i&&"number"==typeof t&&Number.isFinite(t)&&t>0&&(o[i]=t)}),o}catch(e){try{o?.(e)}catch(e){console.warn("fetchExchangeRates: onError callback threw",e)}return{}}};e.exports.fetchExchangeRates=i}),o("igUcG",function(e,t){"use strict";Object.defineProperty(e.exports,"__esModule",{value:!0}),e.exports.formatMoney=e.exports.convertAmount=void 0;var r=s("gUuHZ");e.exports.convertAmount=(e,t)=>{if(Number.isFinite(e)&&Number.isFinite(t)&&!(t<=0))return e*t},e.exports.formatMoney=(e,t,{precision:i=0}={})=>{let s=(0,r.toSupportedToCurrency)(t);if(!s||!Number.isFinite(e))return;let o=Number.isInteger(i)?i:0,n=Number.isInteger(e)?0:Math.min(Math.max(o,0),20);return new Intl.NumberFormat("en-US",{style:"currency",currency:s.toUpperCase(),minimumFractionDigits:n,maximumFractionDigits:n}).format(e)}});var n={},a={};a={getVideoFirstFrame(e){let t="https://res.cloudinary.com/";if(!e||!e.startsWith(t))return null;let r=e.replace(t,"").replace("f_auto:video","f_auto").split("/");if(-1===r[1].toLowerCase().indexOf("video"))return null;let i=r[r.length-1];i.lastIndexOf(".")>-1?i=`${i.slice(0,i.lastIndexOf("."))}.jpg`:i+=".jpg",r[r.length-1]=i;let s=3;"videos"===r[1].toLowerCase()&&""!==r[2]&&(s=2);let o=/^(?:[a-z]{1,3}|\$\w+)_\S+$/;for(;s<r.length-1&&o.test(r[s]);)s++;return r.splice(s,0,"so_0,eo_0"),t+r.join("/")}};let l={amp:"&",lt:"<",gt:">",quot:'"',apos:"'",nbsp:" "},d=/&(?:amp|lt|gt|quot|apos|nbsp|#(?:[0-9]+|[xX][0-9a-fA-F]+));/y,c=/[<&]/g,u=/["'>]/g,h=/<\/p\s*>|<br\s*\/?>|[\r\n\u2028\u2029]/g;function p(e,t){let r="";for(let i=0;i<e.length;){c.lastIndex=i;let s=c.exec(e);if(!s){r+=e.slice(i);break}let o=s.index;r+=e.slice(i,o);let n="&"===e[o]?function(e,t){d.lastIndex=t;let r=d.exec(e);return{text:r?function(e){if("#"!==e[1])return l[e.slice(1,-1)];
1777let t="x"===e[2]||"X"===e[2],r=parseInt(e.slice(t?3:2,-1),t?16:10);return 0===r||r>1114111||r>=55296&&r<=57343?e:160===r?" ":String.fromCodePoint(r)}(r[0]):"&",end:r?d.lastIndex:t+1}}(e,o):function(e,t,r){let i=function(e,t){let r=null;u.lastIndex=t+1;let i=u.exec(e);for(;i;){let t=i[0];if(r)t===r&&(r=null);else if('"'===t||"'"===t)r=t;else if(">"===t)return u.lastIndex;i=u.exec(e)}return -1}(e,t);return{text:-1===i?"<":function(e,t,r,i){if(!i)return"";let s=e.slice(t,r);if(/^<br\s*\/?>$/.test(s))return" ";if(/^<\/p\s*>$/.test(s)){h.lastIndex=r;let t=h.exec(e);if(t&&"<"===t[0][0])return" "}return""}(e,t,i,r),end:-1===i?t+1:i}}(e,o,t);r+=n.text,i=n.end}return r}n=function(e,{isEqual:t}){let r=[{field:"thumbnailUrl",w:320},{field:"smallUrl",w:960},{field:"mediumUrl",w:1280},{field:"largeUrl",w:1920},{field:"xLargeUrl",w:2560},{field:"xxLargeUrl",w:3456}],i=function(e,t,r){let i="en-US";if(!e)return"";if("string"==typeof e){let t=e.trim();if(/[^+\-0-9.]/.test(t))return e;if(!(e=parseFloat(t)))return""}let s="number"==typeof r?r:0,o=Number.isInteger(e)?0:s,n={minimumFractionDigits:o,maximumFractionDigits:o};return"USD"===t?`$${e.toLocaleString(i,n)}`:"CAD"===t?`$${e.toLocaleString(i,n)} CAD`:"EUR"===t?`\u{20AC}${e.toLocaleString(i,n)}`:"GBP"===t?`\xa3${e.toLocaleString(i,n)}`:"PERCENT"===t?`${e}%`:"number"==typeof r&&r>-1?e.toLocaleString(i,{maximumFractionDigits:r}):e.toLocaleString(i)},s=function(e){switch(e){case"DAY":return"daily";case"MONTH":return"monthly";case"WEEK":return"weekly";case"YEAR":return"yearly";case"QUARTER":return"quarterly";case"HALF_YEAR":return"semi-annually";case"NIGHTLY":return"nightly";case"SEASONAL":return"seasonally";default:return""}},o=function(e){switch(e){case"DAY":return"day";case"WEEK":return"wk";case"MONTH":return"mo";case"YEAR":return"yr";case"QUARTER":return"3 mos";case"HALF_YEAR":return"6 mos";case"NIGHTLY":return"night";case"SEASONAL":return"season";default:return""}},n=function(e){switch(e){case"DAY":return"day";case"WEEK":return"week";case"MONTH":return"month";case"YEAR":return"year";case"QUARTER":return"quarter";case"HALF_YEAR":return"6 months";case"NIGHTLY":return"night";case"SEASONAL":return"season";default:return""}},l=function(e,t){let r,i,a=t||{};switch(a.mode){case"short":r=o(e),i=a.frequencySeparator||"/";break;case"standard":case"std":r=n(e),i=a.frequencySeparator||"/";break;default:r=s(e),i=a.frequencySeparator||" "}return r?a.frequencyTag||a.frequencyClass?`${i}<${a.frequencyTag||"span"}${a.frequencyClass?` class="${a.frequencyClass}"`:""}>${r}</${a.frequencyTag||"span"}>`:i+r:""};return{isEmpty(e,t){let r=!e||"string"==typeof e&&!e.trim()||!Object.keys(e).length;return t.fn?r?t.fn(this):t.inverse(this):r},ifEquals(e,r,i){return t(e,r)?i.fn(this):i.inverse(this)},"raw-helper":function(e){return e.fn()},striptags:e=>e?p(e=(e=e.replace(/<\!--(.|[\r\n])*?-\->/g,"")).replace(/<(xml|style|svg)("[^"]*"|'[^']*'|[^>])*>(.|[\r\n])*?<\/\1>/gi,""),!1):"",striptagsLineBreaks:e=>e?p(e=(e=e.replace(/<\!--(.|[\r\n])*?-\->/g,"")).replace(/<(xml|style|svg)("[^"]*"|'[^']*'|[^>])*>(.|[\r\n])*?<\/\1>/gi,""),!0):"",truncate:(e,t,r)=>e?e.length>t?"string"==typeof r?e.slice(0,t-r.length)+r:e.slice(0,t):e:"",setSubArray(e=[],t,r,i,s){s.data.root[i]=e.slice(t,r)},formatAreaUnit(e){switch(e){case"ACRE":return"Acres";case"SQUARE_METER":return"Sq.M.";case"SQUARE_YARD":return"Sq.Yd.";default:return"Sq.Ft."}},formatFrequency:s,formatFrequencyShort:o,lpFormatFrequency:(e,t)=>l(e,t&&t.hash),subArray(e,t,r,i){return e>=t&&e<r?i.fn(this):i.inverse(this)},formatPropertyStatus(e,t,r){let i="";switch(e){case"SOLD":i="Sold";break;case"FOR_SALE":i="For Sale";break;case"COMING_SOON":i="Coming Soon";break;case"INACTIVE":i="Inactive";break;case"POCKET_LISTING":i="Pocket Listing";break;case"PENDING":i="Pending";break;case"UNDER_CONTRACT":i="Under Contract";break;case"ACTIVE_UNDER_CONTRACT":i="Active Under Contract";break;default:i=e}return("Sold"===i||"Leased"===i)&&t&&"string"==typeof r&&r&&(i+=` on ${r}`),i},formatGrade(e){switch(e){case"UNDERGRADUATE_COURSES":return"Undergrad";case"PRE_KINDERGARTEN":return"PreK";case"KINDERGARTEN":return"K";case"FIRST_GRADE":return"1st";case"SECOND_GRADE":return"2nd";case"THIRD_GRADE":return"3rd";case"FOURTH_GRADE":return"4th";case"FIFTH_GRADE":return"5th";case"SIXTH_GRADE":return"6th";case"SEVENTH_GRADE":return"7th";case"EIGHTH_GRADE":return"8th";case"NINTH_GRADE":return"9th";case"TENTH_GRADE":return"10th";case"ELEVENTH_GRADE":return"11th";case"TWELFTH_GRADE":return"12th";default:return""}},encodeURI:e=>encodeURI(e),encodeURIComponent:e=>encodeURIComponent(e),hbFormatDate(e,t){if(!e)return"";let r="current"===e?new Date:new Date(e);if(Number.isNaN(r.getTime()))return"";if("YYYY"===t||"year"===t)return`${r.getFullYear()}`;if("MM/DD/YY"===t){let e=r.getMonth()+1;return e<10&&(e=`0${e.toString()}`),`${e}/${r.getDate()}/${r.getFullYear().toString().substr(-2)}`}return`${["January","February","March","April","May","June","July","August","September","October","November","December"][r.getMonth()]} ${r.getDate()}, ${r.getFullYear()}`},openHousesFormat(e,t,r){if(!e||!t)return"";let i=e=>{let t=e.getHours();t>12&&(t-=12);let r=`${t}:${e.getMinutes()>9?e.getMinutes():"0"+e.getMinutes()}`;return e.getHours()>11?r+="PM":r+="AM",r},s="",o=e,n=t;
1777r&&(o=new Date(e).toLocaleString("en-US",{timeZone:r}),n=new Date(t).toLocaleString("en-US",{timeZone:r}),[,,,s]=new Date(t).toLocaleString("en-US",{timeZone:r,timeZoneName:"short"}).split(" "));let a=new Date(o),l=a.toLocaleDateString("en-US"),d=i(a),c=i(new Date(n));return`${l} ${d} - ${c} ${s}`},math:(e,t,r)=>(e=parseFloat(e),({"+":e+(r=parseFloat(r)),"-":e-r,"*":e*r,"/":e/r,"%":e%r})[t]),findByKey(e,t,r,i){let s=(e||[]).find(e=>e[t]===r);return i.fn(s)},capitalize(e,t,r){let i;return"string"==typeof e&&e.length&&(i=e.toLowerCase().split(t).map(e=>e.charAt(0).toUpperCase()+e.slice(1)).join(" ").toString()),i},and:(...e)=>Array.prototype.slice.call(e).every(Boolean),or:(...e)=>Array.prototype.slice.call(e,0,-1).some(Boolean),not:e=>!e,orderByIds(t,r,i){let s="",o=null;i.data&&(o=e.createFrame(i.data));let n=(r||[]).filter(Boolean);if(n&&n.length){let e=0;s=n.reduce((r,s,n)=>{let a=(t||[]).find(e=>e.id===s);return a?(o&&(o.index=n-e),r+i.fn(a,{data:o})):(e+=1,r)},"")}else for(let e=0,r=(t||[]).length;e<r;e++)o&&(o.index=e),s+=i.fn(t[e],{data:o});return s},ifIn(e,t,r){return t&&t.indexOf(e)>-1?r.fn(this):r.inverse(this)},partial:(t,r)=>(e.registerPartial(t,e.compile(r.fn())),`
1777<script type="text/x-handlebars-template" class="${t} pagination-script">${r.fn()}<\/script>`),numCompare(e,t,r,i){return({"==":function(e,t){return e==t},"===":function(e,t){return e===t},"!=":function(e,t){return e!=t},"<":function(e,t){return e<t},">":function(e,t){return e>t},"<=":function(e,t){return e<=t},">=":function(e,t){return e>=t}})[r](e,t)?!i.fn||i.fn(this):!!i.fn&&i.inverse(this)},lpFormatNumber:i,arrayToHtmlList:(e,t)=>e.reduce((e,t)=>{try{if("object"==typeof t||null===t)return e;return e+=`<li>${t}</li>`}catch(e){}},""),join:(e,t,r)=>e&&e.join?e.join("string"==typeof t?t:", "):"",dedupe(t,r,i){let s=null,o=0,n=new Set;return i.data&&(s=e.createFrame(i.data)),(t||[]).reduce((e,t,a)=>{let l=r?t[r]:t;return!n.has(l)||r&&void 0===l?(n.add(l),s&&(s.index=a-o),e+i.fn(t,{data:s})):(o+=1,e)},"")},JSONstringify:(e,t)=>JSON.stringify(e),formatPropertyPrice(...t){let r=t[t.length-1].hash,s=t.length>1?t[0]:r.property,o=r.precision||0;t.length>2&&(r.mode=t[1]),r.mode||(r.mode="short");let n=t.length>3?t[2]:r.separator;if("string"!=typeof n&&(n=" | "),s.isPasswordProtected)return"Exclusive Listing";let a=t.length>4?t[3]:r.priceUponRequestText;if("string"!=typeof a&&(a="Price Upon Request"),s.priceUponRequest)return a;let d=s.salesPrice,c=null;"SOLD"!==s.status&&"Leased"!==s.status&&s.reducedPrice&&(r.reducedClass?c=s.reducedPrice:d=s.reducedPrice);let u="";c&&(u+=`<${r.reducedTag||"span"} class="${r.reducedClass}">${i(c,s.currency,o)}</${r.reducedTag||"span"}>`),d&&(d=i(d,s.currency,o),r.priceTag||r.priceClass?u+=`<${r.priceTag||"span"}${r.priceClass?` class="${r.priceClass}"`:""}>${d}</${r.priceTag||"span"}>`:u+=d);let h=s.leasePrice&&i(s.leasePrice,s.currency,o);if(h){u&&(u+=n);let e=`${h}${l(s.leasePeriod,r)}`;r.leaseTag||r.leaseClass?u+=`<${r.leaseTag||"span"}${r.leaseClass?` class="${r.leaseClass}"`:""}>${e}</${r.leaseTag||"span"}>`:u+=e}
1777return new e.SafeString(u)},mediaImage(t,i={}){if(!t)return;let{lazy:s,...o}=i.hash,n="",a="";if("string"==typeof t)n=t;else{let e={},{height:s,width:l,altTagText:d}=t;r.forEach(r=>{t[r.field]&&!e[t[r.field]]&&(e[t[r.field]]=r.w)});let c=Object.keys(e);if(!c.length)return;if(d&&(o.alt=d),s&&l&&(s>=l&&(o.class?o.class+=" portrait":o.class="portrait"),"setDims"in i.hash&&(o.width=l,o.height=s)),c.length>1&&l&&l<e[c[c.length-1]]){let t=c.findIndex(t=>e[t]>=l);c.splice(t+1),e[c[c.length-1]]=l}c.length>1&&(a=c.map(t=>`${t} ${e[t]}w`).join(", "),c.sort((t,r)=>Math.abs(e[t]-1280)-Math.abs(e[r]-1280))),n=c[0]}delete o.setDims,a||delete o.sizes,"alt"in o||(o.alt=""),!("loading"in o)&&(i?.data?.root?.sectionIndex>1||s)&&(o.loading="lazy");let l=Object.keys(o).map(t=>`${e.escapeExpression(t)}="${e.escapeExpression(o[t])}"`).join(" ");return new e.SafeString(`<img src="${n}"${a?` srcset="${a}"`:""}${l?` ${l}`:""}>`)},bgImage:e=>e?"string"==typeof e?e:e.largeUrl||e.url||"":"",concat(...e){let t="";for(let r in e)null!==e[r]&&void 0!==e[r]&&"object"!=typeof e[r]&&(t+=e[r]);return t},setVideoExtension(e,t){if(!e||!t)return"";let r=new URL(e);if("res.cloudinary.com"!==r.host)return r.pathname.endsWith(`.${t}`)?e:"";let i=r.pathname.lastIndexOf("."),s=r.pathname;return -1!==i&&(s=r.pathname.substr(0,i)),r.pathname=`${s}.${t}`,r.toString()},addVideoSources(e){if(!e)return"";if(!e.includes("res.cloudinary.com"))return`<source data-src="${e}">`;let t=e.replace(/\.(?:3gp|mpeg|mp4|m4v|m4p|ogv|ogg|mov|webm)$/,"");return[{format:"webm",codec:"vp9",htmlCodecs:";codecs=vp9"},{format:"mp4",codec:"h265",htmlCodecs:";codecs=hvc1"},{format:"mp4",codec:"h264",htmlCodecs:""}].map(e=>{let r=`${t.replace(/f_auto(?::video)?(?:,q_auto(?::\w+)?)?/,`f_${e.format},vc_${e.codec},q_auto:best,w_1920,c_limit`)}.${e.format}`;return`<source data-src="${r}" type="video/${e.format}${e.htmlCodecs}">`}).join("\n")},cloudinaryVideoFirstFrame:a.getVideoFirstFrame,initials(e,t){if(!e)return"";t?.hash?.endChar&&(e=e.split(t.hash.endChar)[0]);let r=+t?.hash?.maxChars||2,i=e.match(/\b\w/g)?.slice(0,r);return i?(t?.hash?.addText&&(i=i.map(e=>e+t.hash.addText)),i.join(t?.hash?.joinWith||"").toUpperCase()):""},normalizePhone(e){if(!e)return"";let t=String(e).trim();return(t.startsWith("+")?"+":"")+t.replace(/\D/g,"")}}};class m{constructor(e,t,r){if(this.config=e,this.window=t,this.document=r,!this.destroy)throw Error("Controllers must implement a deconstructor")}}let g="lp_lead_form_conversion_fired";function y(e,t){if(e&&t&&"function"==typeof t.sendGoogleTagManagerEvent&&!function(e){try{return"true"===e.sessionStorage.getItem(g)}catch{return!1}}(e))try{t.sendGoogleTagManagerEvent("event","generate_lead");try{e.sessionStorage.setItem(g,"true")}catch{}}catch{}}function f(e){return!!e&&(!!e.expired||Date.now()>=e.expiresAt)}let b="/api/v1/home-valuation";class v extends m{destroy(){}_cleanAddressString(e){if(!e||"string"!=typeof e)return"";let t=e.trim();if(t.includes("User entered address:")){let e=t.match(/User entered address:\s*\n?\s*([^\n]+)/);e&&e[1]&&(t=e[1].trim())}let r=t.indexOf(", call time frame:");return -1!==r&&(t=t.substring(0,r).trim()),t}_transformAddressComponents(e){let t=t=>(e.find(e=>e.componentType===t)||{}).componentName?.text,r={},i=t("street_number"),s=t("route"),o=t("administrative_area_level_1"),n=t("postal_code"),a=t("subpremise"),l=t("locality")||t("sublocality_level_1")||t("neighborhood");return i&&(r.streetNumber=i),s&&(r.streetName=s),l&&(r.city=l),o&&(r.state=o),n&&(r.zipcode=n),a&&(r.addressLine2=a),r}_extractAddressAndCoordinates(e){let t=null,r=null;if(e?.result){let{result:i}=e;i.address?.addressComponents&&(t=this._transformAddressComponents(i.address.addressComponents)),i.geocode?.location&&(r={latitude:i.geocode.location.latitude,longitude:i.geocode.location.longitude})}return{structuredAddress:t,coordinates:r}}_filterEmptyStrings(e){let t={};for(let[r,i]of Object.entries(e))""!==i&&null!=i&&(t[r]=i);return t}_getRawAddress(e){let t=e.activity.content||{},r=e.activity.comments_attributes?.[0]?.text;return[t.address,t["property-address"],t.property_address,t.Property_Address,r,t.message,t.homeValuationAddress,t.propertyAddress].map(e=>e&&this._cleanAddressString(e)).find(Boolean)||""}_logLeadEvent(e,t,r=null){let i={event:e,companyId:this.config.companyId,websiteId:this.config.websiteId,timestamp:new Date().toISOString(),hasEmail:!!t.activity?.author_email,hasAddress:!!this._getRawAddress(t)};if(r&&(i.errorMessage=r.userMessage||(r.status?`Request failed with status ${r.status}`:"An error occurred"),i.errorName=r.name,i.errorStatus=r.status),console.error(`[HomeValuation] ${e}`,JSON.stringify(i)),this.window.posthog)try{this.window.posthog.capture(e,i)}catch(e){console.error("[HomeValuation] PostHog capture failed:",e)}}_getUserFriendlyErrorMessage(e){return"AbortError"===e.name||e.message?.includes("timeout")?"Connection timed out. Please try again.":"TypeError"===e.name&&e.message?.includes("fetch")?"Unable to connect. Please check your internet connection and try again.":503===e.status||502===e.status||504===e.status?"Service temporarily unavailable. Please try again in a moment.":400===e.status?"Please check your information and try again.":"Something went wrong. Please try again or c
1777ontact us directly."}_formatStructuredAddress(e){if(!e||0===Object.keys(e).length)return"";let t=[];return t.push([e.streetNumber,e.streetName,e.addressLine2].filter(Boolean).join(" ")),t.push([[e.city,e.state].filter(Boolean).join(", "),e.zipcode].filter(Boolean).join(" ")),t.filter(Boolean).join(", ")}_buildHomeValuationData(e,t,r,i){let s=this._formatStructuredAddress(r)||this._getRawAddress(e);if(!s)throw Error("Unable to extract home valuation address from form data");let o={companyId:e.companyId,homeValuationAddress:s,homeValuationEstimate:t?new Intl.NumberFormat("en-US",{style:"currency",currency:"USD",maximumFractionDigits:0,minimumFractionDigits:0}).format(t):null,websiteId:e.page.websiteId,sourceUrl:e.activity.source_url},n={leadEmailAddress:e.activity.author_email,leadFullName:e.activity.author_name,leadFirstName:e.activity.firstName,leadLastName:e.activity.lastName,leadPhoneNumber:e.activity.author_phone,parcelId:e.activity.content?.parcelId,resourceId:e.page.pageMeta?.resourceId,pageId:e.page.pageId,sourceResource:e.page.pageMeta?.s
1777ourceResource,pageElementId:e.page.pageMeta?.pageElementId,formId:e.page.pageMeta?.formId,utmSource:e.activity.content?.utm_source,utmMedium:e.activity.content?.utm_medium,utmCampaign:e.activity.content?.utm_campaign,utmTerm:e.activity.content?.utm_term,utmContent:e.activity.content?.utm_content,utmId:e.activity.content?.utm_id,timeToSell:e.activity.content?.timeToSell,lookingToBuy:e.activity.content?.lookingToBuy,consented:!!e.activity.content?.termsAccepted,referrer:e.referrer,content:e.activity.content||{},fields:e.fields||{}},a=this._filterEmptyStrings(n);return{...o,...a,...r&&{address:r},...i&&{coordinates:i}}}async _validateAddressSafely(e){if(!e)return console.error("Home valuation: No address found in form data"),null;try{return await this._validateAddressWithGoogleMaps(e)}catch(e){throw console.error("Error validating address with Google Maps:",e),e.userMessage=this._getUserFriendlyErrorMessage(e),e}}async _getHomeValuationEstimateSafely(e){try{return await this._getHomeValuationEstimate(e)}catch(e){throw console.error("Error getting home valuation estimate:",e),e.userMessage=this._getUserFriendlyErrorMessage(e),e}}_isSafeRedirectUrl(e){try{let{protocol:t}=new URL(e,this.window.location.href);return"https:"===t||"http:"===t}catch{return!1}}_parseResponsePayload(e){try{return e?JSON.parse(e):{}}catch{return{raw:e}}}_createResponseError(e,t){let r=Error(e&&"object"==typeof e&&Object.keys(e).length?e.message||JSON.stringify(e):"Request failed");return e&&"object"==typeof e&&Object.keys(e).length&&Object.assign(r,e),r.status=t,r}_resolveValuationApiBase(){let{config:e}=this;if(void 0!==e.valuationApiBase&&null!==e.valuationApiBase&&(""!==e.valuationApiBase||!e.isBuilder))return e.valuationApiBase;if(e.websiteApiGatewayUrl)return e.websiteApiGatewayUrl;throw Error("websiteApiGatewayUrl/valuationApiBase not configured for home valuation")}async _submitLead(e,t,r){let i=new AbortController,s=setTimeout(()=>i.abort(),1e4);try{let o=await fetch(e,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(t),signal:i.signal});clearTimeout(s);let n=await o.text(),a=this._parseResponsePayload(n);if(!o.ok)throw this._createResponseError(a,o.status);if(a&&"success"===a.status&&a.redirectUrl){if(f(r))return a;if(!this._isSafeRedirectUrl(a.redirectUrl))return console.error("Home valuation: refusing redirect to unsupported protocol"),a;return this.window.location.href=a.redirectUrl,{redirected:!0,url:a.redirectUrl}}return a}catch(e){throw clearTimeout(s),e}}async _submitHomeValuationRequest(e){let t=this._resolveValuationApiBase();this._logLeadEvent("home_valuation_submission_started",e);try{let r=this._getRawAddress(e),i=null;try{i=await this._validateAddressSafely(r)}catch(t){throw this._logLeadEvent("home_valuation_address_validation_failed",e,t),t}let s=null;try{s=await this._getHomeValuationEstimateSafely(i)}catch(t){this._logLeadEvent("home_valuation_estimate_failed",e,t),s=null}let{structuredAddress:o,coordinates:n}=this._extractAddressAndCoordinates(i),a=`${t}${b}`,l=this._buildHomeValuationData(e,s,o,n),d=await this._submitLead(a,l,e.deadline);return this._logLeadEvent("home_valuation_submission_success",e),d}catch(t){throw t.userMessage||(t.userMessage=this._getUserFriendlyErrorMessage(t)),this._logLeadEvent("home_valuation_submission_failed",e,t),t}}async _validateAddressWithGoogleMaps(e){let{config:t,window:r}=this,i=t.googleMapsAPIKey;if(!i&&r.luxuryPresence?.mapApiLoader&&(i=await r.luxuryPresence.mapApiLoader.getMapApiKey()),!i)throw Error("Google Maps API key not configured");let s=new AbortController,o=setTimeout(()=>s.abort(),1e4);try{let t=await fetch(`https://addressvalidation.googleapis.com/v1:validateAddress?key=${i}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({address:{addressLines:[e]},enableUspsCass:!1}),signal:s.signal});if(clearTimeout(o),!t.ok){let e=Error(`Address validation failed: ${t.status}`);throw e.status=t.status,e}return t.json()}catch(e){throw clearTimeout(o),e}}_hasMandatoryAddressFields(e){return!!(e.streetNumber&&e.streetName&&e.city&&e.state&&e.zipcode)}_logMissingAddressFields(e){let t=[];e.streetNumber||t.push("streetNumber"),e.streetName||t.push("streetName"),e.city||t.push("city"),e.state||t.push("state"),e.zipcode||t.push("zipcode"),console.log("Home valuation estimate skipped - missing required fields:",t.join(", "),"Available fields:",Object.keys(e).join(", "))}_buildAddressQueryString(e){return Object.entries(e).map(([e,t])=>`${encodeURIComponent(e)}=${encodeURIComponent(t)}`).join("&")}async _getHomeValuationEstimate(e=null){let t=`${this._resolveValuationApiBase()}${b}`;if(!e?.result?.address?.addressComponents)return null;let r=this._transformAddressComponents(e.result.address.addressComponents);if(!this._hasMandatoryAddressFields(r))return this._logMissingAddressFields(r),null;let i=this._buildAddressQueryString(r),s=`${t}?${i}`,o=new AbortController,n=setTimeout(()=>
1777o.abort(),1e4);try{let e=await fetch(s,{headers:{Accept:"application/json"},signal:o.signal});if(clearTimeout(n),!e.ok){let t=Error(`Home valuation estimate failed: ${e.status}`);throw t.status=e.status,t}let t=await e.json();return t?.valueDollars??null}catch(e){throw clearTimeout(n),e}}}let w="middleName",E="redirect-pending",_=["name","firstName","lastName",w,"email","phone","phoneNumber","source","message","mlsId","sourceUrl"],S="lp_map_key_failed",C="oauthSuccess",I={cookieyes:{eventName:"cookieyes_consent_update",hasAnalyticsConsent:e=>(function(e){let t=e.cookie.match(/cookieyes-consent=([^;]+)/);if(!t)return!1;try{let e=decodeURIComponent(t[1]);if(e.includes(",")){let t=e.split(",").map(e=>e.trim());if(t.some(e=>e.includes(":")))return t.some(e=>"analytics:yes"===e);return t.includes("analytics")}return e.includes("analytics")}catch(e){return!1}})(e),isAnalyticsAccepted:e=>Array.isArray(e?.accepted)&&e.accepted.includes("analytics")},"lp-consent":{eventName:"lp_consent_update",hasAnalyticsConsent:(e,t)=>!!t.__lpConsent?.state?.c?.analytics,isAnalyticsAccepted:e=>!!e?.choices?.analytics}};function A(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)}function x(e,t){t.forEach(t=>{let r=e[t];Array.isArray(r)&&0===r.length&&delete e[t]})}function R(e,t,r,i){let s=t.map(t=>(function e(t){return Array.isArray(t)?t.flatMap(t=>e(t)):"string"==typeof t?t.split(/\s+/).filter(Boolean):null==t?[]:[t]})(e[t])),o=i?.merge?s.flat():s.find(e=>e.length>0)??[];t.forEach(t=>{delete e[t]}),o.length>0&&(e[r]=[...new Set(o)])}function T(e){let t={...e};if(t.urlWebsite||(t.urlWebsite=null),t.urlYoutube=null,t.urlFacebook=null,t.urlInstagram=null,t.urlLinkedin=null,t.urlPodcast=null,t.urlTwitter=null,Array.isArray(e.socialLinks)){let r=[...e.socialLinks].sort((e,t)=>{let r=e.type?.toLowerCase()||"",i=t.type?.toLowerCase()||"";return r.localeCompare(i)});t.socialLinks=r;let i={youtube:"urlYoutube",facebook:"urlFacebook",instagram:"urlInstagram",linkedin:"urlLinkedin",podcast:"urlPodcast",twitter:"urlTwitter"};r.forEach(e=>{let r=i[e.type?.toLowerCase()??""];r&&(t[r]=e.link)})}return t}function L(e){return e&&Array.isArray(e)?e.map(e=>T(e)):e}function k(e){let{region:t}=e;if(!A(t))return e;let{schools:r,pois:i,...s}=t,o={...s,schools:A(r)?r.data??[]:[],...Array.isArray(i)?{pois:i.map(e=>({...e,category:"string"==typeof e.category?e.category.toUpperCase():e.category}))}:{}};return{...e,region:o}}function M(e){return e&&Array.isArray(e)?e.map(e=>k(e)):e}function $(e){let t=e.featuresAndAmenities;if(!Array.isArray(t))return e;let r=t.map(e=>({featureIds:e.featureIds??[],features:e.features??[],description:e.description}));return{...e,featuresAndAmenities:r}}function U(e){return e&&Array.isArray(e)?e.map(e=>$(e)):e}function P(e,t){return A(e)?t(e):e}function O(e,t){return Array.isArray(e)?t(e):e}var N={};N=` 1778 query PropertyDisclaimers($input: PropertyDisclaimersInput!) { 1779 propertyDisclaimers(input: $input) { 1780 feedId 1781 listingId 1782 resolvedFromListing 1783 listingCardAttribution 1784 listingDetailCourtesy 1785 listingDetailFooter 1786 logo 1787 } 1788 } 1789`;let D={mlsAttribution:"listingCardAttribution",mlsLogo:"logo",listingDetailCourtesy:"listingDetailCourtesy",listingDetailFooter:"listingDetailFooter"};var F={};F=s("ikl6F");let B=new class{constructor(e){this.isBuilder=!1,this.companyId=null,this.websiteId=null,this.pageId=null,this.shareId=null,this.pageMeta=null,this.websiteApiGatewayUrl=null,this.buyerSellerServiceUrl=null,this.leadIngesterUrl=null,this.divolteServiceUrl=null,this.eventBus=null,this.templateId=null,this.myhomeDashboardEnabled=!1,this.mlsEnabled=!1,this.hstValuationRedirectEnabled=!1,this.hvStepTwoCaptureEnabled=!1,this.googleMapsAPIKey=null,this.currencyConversionEnabled=!1,this.enabledCurrencies=[]}get valuationApiBase(){return this.isBuilder?this.websiteApiGatewayUrl:""}destroy(){}setPage(e,t={}){this.pageId=e,this.shareId=t.shareId||null,this.pageMeta={sourceResource:t.sourceResource,pageElementId:t.pageElementId,pageQueryVariables:t.pageQueryVariables||{}}}setIsBuilder(e){this.isBuilder=e}setCompany(e,t={}){this.companyId=e}setWebsite(e,t={}){this.websiteId=e,t.myhomeDashboardEnabled&&(this.myhomeDashboardEnabled=t.myhomeDashboardEnabled),t.mlsEnabled&&(this.mlsEnabled=t.mlsEnabled),t.hstValuationRedirectEnabled&&(this.hstValuationRedirectEnabled=t.hstValuationRedirectEnabled),t.hvStepTwoCaptureEnabled&&(this.hvStepTwoCaptureEnabled=t.hvStepTwoCaptureEnabled)}setWebsiteApiGatewayUrl(e,t={}){this.websiteApiGatewayUrl=e}setBuyerSellerServiceUrl(e,t={}){this.buyerSellerServiceUrl=e}setDivolteServiceUrl(e,t={}){this.divolteServiceUrl=e}setEventBusUrl(e,t={}){this.eventBusUrl=e}setTemplateId(e,t={}){this.templateId=e}setLeadIngesterUrl(e,t={}){this.leadIngesterUrl=e}setGoogleMapsAPIKey(e,t={}){this.googleMapsAPIKey=e}setCurrencyConversion({enabled:e,enabledCurrencies:t}={}){this.currencyConversionEnabled=!0===e,this.enabledCurrencies=Array.isArray(t)?t.filter(e=>"string"==typeof e):[]}setEventBus({enabled:e,apiKey:t,url:r}){this.eventBus={enabled:e,apiKey:t,url:r}}}({}),q=new class extends m{constructor(e,t,r){super(e,t,r),this.setLoginState=this.setLoginState.bind(this),this.pageId=null,this.modals=[],this.exitModalTriggered={},this.exitModalEventListeners=[]}initialize(e){try{let{config:t,document:r}=this;this.pageId=t.pageId,this.modals=r.querySelectorAll("body > #modals >
1789 .modal"),e.modals.forEach(e=>{this._attachModalHandler(e)})}catch(e){console.log(e)}}destroy(){let{document:e}=this;this.exitModalEventListeners.forEach(t=>{e.removeEventListener("mouseout",t)}),this.modals=[],this.exitModalTriggered={},this.exitModalEventListeners=[]}setModalWithExpiry(e){let{window:t}=this,r=new Date().getTime()+864e5,i=`modal-controller-${e}`;try{t.localStorage.setItem(i,JSON.stringify(r))}catch(e){}}setLoginState(){let{window:e}=this;try{e.localStorage.setItem("isSignedUp","true")}catch(e){}}getModalWithExpiry(e){let{window:t}=this,r=t.localStorage,i=r.getItem(`modal-controller-${e}`);if(!i)return!1;let s=JSON.parse(i);return!(new Date().getTime()>s)||(r.removeItem(`modal-controller-${e}`),!1)}show(e,t={}){let{window:r}=this,i=this.getModalWithExpiry(e);(e&&!i||!0===t.forced)&&(r.lpUI.showModal(`modal-${e}`,t),this.setModalWithExpiry(e))}_attachModalHandler(e){let{pageId:t}=this,{trigger:r,pageSpecific:i}=e;(!i||e.pages.map(e=>e.pageId).includes(t))&&("EXIT"===r?this._exitModalHandler(e):"TIMER"===r?this._timerModalHandler(e):"FORCED"===r&&this._forcedModalHandler(e))}_exitModalHandler(e){let t=this,{document:r,exitModalTriggered:i}=this,{modalId:s}=e;function o(e){!i[s]&&(e.toElement||e.relatedTarget||(t.show(s),i[s]=!0))}r.addEventListener("mouseout",o),this.exitModalEventListeners.push(o)}_timerModalHandler(e){let{modalId:t,timerDelay:r}=e;setTimeout(()=>{this.show(t)},r)}_forcedModalHandler(e){let{modalId:t}=e,{window:r,document:i}=this;if("true"!==r.localStorage.getItem("isSignedUp")){let e=i.querySelector(`#modal-${t}`),s=e?.querySelector("form"),o=s?.dataset.delay||2e3;s.addEventListener("formsubmitted",()=>{this.setLoginState()}),r.addEventListener("oauthSuccess",()=>{this.setLoginState(),s.classList.add("success"),setTimeout(()=>{r.lpUI.hideModal(`modal-${t}`),s.reset(),s.classList.remove("success")},o)}),this.show(t,{forced:!0})}}}(B,window,document),V=new class extends m{constructor(e,t,r){super(e,t,r),this._boundClickHandler=this._buttonClickHandler.bind(this)}initialize(e={}){try{let{document:e}=this;e.body.removeEventListener("click",this._boundClickHandler),e.body.addEventListener("click",this._boundClickHandler)}catch(e){console.error(e)}}destroy(){let{document:e}=this;e.body.removeEventListener("click",this._boundClickHandler)}_buttonClickHandler(e){this._handleButtonClick(e).catch(e=>console.error(e))}async _handleButtonClick(e){let{window:t,document:r}=this,i=e.target.closest("button, a");if(!i)return;let s=i.dataset.type||"",o=i.href||i.dataset.href||"",n=i.target||"",{submit:a}=i.dataset;if(a){try{await this._handleSubmit(i)}catch(e){console.error(e)}((e,t=!1)=>{if(e){if(t)return window.open(e);window.location.assign(e)}})(o,"_blank"===n)}if(this._trackConversion(i),"VIDEO"===s)return void this._handleVideoButton(i);if("CONTACT_US"===s)return void this._handleContactUsButton(i);if("SUBSCRIBE"===s)return void t.lpUI.showModal("modal-global-subscribe");if("MY_ACCOUNT"===s)return void t.lpUI.showModal("modal-global-my-account");if("SHARE_POPUP"===s){let t=i.querySelector(".share-popup");t&&(t.style.display="flex"),e.stopPropagation();return}if("MODAL_"===s.substring(0,6)){let e=s.substring(6);t.lpUI.showModal(`modal-${e}`);return}if(o?.startsWith("mailto:")){let e=o.substring(7);r.sendGoogleAnalyticsEvent({hitType:"event",eventCategory:"button",eventAction:"click",eventLabel:"Email",eventValue:e})}else if(o?.startsWith("tel:")){let e=o.substring(4);r.sendGoogleAnalyticsEvent({hitType:"event",eventCategory:"button",eventAction:"click",eventLabel:"Phone",eventValue:e})}}async _handleSubmit(e){let t=e.closest("form"),{window:r}=this;return t?await r.luxuryPresence.contactForms.submitForm(t):null}_getVimeoSrc(e){if(!e||!e.includes("vimeo.com")||e.length>2e3)return null;let t=e.match(/(?:(?:www\.)?vimeo\.com\/(?:showcase\/\d+(?:\/video\/|\?video[=/])|channels\/(?:\w+\/)?|groups\/(?:[^/]*)\/videos\/|)|player\.vimeo\.com\/video\/)(\d+)(?:(?:\?.*&*h=|\/)+([\d,a-f]+))?/);if(!t)return null;let[,r,i]=t,s=`https://player.vimeo.com/video/${r}?`;return i&&(s+=`h=${i}&`),s+="autoplay=1"}_handleVideoButton(e){let{document:t}=this,r=e.closest("section"),{src:i}=e.dataset,s="";if(i&&(i.includes("youtube.com")||i.includes("youtu.be"))&&!i.includes("youtube.com/embed")){let e=i.match(/(?:youtube\.com\/\S*(?:(?:\/e(?:mbed))?\/|watch\?(?:\S*?&?v=)
1789)|youtu.be\/)([a-zA-Z0-9_-]{6,11})/);e&&(s=e[1])}let o=this._getVimeoSrc(i);if(s?i=`https://youtube.com/embed/${s}?autoplay=1&controls=0`:o&&(i=o),!i||!r)return;let n=i.endsWith(".mp4")||i.endsWith(".webm")||i.includes("cloudinary.com"),a=` 1790 <div id="modal-${r.id}" class="modal visible"> 1791 <div class="modal-content"> 1792 <div class="lightbox-video"> 1793 <div class="video-player"> 1794 <div class="embed-container"> 1795 ${n?`<video controls autoplay src="${i}"></video>`:`<iframe frameborder="0" allowfullscreen="1" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" title="YouTube video player" width="100%" height="100%" src="${i}"></iframe>`} 1796 </div> 1797 </div> 1798 </div> 1799 </div> 1800 <button class="close lp-close" type="button" aria-label="close modal"><span class="lp-close-icon" aria-hidden="true"></span></button> 1801 </div> 1802 `;t.body.insertAdjacentHTML("beforeend",a);let l=t.getElementById(`modal-${r.id}`);l.querySelector(".close").addEventListener("click",()=>{l.remove()})}_handleContactUsButton(e){let{window:t,document:r}=this;r.sendGoogleAnalyticsEvent({hitType:"event",eventCategory:"button",eventAction:"click",eventLabel:"contact"}),t.lpUI.showModal("modal-global-contact-us",{scrollLock:!0})}_trackConversion(e){let{window:t,document:r}=this,{gtagConversionId:i,gtagConversionLabel:s,fbEventName:o}=e.dataset;if(i&&s){t.dataLayer&&t.dataLayer.length&&(t.dataLayer.some(e=>e.length&&"config"===e[0]&&e[1]===i)||r.sendGoogleTagManagerEvent("config",i));let e=`${i}/${s}`;r.sendGoogleTagManagerEvent("event","conversion",{send_to:e})}t.fbq&&o&&t.fbq("track",o,{})}}(B,window,document),j=new class extends m{constructor(e,t,r){super(e,t,r),this.validatedForms=[]}initialize(e={}){try{let{window:t,document:r}=this,{selector:i}=e,s=[];if(s=i?r.querySelectorAll(`${i} form[data-type="contact-form"]`):r.querySelectorAll('form[data-type="contact-form"]'),r.querySelectorAll('input[type="tel"]').length&&!t.libphonenumber&&t?.luxuryPresence?.libs){let{loadJs:e,jsLibsMap:r}=t.luxuryPresence.libs,{libphonenumber:i}=r;e(i.jsSrc,this.attachValidation.bind(this,s))}else this.attachValidation(s);this.validatedForms=this.validatedForms.concat(s)}catch(e){console.log(e)}}destroy(){this.validatedForms=[]}attachValidation(e){e.forEach(e=>{e.querySelectorAll("input, select, textarea").forEach(e=>{this.applyFieldValidation(e)})})}applyFieldValidation(e){"tel"===e.getAttribute("type")&&this._applyPhoneValidation(e)}_applyPhoneValidation(e){let{window:t}=this;if(t.libphonenumber){let r=t.libphonenumber.isValidPhoneNumber;e.addEventListener("keyup",function(){if(this.hasAttribute("required")||this.value.replace(/\s/g,"").length)try{let e=this.value;r(e,"US")?this.setCustomValidity(""):this.setCustomValidity("Please enter a valid phone number.")}catch(e){this.setCustomValidity("Please enter a valid phone number.")}else this.setCustomValidity("")})}}}(B,window,document),H=new class extends m{constructor(e,t,r){super(e,t,r),this.forms=[],this.homeValuationService=new v(e,t,r)}initialize(e={}){try{let{document:t}=this,{selector:r}=e,i=[];(i=r?t.querySelectorAll(`${r} form[data-type="contact-form"]`):t.querySelectorAll('form[data-type="contact-form"]')).forEach(e=>{this._attachSubmitHandler(e)}),this.forms=this.forms.concat(i)}catch(e){console.log(e)}}destroy(){this.forms=[]}submitForm(e){this._handleSubmit(null,e).catch(e=>console.error(e))}_attachValidation(e){let{window:t}=this;e.querySelectorAll("input, select, textarea").forEach(e=>{t.luxuryPresence.validation.applyFieldValidation(e)})}_attachSubmitHandler(e){e.addEventListener("submit",t=>this._handleSubmit(t,e))}_extractFormValues(e){let t=new FormData(e),r={},i=[],s=/^name(?:-\d+)?$/;return t.forEach((e,t)=>{if("string"==typeof e){let o=e.trim();s.test(t)&&o&&i.push(o);let n=r[t];r[t]=n?`${n} ${o}`:o}else r[t]=e}),i.length?r.name=i.join(" ").trim():!r.name&&r.firstName&&(r.name=r.firstName,r.lastName&&(r.name+=` ${r.lastName}`)),this._deriveNameParts(r)}_deriveNameParts(e){if(e.firstName||!e.name)return e;let t=e.name.indexOf(" ");return -1===t?{...e,firstName:e.name}:{...e,firstName:e.name.slice(0,t),lastName:e.lastName||e.name.slice(t+1).trim()}}_buildSubmissionData(e,t,r){let{window:i,config:s}=this,o=Object.keys(e).filter(e=>!_.includes(e)).reduce((t,r)=>(t[r]=e[r],t),{}),{pageId:n,companyId:a,websiteId:l,pageMeta:d}=s,c=i.localStorage.getItem("utm_vars")||"{}",u=i.localStorage.getItem("referrer")||"",h=this._getFormId(r);return{activity:{author_email:e.email,author_name:e.name,firstName:e.firstName||void 0,lastName:e.lastName||void 0,author_phone:e.phone||e.phoneNumber,activity_source:e.source||"CONTACT_INQUIRY",comments_attributes:[{text:e.message||void 0}],source_url:i.location.href,content:{...o,...JSON.parse(c)}},page:{pageId:n,companyId:a,websiteId:l,pageMeta:{...d,formId:h}},companyId:a,referrer:u,fields:t}}_handleSubmissionSuccess(e){let{window:t}=this,r=e.dataset.delay||2e3;e.classList.remove("loading"),e.classList.remove("error"),e.classList.add("success"),e.querySelectorAll(".success").forEach(e
1802=>e.classList.remove("hide")),e.dispatchEvent(new Event("formsubmitted")),setTimeout(()=>{t.lpUI.hideClosestModal(e),e.reset(),t.lpUI.sideMenuHide(),e.querySelectorAll(".success").forEach(e=>e.classList.add("hide")),e.classList.remove("success")},r)}async _handleSubmit(e,t){if(e&&e.preventDefault(),!t.classList.contains("loading")){this._hideSubmissionError(t),t.classList.remove("error"),t.classList.add("loading");try{let e=this._extractFormValues(t);if(e.middleName)return void t.classList.remove("loading");let r=this._getFields(t),i=this._buildSubmissionData(e,r,t);y(this.window,this.document);let s=await this._waitForLeadSubmit(e=>this._submitLeadRequest(i,e));if(this._sendGAEvent(i),s?.redirected)return void this._showRedirectPending(t);this._handleSubmissionSuccess(t)}catch(e){console.error("Form submission failed:",e),t.dispatchEvent(new Event("formsubmiterror")),t.classList.remove("loading"),t.classList.add("error"),e.userMessage?this._showSubmissionError(t,e.userMessage):this._showSubmissionError(t,"Something went wrong. Please try again.")}}}async _waitForLeadSubmit(e){let t,r={expired:!1,expiresAt:Date.now()+6e3},i=new Promise(e=>{t=setTimeout(()=>{r.expired=!0,e(null)},6e3)}),s=e(r).catch(e=>{if(f(r))return null;throw e});try{return await Promise.race([s,i])}finally{clearTimeout(t)}}_showRedirectPending(e){if(e.classList.add(E),e.querySelector(`.${E}__indicator`))return;let t=this.document.createElement("div");t.className=`${E}__indicator`,t.setAttribute("role","status"),t.setAttribute("aria-label","Loading"),t.innerHTML='<span class="lp-i lp-i--spinner lp-i--pulse" aria-hidden="true"></span>',e.appendChild(t)}_aliasUserWithEventBus(e){try{if(!this.window.eventBusProvider?.alias||!this.window.eventBusProvider?.isIdentified||!this.window.eventBusProvider?.getDistinctId||!this.window.LuxuryPresenceEventBus?.generateUUIDv5FromCompanyEmail)return;if(this.window.eventBusProvider.isIdentified())return void console.log("[EventBus] User already identified, skipping alias");let t=e.activity?.author_email,{companyId:r}=this.config;if(!t||!r)return void console.warn("[EventBus] Missing required data for user alias");let i=this.window.eventBusProvider.getDistinctId();if(!i)return void console.warn("[EventBus] No anonymous ID available for alias");let s=this.window.LuxuryPresenceEventBus.generateUUIDv5FromCompanyEmail(r,t);this.window.eventBusProvider.alias({anonId:i,canonicalId:s}),console.log("[EventBus] User aliased with canonical ID")}catch(e){console.error("[EventBus] User alias failed:",e)}}async _submitLeadRequest(e,t){let{config:r}=this;return(this._aliasUserWithEventBus(e),r.myhomeDashboardEnabled&&(e.activity?.activity_source==="HOME_VALUATION"||e.activity?.activity_source==="HOME_VALUE"))?this.homeValuationService._submitHomeValuationRequest({...e,deadline:t}):fetch(`${r.leadIngesterUrl}/api/v1/leads`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)}).then(e=>e.ok?e.json():e.json().then(e=>{throw e}))}_sendGAEvent(e){let{document:t}=this,r={hitType:"event",eventCategory:"button",eventAction:"click"};switch(e.activity.activity_source){case"NEWSLETTER_SIGNUP":r.eventLabel="Newsletter",t.sendGoogleTagManagerEvent("event","newsletter_signup");break;case"HOME_SEARCH":r.eventLabel="HomeSearch",t.sendGoogleTagManagerEvent("event","home_search");break;case"HOME_VALUE":case"HOME_VALUATION":r.eventLabel="HomeValue",t.sendGoogleTagManagerEvent("event","home_valuation");break;case"EBOOK":r.eventLabel="Ebook",t.sendGoogleTagManagerEvent("event","ebook_download");break;default:r={hitType:"pageview",page:"/thank-you"},t.sendGoogleTagManagerEvent("event","contact_inquiry")}t.sendGoogleAnalyticsEvent(r)}_getFields(e){let t=e.querySelectorAll("input, select, textarea"),r={};return t.forEach(t=>{let{id:i,name:s,type:o}=t;if(s===w)return!0;let n="";if(i){let r=e.querySelector(`label[for='${i}']`);r?n=r.textContent.trim():t.placeholder&&(n=t.placeholder.trim())}r[s]={label:n,type:t.tagName,inputType:"INPUT"===t.tagName?o:"text"}}),r}_getFormId(e){let t=e.closest("section[id^='section-'], footer[id], .modal[id^='modal-']");return t?.id?this._cleanFormId(t.id):""}_cleanFormId(e){for(let t of["section-","modal-"])if(e.startsWith(t))return e.substring(t.length);return e}_showSubmissionError(e,t){let r=e.querySelector(".submission-error-message");r||((r=this.document.createElement("div")).className="submission-error-message",r.setAttribute("role","alert"),e.appendChild(r)),r.textContent=t||"Something went wrong. Please try again.",r.style.display="block"}_hideSubmissionError(e){let t=e.querySelector(".submission-error-message");t&&(t.style.display="none")}}(B,window,document),G=new class extends m{constructor(e,t,r){super(e,t,r),this.retries=3,this.callbacks=[],this.id=`__googleMapsScriptId${Date.now()}`,this._apiKey="",this.reset()}set apiKey(e){this._apiKey=e,this.config.setGoogleMapsAPIKey(e)}get apiKey(){return this._apiKey}reset(){this.deleteScript(),this.done=!1,this.loading=!1,this.failed=!1,this.errors=[],this.onerrorEvent=null}destroy(){this.reset()}async getMapApiKey(){if(this.apiKey)return this.apiKey;let e=this._hadPreviousFailure(),t=!1;for(let r=1;r<=3;r+=1){let i=e&&!t;try{let e=await fetch(this._getMapKeyUrl(r,i));if(t=t||i,this._setFailureFlag(!1),!e.ok)throw Error(`Failed to fetch API key: ${e.status}`);let s=await e.text();if(!s)return"";return this.apiKey=s,this.apiKey}catch(e){console.error(e),r<3&&await this._delay(300*2**(r-1))}}return this._setFailureFlag(!0),""}_getMapKeyUrl(e,t){let r=[];e>1&&r.push(`attempt=${e}`),t&&r.push("recovered_after_failure=1");let i=r.length?`?${r.join("&")}`:"";return`${this._getBaseUrl()}/api/v1/map${i}`}_hadPreviousFailure(){try{return"1"===this.window.sessionStorage.getItem(S)}catch(e){return!1}}_setFailureFlag(e){try{e?this.window.sessionStorage.setItem(S,"1"):this.window.sessionStorage.removeItem(S)}catch(e){}}_delay(e){return new Promise(t=>{this.window.setTimeout(t,e)})}async createUrl(){let e=await this.getMapApiKey();if(!e)throw Error("Refusing to load Google Maps without an API key");
1802let t="https://maps.googleapis.com/maps/api/js";return t+`?callback=__googleMapsCallback&key=${e}&libraries=places`}async setScript(){let e;if(this.document.getElementById(this.id))return void this.callback();try{e=await this.createUrl()}catch(e){console.error(e),this.failed=!0,this.loading=!1,this.onerrorEvent=e,this.callback();return}let t=this.document.createElement("script");t.id=this.id,t.type="text/javascript",t.src=e,t.onerror=this.loadErrorCallback.bind(this),t.defer=!0,t.async=!0,this.document.head.appendChild(t)}loadErrorCallback(e){if(this.errors.push(e),this.errors.length<=this.retries){let e=this.errors.length*2**this.errors.length;console.log(`Failed to load Google Maps script, retrying in ${e} ms.`),setTimeout(()=>{this.deleteScript(),this.setScript().catch(e=>console.error(e))},e)}else this.failed=!0,this.onerrorEvent=e,this.callback()}deleteScript(){let e=this.document.getElementById(this.id);e&&e.remove()}load(){return this.loadPromise()}loadPromise(){return new Promise((e,t)=>{this.loadCallback(r=>{r?t(r):e()})})}loadCallback(e){this.callbacks.push(e),this.execute()}setCallback(){this.window.__googleMapsCallback=this.callback.bind(this)}resetIfRetryingFailed(){this.failed&&this.reset()}callback(){this.done=!0,this.loading=!1,this.callbacks.forEach(e=>{e(this.onerrorEvent)}),this.callbacks=[]}execute(){this.window.google&&this.window.google.maps&&this.window.google.maps.version&&this.callback(),this.resetIfRetryingFailed(),this.done?this.callback():this.loading||(this.loading=!0,this.setCallback(),this.setScript().catch(e=>console.error(e)))}_getBaseUrl(){let{isBuilder:e,websiteApiGatewayUrl:t}=this.config;return e?t:""}resizeStaticMapDimensions(e,t){if(e<=1024&&t<=1024)return{width:e,height:t};let r=Math.min(1024/e,1024/t);return{width:parseInt(e*r),height:parseInt(t*r)}}convertThemeToStaticApiUrl(e){return e.map(e=>{let t=e.stylers.reduce((e,t)=>{let r=t.visibility?`visibility:${t.visibility}`:"",i=t.color?`color:${t.color.replace("#","0x")}`:"",s=t.lightness?`lightness:${t.lightness}`:"";return`${e}|${r}${i}${s}`},""),r=e.elementType?`|element:${e.elementType}`:"";return`feature:${e.featureType}${r}${t}`})}async getMapApiSignedUrl(e){try{let t=await fetch(`${this._getBaseUrl()}/api/v1/map/signature?${e}`);if(!t.ok)throw Error("Failed to fetch signed URL");let{url:r}=await t.json();return r}catch(e){return console.error(e),""}}generateStaticMapUrl(e,t,r,i,s,o){let{width:n,height:a}=this.resizeStaticMapDimensions(s,o),l={center:`${e},${t}`,zoom:r,scale:2,size:`${n}x${a}`,key:this.apiKey};i&&(l.style=this.convertThemeToStaticApiUrl(i));let d=new URLSearchParams;return Object.entries(l).forEach(([e,t])=>{Array.isArray(t)?t.forEach(t=>d.append(e,t.toString())):d.append(e,t.toString())}),`https://maps.googleapis.com/maps/api/staticmap?${d.toString()}`}async generateDigitallySignedStaticMapUrl({srcWidth:e,srcHeight:t,theme:r,...i}){let{width:s,height:o}=this.resizeStaticMapDimensions(e,t),n={...i,size:`${s}x${o}`};r&&(n.style=this.convertThemeToStaticApiUrl(r));let a=new URLSearchParams;Object.entries(n).forEach(([e,t])=>{Array.isArray(t)?t.forEach(t=>a.append(e,t.toString())):a.append(e,t.toString())});let l=a.toString();try{return await this.getMapApiSignedUrl(l)}catch(e){return console.error(e),""}}}(B,window,document),K=new class extends m{destroy(){}updateQueryString(e,t,r){r||(r=this.window.location.href);let i=RegExp(`([?&])${e}=.*?(&|#|$)`,"i"),s="";null!=t&&(Array.isArray(t)?t.length&&(s=this.serializeArray(e,t)):"object"==typeof t?(i=RegExp(`([?&])${e}\\[[^=]*\\]=.*?(&|#|$)`,"i"),s=this.serializeObj(t,"",e)):s=`${e}=${encodeURIComponent(t)}`);let o=r.split("#"),n=o[0];if(i.test(r)){let e=n;for(s=s?`$1${s}$2`:"$1";i.test(e);)n=e.replace(i,s),e=e.replace(i,"$1");n=n.replace(/(&|\?)$/,"")}else if(s){let e=-1!==n.indexOf("?")?"&":"?";n+=`${e}${s}`}return void 0!==o[1]&&null!==o[1]&&(n+=`#${o[1]}`),n}getParameterByName(e,t){t||(t=this.window.location.href),e=e.replace(/[[\]]/g,"\\$&");let r=RegExp(`[?&]${e}(=([^&#]*)|&|#|$)`),i=Array.from(RegExp.prototype[Symbol.matchAll].call(r,t)).flat();if(!i.length){let r=RegExp(`[?&]${e}(\\[.*?\\])=(.*?)(?=&|#|$)`,"g");return i=Array.from(RegExp.prototype[Symbol.matchAll].call(r,t)).flat(),this._parseParamToObject(i,"advancedFilters"===e)}return i.length>3?i.reduce((e,t,r)=>((r+1)%3==0&&e.push(decodeURIComponent(t.replace(/\+/g," "))),e),[]):i[2]?decode
1802URIComponent(i[2].replace(/\+/g," ")):""}makePageKey(e){return e.replace("section-","").replace(/-/g,"")}makeParamKey(e,t){return e.global?e.urlKey:`${t}-${e.urlKey}`}deserializeParams(e,t){let r={},i=this.makePageKey(t),s=this.getParameterByName(i);return s&&(r.page=parseInt(s)),Array.isArray(e)&&e.forEach(e=>{let t=this.makeParamKey(e,i),s=this.getParameterByName(t);if("int"===e.type)isFinite(s=parseInt(s))||(s=null);else if("bool"===e.type||"boolean"===e.type)s="true"===s||"false"!==s&&null;else if("json"===e.type)try{s=JSON.parse(s)}catch(e){}r[e.formKey||e.param]=s}),r}serializeParams(e,t,r){let i=this.window.location.href,s=this.makePageKey(t);return i=this.updateQueryString(s,r.page,i),Array.isArray(e)&&e.forEach(e=>{let t=this.makeParamKey(e,s),o=r[e.formKey||e.param];"json"===e.type&&null!=o&&(o=JSON.stringify(o)),i=this.updateQueryString(t,o,i)}),i}formatSliderAtom(e,t=""){return t+(Number.isInteger(e)?e:e.toFixed(2))}formatSliderValue(e,t="",r=""){return e<1e3?this.formatSliderAtom(e,t):e<1e6?`${this.formatSliderAtom(e/1e3,t)}${r}K`:`${this.formatSliderAtom(e/1e6,t)}${r}M`}formatSliderPriceRange(e,t,r,i){return t.min===e&&0!==e?`${i.lowPrefix}${this.formatSliderValue(e,r," ")}`:t.max===e?`${this.formatSliderValue(e,r," ")}${i.highSuffix}`:`${this.formatSliderValue(e,r," ")}`}formatSliderAreaRange(e,t,r,i){return t.min===e&&0!==e?`${i.lowPrefix}${this.formatSliderValue(e)} ${r}`:t.max===e?`${this.formatSliderValue(e)}${i.highSuffix} ${r}`:`${this.formatSliderValue(e)} ${r}`}getSearchFormValues(e){let{queryElement:t,priceSliderElement:r,areaSliderElement:i,neighborhoodSelect:s}=e,o={};if(t&&(o.search=t.value||null),r){let e=r.value.split(";"),t=parseInt(r.dataset.min),i=parseInt(r.dataset.max),s=parseInt(e[0]),n=parseInt(e[1]);o.priceMin=s!==t?s:null,o.priceMax=n!==i?n:null}if(i){let e=i.value.split(";"),t=parseInt(i.dataset.min),r=parseInt(i.dataset.max),s=parseInt(e[0]),n=parseInt(e[1]);o.areaMin=s!==t?s:null,o.areaMax=n!==r?n:null}return s&&(o.neighborhoodId=s.value||null),o}serializeObj(e,t="",r=""){let i=[];for(let s in e)if(e.hasOwnProperty(s)){let o,n=e[s];if(r){let e=t?`[${t}][${s}]`:`[${s}]`;o=`${r}${e}`}else o=t?`${t}[${s}]`:s;null!==n&&Array.isArray(n)?n.length&&i.push(this.serializeArray(o,n)):null!==n&&"object"==typeof n?i.push(this.serializeObj(n,o)):i.push(`${o}=${encodeURIComponent(n)}`)}return i.join("&")}serializeArray(e,t,r=""){let i=[];return t.forEach(t=>{let s=r?`${r}${e}`:e;i.push(`${s}=${encodeURIComponent(t)}`)}),i.join("&")}_parseParamToObject(e,t=!1){if(!e.length)return null;let r={};for(let i=0;i<e.length;i++)if((i+1)%3==0){let s=decodeURIComponent(e[i].replace(/\+/g," ")),o=e[i-1];Object.assign(r,this._setObjectPath(o,s,r,t))}return r}_setObjectPath(e,t,r,i=!1){let s=e.split(/[\[\]]/).filter(Boolean),o=["in","nin","btw","ciin","cinin"],n={},a=n,l=((e,t,r)=>{if(!t)return;let i=(Array.isArray(t)?t:t.match(/([^[.\]])+/g)).reduce((e,t)=>e&&e[t],e);return void 0===i?r:i})(r,s.join("."));return s.forEach((e,n)=>{n===s.length-1?l?a[e]=Array.isArray(l)?[...l,t]:[l,t]:a[e]=i&&o.includes(e)?[t]:t:(a[e]=r[e]?r[e]:{},a=a[e])}),n}}(B,window,document),Y=new class extends m{constructor(e,t,r){super(e,t,r),this._createLightbox=this._createLightbox.bind(this),this.expandSliders=[]}initialize(e={}){try{let{document:e}=this,t=e.querySelectorAll(".has-mobile-expand");t.forEach(e=>{this._addExpandButton(e)}),this.expandSliders=this.expandSliders.concat(t)}catch(e){console.log(e)}}destroy(){let{document:e}=this;e.querySelectorAll(".lp-expand-btn, .lp-expand-btn-wrapper").forEach(e=>e.remove()),this.expandSliders=[]}_addExpandButton(e){let{document:t}=this,r=e.closest("section[id]"),i=e.dataset.append,s=r.querySelector(".lp-expand-btn");if(!s)if((s=t.createElement("button")).className="lp-expand-btn",s.setAttribute("aria-label","Open a lightbox"),s.innerHTML='<span class="lp-i lp-i--expand-alt" aria-hidden="true"></span>',i){let e=r.querySelector(i);e&&e.appendChild(s)}else{let r=t.createElement("div");r.className="lp-expand-btn-wrapper",r.style.position="relative",r.appendChild(s),e.parentNode.insertBefore(r,e.nextSibling)}s.addEventListener("click",()=>{this._createLightbox({slider:e,section:r})})}_createLightbox({slider:e,section:t,initialIndex:r}){let{window:i,document:s}=this,o=`lightbox-for-${t?.id}`,n=i.$&&i.$.fn.slick,a=n&&e.slick,l="function"==typeof i.Splide,d=e.classList.contains("is-initialized")&&e.classList.contains("splide");function c(){let t=s.createElement("div");t.id=o,t.className="lp-lightbox",t.setAttribute("tabindex","-1"),t.setAttribute("role","dialog"),t.setAttribute("aria-modal","true"),t.innerHTML=` 1803 <button class="lp-lightbox__close" aria-label="close modal"></button> 1804 <div class="lp-lightbox__content"> 1805 <div class="lp-lightbox__carousel splide" role="group" aria-label="Image Gallery"> 1806 <div class="splide__arrows"> 1807 <button class="splide__arrow splide__arrow--prev lp-lightbox-arrow lp-lightbox-arrow--prev"></button> 1808 <button class="splide__arrow splide__arrow--next lp-lightbox-arrow lp-lightbox-arrow--next"></button> 1809 </div> 1810 <div class="splide__track"> 1811 <ul class="splide__list"></ul> 1812 </div> 1813 </div> 1814 </div> 1815 `,"function"==typeof i.lpUI.requestScrollLock?i.lpUI.requestScrollLock(o):s.body.style.overflow="hidden",s.body.appendChild(t);let n=t.querySelector(".lp-lightbox__carousel"),a=n.querySelector(".splide__list");t.classList.add("show"),(d?e.querySelectorAll(".splide__slide:not(.splide__slide--clone) img"):e.querySelectorAll("img")).forEac
1815h(e=>{let t=e.cloneNode(!0);t.removeAttribute("style");let r=s.createElement("li");r.className="lp-lightbox__slide splide__slide",r.appendChild(t),a.appendChild(r)});let l=new i.Splide(n,{rewind:!0,arrows:!0,arrowPath:"",type:"loop",clones:1,pagination:!1,perPage:1,perMove:1});l.mount(),void 0!==r&&r>=0&&l.go(r),setTimeout(()=>{t.focus()},100);let c=e=>{if(!t.classList.contains("show"))return;let r=t.querySelector(".splide__arrow--prev"),i=t.querySelector(".splide__arrow--next"),s=t.querySelector(".lp-lightbox__close");"ArrowLeft"===e.key&&r?(e.preventDefault(),r.click()):"ArrowRight"===e.key&&i?(e.preventDefault(),i.click()):"Escape"===e.key&&s&&(e.preventDefault(),s.click())};s.addEventListener("keydown",c),t.querySelector(".lp-lightbox__close").addEventListener("click",()=>{s.removeEventListener("keydown",c),t.classList.remove("show"),l&&l.destroy(),"function"==typeof i.lpUI.releaseScrollLock?i.lpUI.releaseScrollLock(o):s.body.style.overflow="",t.remove()})}if("function"==typeof i.lpUI.requestScrollLock?i.lpUI.requestScrollLock(o):s.body.style.overflow="hidden",n&&!d){let t,r,n,l,d;r={arrows:!0,dots:!1,infinite:!0,draggable:!0,prevArrow:'<button type="button" class="lp-lightbox-arrow--prev lp-lightbox-arrow" aria-label="Previous"></button>',nextArrow:'<button type="button" class="lp-lightbox-arrow--next lp-lightbox-arrow" aria-label="Next"></button>'},(n=s.createElement("div")).id=o,n.className="lp-lightbox",n.setAttribute("tabindex","-1"),n.setAttribute("role","dialog"),n.setAttribute("aria-modal","true"),n.innerHTML=` 1816 <button class="lp-lightbox__close" aria-label="close modal"></button> 1817 <div class="lp-lightbox__content"> 1818 <div class="lp-lightbox__carousel"></div> 1819 </div> 1820 `,s.body.appendChild(n),l=n.querySelector(".lp-lightbox__carousel"),n.classList.add("show"),a?(t=e.slick.$slides.find("img"),r.initialSlide=e.slick?.currentSlide||0,t.each(function(){i.$(".lp-lightbox__carousel").append(i.$(this).clone(!1).removeAttr("style").wrap('<div class="lp-lightbox__slide"></div>').parent())})):(t=e.querySelectorAll("img")).forEach(e=>{let t=e.cloneNode(!0);t.removeAttribute("style");let r=s.createElement("div");r.className="lp-lightbox__slide",r.appendChild(t),l.appendChild(r)}),i.$(l).slick(r),setTimeout(()=>{n.focus()},100),d=e=>{if(!n.classList.contains("show"))return;let t=n.querySelector(".lp-lightbox-arrow--prev"),r=n.querySelector(".lp-lightbox-arrow--next"),i=n.querySelector(".lp-lightbox__close");"ArrowLeft"===e.key&&t?(e.preventDefault(),t.click()):"ArrowRight"===e.key&&r?(e.preventDefault(),r.click()):"Escape"===e.key&&i&&(e.preventDefault(),i.click())},s.addEventListener("keydown",d),n.querySelector(".lp-lightbox__close").addEventListener("click",()=>{s.removeEventListener("keydown",d),n.classList.remove("show");let t=l?.slick?i.$(l).slick("slickCurrentSlide"):0;l?.slick&&i.$(l).slick("unslick"),a&&i.$(e).slick("slickGoTo",t),"function"==typeof i.lpUI.releaseScrollLock?i.lpUI.releaseScrollLock(o):s.body.style.overflow="",n.remove()})}else l?c():(i.luxuryPresence.libs.loadCss(i.luxuryPresence.libs.jsLibsMap.splide.cssSrc),i.luxuryPresence.libs.loadJs(i.luxuryPresence.libs.jsLibsMap.splide.jsSrc,()=>{c(),i.luxuryPresence.libs.jsLibsMap.splide.isLoaded=!0}))}}(B,window,document),z=new class extends m{destroy(){this.window.divolte||(this.window.divolteLp=function(){(this.window.divolteLp.q=this.window.divolteLp.q||[]).push(arguments)})}initialize(e={}){let{divolteServiceUrl:t}=this.config;t&&!this.window.divolte&&this.loadScript()}loadScript(){let{divolteServiceUrl:e}=this.config,t=this.document.createElement("script");t.id="divolte-script",t.type="text/javascript",t.defer=!0,t.async=!0,t.src=`${e}/divolte.js`,this.document.head.appendChild(t),t.addEventListener("load",this.executeQueue.bind(this))}executeQueue(){(this.window.divolteLp.q||[]).forEach(([e,t])=>{this[e](t)}),this.window.divolteLp=this.divolteLp.bind(this)}divolteLp(e,t){try{this[e](t)}catch(e){console.log(e)}}sendLpEvent(e,t){if(!e.includes("pageView"))return void console.log(`${e} IS NOT SUPPORTED`);let{companyId:r,templateId:i,websiteId:s,pageId:o,shareId:n,pageMeta:a}=this.config;this.window.divolte.signal(e,Object.assign({companyId:r,templateId:i,websiteId:s,pageId:o,shareId:n,pageMeta:a},t))}sendLpPageView(){this.sendLpEvent("pageView",{})}}(B,window,document),W=new class extends m{constructor(e,t,r){super(e,t,r)}initialize(e={}){(void 0!==e.enabled?e.enabled:this.config.eventBus?.enabled)&&this.config.eventBus?.apiKey&&this.config.eventBus?.url&&this.loadScript()}loadScript(){let{eventBusUrl:e}=this.config,t=this.document.createElement("script");t.id="posthog-script",t.type="text/javascript",t.defer=!0,t.async=!0,t.src=`${e}/v2.8.0/event-bus-js.js`,this.document.head.appendChild(t),t.addEventListener("load",this.executeQueue.bind(this))}executeQueue(){this.window.LuxuryPresenceEventBus&&(this.window.eventBusProvider=this.window.LuxuryPresenceEventBus.createEventBusProvider({apiKey:this.config.eventBus.apiKey,host:this.config.eventBus.url,defaultSource:"frontend://website-render-engine"}
1820)),(this.window.eventBusLp.q||[]).forEach(([e,t])=>{this[e](t)}),this.window.eventBusLp=this.eventBusLp.bind(this)}destroy(){if(!this.window.eventBusProvider){this.window.eventBusLp=function(){(this.window.eventBusLp.q=this.window.eventBusLp.q||[]).push(arguments)};return}this.window.eventBusProvider.shutdown()}sendLpEvent(e,t){if("user.activity.page.viewed"!==e)return void console.log(`${e} IS NOT SUPPORTED`);if(!this.window.eventBusProvider)return;let{companyId:r}=this.config;try{this.window.eventBusProvider.capture(e,{company:r,data:{}})}catch(e){console.log("EventBus capture error:",e)}}eventBusLp(e,t){try{this[e](t)}catch(e){console.log(e)}}sendLpPageView(){this.sendLpEvent("user.activity.page.viewed",{})}}(B,window,document),Q=new class extends m{constructor(e,t,r){super(e,t,r),this.successListeners=[],this._listenToMessages=this._listenToMessages.bind(this),this._listenToOneTapMessage=this._listenToOneTapMessage.bind(this)}initialize(e={}){try{e.googleSignOnEnabled&&!e.iframe&&this._renderGoogleOneTap(),this.document.querySelectorAll('div[data-signin-type="google-sign-in"]').forEach(e=>this._convertGoogleSignIn(e)),this.document.querySelectorAll('div[data-signin-type="facebook-sign-in"]').forEach(e=>this._convertFacebookSignIn(e))}catch(e){console.log(e)}}destroy(){this.successListeners.forEach(e=>{this.window.removeEventListener("message",this._listenToMessages),this.window.removeEventListener("message",this._listenToOneTapMessage),this.window.removeEventListener(C,this.window[e])})}_renderGoogleOneTap(){if(!this._isGoogleOneTapOnCooldown()){let e=this.document.createElement("div");google.accounts.id.initializeIntermediate({src:this._buildUrlAndCopyAttributes(e,e,"googleOneTap")}),this.window.localStorage.removeItem("googleOneTapExpiration"),this.window.addEventListener("message",this._listenToOneTapMessage)}}_listenToOneTapMessage(e){let t="show_intermediate_iframe",{buyerSellerServiceUrl:r}=this.config,{data:i,origin:s}=e,{type:o,height:n,event:a,source:l,token:d}=i;if(o===t||"hide_intermediate_iframe"===o){let e=this.document.getElementById("onetap_google_intermediate_iframe");e&&(e.style.height=n,e.style.display=o===t?"unset":"none")}s===r&&"GOOGLE_SIGN_ON"===l&&("success"===a?(this._setExpirationLsItem(864e5),this._handleQualifyingQuestionsModal(d)):"cancel"===a&&this._setExpirationLsItem(72e5))}_setExpirationLsItem(e){let t=new Date().getTime()+e;this.window.localStorage.setItem("googleOneTapExpiration",t)}_isGoogleOneTapOnCooldown(){return Number(this.window.localStorage.getItem("googleOneTapExpiration"))>new Date().getTime()}_convertGoogleSignIn(e){this._replaceWithIframe("googleSignIn",e)}_convertFacebookSignIn(e){this._replaceWithIframe("facebookSignIn",e)}_replaceWithIframe(e,t){this._attachSuccessCallback(t);let r=this.document.createElement("iframe");r.src=this._buildUrlAndCopyAttributes(t,r,e),r.dataset.isSocialOauthButton=!0,t.replaceWith(r)}_listenToMessages(e){let{buyerSellerServiceUrl:t}=this.config;if(e.origin===t&&"success"===e.data.event){let e=new Event(C);this.window.dispatchEvent(e),y(this.window,this.document),this.successListeners.forEach(t=>{this.window[t]?this.window[t](e):console.error(`Callback function ${t} not found on window object`)}),this.document.documentElement.classList.add("is-login-success")}}_attachSuccessCallback(e){this.window.addEventListener("message",this._listenToMessages);let t=e.dataset.onSuccessFunctionName;t&&this.successListeners.push(t)}_buildUrlAndCopyAttributes(e,t,r){let{buyerSellerServiceUrl:i,companyId:s,websiteId:o,pageId:n,pageMeta:a}=this.config,{location:l}=this.window,d=l.origin+l.pathname,c=new URL(`${i}/buttons/${r}`),u=this.window.localStorage.getItem("utm_vars"),h=this.window.localStorage.getItem("referrer");c.searchParams.append("companyId",s),c.searchParams.append("websiteId",o),c.searchParams.append("pageId",n),c.searchParams.append("sourceUrl",d),c.searchParams.append("pageMeta",JSON.stringify(a)),u&&c.searchParams.append("utm",u),h&&c.searchParams.append("referrer",h);let p=["data-size","data-width","data-text","data-button-type","data-shape","data-layout","data-max-rows","data-use-continue-as","data-type","data-theme","data-logo_alignment","data-locale"];
1820return Array.from(e.attributes).forEach(e=>{p.includes(e.nodeName)?c.searchParams.append(e.nodeName,e.nodeValue):t.setAttribute("id"===e.nodeName?"data-id":e.nodeName,e.nodeValue)}),c.toString()}_decodeToken(e){try{let t=e.split(".")[1].replace(/-/g,"+").replace(/_/g,"/"),r=4-t.length%4,i=4===r?t:t+"=".repeat(r);return JSON.parse(atob(i))}catch(e){return null}}_handleQualifyingQuestionsModal(e){if(e&&this.window.luxuryPresence&&this.window.luxuryPresence.qualifyingQuestionsModal){let t=this._decodeToken(e);t&&t.email&&this.window.luxuryPresence.qualifyingQuestionsModal.showModal(t.email,"Google Sign On")}}}(B,window,document),J=new class extends m{constructor(e,t,r){super(e,t,r),this.showModal=this.showModal.bind(this),this.hasModalBeenSubmitted=this.hasModalBeenSubmitted.bind(this),this.modalId="qualifying-questions-modal",this.cookieKey="qualifyingQuestionsModalSubmitted",this.qualifyingQuestionsModalEnabled=!0,this.eventListeners=[],this.timeouts=[]}initialize(e={}){this.qualifyingQuestionsModalEnabled=e.qualifyingQuestionsModalEnabled??this.qualifyingQuestionsModalEnabled,this.qualifyingQuestionsModalEnabled&&this.attachModalCloseListeners()}destroy(){this.eventListeners.forEach(({element:e,event:t,handler:r})=>{e&&e.removeEventListener&&e.removeEventListener(t,r)}),this.timeouts.forEach(e=>{clearTimeout(e)}),this.restoreBodyScroll(),this.eventListeners=[],this.timeouts=[]}hasModalBeenSubmitted(){return"true"===this.getCookie(this.cookieKey)}setModalSubmittedCookie(){this.setCookie(this.cookieKey,"true",365)}showModal(e,t){!this.qualifyingQuestionsModalEnabled||this.hasModalBeenSubmitted()||(this.updateEmailValue(e),this.updateTriggerSourceValue(t),this.showModalElement())}getModalElement(){let e=this.document.getElementById(this.modalId);return e||console.error("Modal element not found:",this.modalId),e}updateEmailValue(e){let t=this.getModalElement();if(!t)return;let r=t.querySelector('input[name="email"]');r&&"string"==typeof e&&(r.value=e)}updateTriggerSourceValue(e){let t=this.getModalElement();if(!t)return;let r=t.querySelector(`#${this.modalId}-triggerSource`);r&&"string"==typeof e&&(r.value=e)}showModalElement(){let e=this.getModalElement();e&&(e.style.display="flex",this.blockBodyScroll())}getCookie(e){let t=`; ${this.document.cookie}`.split(`; ${e}=`);return 2===t.length?decodeURIComponent(t.pop().split(";").shift()):null}setCookie(e,t,r){let i="";if(r){let e=new Date;e.setTime(e.getTime()+864e5*r),i=`; expires=${e.toUTCString()}`}let s="; path=/; SameSite=Lax";this.window&&this.window.location&&"https:"===this.window.location.protocol&&(s+="; Secure"),this.document.cookie=`${e}=${encodeURIComponent(t||"")}${i}${s}`}blockBodyScroll(){this._prevOverflow=this.document.body.style.overflow,this.document.body.style.overflow="hidden"}restoreBodyScroll(){this.document.body.style.overflow=this._prevOverflow||"",this._prevOverflow=null}attachModalCloseListeners(){let e=this.getModalElement();if(!e)return;let t=this.document.getElementById(`${this.modalId}-form`);if(t){let r=()=>{this.setModalSubmittedCookie();let t=setTimeout(()=>{e.style.display="none",this.restoreBodyScroll()},100);this.timeouts.push(t)};t.addEventListener("formsubmitted",r),this.eventListeners.push({element:t,event:"formsubmitted",handler:r})}let r=e.querySelector('[data-dismiss="modal"]');if(r){let t=()=>{e.style.display="none",this.restoreBodyScroll()};r.addEventListener("click",t),this.eventListeners.push({element:r,event:"click",handler:t})}let i=t=>{(t.target===e||t.target.id===this.modalId)&&(e.style.display="none",this.restoreBodyScroll())};e.addEventListener("click",i),this.eventListeners.push({element:e,event:"click",handler:i})}}(B,window,document),X=new class extends m{constructor(e,t,r){super(e,t,r),this.isValidating=!1,this.lastValidationResult=null,this.lastValidationTime=null,this.validationCacheDuration=3e5}destroy(){this.isValidating=!1,this.lastValidationResult=null,this.lastValidationTime=null}async validateSession(e={}){let{useCache:t=!0}=e;if(t&&null!==this.lastValidationResult&&this.lastValidationTime&&Date.now()-this.lastValidationTime<this.validationCacheDuration)return this.lastValidationResult;if(this.isValidating)return null!==this.lastValidationResult&&this.lastValidationResult;this.isValidating=!0;let r=` 1821 query { 1822 validSession { 1823 success 1824 } 1825 } 1826 `;try{let e=await this.window.fetch("/graphql",{method:"POST",headers:{"Content-Type":"application/json"},credentials:"include",body:JSON.stringify({query:r})});if(!e.ok)return console.error("SessionController: HTTP error during session validation",e.status),this.lastValidationResult=!1,this.lastValidationTime=Date.now(),!1;let t=await e.json();if(t.errors)return this.lastValidationResult=!1,this.lastValidationTime=Date.now(),!1;let i=t.data?.validSession?.success===!0;return this.lastValidationResult=i,this.lastValidationTime=Date.now(),i}catch(e){return console.error("SessionController: Error validating session",e),this.lastValidationResult=!1,this.lastValidationTime=Date.now(),!1}finally{this.isValidating=!1}}clearCache(){this.lastValidationResult=null,this.lastValidationTime=null}}(B,window,document),Z=new class extends m{constructor(e,t,r){super(e,t,r),this.consentListener=null,this.eventName=null}destroy(){this.consentListener&&this.eventName&&(this.document.removeEventListener(this.eventName,this.consentListener),this.consentListener=null)}loadScript(){this.document.getElementById("posthog-script")||this.window.luxuryPresence.eventBus.initialize({enabled:this.config.eventBus?.enabled}),this.document.getElementById("divolte-script")||this.window.luxuryPresence.divolte.initialize({})}removeScripts(){this.window.luxuryPresence?.eventBus?.destroy?.(),this.window.luxuryPresence?.divolte?.destroy?.(),this.document.getElementById("posthog-script")?.remove(),this.document.getElementById("divolte-script")?.remove()}async initialize(e={}){let t=I[e.provider];if(!t)return;this.eventName=t.eventName;let r=await this.window.luxuryPresence.session.validateSession();(t.hasAnalyticsConsent(this.document,this.window)||r)&&this.loadScript(),this.consentListener||(this.consentListener=e=>{t.isAnalyticsAccepted(e.detail)?this.loadScript():this.removeScripts()},this.document.addEventListener(t.eventName,this.consentListener))}}(B,window,document),ee=new class extends m{destroy(){}transformVariables(e,t){let r;return x(r={...t},["testimonialId"]),R(r,["testimonialId"],"testimonialIds"),0===r.limit&&delete r.limit,(void 0===r.limit||null===r.limit)&&(("testimonials"===e||"testimonialsCount"===e)&&(r.limit=50),("agents"===e||"agentsCount"===e||"developments"===e||"developmentsCount"===e||"neighborhoods"===e||"neighborhoodsCount"===e||"posts"===e||"postsCount"===e||"pressReleases"===e||"pressReleasesCount"===e)&&(r.limit=100)),!function(e){let{sortDir:t}=e;"string"==typeof t&&t.includes("_")&&(e.sortDir=t.replace(/_/g," "))}(r),!function(e,t){switch(t){case"agent":break;case"testimonials":case"testimonialsCount":x(e,["testimonialIds"]);break;case"agents":case"agentsCount":x(e,["officeId","teamId","developmentId","agentIds","tags"]),R(e,["officeId"],"officeIds"),R(e,["teamId"],"teamIds"),R(e,["developmentId"],"developmentIds");break;case"neighborhoods":case"neighborhoodsCount":x(e,["neighborhoodIds","neighborhoodId"]),R(e,["neighborhoodIds","neighborhoodId"],"neighborhoodId");break;case"developments":case"developmentsCount":x(e,["agentId","neighborhoodIds","neighborhoodId","developmentIds","tag"]),e.agentId&&Array.isArray(e.agentId)&&([e.agentId]=e.agentId),R(e,["neighborhoodIds","neighborhoodId"],"neighborhoodIds"),R(e,["developmentIds","developmentId"],"developmentIds");break;case"properties":case"propertiesCount":x(e,["statusIds","statusId","propertyTypeIds","propertyTypeId","propertyId","networkId","propertyIds","agentIds","teamIds","officeIds","neighborhoodIds","
1826spaceTypeIds","addressState","addressCity","backfillProviders","backfillMLSListingIds","backfillMLSAgentIds","backfillMLSOfficeIds"]),["propertyIds","agentIds","teamIds","officeIds","neighborhoodIds","spaceTypeIds","backfillMLSListingIds","backfillMLSAgentIds","backfillMLSOfficeIds"].forEach(t=>R(e,[t],t)),R(e,["statusIds","statusId"],"propertyStatusId"),e.excludeStatusId&&(e.excludePropertyStatusId=e.excludeStatusId,delete e.excludeStatusId),R(e,["propertyTypeIds","propertyTypeId"],"propertyTypeId"),R(e,["networkId"],"networkId"),R(e,["propertyId"],"propertyIds"),["salesPriceGTE","salesPriceLTE","leasePriceGTE","leasePriceLTE","livingSpaceSizeGTE","livingSpaceSizeLTE"].forEach(t=>{null!=e[t]&&(e[t]=Math.trunc(Number(e[t])))});break;case"posts":case"postsCount":x(e,["categoryIds","categoryId","neighborhoodId"]),void 0!==e.order&&(e.sort=e.order,delete e.order),R(e,["categoryIds","categoryId"],"categoryId");break;case"postCategories":x(e,["categoryId","categoryIds"]),void 0!==e.order&&(e.sort=e.order,delete e.order),R(e,["categoryIds","categoryId"],"categoryId");break;case"pressReleases":case"pressReleasesCount":x(e,["pressReleaseId","categories","propertyId","developmentId","agentId","teamId"]),R(e,["pressReleaseId"],"pressReleaseIds");break;case"offices":case"officesCount":x(e,["officeId","officeIds","tags"]),R(e,["officeId"],"officeIds");break;case"teams":case"teamsCount":x(e,["teamId","teamIds"]),R(e,["teamId"],"teamIds");break;case"pois":x(e,["categories"]),Array.isArray(e.categories)&&(e.categories=e.categories.map(e=>e.toLowerCase())),"string"==typeof e.sortBy&&(e.sortBy=e.sortBy.toLowerCase())}}(r,e),r}transformResponse(e,t){return"agent"===e?P(t,T):"agents"===e||"agentsCount"===e?O(t,L):"neighborhood"===e?P(t,k):"neighborhoods"===e||"neighborhoodsCount"===e?O(t,M):"development"===e?P(t,$):"developments"===e||"developmentsCount"===e?O(t,U):t}transformPage(e){return{items:e&&e.items||[],count:e&&e.total||0}}applyPropertyDisclaimers(t,r){if(!Array.isArray(t)||!t.length||!r||!r.length)return Promise.resolve(t);let i=t.filter(e=>e&&e.vendorId&&e.mlsId).map(e=>({feedId:e.vendorId,listingId:e.mlsId,officeName:e.officeName??null,agentMlsId:e.mlsAgentId??null,officeMlsId:e.mlsOfficeId??null,attributionContact:e.attributionContact??null,status:e.status??null,syncedAt:e.syncedAt??null})),s=e=>{let i={};return(e||[]).forEach(e=>{i[`${e.feedId}:${e.listingId}`]=e}),t.map(e=>{let t=e&&i[`${e.vendorId}:${e.mlsId}`],s={};return r.forEach(e=>{let r=t?t[D[e]]:void 0;s[e]=r??null}),{...e,...s}})};if(!i.length)return Promise.resolve(s([]));let{websiteId:o}=this.config;return this.window.superagent?this.window.superagent.post(`${this.window.luxuryPresence.defaults.routerUrl}/graphql`).withCredentials().send({query:e(N),variables:{input:{websiteId:"string"==typeof o?o:void 0,properties:i}}}).then(e=>s(e.body&&e.body.data&&e.body.data.propertyDisclaimers),e=>(console.warn("[RouterApiController] propertyDisclaimers lookup failed:",e),s([]))):Promise.resolve(s([]))}}(B,window,document),et=new class extends m{constructor(e,t,r){super(e,t,r),this.natives=new WeakMap,this.rates=new Map,this.pending=new Map,this.target=void 0,this.generation=0,this.initialized=!1,this.observer=null,this.abortController=null}get currentCurrency(){return this.target}get cookieOptions(){return{document:this.document,location:this.window.location}}get enabledCurrencies(){return(this.config.enabledCurrencies??[]).map(F.toSupportedToCurrency).filter(Boolean)}initialize(){return this.initialized||!this.config.currencyConversionEnabled?Promise.resolve():(this.initialized=!0,this.generation=0,this.abortController=new this.window.AbortController,this.target=(0,F.readValidCurrencyCookie)(this.cookieOptions,{enabled:!0,enabledCurrencies:this.enabledCurrencies}),this.observer=new this.window.MutationObserver(()=>this.ensureRates(this.apply())),this.observer.observe(this.document.body,{childList:!0,subtree:!0}),this.ensureRates(this.apply()))}setCurrency(e){if(!this.config.currencyConversionEnabled)return!1;let t=(0,F.toSupportedToCurrency)(e);return!!t&&!!this.enabledCurrencies.includes(t)&&(this.target=t,this.generation+=1,(0,F.writeCurrencyCookie)(this.cookieOptions,t)||console.warn("[CurrencyConversionController] could not persist currency preference:",t),this.apply(),!0)}reset(){this.config.currencyConversionEnabled&&(this.target=void 0,this.generation+=1,(0,F.clearCurrencyCookie)(this.cookieOptions),this.apply())}destroy(){this.observer?.disconnect(),this.observer=null,this.abortController?.abort(),this.abortController=null,this.pending.clear(),this.rates.clear(),this.generation=null,this.initialized=!1}apply(){let e=new Set;return this.document.querySelectorAll("[data-lp-price]").forEach(t=>{let r=this.natives.get(t);if(!r){if(!(r=(e=>{let t=e.getAttribute("data-lp-native-amount"),r=null===t||""===t.trim()?NaN:Number(t),i=(0,F.toSupportedFromCurrency)(e.getAttribute("data-lp-native-currency"));if(!Number.isFinite(r)||r<0||!i)return;let s=Number(e.getAttribute("data-lp-precision"));return{amount:r,currency:i,precision:Number.isInteger(s)&&s>=0?s:0,originalHTML:e.innerHTML}})(t)))return;this.natives.set(t,r)}this.rates.has(r.currency)||e.add(r.currency),this.render(t,r)}),[...e]}render(e,t){let r=this.convertedText(t);if(void 0===r){e.innerHTML!==t.originalHTML&&(e.innerHTML=t.originalHTML);return}e.textContent!==r&&(e.textContent=r)}convertedText(e){if(!this.target||this.target===e.currency)return;let t=this.rates.get(e.currency)?.[this.target];
1826if("number"!=typeof t||!Number.isFinite(t))return;let r=(0,F.convertAmount)(e.amount,t);if(void 0!==r)return(0,F.formatMoney)(r,this.target,{precision:e.precision})}ensureRates(e){return e.length?Promise.all(e.map(e=>this.requestRates(e))).then(()=>{null!==this.generation&&this.apply()}):Promise.resolve()}requestRates(e){let t=this.pending.get(e);if(t)return t;let r=this.abortController?.signal,i=(0,F.fetchExchangeRates)(e,{baseUrl:this.config.valuationApiBase,signal:r,onError:t=>console.warn(`[CurrencyConversionController] exchange rate fetch failed for ${e}:`,t)}).then(t=>{r?.aborted||this.rates.set(e,t??{})});return this.pending.set(e,i),i}}(B,window,document);function er(e,t){if(window.luxuryPresence[e])try{window.luxuryPresence[e].destroy()}catch(e){console.log(e)}window.luxuryPresence[e]=t}er("config",B),er("modals",q),er("buttons",V),er("validation",j),er("contactForms",H),er("mapApiLoader",G),er("pagination",K),er("expandSliders",Y),er("divolte",z),er("eventBus",W),er("oauth",Q),er("qualifyingQuestionsModal",J),er("session",X),er("consent",Z),er("redirects",{checkHstRedirect:function(e){let{config:t}=window.luxuryPresence;return!t.hvStepTwoCaptureEnabled&&!!t.hstValuationRedirectEnabled&&!!t.mlsEnabled&&!!t.myhomeDashboardEnabled&&(window.location.href=`/home-search/home-valuation?address=${encodeURIComponent(e)}`,!0)},destroy(){}}),er("routerApi",ee),er("currencyConversion",et),window.luxuryPresence.formatSliderPriceRange=K.formatSliderPriceRange.bind(K),window.luxuryPresence.formatSliderAreaRange=K.formatSliderAreaRange.bind(K),window.luxuryPresence.getSearchFormValues=K.getSearchFormValues.bind(K),window.luxuryPresence.handlebarsHelpersFactory=function(t){return e(n)(t,{isEqual:(e,t)=>e==t})}})(); 1827//# sourceMappingURL=lp-sdk.js.map 1828 1829 </script>
1829 1830 1831
1831<script> 1832 var lpGlobalInitialized = false; 1833 1834 function lpGlobalInit () { 1835 if (lpGlobalInitialized) { 1836 return; 1837 } 1838 lpGlobalInitialized = true; 1839 // Initialize wow animation plugin only according to turbolinks 1840 var wow; 1841 if (window.WOW) { 1842 wow = new WOW({ 1843 animateClass: 'animated', 1844 offset: wowOffset, 1845 live: false, 1846 callback: function(box) {} 1847 }); 1848 } 1849 // Initialize handlebar helpers only once 1850 function handlebarsInit() { 1851 if (!window.Handlebars) { 1852 return; 1853 } 1854 HandlebarsIntl.registerWith(Handlebars); 1855 Handlebars.registerHelper(window.luxuryPresence.handlebarsHelpersFactory(Handlebars)); 1856 } 1857 1858 handlebarsInit(); 1859 1860 /* Initialize Luxury Presence SDK */ 1861 try { 1862 window.luxuryPresence.config.setCompany("c1908ce5-efe4-423f-a0b8-f9e844db2413", {}); 1863 window.luxuryPresence.config.setWebsite("e8034653-cea9-43db-b10d-f8cf56e2295a", { 1864 myhomeDashboardEnabled: true, 1865 mlsEnabled: true, 1866 hstValuationRedirectEnabled: true, 1867 hvStepTwoCaptureEnabled: false 1868 }); 1869 const url = new URL(window.location.href); 1870 const shareId = url.searchParams.get('shareId'); 1871 window.luxuryPresence.config.setPage("82db1dbb-f788-4441-ac49-7470ecf525b1", { 1872 sourceResource: "", 1873 pageElementId: "", 1874 pageQueryVariables: {}, 1875 shareId: "", 1876 }); 1877 window.luxuryPresence.config.setWebsiteApiGatewayUrl("https://wgw.luxurypresence.com", {}); 1878 window.luxuryPresence.config.setBuyerSellerServiceUrl("https://bss.luxurypresence.com", {}); 1879 window.luxuryPresence.config.setDivolteServiceUrl("https://t.luxurypresence.com", {}); 1880 window.luxuryPresence.config.setEventBusUrl("https://cdn.luxurypresence.com/scripts/event-bus-js", {}); 1881 window.luxuryPresence.config.setEventBus({ 1882 enabled: true, 1883 apiKey: "phc_PMYT31xlmXBaTCwpIRx1v6RrpLVZIuP47N3mOT6KLnr", 1884 url: "https://p.luxurypresence.com", 1885 }); 1886 window.luxuryPresence.config.setTemplateId("1d3967df-14f2-449d-87b7-bd68bf93906f", {}); 1887 window.luxuryPresence.config.setLeadIngesterUrl("https://leads.luxurypresence.com", {}); 1888 window.luxuryPresence.buttons.initialize({}); 1889 window.luxuryPresence.consent.initialize({ provider: 'lp-consent' }); 1890 window.luxuryPresence.contactForms.initialize({}); 1891 window.luxuryPresence.validation.initialize({}); 1892 window.luxuryPresence.expandSliders.initialize({}); 1893 window.luxuryPresence.oauth.initialize({ googleSignOnEnabled: true, iframe: false }); 1894 window.luxuryPresence.qualifyingQuestionsModal.initialize({ qualifyingQuestionsModalEnabled: true }); 1895 /* Optional: cached pages / older SDKs may not carry this controller */ 1896 window.luxuryPresence.currencyConversion?.initialize(); 1897 } catch (e) { 1898 console.log(e); 1899 } 1900 1901 /* Inject Section Specific Javascript */ 1902 try { 1903(function init(sectionDomId) { 1904 const section = document.getElementById(sectionDomId); 1905 const contactTitle = section.querySelector('.js-contact-title'); 1906 const emailInput = section.querySelector('.js-email-input'); 1907 const emailRegex = /[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~\-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)+/; 1908 emailInput.addEventListener('input', function () { 1909 if (emailRegex.test(this.value)) { 1910 this.setCustomValidity(''); 1911 } else { 1912 this.setCustomValidity('Please enter a valid email address.'); 1913 } 1914 this.reportValidity(); 1915 }); 1916 const inputName = section.querySelector('.js-input-name'); 1917 inputName.addEventListener('keyup', function () { 1918 if (this.value.replaceAll(/\d/g, "").trim().split(" ").length < 2 || this.value.replaceAll(/\d/g, "").trim() === "") { 1919 this.setCustomValidity("Please input your first name and last name."); 1920 } else { 1921 this.setCustomValidity(""); 1922 } 1923 }); 1924 function setHttp(link) { 1925 if (link.search(/^http[s]?\:\/\/|\//) == -1) { 1926 link = 'https://' + link; 1927 } 1928 return link; 1929 } 1930 const socialLinks = section.querySelectorAll('.lp-socials__link, .contact-form-modal-details__socials-l
1930ink'); 1931 socialLinks.forEach(linkElement => { 1932 const href = linkElement.getAttribute('href'); 1933 if (href) { 1934 linkElement.setAttribute('href', setHttp(href)); 1935 } 1936 }); 1937 if (contactTitle.length < 1) return; 1938 let words = contactTitle.textContent.split(" "); 1939 if (words.length > 1) { 1940 contactTitle.innerHTML = `<span class="contact__title-top">${words[0]} </span><span class="contact__title-bottom">${words.splice(1).join(" ")}</span>`; 1941 } 1942 const addRedirectToForm = () => { 1943 const redirectLink = document.getElementById(`${sectionDomId}`).querySelector('.js-redirect-link'); 1944 const form = document.getElementById(`${sectionDomId}`).querySelector('.js-form'); 1945 function redirectPage(link) { 1946 if (link) { 1947 const rawHref = link.getAttribute('href'); 1948 link.setAttribute('href', setHttp(rawHref)); 1949 link.click(); 1950 } 1951 } 1952 function setHttp(link) { 1953 if (link.search(/^http[s]?\:\/\/|\//) == -1) { 1954 link = 'http://' + link; 1955 } 1956 return link; 1957 } 1958 form.addEventListener("reset", function () { 1959 redirectPage(redirectLink); 1960 }); 1961 }; 1962 addRedirectToForm(); 1963})('modal-global-contact-us'); 1964} catch(e) { 1965console.log(e); 1966} 1967 1968 try { 1969(function init(sectionDomId) { 1970 (function () { 1971 const observer = new IntersectionObserver(entries => { 1972 entries.forEach(entry => { 1973 if (entry.isIntersecting) entry.target.classList.add('is-in-viewport'); 1974 }); 1975 }, { 1976 threshold: 0.5 1977 }); 1978 const initialElements = document.querySelectorAll('[data-animate="true"]'); 1979 initialElements.forEach(element => observer.observe(element)); 1980 const container = document.querySelector('.data-container'); 1981 if (container) { 1982 const mutationObserver = new MutationObserver(mutations => { 1983 mutations.forEach(mutation => { 1984 if (mutation.type === 'childList') { 1985 mutation.addedNodes.forEach(node => { 1986 if (node.nodeType === 1 && node.getAttribute('data-animate') === 'true') observer.observe(node); 1987 }); 1988 } 1989 }); 1990 }); 1991 mutationObserver.observe(container, { 1992 childList: true, 1993 subtree: true 1994 }); 1995 } 1996 })(); 1997 const sectionSelector = document.getElementById(sectionDomId); 1998 const searchToggleSelector = sectionSelector.querySelector('.js-search-toggle-btn'); 1999 const searchWrapperSelector = sectionSelector.querySelector('.js-header-search'); 2000 const header = sectionSelector.querySelector('.js-header'); 2001 let lastScrollTop = 0; 2002 (function (stickyAnchorRoot) { 2003 if (!stickyAnchorRoot) return; 2004 function getInFlowTop(target) { 2005 var inlineValue = target.style.getPropertyValue('position'); 2006 var inlinePriority = target.style.getPropertyPriority('position'); 2007 target.style.setProperty('position', 'relative', 'important'); 2008 var top = target.getBoundingClientRect().top + window.pageYOffset; 2009 if (inlineValue) target.style.setProperty('position', inlineValue, inlinePriority);else target.style.removeProperty('position'); 2010 var scrollMarginTop = parseFloat(window.getComputedStyle(target).scrollMarginTop) || 0; 2011 return Math.max(0, top - scrollMarginTop); 2012 } 2013 stickyAnchorRoot.addEventListener('click', function (event) { 2014 if (event.defaultPrevented || event.button !== 0) return; 2015 if (event.metaKey || event.ctrlKey || event.shiftKey || event.altKey) return; 2016 if (document.body.hasAttribute('data-scroll-container')) return; 2017 var link = event.target.closest('a[href]'); 2018 if (!link || !stickyAnchorRoot.contains(link) || link.target === '_blank') return; 2019 var href = link.getAttribute('href'); 2020 if (!/^#[^#]/.test(href)) return; 2021 var targetId; 2022 try { 2023 targetId = decodeURIComponent(href.slice(1)); 2024 } catch (e) { 2025 return; 2026 } 2027 var target = document.getElementById(targetId); 2028 if (!target || window.getComputedStyle(target).position !== 'sticky') return; 2029 event.preventDefault(); 2030 if (window.location.hash !== href) window.history.pushState(null, '', href); 2031 window.requestAnimationFrame(function () { 2032 window.scrollTo({ 2033 top: getInFlowTop(target) 2034 }); 2035 }); 2036 }); 2037 })(document.getElementById(sectionDomId)); 2038 const subNavOpeners = sectionSelector.querySelectorAll('.js-subnav-opener');
2039 subNavOpeners.forEach(opener => { 2040 opener.addEventListener('click', function (e) { 2041 e.preventDefault(); 2042 e.stopPropagation(); 2043 const parent = opener.parentElement; 2044 subNavOpeners.forEach(otherOpener => { 2045 if (otherOpener !== opener) { 2046 otherOpener.parentElement.classList.remove('header-navigation__item--sub-nav--opened'); 2047 } 2048 }); 2049 parent.classList.toggle('header-navigation__item--sub-nav--opened'); 2050 }); 2051 }); 2052 document.addEventListener('click', function (e) { 2053 if (!e.target.closest('.js-subnav-opener') && !e.target.closest('.header-navigation__item--sub-nav--opened')) { 2054 subNavOpeners.forEach(opener => { 2055 opener.parentElement.classList.remove('header-navigation__item--sub-nav--opened'); 2056 }); 2057 } 2058 }); 2059 function initHeaderColors() { 2060 try { 2061 var colorStr = window.getComputedStyle(header).getPropertyValue("--backgroundColor"); 2062 var bgColor = makeColor(colorStr); 2063 var isDark = (bgColor.rgba.r * 299 + bgColor.rgba.g * 587 + bgColor.rgba.b * 114) / 1000 < 128; 2064 sectionSelector.classList.add('is-background-color-' + (isDark ? 'dark' : 'light')); 2065 } catch (e) {} 2066 } 2067 function makeColor(str) { 2068 var color = { 2069 rgba: { 2070 r: 0, 2071 g: 0, 2072 b: 0, 2073 a: 0 2074 } 2075 }; 2076 if (str && str.match) { 2077 var m = str.match(/rgba?\s*\((\d+)\s*,\s*(\d+)\s*,\s*(\d+)(?:\s*,\s*([\.0-9]+))?\)/); 2078 if (m) { 2079 color.rgba.r = parseInt(m[1]); 2080 color.rgba.g = parseInt(m[2]); 2081 color.rgba.b = parseInt(m[3]); 2082 color.rgba.a = parseFloat(m[4]); 2083 if (isNaN(color.rgba.a)) { 2084 color.rgba.a = 1; 2085 } 2086 } 2087 } 2088 return color; 2089 } 2090 initHeaderColors(); 2091 var navEl = document.querySelector('nav > header') || document.querySelector('nav'); 2092 var navbarHeight = navEl ? navEl.offsetHeight : 0; 2093 if (navEl) { 2094 if (window.ResizeObserver) { 2095 new ResizeObserver(function (entries) { 2096 if (!entries.length) return; 2097 navbarHeight = entries[0].target.offsetHeight; 2098 }).observe(navEl); 2099 } else { 2100 window.addEventListener('resize', function () { 2101 navbarHeight = navEl.offsetHeight; 2102 }); 2103 } 2104 } 2105 function isLocomotiveActive() { 2106 return document.body.hasAttribute('data-scroll-container'); 2107 } 2108 function updateHeaderVisibility(currentScrollTop) {
2109 if (!searchWrapperSelector || searchWrapperSelector.style.display !== 'block') { 2110 if (currentScrollTop === 0) header.classList.remove('header--hide');else if (currentScrollTop > lastScrollTop) header.classList.add('header--hide');else header.classList.remove('header--hide'); 2111 } 2112 lastScrollTop = currentScrollTop; 2113 } 2114 function customHeaderHideShow(currentScrollTop) { 2115 if (!navEl) return; 2116 if (currentScrollTop > 0) { 2117 navEl.classList.add('scroll'); 2118 } else { 2119 navEl.classList.remove('scroll'); 2120 } 2121 if (currentScrollTop > lastScrollTop && currentScrollTop > navbarHeight) { 2122 document.documentElement.style.setProperty('--global-header-height', '0px'); 2123 } else { 2124 document.documentElement.style.setProperty('--global-header-height', navbarHeight + 'px'); 2125 } 2126 } 2127 window.addEventListener('scroll', function () { 2128 if (isLocomotiveActive()) return; 2129 var currentScrollTop = window.scrollY || document.documentElement.scrollTop; 2130 updateHeaderVisibility(currentScrollTop); 2131 }); 2132 var isTicking = false; 2133 var latestLocoScrollY = 0; 2134 window.addEventListener('locomotive-scroll', function (e) { 2135 latestLocoScrollY = e.detail.scrollY; 2136 if (!isTicking) { 2137 window.requestAnimationFrame(function () { 2138 customHeaderHideShow(latestLocoScrollY); 2139 updateHeaderVisibility(latestLocoScrollY); 2140 isTicking = false; 2141 }); 2142 isTicking = true; 2143 } 2144 }); 2145 if (searchToggleSelector !== null) { 2146 searchToggleSelector.addEventListener('click', function () { 2147 if (searchWrapperSelector.style.display === 'block') { 2148 searchWrapperSelector.style.display = 'none'; 2149 } else { 2150 searchWrapperSelector.style.display = 'block'; 2151 header.classList.remove('header--hide'); 2152 } 2153 }); 2154 document.addEventListener('click', function (evt) { 2155 if (!searchToggleSelector.contains(evt.target) && !searchWrapperSelector.contains(evt.target)) searchWrapperSelector.style.display = 'none'; 2156 }); 2157 } 2158 window.luxuryPresence.mapApiLoader.load().then(() => {
2159 if (!searchWrapperSelector) return; 2160 const templateHTML = sectionSelector.querySelector('.js-card-template')?.innerHTML; 2161 const itemTemplate = templateHTML && Handlebars.compile(templateHTML); 2162 const searchMls = searchWrapperSelector.dataset.searchMls === 'true'; 2163 const searchProperties = searchWrapperSelector.dataset.searchProperties === 'true'; 2164 const selectedCountries = searchWrapperSelector.dataset.locations; 2165 const searchInputSelector = sectionSelector.querySelector('.js-header-search-input'); 2166 const searchIconSelector = sectionSelector.querySelector('.js-header-btn-search'); 2167 const closeIconSelector = sectionSelector.querySelector('.js-header-btn-close'); 2168 const searchResultsSelector = sectionSelector.querySelector('.js-header-search-results-holder'); 2169 const resultsContainerSelector = sectionSelector.querySelector('.js-header-results-container'); 2170 const loaderSelector = sectionSelector.querySelector('.js-header-spinner'); 2171 const predefinedSelector = sectionSelector.querySelector('.js-header-search-results-predefined'); 2172 const nothingFoundSelector = sectionSelector.querySelector('.js-header-spinner-nothing-found'); 2173 const service = new google.maps.places.AutocompleteService(); 2174 const geocoder = new google.maps.Geocoder(); 2175 var keyword; 2176 var leasePropertyState = false; 2177 var leasePropertySearched; 2178 var isLoading = false; 2179 var newSearchTimer; 2180 var placesResult = {}; 2181 function updateSearchDisplay() { 2182 var hasResults = !!resultsContainerSelector.innerHTML; 2183 var hasPredefined = predefinedSelector.querySelectorAll('a:not(.not-processed)').length > 0; 2184 nothingFoundSelector.style.display = 'none'; 2185 if (hasResults) { 2186 predefinedSelector.style.display = 'none'; 2187 loaderSelector.style.display = 'none'; 2188 resultsContainerSelector.style.display = 'block'; 2189 } else if (isLoading) { 2190 resultsContainerSelector.style.display = 'none'; 2191 predefinedSelector.style.display = 'none'; 2192 loaderSelector.style.display = 'block'; 2193 } else if (hasPredefined) { 2194 resultsContainerSelector.style.display = 'none'; 2195 loaderSelector.style.display = 'none'; 2196 predefinedSelector.style.display = 'block'; 2197 } else { 2198 resultsContainerSelector.style.display = 'none'; 2199 loaderSelector.style.display = 'none'; 2200 predefinedSelector.style.display = 'none'; 2201 if (keyword) nothingFoundSelector.style.display = 'block'; 2202 } 2203 } 2204 function moveSelection(up) { 2205 var count = resultsContainerSelector.innerHTML ? resultsContainerSelector : predefinedSelector; 2206 var links = count.querySelectorAll('.results-link'); 2207 if (!links.length) return; 2208 var idx = -1; 2209 links.forEach((link, i) => { 2210 if (idx === -1 && link.classList.contains('header-search-results__link--selected')) idx = i; 2211 }); 2212 var newIdx; 2213 if (up) { 2214 newIdx = idx - 1; 2215 if (newIdx < 0) newIdx = links.length - 1; 2216 } else { 2217 newIdx = idx + 1; 2218 if (newIdx > links.length - 1) newIdx = 0; 2219 } 2220 if (newIdx !== idx) { 2221 searchResultsSelector.querySelector('.header-search-results__link--selected')?.classList.remove('header-search-results__link--selected'); 2222 links[newIdx].classList.add('header-search-results__link--selected'); 2223 } 2224 } 2225 function startSearch() { 2226 const term = searchInputSelector.value; 2227 if (term === keyword && leasePropertySearched === leasePropertyState) return; 2228 leasePropertySearched = leasePropertyState; 2229 keyword = term; 2230 if (term) doSearch(term, leasePropertySearched);else setResults(null); 2231 } 2232 function mlsSearch(term) { 2233 var query = { 2234 omnibox: term, 2235 limit: 5 2236 }; 2237 return superagent.get(window.location.protocol + '//' + window.location.host + '/home-search/listings.json').query(query).then(function (res) { 2238 if (!Array.isArray(res.body)) return []; 2239 return res.body.map(function (item) { 2240 return { 2241 id: item.id, 2242 display_address: [item.address_1, item.city, [item.state, item.postal_code].filter(function (i) { 2243 return i; 2244 }).join(' ')].filter(function (i) { 2245 return i; 2246 }).join(', ') 2247 }; 2248 }); 2249 }, function (e) { 2250 console.log(e); 2251 return []; 2252 }); 2253 } 2254 function resolveGeoBounds(placeId, description) { 2255 return new Promise(function (resolve, reject) { 2256 geocoder.geocode({ 2257 'placeId': placeId 2258 }, function (results, status) { 2259 if (status != 'OK') return resolve(null); 2260 var result = results[0]; 2261 var bounds = new google.maps.LatLngBounds();
2262 bounds.extend(result.geometry.viewport.getSouthWest()); 2263 bounds.extend(result.geometry.viewport.getNorthEast()); 2264 result.geometry.bounds = bounds.toJSON(); 2265 var placeUrl = window.luxuryPresence.makeMlsLink(result); 2266 return resolve({ 2267 placeUrl: placeUrl, 2268 description: description 2269 }); 2270 }); 2271 }); 2272 } 2273 function addRestrictions(request) { 2274 switch (selectedCountries) { 2275 case 'Worldwide': 2276 return request; 2277 case 'US & Canada': 2278 request.componentRestrictions = { 2279 country: ['us', 'ca'] 2280 }; 2281 return request; 2282 default: 2283 request.componentRestrictions = { 2284 country: 'us' 2285 }; 2286 return request; 2287 } 2288 } 2289 function resolveAutocomplete(term, deeper) { 2290 var request = addRestrictions({ 2291 input: term, 2292 types: deeper ? ['geocode'] : ['(regions)'], 2293 limit: 1 2294 }); 2295 return new Promise(function (resolve, reject) { 2296 service.getPlacePredictions(request, function (results, status) { 2297 if (status !== google.maps.places.PlacesServiceStatus.OK) { 2298 resolve(null); 2299 return; 2300 } 2301 if (!Array.isArray(results)) { 2302 resolve(null); 2303 return; 2304 } 2305 if (deeper) { 2306 var allowedTypes = { 2307 'neighborhood': true, 2308 'administrative_area_level_3': true, 2309 'administrative_area_level_4': true, 2310 'administrative_area_level_5': true, 2311 'sublocality_level_1': true, 2312 'sublocality_level_2': true, 2313 'sublocality_level_3': true 2314 }; 2315 results = results.filter(function (res) { 2316 return res.types.find(t => allowedTypes[t]); 2317 }); 2318 } 2319 if (!results.length) { 2320 resolve(null); 2321 return; 2322 } 2323 resolve(results); 2324 }); 2325 }); 2326 } 2327 function placesSearch(term, ignoreInput) { 2328 if (placesResult.term !== term) { 2329 placesResult = { 2330 term: term, 2331 result: resolveAutocomplete(term).then(function (results) { 2332 if (!ignoreInput && term !== keyword) return null; 2333 if (ignoreInput && !results) return resolveAutocomplete(term, true); 2334 return results; 2335 }).then(function (results) { 2336 if (!ignoreInput && term !== keyword || !results) return []; 2337 var geoResultPromises = results.map(function (result) { 2338 return resolveGeoBounds(result.place_id, result.description); 2339 }); 2340 return Promise.all(geoResultPromises).then(function (geoLinks) { 2341 return geoLinks.filter(function (i) { 2342 return i; 2343 }).slice(0, 3); 2344 }); 2345 }) 2346 }; 2347 } 2348 return placesResult.result; 2349 } 2350 function propertiesSearch(term) { 2351 var payload = { 2352 companyId: window.luxuryPresence.defaults.companyId, 2353 search: term, 2354 offset: 0, 2355 limit: 4, 2356 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"] 2357 }; 2358 var gqlQuery = 'query ($companyId: String, $search: String, $offset: Int, $limit: Int, $propertyStatusId: [String!]) {properties (companyId: $companyId, search: $search, offset: $offset, limit: $limit, propertyStatusId: $propertyStatusId) {items {id name slug fullAddress privateAddress status isPasswordProtected priceUponRequest salesPrice reducedPrice leasePrice currency media {smallUrl mediumUrl largeUrl xLargeUrl xxLargeUrl height width altTagText}}}}'; 2359 return superagent.post(window.luxuryPresence.defaults.routerUrl + '/graphql').send({ 2360 query: gqlQuery, 2361 variables: window.luxuryPresence.routerApi.transformVariables('properties', payload) 2362 }).then(function (res) { 2363 var page = (res.body.data || {}).properties; 2364 return page && page.items || []; 2365 }, function (err) { 2366 return []; 2367 }); 2368 } 2369 function doSearch(term, leaseProperty) { 2370 isLoading = true; 2371 updateSearchDisplay(); 2372 Promise.all([searchMls ? mlsSearch(term, leaseProperty) : [], searchMls ? placesSearch(term) : [], searchProperties ? propertiesSearch(term, leaseProperty) : []]).then(function (res) { 2373 if (term !== keyword) return; 2374 setResults(res[0], res[1], res[2], leaseProperty); 2375 }); 2376 } 2377 function makeResultsBlockHtml(title, elementClass, links) { 2378 if (!links || !links.length) return '';else return '<div class="header-search-results__block"><div class="header-search-results__title">' + title + '</div><div class="' + elementClass + '">' + links.join('') + '</div></div>'; 2379 } 2380 function setResults(mlsResults, placesResults, propertiesResults, leaseProperty) { 2381 searchResultsSelector.querySelector('.header-search-results__link--selected')?.classList.remove('header-search-results__link--selected'); 2382 isLoading = false;
2383 updateSearchDisplay(); 2384 if (!mlsResults) { 2385 resultsContainerSelector.innerHTML = ''; 2386 updateSearchDisplay(); 2387 return; 2388 } 2389 if (!mlsResults.length && !placesResults.length && !propertiesResults.length) { 2390 updateSearchDisplay(); 2391 return; 2392 } 2393 var propertiesHtml = makeResultsBlockHtml('Featured Properties', 'header-properties', propertiesResults.map(function (result) { 2394 return itemTemplate(result); 2395 })); 2396 var placesHtml = makeResultsBlockHtml('Locations', '', placesResults.map(function (result) { 2397 return `<a class="header-search-results__link lp-icon" href="${result.placeUrl}${leaseProperty ? '&lease_property=true' : ''}">${result.description}</a>`; 2398 })); 2399 var mlsHtml = makeResultsBlockHtml('Address', '', mlsResults.map(function (result) { 2400 return `<a href="/home-search/listings/${result.id}" class="header-search-results__link lp-icon">${result.display_address}</a>`; 2401 })); 2402 resultsContainerSelector.innerHTML = propertiesHtml + placesHtml + mlsHtml; 2403 updateSearchDisplay(); 2404 } 2405 var neighborhoods = null; 2406 function fetchNeighborhoods() { 2407 var url = window.luxuryPresence.defaults.routerUrl; 2408 var gqlQuery = 'query ($companyId: String, $offset: Int, $limit: Int) {neighborhoods (companyId: $companyId, offset: $offset, limit: $limit) {items {id, name, mlsLink, googlePlaceData}}}'; 2409 var payload = {}; 2410 payload.offset = 0; 2411 payload.limit = 100; 2412 payload.companyId = window.luxuryPresence.defaults.companyId; 2413 return superagent.post(url + '/graphql').withCredentials().send({ 2414 query: gqlQuery, 2415 variables: payload 2416 }).then(function (res) { 2417 var data = res.body.data && res.body.data.neighborhoods; 2418 neighborhoods = data && data.items || null; 2419 if (neighborhoods && !neighborhoods.length) { 2420 neighborhoods = null; 2421 } 2422 }); 2423 } 2424 function setPredefinedNeighborhoods() { 2425 return fetchNeighborhoods().then(function () { 2426 if (!neighborhoods) return; 2427 var placesHtml = makeResultsBlockHtml('Locations', neighborhoods.map(function (item) { 2428 return `<a class="header-search-results__link lp-icon" href="${item.mlsLink}${leasePropertyState ? '&lease_property=true' : ''}">${item.googlePlaceData && item.googlePlaceData.formatted_address || item.name}</a>`; 2429 })); 2430 predefinedSelector.innerHTML = placesHtml; 2431 updateSearchDisplay(); 2432 }); 2433 } 2434 if (searchMls) setPredefinedNeighborhoods(); 2435 closeIconSelector.style.opacity = '0'; 2436 closeIconSelector.style.pointerEvents = 'none'; 2437 searchInputSelector.setAttribute('inputmode', 'search'); 2438 searchInputSelector.addEventListener('input', function () { 2439 if (this.value === '') { 2440 closeIconSelector.style.opacity = '0'; 2441 closeIconSelector.style.pointerEvents = 'none'; 2442 searchIconSelector.style.opacity = '1'; 2443 searchIconSelector.style.pointerEvents = 'auto'; 2444 } else { 2445 closeIconSelector.style.opacity = '1'; 2446 closeIconSelector.style.pointerEvents = 'auto'; 2447 searchIconSelector.style.opacity = '0'; 2448 searchIconSelector.style.pointerEvents = 'none'; 2449 } 2450 window.clearTimeout(newSearchTimer); 2451 newSearchTimer = window.setTimeout(startSearch, 300); 2452 }); 2453 searchInputSelector.addEventListener('keydown', function (ev) { 2454 if (ev.which === 38) { 2455 ev.preventDefault(); 2456 moveSelection(true); 2457 return false; 2458 } 2459 if (ev.which === 40) { 2460 ev.preventDefault(); 2461 moveSelection(); 2462 return false; 2463 } 2464 if (ev.which === 13) { 2465 let $lnk = searchResultsSelector.querySelector('.header-search-results__link--selected'); 2466 if ($lnk) { 2467 $lnk.click(); 2468 searchActive = false; 2469 updateSearchDisplay(); 2470 } else { 2471 $searchBtn.click(); 2472 } 2473 } 2474 }); 2475 closeIconSelector.addEventListener('click', function () { 2476 searchInputSelector.value = ''; 2477 searchInputSelector.dispatchEvent(new Event('input')); 2478 searchActive = false;
2479 updateSearchDisplay(); 2480 }); 2481 searchResultsSelector.addEventListener('mouseenter', function (ev) { 2482 searchResultsSelector.querySelector('.header-search-results__link--selected')?.classList.remove('header-search-results__link--selected'); 2483 }); 2484 function outsideClickHandler(e) { 2485 if (searchWrapperSelector.contains(e.target)) return; 2486 searchActive = false; 2487 updateSearchDisplay(); 2488 } 2489 document.addEventListener('click', outsideClickHandler); 2490 }); 2491})('global-navbar'); 2492} catch(e) { 2493console.log(e); 2494} 2495 try { 2496(function init(sectionDomId, options) { 2497 var elementSelector = options.elementSelector || 'nav'; 2498 var element = document.querySelector(elementSelector); 2499 var sections = document.querySelectorAll('body > section'); 2500 var subNavContainers = element.querySelectorAll('.sub-nav'); 2501 var initialBackgroundColor = options.initialBackgroundColor || element.style.backgroundColor; 2502 var backgroundColorScroll = options.backgroundColorScroll || '#191919'; 2503 var fontColor = options.fontColor || '#fff'; 2504 var fontColorScroll = options.fontColorScroll || '#000'; 2505 var didScroll = false; 2506 var lastScrollTop = 0; 2507 var delta = 5; 2508 2509 // eslint-disable-next-line sonarjs/no-collapsible-if 2510 if (wow) { 2511 // Wowjs might not trigger for position fixed elements 2512 if (window.scrollY > 0) { 2513 element.querySelectorAll('.wow').forEach(el => wow.show(el)); 2514 } 2515 } 2516 function adjustNavPinState() { 2517 // Remove 'visible' class from all subNavContainers 2518 for (let i = 0; i < subNavContainers.length; i++) { 2519 subNavContainers[i].classList.remove('visible'); 2520 } 2521 if (window.scrollY > 0) { 2522 element.style.backgroundColor = backgroundColorScroll; 2523 element.style.color = fontColorScroll; 2524 element.classList.add('scroll'); 2525 } else { 2526 element.style.backgroundColor = initialBackgroundColor; 2527 element.style.color = fontColor; 2528 element.classList.remove('scroll'); 2529 } 2530 } 2531 adjustNavPinState(); 2532 function onScroll() { 2533 didScroll = true; 2534 } 2535 window.addEventListener('scroll', onScroll); 2536 2537 // eslint-disable-next-line 2538 var debounceInterval = setInterval(() => { 2539 if (didScroll) { 2540 // eslint-disable-next-line 2541 hasScrolled(); 2542 didScroll = false; 2543 } 2544 }, 250); 2545 function hasScrolled() { 2546 adjustNavPinState(); 2547 // eslint-disable-next-line 2548 var navbarHeight = element.offsetHeight; 2549 // eslint-disable-next-line 2550 var st = window.scrollY; 2551 2552 // Make sure they scroll more than delta 2553 if (Math.abs(lastScrollTop - st) <= delta) { 2554 return; 2555 } 2556 if (st > lastScrollTop && st > navbarHeight) { 2557 // Scroll Down 2558 element.style.transform = `translateY(-${navbarHeight}px) scaleY(0)`; 2559 document.documentElement.style.setProperty('--global-header-height', '0px'); 2560 2561 // Some sections "follow" the navbar with class sticky (i.e. Producer search) 2562 sections.forEach(section => { 2563 if (section.classList.contains('sticky')) { 2564 section.style.top = '0px'; 2565 } 2566 }); 2567 } else { 2568 // Scroll Up 2569 // eslint-disable-next-line 2570 if (st + window.innerHeight < document.documentElement.scrollHeight) { 2571 element.style.transform = `translateY(0) scaleY(1)`; 2572 document.documentElement.style.setProperty('--global-header-height', `${navbarHeight}px`); 2573 sections.forEach(section => { 2574 if (section.classList.contains('sticky')) { 2575 section.style.top = `${navbarHeight}px`; 2576 } 2577 }); 2578 } 2579 } 2580 lastScrollTop = st; 2581 } 2582})('NAVBAR', JSON.parse("{\"fontColor\":\"#161515\",\"elementSelector\":\".header\",\"fontColorScroll\":\"#fff\",\"backgroundColorScroll\":\"rgba(26,26,26, .8)\",\"initialBackgroundColor\":\"#fff\"}")); 2583} catch(e) { 2584console.log(e); 2585} 2586 try { 2587(function init(sectionDomId) { 2588 if (sectionDomId === "main-section") sectionDomId = "global-sidemenu"; 2589 (function (stickyAnchorRoot) { 2590 if (!stickyAnchorRoot) return; 2591 function getInFlowTop(target) { 2592 var inlineValue = target.style.getPropertyValue('position'); 2593 var inlinePriority = target.style.getPropertyPriority('position'); 2594 target.style.setProperty('position', 'relative', 'important'); 2595 var top = target.getBoundingClientRect().top + window.pageYOffset; 2596 if (inlineValue) target.style.setProperty('position', inlineValue, inlinePriority);else target.style.removeProperty('position'); 2597 var scrollMarginTop = parseFloat(window.getComputedStyle(target).scrollMarginTop) || 0; 2598 return Math.max(0, top - scrollMarginTop); 2599 } 2600 stickyAnchorRoot.addEventListener('click', function (event) { 2601 if (event.defaultPrevented || event.button !== 0) return; 2602 if (event.metaKey || event.ctrlKey || event.shiftKey || event.altKey) return; 2603 if (document.body.hasAttribute('data-scroll-container')) return; 2604 var link = event.target.closest('a[href]'); 2605 if (!link || !stickyAnchorRoot.contains(link) || link.target === '_blank') return; 2606 var href = link.getAttribute('href'); 2607 if (!/^#[^#]/.test(href)) return; 2608 var targetId;
2609 try { 2610 targetId = decodeURIComponent(href.slice(1)); 2611 } catch (e) { 2612 return; 2613 } 2614 var target = document.getElementById(targetId); 2615 if (!target || window.getComputedStyle(target).position !== 'sticky') return; 2616 event.preventDefault(); 2617 if (window.location.hash !== href) window.history.pushState(null, '', href); 2618 window.requestAnimationFrame(function () { 2619 window.scrollTo({ 2620 top: getInFlowTop(target) 2621 }); 2622 }); 2623 }); 2624 })(document.getElementById(sectionDomId)); 2625 var sidemenu = document.getElementById(sectionDomId); 2626 var openers = sidemenu.querySelectorAll('.js-sub-nav-opener'); 2627 var items = sidemenu.querySelectorAll('.js-idemenu-navigation-item'); 2628 var watermark = document.querySelector('.js-sidemenu-watermark'); 2629 var onShow = function () { 2630 window.lpUI.requestScrollLock(sectionDomId); 2631 }; 2632 var onHide = function () { 2633 window.lpUI.releaseScrollLock(sectionDomId); 2634 }; 2635 sidemenu.addEventListener('lpui-show', onShow); 2636 sidemenu.addEventListener('lpui-hide', onHide); 2637 openers.forEach(function (opener) { 2638 opener.addEventListener('click', function (event) { 2639 event.preventDefault(); 2640 this.classList.toggle('sidemenu-navigation__link--active'); 2641 this.classList.toggle('sidemenu-navigation__link--sub-nav-active'); 2642 }); 2643 }); 2644 document.body.addEventListener('click', function (evt) { 2645 if (!evt.target.closest('.sidemenu') && !evt.target.closest('.js-sidemenu-opener')) { 2646 window.lpUI.sideMenuHide(); 2647 } 2648 }); 2649 const handleLinkClick = function (href) { 2650 if (href && href.match(/^#[^#].*$/)) { 2651 window.lpUI.sideMenuHide(); 2652 } 2653 }; 2654 const mainNavLinks = sidemenu.querySelectorAll('.sidemenu-navigation__link'); 2655 mainNavLinks.forEach(function (link) { 2656 link.addEventListener('click', function (event) { 2657 const href = this.getAttribute('href'); 2658 handleLinkClick(href); 2659 }); 2660 }); 2661 const subNavLinks = sidemenu.querySelectorAll('.sidemenu-navigation-sub-nav__link'); 2662 subNavLinks.forEach(function (link) { 2663 link.addEventListener('click', function (event) { 2664 const href = this.getAttribute('href'); 2665 handleLinkClick(href); 2666 }); 2667 }); 2668 if (watermark) { 2669 items.forEach(function (item, index) { 2670 item.setAttribute("data-id", index <= 9 ? "0" + (index + 1) : index + 1); 2671 }); 2672 items.forEach(function (item) { 2673 item.addEventListener('mouseenter', function () { 2674 watermark.setAttribute("data-id", item.getAttribute("data-id")); 2675 watermark.style.opacity = 1; 2676 }); 2677 item.addEventListener('mouseleave', function () { 2678 watermark.style.opacity = 0; 2679 }); 2680 }); 2681 } 2682})('global-sidemenu'); 2683} catch(e) { 2684console.log(e); 2685} 2686 2687 try { 2688(function init(sectionDomId) { 2689 const sectionDom = document.getElementById(sectionDomId); 2690 const backToTopBtn = sectionDom.querySelector('.js-back-to-top'); 2691 backToTopBtn?.addEventListener('click', () => { 2692 window.scrollTo({ 2693 top: 0, 2694 behavior: 'smooth' 2695 }); 2696 }); 2697})('global-footer'); 2698} catch(e) { 2699console.log(e); 2700} 2701 2702 try { 2703(function init(sectionDomId) { 2704 const customDropdownHTML = ` 2705 <div class="custom-select" role="presentation"> 2706 <button class="custom-select-toggle" type="button" aria-haspopup="true" aria-expanded="false" role="combobox"></button> 2707 <div class="custom-select-menu"><div class="custom-select-content"></div></div> 2708 </div>`; 2709 const hideOriginalSelect = originalSelect => { 2710 originalSelect.classList.remove(...originalSelect.classList); 2711 originalSelect.classList.add("sr-only"); 2712 }; 2713 const openCustomSelect = customSelectToggle => {
2714 let customSelectMenu = customSelectToggle.nextElementSibling; 2715 customSelectMenu.classList.add("open"); 2716 customSelectToggle.classList.add("open"); 2717 customSelectToggle.ariaExpanded = true; 2718 }; 2719 const closeCustomSelect = customSelectToggle => { 2720 let customSelectMenu = customSelectToggle.nextElementSibling; 2721 customSelectMenu.classList.remove("open"); 2722 customSelectToggle.classList.remove("open"); 2723 customSelectToggle.ariaExpanded = false; 2724 }; 2725 const inheritAttributes = (originalSelect, customSelectToggle, customSelectMenu) => { 2726 customSelectToggle.className = customSelectToggle.className.concat(' ', originalSelect.className); 2727 customSelectToggle.id = originalSelect.getAttribute("id") + "custom"; 2728 customSelectToggle.dataset.name = originalSelect.getAttribute("name"); 2729 customSelectMenu.setAttribute("aria-labelledby", customSelectToggle.id); 2730 }; 2731 const initiateQuerySelectors = customSelect => { 2732 let customSelectToggle = customSelect.querySelector('.custom-select-toggle'), 2733 customSelectMenu = customSelect.querySelector('.custom-select-menu'), 2734 customSelectContent = customSelect.querySelector('.custom-select-content'); 2735 return { 2736 customSelectToggle, 2737 customSelectMenu, 2738 customSelectContent 2739 }; 2740 }; 2741 const initiateToggleText = (originalSelect, customSelectToggle) => { 2742 const dataLabelOption = originalSelect.querySelector("[data-label]"); 2743 const isMultiple = originalSelect?.multiple; 2744 if (!isMultiple) { 2745 const toggleText = dataLabelOption && dataLabelOption.dataset.label || originalSelect.querySelector(":checked")?.textContent || originalSelect.querySelector("option")?.textContent; 2746 customSelectToggle.classList.add("is-placeholder"); 2747 customSelectToggle.innerHTML = toggleText; 2748 } else { 2749 const placeholderText = dataLabelOption && dataLabelOption.dataset.label || originalSelect.querySelector("option")?.textContent || "Select"; 2750 const selectedOptions = Array.from(originalSelect.querySelectorAll("option:checked")).filter(opt => opt.value !== ""); 2751 if (selectedOptions.length === 0) { 2752 customSelectToggle.innerHTML = placeholderText; 2753 customSelectToggle.classList.add("is-placeholder"); 2754 } else if (selectedOptions.length === 1) { 2755 customSelectToggle.innerHTML = selectedOptions[0].textContent; 2756 customSelectToggle.classList.remove("is-placeholder"); 2757 } else { 2758 customSelectToggle.innerHTML = `${selectedOptions[0].textContent} +${selectedOptions.length - 1}`; 2759 customSelectToggle.classList.remove("is-placeholder"); 2760 } 2761 } 2762 }; 2763 const convertOptionsToButtons = (originalSelect, customSelectContent) => { 2764 originalSelect.querySelectorAll('option').forEach(option => { 2765 const button = createButtonFromOption(option); 2766 customSelectContent.appendChild(button); 2767 }); 2768 }; 2769 const createButtonFromOption = option => { 2770 let button = document.createElement('button'); 2771 button.className = "custom-select-item"; 2772 button.setAttribute("role", "option"); 2773 button.setAttribute("type", "button"); 2774 button.textContent = option.textContent; 2775 button.setAttribute('value', option.value); 2776 if (option.disabled) { 2777 button.setAttribute("disabled", "true"); 2778 } 2779 if (option.selected && option.value !== "") { 2780 button.classList.add("is-selected"); 2781 button.setAttribute("aria-selected", "true"); 2782 } 2783 return button; 2784 }; 2785 const initiateEventListeners = (originalSelect, customSelectToggle, customSelectMenu) => { 2786 const isMultiple = originalSelect?.multiple; 2787 originalSelect.addEventListener("focus", function () { 2788 openCustomSelect(customSelectToggle); 2789 customSelectToggle.focus(); 2790 }); 2791 customSelectToggle.addEventListener("click", function () { 2792 if (customSelectToggle.getAttribute("aria-expanded") === "true") { 2793 closeCustomSelect(customSelectToggle); 2794 } else { 2795 openCustomSelect(customSelectToggle); 2796 } 2797 }); 2798 customSelectMenu.addEventListener("click", function (event) { 2799 if (event.target.classList.contains('custom-select-item')) { 2800 const clickedValue = event.target.value; 2801 const clickedOption = originalSelect.querySelector(`option[value="${clickedValue}"]`); 2802 const placeholderOption = originalSelect.querySelector("[data-label]"); 2803 const placeholderText = placeholderOption?.dataset.label || originalSelect.querySelector("option")?.textContent || "Select"; 2804 if (!isMultiple) { 2805 let opts = customSelectMenu.querySelectorAll(".is-selected"); 2806 [].forEach.call(opts, function (el) { 2807 el.classList.remove("is-selected"); 2808 }); 2809 event.target.classList.add("is-selected"); 2810 clickedOption.selected = true; 2811 customSelectToggle.innerHTML = clickedOption.textContent; 2812 if (clickedValue === "" || event.target.classList.contains("is-placeholder")) { 2813 customSelectToggle.classList.add("is-placeholder"); 2814 } else { 2815 customSelectToggle.classList.remove("is-placeholder"); 2816 } 2817 let changeEvent = new Event('change', { 2818 bubbles: true 2819 }); 2820 originalSelect.dispatchEvent(changeEvent); 2821 closeCustomSelect(customSelectToggle); 2822 } else { 2823 if (clickedValue === "") { 2824 customSelectMenu.querySelectorAll(".is-selected").forEach(el => { 2825 el.classList.remove("is-selected"); 2826 el.setAttribute("aria-selected", "false"); 2827 }); 2828 originalSelect.querySelectorAll("option").forEach(opt => opt.selected = false); 2829 customSelectToggle.innerHTML = placeholderText; 2830 customSelectToggle.classList.add("is-placeholder"); 2831 } else { 2832 const isCurrentlySelected = event.target.classList.contains("is-selected"); 2833 event.target.classList.toggle("is-selected"); 2834 event.target.setAttribute("aria-selected", (!isCurrentlySelected).toString()); 2835 clickedOption.selected = !isCurrentlySelected; 2836 const allItem = customSelectMenu.querySelector('.custom-select-item[value=""]'); 2837 if (allItem) { 2838 allItem.classList.remove("is-selected"); 2839 allItem.setAttribute("aria-selected", "false"); 2840 } 2841 const allOption = originalSelect.querySelector('option[value=""]'); 2842 if (allOption) allOption.selected = false;
2843 const selectedItems = customSelectMenu.querySelectorAll(".custom-select-item.is-selected"); 2844 if (selectedItems.length === 0) { 2845 customSelectToggle.innerHTML = placeholderText; 2846 customSelectToggle.classList.add("is-placeholder"); 2847 } else if (selectedItems.length === 1) { 2848 customSelectToggle.innerHTML = selectedItems[0].textContent; 2849 customSelectToggle.classList.remove("is-placeholder"); 2850 } else { 2851 customSelectToggle.innerHTML = `${selectedItems[0].textContent} +${selectedItems.length - 1}`; 2852 customSelectToggle.classList.remove("is-placeholder"); 2853 } 2854 } 2855 let changeEvent = new Event('change', { 2856 bubbles: true 2857 }); 2858 originalSelect.dispatchEvent(changeEvent); 2859 } 2860 } 2861 }); 2862 document.addEventListener("click", function (event) { 2863 if (!customSelectMenu.contains(event.target) && !customSelectToggle.contains(event.target)) { 2864 closeCustomSelect(customSelectToggle); 2865 } 2866 }); 2867 }; 2868 const createCustomSelect = originalSelect => { 2869 const customSelect = document.createElement('div'); 2870 customSelect.innerHTML = customDropdownHTML; 2871 const { 2872 customSelectToggle, 2873 customSelectMenu, 2874 customSelectContent 2875 } = initiateQuerySelectors(customSelect); 2876 inheritAttributes(originalSelect, customSelectToggle, customSelectMenu); 2877 hideOriginalSelect(originalSelect); 2878 initiateToggleText(originalSelect, customSelectToggle); 2879 convertOptionsToButtons(originalSelect, customSelectContent); 2880 initiateEventListeners(originalSelect, customSelectToggle, customSelectMenu); 2881 return customSelect; 2882 }; 2883 const setCustomSelectValue = (originalSelect, value) => {
2884 let customSelect = originalSelect.nextElementSibling; 2885 let customSelectToggle = customSelect.querySelector(".custom-select-toggle"); 2886 let customSelectContent = customSelect.querySelector(".custom-select-content"); 2887 if (!customSelectContent) return; 2888 let selectedOption = value ? Array.from(customSelectContent.children).find(function (b) { 2889 return b.value === value; 2890 }) : customSelectContent.firstChild; 2891 if (!selectedOption) { 2892 return; 2893 } 2894 if (selectedOption.classList.contains("is-disabled")) return; 2895 let elementNumber = Array.from(selectedOption.parentNode.children).indexOf(selectedOption); 2896 let linkedOption = originalSelect.querySelectorAll("option")[elementNumber]; 2897 linkedOption.selected = true; 2898 selectedOption.classList.add("is-selected"); 2899 selectedOption.parentNode.querySelectorAll(".custom-select-item").forEach(el => { 2900 if (el !== selectedOption) { 2901 el.classList.remove("is-selected"); 2902 } 2903 }); 2904 closeCustomSelect(customSelectToggle); 2905 customSelectToggle.innerHTML = linkedOption.innerHTML; 2906 if (linkedOption.value) { 2907 customSelectToggle.classList.remove("is-placeholder"); 2908 if (linkedOption.value !== "") { 2909 customSelect.classList.add("has-selection"); 2910 } else { 2911 customSelect.classList.remove("has-selection"); 2912 } 2913 } else { 2914 customSelect.classList.remove("has-selection"); 2915 customSelectToggle.classList.add("is-placeholder"); 2916 } 2917 }; 2918 const customSelect = originalSelect => { 2919 const customSelect = createCustomSelect(originalSelect); 2920 originalSelect.insertAdjacentElement('afterend', customSelect); 2921 return customSelect; 2922 }; 2923 const resetCustomSelect = originalSelect => { 2924 const customSelectEl = originalSelect.nextElementSibling; 2925 const customSelectToggle = customSelectEl?.querySelector('.custom-select-toggle'); 2926 const customSelectContent = customSelectEl?.querySelector('.custom-select-content'); 2927 if (!customSelectToggle || !customSelectContent) return; 2928 const placeholderOption = originalSelect.querySelector("[data-label]"); 2929 const placeholderText = placeholderOption?.dataset.label || originalSelect.querySelector("option")?.textContent || "Select"; 2930 customSelectContent.querySelectorAll('.custom-select-item').forEach(item => { 2931 item.classList.remove('is-selected'); 2932 item.setAttribute('aria-selected', 'false'); 2933 }); 2934 originalSelect.querySelectorAll('option').forEach(opt => opt.selected = false); 2935 customSelectToggle.innerHTML = placeholderText; 2936 customSelectToggle.classList.add('is-placeholder'); 2937 const customSelectWrapper = customSelectEl.querySelector('.custom-select'); 2938 if (customSelectWrapper) { 2939 customSelectWrapper.classList.remove('has-selection'); 2940 } 2941 }; 2942 const section = document.getElementById(sectionDomId); 2943 const closeBtn = section.querySelector(".js-close-btn"); 2944 const connectBtn = section.querySelector(".js-btn-connect"); 2945 const popUp = section.querySelector(".js-pop-up"); 2946 const btnHolder = section.querySelector(".js-btn-holder"); 2947 const form = section.querySelector(".js-form"); 2948 const successMessage = section.querySelector(".js-success"); 2949 const redirectLink = section.querySelector(".js-redirect-link"); 2950 function setHttp(link) { 2951 if (link.search(/^(http[s]?\:\/\/|\/)/) == -1) { 2952 link = "https://" + link; 2953 } 2954 return link; 2955 } 2956 function redirectPage(link) { 2957 if (link) { 2958 window.location.href = setHttp(link.getAttribute("href")); 2959 } 2960 } 2961 const selects = document.querySelectorAll(".floating-contact-button select.js-select"); 2962 selects.forEach(function (el) { 2963 customSelect(el); 2964 }); 2965 const inputName = form.querySelector('.js-input-name'); 2966 inputName.addEventListener('keyup', function () { 2967 if (this.value.replaceAll(/\d/g, "").trim().split(" ").length < 2 || this.value.replaceAll(/\d/g, "").trim() === "") { 2968 this.setCustomValidity("Please input your first name and last name."); 2969 } else { 2970 this.setCustomValidity(""); 2971 } 2972 }); 2973 function showSuccessMessage() { 2974 successMessage.style.display = "block"; 2975 form.style.display = "none"; 2976 } 2977 form.addEventListener("formsubmitted", showSuccessMessage); 2978 form.addEventListener("reset", function () { 2979 showSuccessMessage(); 2980 redirectPage(redirectLink); 2981 }); 2982 window.addEventListener("scroll", function () { 2983 if (window.scrollY >= 150 && window.getComputedStyle(popUp).display !== "block") btnHolder.classList.add("floating-contact-button__btn-holder--visible");else btnHolder.classList.remove("floating-contact-button__btn-holder--visible"); 2984 }); 2985 closeBtn.addEventListener("click", function () { 2986 popUp.style.display = "none"; 2987 btnHolder.classList.add("floating-contact-button__btn-holder--visible"); 2988 }); 2989 connectBtn.addEventListener("click", function () { 2990 popUp.style.display = "block"; 2991 btnHolder.classList.remove("floating-contact-button__btn-holder--visible"); 2992 }); 2993})('global-mobile-contact'); 2994} catch(e) { 2995console.log(e); 2996} 2997 2998 try { 2999(function init(sectionDomId) { 3000 const scrollSection = document.getElementById(`${sectionDomId}`).querySelector('.js-scroll-section'); 3001 const introBtn = document.getElementById(`${sectionDomId}`).querySelector('.jsScrollBtn'); 3002 introBtn.addEventListener("click", function (e) { 3003 e.preventDefault(); 3004 window.scrollTo({ 3005 top: scrollSection.offsetTop + scrollSection.offsetHeight, 3006 behavior: "smooth" 3007 }); 3008 }); 3009})('section-771ca4c0-dfe5-4a13-818a-e283d65c7e1f', 'undefined'); 3010} catch(e) { 3011console.log(e); 3012} 3013 try { 3014(function init(sectionDomId, options) { 3015 let section = null; 3016 switch (sectionDomId) { 3017 case 'NAVBAR': 3018 section = document.querySelector('body > nav, #global-navbar'); 3019 break; 3020 case 'FOOTER': 3021 section = document.querySelector('body > footer, #global-footer'); 3022 break; 3023 case 'SIDEMENU': 3024 section = document.querySelector('body > div.sidemenu, #global-sidemenu'); 3025 break; 3026 case 'CONTACT':
3027 section = document.querySelector('#modal-global-contact-us'); 3028 break; 3029 case 'MOBILE_CONTACT': 3030 section = document.querySelector('body > div.mobile-contact-wrapper, #global-mobile-contact'); 3031 break; 3032 case 'SUBSCRIBE': 3033 // Subscribe Not Implemented 3034 section = null; 3035 break; 3036 case 'ACCOUNT': 3037 // Account Not Implemented 3038 section = null; 3039 break; 3040 default: 3041 section = document.querySelector('#' + sectionDomId); 3042 } 3043 if (!section) { 3044 return; 3045 } 3046 3047 // Where content / items are rendered 3048 const dataContainer = section.querySelector('.data-container'); 3049 if (!dataContainer) { 3050 // no place to render items = no need to query server or do anything else 3051 return; 3052 } 3053 let variables = options.variables || {}; 3054 3055 // Some variables in options may not have been injected - remove 3056 Object.keys(variables).forEach(function (variableName) { 3057 if (typeof variables[variableName] === 'string' && variables[variableName].match(/^{{.*}}$/)) { 3058 delete variables[variableName]; 3059 } 3060 }); 3061 3062 // Merge page query variables 3063 if (options.usePageResource) { 3064 variables = { 3065 ...variables, 3066 ...window.luxuryPresence.config.pageMeta.pageQueryVariables[options.resource] 3067 }; 3068 } 3069 3070 // ROUTER-CLEANUP: keep router branch, drop legacy when API retired. Callers 3071 // resolve the flag â fetchData reads the section stamp, aux fetches read 3072 // their own resource's stamp (auxUsesRouter). 3073 function apiUrl(useRouter) { 3074 return options.url || (useRouter ? window.luxuryPresence.defaults.routerUrl : window.luxuryPresence.defaults.apiGatewayUrl); 3075 } 3076 3077 // ROUTER-CLEANUP: aux resources roll out on their own flag, not the section's 3078 // (options.routerApiAux is stamped per aux resource server-side). 3079 function auxUsesRouter(resource) { 3080 return !!(options.routerApiAux && options.routerApiAux[resource]); 3081 } 3082 3083 // Pagination Executes on a Numbered Pagination Container 3084 // Or via a load more button 3085 let mode = 'BUTTONLESS_PAGINATION'; 3086 const container = section.querySelector('.pagination-container');
3087 const loadMoreButton = section.querySelector(options?.loadMoreSelector); 3088 if (container) { 3089 mode = 'NUMBERED_PAGINATION'; 3090 } 3091 if (loadMoreButton) { 3092 mode = 'LOAD_MORE_BUTTON'; 3093 } 3094 let searchContainer = section.querySelector('.search-container'); 3095 const hidePaginationOnFirstPage = options.hidePaginationOnFirstPage || false; 3096 const eventPrefix = '__pagination-'; 3097 const searchFormParams = options.searchFormParams || (options.resource === 'properties' ? [{ 3098 param: 'neighborhoodId', 3099 urlKey: 'neighborhood' 3100 }, { 3101 param: 'search', 3102 urlKey: 'search' 3103 }, { 3104 param: 'salesPriceGTE', 3105 urlKey: 'pricemin', 3106 formKey: 'priceMin', 3107 type: 'int' 3108 }, { 3109 param: 'salesPriceLTE', 3110 urlKey: 'pricemax', 3111 formKey: 'priceMax', 3112 type: 'int' 3113 }, { 3114 param: 'livingSpaceSizeGTE', 3115 urlKey: 'areamin', 3116 formKey: 'areaMin', 3117 type: 'int' 3118 }, { 3119 param: 'livingSpaceSizeLTE', 3120 urlKey: 'areamax', 3121 formKey: 'areaMax', 3122 type: 'int' 3123 }] : []); 3124 3125 // Total entries - initialized in first render 3126 let totalNumber = 0; 3127 const DefaultSearchParams = { 3128 page: 1 3129 }; 3130 searchFormParams.forEach(function (formParam) { 3131 DefaultSearchParams[formParam.formKey || formParam.param] = null; 3132 }); 3133 let searchParams = { 3134 ...DefaultSearchParams 3135 }; 3136 const offset = options.variables?.offset || 0; 3137 let scrollTarget = options.scrollTargetSelector ? section.querySelector(options.scrollTargetSelector) || section : section; 3138 let scrollOffset = (parseInt(options.scrollOffset, 10) || 0) ?? 100; 3139 3140 // entries of per page 3141 // when query variables for a given section would't be filled options.pageSize can store 3142 // template string, ex: "{{variables.limit}}", below code handles that case and set 9 as a default value 3143 let pageSize = parseInt(options.pageSize, 10) || 9; 3144 3145 // Adding mobile pageRange support 3146 var NARROW_BREAKPOINT = 600; 3147 var mobileBreakpoint = options.mobileBreakpoint > 0 ? options.mobileBreakpoint : NARROW_BREAKPOINT; 3148 var paginationMql = window.matchMedia(`(max-width: ${mobileBreakpoint}px)`); 3149 3150 // Page range (pages on both sides of the current page) 3151 var mobilePageRange = options.mobilePageRange > 0 ? options.mobilePageRange : 0; 3152 var desktopPageRange = options.pageRange >= 0 ? options.pageRange : 2; 3153 var pageRange = paginationMql.matches ? mobilePageRange : desktopPageRange; 3154 3155 // Whether to display the 'Previous' button 3156 var showPrevious = true; 3157 3158 // Whether to display the 'Next' button 3159 var showNext = true; 3160 3161 // Whether to display the page buttons 3162 var showPageNumbers = true; 3163 3164 // 'Previous' text 3165 var prevText = options.prevText || '«'; 3166 3167 // 'Next' text 3168 var nextText = options.nextText || '»'; 3169 3170 // Ellipsis text 3171 var ellipsisText = '…'; 3172 var classPrefix = 'paginationjs'; 3173 3174 // Default active class 3175 var activeClassName = 'active'; 3176 3177 // Default disable class 3178 var disableClassName = 'disabled'; 3179 3180 // Pagination element's position in the container 3181 var position = 'bottom'; 3182 3183 // Whether to trigger pagination at initialization 3184 var triggerPagingOnInit = !options.skipInitialLoad; 3185 var showFirstOnEllipsisShow = true; 3186 var showLastOnEllipsisShow = true; 3187 3188 // Instantiated in init() 3189 var el = null; 3190 3191 // Controls scrollTop logic 3192 var firstRender = true; 3193 var renderBySearch = false; 3194 var disabled = false; 3195 3196 // Pagination script class selector 3197 var paginationScriptSelector = options.paginationPartialName ? `.${options.paginationPartialName}` : '.pagination-script'; 3198 3199 // Property Specific Image Override if No Image 3200 var propertyPlaceholderImage = window.luxuryPresence.defaults.propertyPlaceholderImage; 3201 3202 // Construct template 3203 var templateHTML = section.querySelector(`script${paginationScriptSelector}`)?.innerHTML || ''; 3204 var template = Handlebars.compile(templateHTML); 3205 3206 // Initialize 3207 init(); 3208 function init() { 3209 Object.assign(searchParams, window.luxuryPresence.pagination.deserializeParams(searchFormParams, sectionDomId)); 3210 3211 // Append/prepend pagination element to the pagination container 3212 if (mode === 'NUMBERED_PAGINATION') { 3213 el = document.createElement('div'); 3214 el.className = 'paginationjs';
3215 container[position === 'bottom' ? 'append' : 'prepend'](el); 3216 } 3217 if (searchContainer) { 3218 initSearchContainer({ 3219 fetchNeighborhoods: searchContainer.dataset.fetchNeighborhoods === 'true', 3220 fetchPostCategories: searchContainer.dataset.fetchPostCategories === 'true', 3221 fetchOffices: searchContainer.dataset.fetchOffices === 'true', 3222 fetchRentalRates: searchContainer.dataset.fetchRentalRates === 'true' 3223 }, function () { 3224 syncSearchFormState(searchParams); 3225 }); 3226 } 3227 3228 // Bind events 3229 observer(); 3230 } 3231 function syncSearchFormState(params) { 3232 searchContainer.dispatchEvent(new CustomEvent('sync', { 3233 detail: params 3234 })); 3235 } 3236 function initSearchContainer(options, done) { 3237 var promises = []; 3238 if (options.fetchNeighborhoods) { 3239 promises.push(fetchAllNeighborhoods(function (neighborhoods) { 3240 searchContainer.dispatchEvent(new CustomEvent('neighborhoods-data', { 3241 detail: { 3242 data: neighborhoods.map(function (item) { 3243 return { 3244 value: item.id, 3245 label: item.name 3246 }; 3247 }) 3248 } 3249 })); 3250 })); 3251 } 3252 if (options.fetchPostCategories) { 3253 promises.push(fetchPostCategories(function (categories) { 3254 searchContainer.dispatchEvent(new CustomEvent('post-categories-data', { 3255 detail: { 3256 data: categories 3257 } 3258 })); 3259 })); 3260 } 3261 if (options.fetchOffices) { 3262 promises.push(fetchOffices(function (offices) { 3263 searchContainer.dispatchEvent(new CustomEvent('offices-data', { 3264 detail: { 3265 data: offices 3266 } 3267 })); 3268 })); 3269 } 3270 if (options.fetchRentalRates) { 3271 promises.push(fetchAllRentalRates(function (rentalRates) { 3272 searchContainer.dispatchEvent(new CustomEvent('rental-rates-data', { 3273 detail: { 3274 data: rentalRates 3275 } 3276 })); 3277 })); 3278 } 3279 if (promises.length > 0) { 3280 Promise.all(promises).then(function () { 3281 done(); 3282 }); 3283 } else { 3284 // element's custom code is not executed yet, so we're scheduling callback to after element's code 3285 setTimeout(done); 3286 } 3287 } 3288 function fetchAllNeighborhoods(done) { 3289 var useRouter = auxUsesRouter('neighborhoods'); 3290 // ROUTER-CLEANUP: keep router branch, drop legacy when API retired. Same 3291 // args on both APIs (the federated neighborhoods field accepts 3292 // withProperties/withBlogPosts); only the selection set differs. 3293 var gqlQuery = 'query ($companyId: String, $withProperties: NeighborhoodPropertiesFilter, $withBlogPosts: NeighborhoodBlogPostsFilter, $offset: Int, $limit: Int) {' + 'neighborhoods (companyId: $companyId, withProperties: $withProperties, withBlogPosts: $withBlogPosts, offset: $offset, limit: $limit) {' + (useRouter ? 'items {id, name}' : 'id, name') + '}}'; 3294 var payload = {}; 3295 payload.offset = 0; 3296 payload.limit = 100; 3297 payload.companyId = variables.companyId; 3298 if (options.resource === 'properties') { 3299 payload.withProperties = { 3300 active: true 3301 }; 3302 ['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) { 3303 if (variables[field] !== undefined && variables[field] !== null) { 3304 payload.withProperties[field] = variables[field]; 3305 } 3306 }); 3307 } 3308 if (options.resource === 'posts') { 3309 payload.withBlogPosts = { 3310 active: true 3311 }; 3312 ['search', 'postStatusId', 'featured', 'categoryId', 'categoryIds', 'neighborhoodId', 'slug'].forEach(function (field) { 3313 if (variables[field] !== undefined && variables[field] !== null) { 3314 payload.withBlogPosts[field] = variables[field]; 3315 } 3316 }); 3317 } 3318 3319 // ROUTER-CLEANUP: keep router branch, drop legacy when API retired 3320 if (useRouter) { 3321 payload = window.luxuryPresence.routerApi.transformVariables('neighborhoods', payload); 3322 } 3323 superagent.post(apiUrl(useRouter) + '/graphql').withCredentials().send({ 3324 query: gqlQuery, 3325 variables: payload 3326 }).then(function (res) { 3327 var value = res.body.data && res.body.data.neighborhoods || {}; 3328 // ROUTER-CLEANUP: keep router branch, drop legacy when API retired 3329 var items = useRouter ? window.luxuryPresence.routerApi.transformPage(value).items : value || []; 3330 done(items, items.length); 3331 }); 3332 } 3333 function fetchPostCategories(done) { 3334 var featured = options.resource === 'posts' && !!variables.featured; 3335 var useRouter = auxUsesRouter('postCategories'); 3336 // ROUTER-CLEANUP: keep router branch, drop legacy when API retired. Only the 3337 // selection set differs ({ items {...} } on the router). 3338 var selection = 'id, name, publishedCount, featuredPublishedCount'; 3339 var gqlQuery = 'query ($companyId: String, $offset: Int, $limit: Int) {' + 'postCategories (companyId: $companyId, offset: $offset, limit: $limit ' + (featured ? ' withFeaturedPublishedOnly: true' : ' withPublishedOnly: true') + ') {' + (useRouter ? 'items {' + selection + '}' : selection) + '}}'; 3340 var payload = {}; 3341 payload.offset = 0; 3342 payload.limit = 100; 3343 payload.companyId = variables.companyId; 3344 superagent.post(apiUrl(useRouter) + '/graphql').withCredentials().send({ 3345 query: gqlQuery, 3346 variables: payload 3347 }).then(function (res) { 3348 var value = res.body.data && res.body.data.postCategories || {}; 3349 // ROUTER-CLEANUP: keep router branch, drop legacy when API retired 3350 var items = useRouter ? window.luxuryPresence.routerApi.transformPage(value).items : value || []; 3351 done(items.map(function (item) { 3352 item.count = featured ? item.featuredPublishedCount : item.publishedCount; 3353 return item; 3354 }), items.length); 3355 }); 3356 } 3357 function fetchOffices(done) { 3358 var useRouter = auxUsesRouter('offices'); 3359 // ROUTER-CLEANUP: keep router branch, drop legacy when API retired. Only the 3360 // selection set differs ({ items {...} } on the router). 3361 var selection = 'id, name, tags'; 3362 // ROUTER-CLEANUP: keep router branch, drop legacy when API retired. The two 3363 // APIs differ in more than the items wrapper: federated offices takes 3364 // companyId: ID! (legacy gateway: String), so each branch builds its whole doc. 3365 var gqlQuery = useRouter ? 'query ($companyId: ID!, $offset: Int, $limit: Int) {' + 'offices (companyId: $companyId, offset: $offset, limit: $limit) {' + 'items {' + selection + '}}}' : 'query ($companyId: String, $offset: Int, $limit: Int) {' + 'offices (companyId: $companyId, offset: $offset, limit: $limit) {' + selection + '}}'; 3366 var payload = { 3367 offset: 0, 3368 limit: 100, 3369 companyId: variables.companyId 3370 }; 3371 3372 // ROUTER-CLEANUP: keep router branch, drop legacy when API retired 3373 if (useRouter) { 3374 payload = window.luxuryPresence.routerApi.transformVariables('office
3374s', payload); 3375 } 3376 superagent.post(apiUrl(useRouter) + '/graphql').withCredentials().send({ 3377 query: gqlQuery, 3378 variables: payload 3379 }).then(function (res) { 3380 var value = res.body.data && res.body.data.offices || {}; 3381 // ROUTER-CLEANUP: keep router branch, drop legacy when API retired 3382 var items = useRouter ? window.luxuryPresence.routerApi.transformPage(value).items : value || []; 3383 done(items, items.length); 3384 }); 3385 } 3386 3387 // ROUTER-CLEANUP: no rentalRates field on the federated router â legacy only. 3388 function fetchAllRentalRates(done) { 3389 var url = options.url || window.luxuryPresence.defaults.apiGatewayUrl; 3390 var gqlQuery = 'query ($companyId: String, $offset: Int, $limit: Int) {' + 'rentalRates (companyId: $companyId, offset: $offset, limit: $limit) {rentalRateId, label}}'; 3391 var payload = { 3392 offset: 0, 3393 limit: 100, 3394 companyId: variables.companyId 3395 }; 3396 superagent.post(url + '/graphql').withCredentials().send({ 3397 query: gqlQuery, 3398 variables: payload 3399 }).then(function (res) { 3400 var items = res.body.data && res.body.data.rentalRates || []; 3401 done(items, items.length); 3402 }).catch(function (err) { 3403 console.error('Error fetching rental rates:', err); 3404 done([], 0); 3405 }); 3406 } 3407 function fetchData(params, done) { 3408 var resource = options.resource; 3409 var gqlQuery = options.query || window.luxuryPresence.defaults.gql[resource]; 3410 var payload = {}; 3411 try { 3412 payload = JSON.parse(JSON.stringify(variables)); 3413 } catch (e) { 3414 Object.keys(variables).forEach(function (variableName) { 3415 payload[variableName] = variables[variableName]; 3416 }); 3417 } 3418 payload.offset = (params.page - 1) * pageSize + offset; 3419 payload.limit = pageSize; 3420 payload.companyId = options.companyId; 3421 searchFormParams.forEach(function (formParam) { 3422 var val = params[formParam.formKey || formParam.param]; 3423 if (val !== null && val !== undefined) { 3424 objSet(payload, formParam.param, val); 3425 } 3426 }); 3427 3428 // ROUTER-CLEANUP: keep router branch, drop legacy when API retired 3429 if (options.useRouterApi) { 3430 payload = window.luxuryPresence.routerApi.transformVariables(resource, payload); 3431 } 3432 3433 // TODO: Disabled loading due to jarring effect 3434 // dataContainer.html('Loading...'); 3435 superagent.post(apiUrl(options.useRouterApi) + '/graphql').withCredentials().send({ 3436 query: gqlQuery, 3437 variables: payload 3438 }).then(function (res) { 3439 if (res.body.errors) { 3440 done(res.body.errors); 3441 return; 3442 } 3443 var data = res.body.data || {}; 3444 // ROUTER-CLEANUP: keep router branch, drop legacy when API retired 3445 var resources; 3446 var resourceCount; 3447 if (options.useRouterApi) { 3448 var page = window.luxuryPresence.routerApi.transformPage(data[resource]); 3449 resources = window.luxuryPresence.routerApi.transformResponse(resource, page.items); 3450 resourceCount = page.count; 3451 } else { 3452 resources = data[resource] || []; 3453 resourceCount = data[resource + 'Count'] && data[resource + 'Count'].count ? data[resource + 'Count'].count : 0; 3454 } 3455 const finish = function (items) { 3456 if (resource === 'properties' && propertyPlaceholderImage?.id) { 3457 items = items.map(item => { 3458 if (item.media?.length === 0) { 3459 return Object.assign(item, { 3460 media: [propertyPlaceholderImage] 3461 }); 3462 } 3463 return item; 3464 }); 3465 } 3466 done(null, items, resourceCount); 3467 }; 3468 3469 // ROUTER-CLEANUP: client half of PLAT-4073 â resolve the requested 3470 // disclaimers before rendering; older SDKs skip (keys stay unset). 3471 if (options.useRouterApi && resource === 'properties' && options.routerPropertyDisclaimers && options.routerPropertyDisclaimers.length && window.luxuryPresence.routerApi && typeof window.luxuryPresence.routerApi.applyPropertyDisclaimers === 'function') { 3472 window.luxuryPresence.routerApi.applyPropertyDisclaimers(resources, options.routerPropertyDisclaimers).then(finish); 3473 return; 3474 } 3475 finish(resources); 3476 }); 3477 } 3478 function getTotalPage() { 3479 return Math.ceil(totalNumber / pageSize); 3480 } 3481 function renderPaginationList() { 3482 var totalPages = getTotalPage(); 3483 var rangeStart = searchParams.page - pageRange; 3484 var rangeEnd = searchParams.page + pageRange; 3485 if (rangeEnd > totalPages) { 3486 rangeEnd = totalPages; 3487 rangeStart = totalPages - pageRange * 2; 3488 rangeStart = rangeStart < 1 ? 1 : rangeStart; 3489 } 3490 if (rangeStart <= 1) { 3491 rangeStart = 1; 3492 rangeEnd = Math.min(pageRange * 2 + 1, totalPages); 3493 } 3494 3495 // Making sure that 1 more page button is shown in edge positions 3496 if (pageRange === 0) { 3497 if (searchParams.page === totalPages) { 3498 rangeStart = totalPages <= 1 ? 1 : totalPages - 1; 3499 } 3500 if (searchParams.page === 1) { 3501 rangeEnd = Math.min(2, totalPages); 3502 } 3503 } 3504 3505 // Render pagination list 3506 if (mode === 'NUMBERED_PAGINATION') { 3507 el.innerHTML = generateHTML({ 3508 currentPage: searchParams.page, 3509 pageRange: pageRange, 3510 rangeStart: rangeStart, 3511 rangeEnd: rangeEnd 3512 }); 3513 if (totalPages < 2 && hidePaginationOnFirstPage) { 3514 container.style.display = 'none'; 3515 } else { 3516 container.style.display = ''; 3517 } 3518 } else if (mode === 'LOAD_MORE_BUTTON') { 3519 if (searchParams.page >= totalPages) {
3520 loadMoreButton.style.display = 'none'; 3521 } else { 3522 loadMoreButton.style.display = ''; 3523 } 3524 } 3525 } 3526 function render(data) { 3527 renderPaginationList(); 3528 3529 // Render new content with handlebars 3530 var html = ''; 3531 if (mode === 'LOAD_MORE_BUTTON' && searchParams.page > 1) { 3532 // If using load more, append search results to existing results 3533 html = dataContainer.innerHTML; 3534 } 3535 for (var i = 0; i < data.length; i++) { 3536 var itemData = recursivelyParse(data[i]); 3537 itemData.sectionIndex = options.sectionIndex; 3538 itemData.renderOptions = options.renderOptions; 3539 html += template(itemData); 3540 } 3541 dataContainer.innerHTML = html; 3542 3543 // Scroll Top 3544 if (!firstRender && mode === 'NUMBERED_PAGINATION' && (!renderBySearch || !options.skipScrollOnSearch)) { 3545 // Only animate to the top if we replace dataContainer (numbered pagination) 3546 setTimeout(() => { 3547 const scrollTargetOffsetTop = scrollTarget.getBoundingClientRect().top + window.scrollY - scrollOffset; 3548 window.scrollTo({ 3549 top: scrollTargetOffsetTop, 3550 behavior: 'smooth' 3551 }); 3552 }, 250); 3553 } 3554 return true; 3555 } 3556 function generateHTML(args) { 3557 const totalPages = getTotalPage(); 3558 const { 3559 rangeStart, 3560 rangeEnd 3561 } = args; 3562 const makeLnk = page => window.luxuryPresence.pagination.serializeParams(searchFormParams, sectionDomId, { 3563 ...searchParams, 3564 page 3565 }); 3566 let html = ''; 3567 if (showPrevious || showPageNumbers || showNext) { 3568 html += '<div class="paginationjs-pages"><ul>'; 3569 3570 // Previous button 3571 if (showPrevious) { 3572 if (searchParams.page <= 1) { 3573 html += `<li class="${classPrefix}-prev ${disableClassName}"><a>${prevText}</a></li>`; 3574 } else { 3575 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>`; 3576 } 3577 } 3578 3579 // Pages 3580 if (showPageNumbers) { 3581 if (rangeStart <= 3) { 3582 for (let i = 1; i < rangeStart; i++) { 3583 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>`; 3584 } 3585 } else { 3586 if (showFirstOnEllipsisShow) { 3587 html += `<li class="${classPrefix}-page ${classPrefix}-first J-paginationjs-page" data-num="1"><a href="${makeLnk(1)}">1</a></li>`; 3588 } 3589 html += `<li class="${classPrefix}-ellipsis ${disableClassName}"><a>${ellipsisText}</a></li>`; 3590 } 3591 for (let i = rangeStart; i <= rangeEnd; i++) { 3592 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>`; 3593 } 3594 if (rangeEnd < totalPages - 2) { 3595 html += `<li class="${classPrefix}-ellipsis ${disableClassName}"><a>${ellipsisText}</a></li>`; 3596 if (showLastOnEllipsisShow) { 3597 html += `<li class="${classPrefix}-page ${classPrefix}-last J-paginationjs-page" data-num="${totalPages}"><a href="${makeLnk(totalPages)}">${totalPages}</a></li>`; 3598 } 3599 } else { 3600 for (let i = rangeEnd + 1; i <= totalPages; i++) { 3601 html += `<li class="${classPrefix}-page J-paginationjs-page" data-num="${i}"><a href="${makeLnk(i)}">${i}</a></li>`; 3602 } 3603 } 3604 } 3605 3606 // Next button 3607 if (showNext) { 3608 if (searchParams.page >= totalPages) { 3609 html += `<li class="${classPrefix}-next ${disableClassName}"><a>${nextText}</a></li>`; 3610 } else { 3611 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>`; 3612 } 3613 } 3614 html += '</ul></div>'; 3615 } 3616 return html; 3617 } 3618 function go(newSearchParams, callback, restorationVisit) { 3619 if (disabled) return; 3620 var goToPageNumber = newSearchParams.page; 3621 3622 // Page number is out of bounds 3623 if (!goToPageNumber || goToPageNumber < 1) return; 3624 var totalPage = getTotalPage(); 3625 3626 // Page number is out of bounds 3627 if (!restorationVisit && totalNumber > 0) { 3628 if (goToPageNumber > totalPage) return; 3629 } 3630 if (!options.skipSerialization && (mode === 'NUMBERED_PAGINATION' || searchContainer)) {
3631 var newURL = window.luxuryPresence.pagination.serializeParams(searchFormParams, sectionDomId, { 3632 ...newSearchParams, 3633 page: goToPageNumber !== 1 && mode === 'NUMBERED_PAGINATION' ? newSearchParams.page : null 3634 }); 3635 if (!areQueryParamsEqual(newSearchParams, searchParams) && !restorationVisit) { 3636 window.history.pushState({}, '', window.luxuryPresence.getPath(newURL, { 3637 queryString: true 3638 })); 3639 } 3640 } 3641 3642 // Fetch and update page 3643 fetchData(newSearchParams, renderWithData); 3644 disabled = true; 3645 function renderWithData(err, data, count) { 3646 if (err) { 3647 dataContainer.dispatchEvent(new Event('error')); 3648 } else { 3649 searchParams = { 3650 ...newSearchParams 3651 }; 3652 totalNumber = count - offset; 3653 if (data.length === 0) { 3654 dataContainer.dispatchEvent(new Event('no-data')); 3655 } else { 3656 dataContainer.dispatchEvent(new Event('data')); 3657 } 3658 render(data); 3659 firstRender = false; 3660 } 3661 disabled = false; 3662 renderBySearch = false; 3663 } 3664 } 3665 function areQueryParamsEqual(first, second) { 3666 var differ = Object.keys(first).find(function (key) { 3667 return first[key] !== undefined && first[key] !== null && first[key] !== second[key]; 3668 }); 3669 if (differ) { 3670 return false; 3671 } 3672 differ = Object.keys(second).find(function (key) { 3673 return second[key] !== undefined && second[key] !== null && second[key] !== first[key]; 3674 }); 3675 return !differ; 3676 } 3677 function next(callback) { 3678 go({ 3679 ...searchParams, 3680 page: searchParams.page + 1 3681 }, callback); 3682 } 3683 function previous(callback) { 3684 go({ 3685 ...searchParams, 3686 page: searchParams.page - 1 3687 }, callback); 3688 } 3689 function refresh(callback) { 3690 go(searchParams, callback); 3691 } 3692 function update(params, callback) { 3693 renderBySearch = true; 3694 go(params, callback); 3695 } 3696 function observer() { 3697 if (searchContainer) { 3698 searchContainer.addEventListener('search', function (event, newSearchParams) { 3699 newSearchParams = event.detail || newSearchParams; 3700 update({ 3701 ...searchParams, 3702 ...newSearchParams, 3703 page: 1 3704 }); 3705 }); 3706 searchContainer.addEventListener('clear-search', function () { 3707 const defaultSearchParams = { 3708 ...DefaultSearchParams 3709 }; 3710 const isCurrentSearchFormStateDefault = areQueryParamsEqual({ 3711 ...defaultSearchParams, 3712 page: null 3713 }, { 3714 ...searchParams, 3715 page: null 3716 }); 3717 3718 // if mode is LOAD_MORE_BUTTON we should't make anything on clear 3719 // when search form have default state 3720 if (isCurrentSearchFormStateDefault && mode !== 'NUMBERED_PAGINATION') { 3721 return; 3722 } 3723 3724 // if someone initially go to some page and click 'Clear' on search from 3725 // we should't navigate to first page. We should preserve page value 3726 if (isCurrentSearchFormStateDefault) { 3727 defaultSearchParams.page = searchParams.page; 3728 } 3729 syncSearchFormState(defaultSearchParams); 3730 update(defaultSearchParams); 3731 }); 3732 } 3733 if (mode === 'LOAD_MORE_BUTTON') { 3734 loadMoreButton.addEventListener('click', function (event) { 3735 go({ 3736 ...searchParams, 3737 page: searchParams.page + 1 3738 }); 3739 return false; 3740 }); 3741 } 3742 if (mode === 'LOAD_MORE_BUTTON' || mode === 'BUTTONLESS_PAGINATION') { 3743 // Do initial render 3744 go(Object.assign({}, searchParams, { 3745 page: 1 3746 })); 3747 return; 3748 } 3749 if (mode === 'NUMBERED_PAGINATION') { 3750 // Go to specified page number 3751 container.addEventListener(eventPrefix + 'go', function (event) { 3752 let { 3753 pageNumber, 3754 done 3755 } = event.detail || {}; 3756 pageNumber = parseInt(pageNumber, 10); 3757 if (!pageNumber) { 3758 return; 3759 } 3760 go({ 3761 ...searchParams, 3762 page: pageNumber 3763 }, done); 3764 }); 3765 3766 // Page number button click 3767 el.addEventListener('click', function (event) { 3768 let clickTarget = event.target; 3769 let current = clickTarget.closest('.J-paginationjs-page, .J-paginationjs-previous, .J-paginationjs-next'); 3770 let pageNumber = current?.getAttribute('data-num'); 3771 if (!pageNumber || current.classList.contains(disableClassName) || current.classList.contains(activeClassName)) { 3772 return; 3773 } else { 3774 go({ 3775 ...searchParams, 3776 page: parseInt(pageNumber, 10) 3777 }); 3778 } 3779 event.preventDefault(); 3780 }); 3781 3782 // Whether to load the default page 3783 var defaultPageNumber = searchParams.page; 3784 if (triggerPagingOnInit) {
3785 container.dispatchEvent(new CustomEvent(eventPrefix + 'go', { 3786 detail: { 3787 pageNumber: defaultPageNumber 3788 } 3789 })); 3790 } 3791 } 3792 window.addEventListener('popstate', function (event) { 3793 var newParams = Object.assign({}, DefaultSearchParams, window.luxuryPresence.pagination.deserializeParams(searchFormParams, sectionDomId)); 3794 if (!areQueryParamsEqual(newParams, searchParams)) { 3795 go(newParams, null, true); 3796 if (searchContainer) { 3797 syncSearchFormState(newParams); 3798 } 3799 } 3800 }); 3801 } 3802 function replaceVariables(template, variables) { 3803 var formattedString; 3804 for (var key in variables) { 3805 var value = variables[key]; 3806 var regexp = new RegExp('<%=\\s*' + key + '\\s*%>', 'img'); 3807 formattedString = (formattedString || template).replace(regexp, value); 3808 } 3809 return formattedString; 3810 } 3811 function isTextEditorValue(obj) { 3812 return 'raw' in obj || 'gjs' in obj; 3813 } 3814 function getTextEditorValue(obj) { 3815 if (!obj.html) { 3816 return ''; 3817 } 3818 var data = obj.html; 3819 var css = (obj.raw || obj.gjs || {}).css; 3820 if (css) { 3821 data = data + '<style>' + css + '</style>'; 3822 } 3823 return data; 3824 } 3825 3826 /** 3827 * check rendered resources for html and raw properties that could indicate if resource is from an advanced text editor. 3828 * strips out raw proprties and returns only HTML if it exists. 3829 * @param {Object} resources a collection retrieved from the database 3830 * @return {Object} the newly modified object. 3831 */ 3832 function recursivelyParse(resources) { 3833 forEach(resources, function (value, key) { 3834 if (!value) { 3835 return; 3836 } 3837 if (value instanceof Object) { 3838 if (isTextEditorValue(value)) { 3839 resources[key] = getTextEditorValue(value); 3840 return; 3841 } else { 3842 return recursivelyParse(value); 3843 } 3844 } 3845 try { 3846 var parsedData = JSON.parse(value); 3847 if (isTextEditorValue(parsedData)) { 3848 resources[key] = getTextEditorValue(parsedData); 3849 } 3850 } catch (e) { 3851 // do nothing if we failed to parse value as JSON 3852 } 3853 }); 3854 return resources; 3855 } 3856 function forEach(collection, iteratee) { 3857 var func = Array.isArray(collection) ? arrayEach : baseFor; 3858 return func(collection, iteratee); 3859 } 3860 function baseFor(object, iteratee) { 3861 if (!object) { 3862 return; 3863 } 3864 var iterable = Object(object); 3865 var props = Object.keys(object); 3866 var length = props.length; 3867 var index = -1; 3868 while (length--) { 3869 var key = props[++index]; 3870 if (iteratee(iterable[key], key, iterable) === false) { 3871 break; 3872 } 3873 } 3874 return object; 3875 } 3876 function objSet(obj, path, value) { 3877 const pathArray = Array.isArray(path) ? path : path.match(/([^[.\]])+/g); 3878 pathArray.reduce((acc, key, i) => { 3879 if (acc[key] === undefined) acc[key] = {}; 3880 if (i === pathArray.length - 1) acc[key] = value; 3881 return acc[key]; 3882 }, obj); 3883 } 3884 function arrayEach(array, iteratee) { 3885 var index = -1; 3886 var length = array.length; 3887 while (++index < length) { 3888 if (iteratee(array[index], index, array) === false) { 3889 break; 3890 } 3891 } 3892 return array; 3893 } 3894 function selectPageRangeMode(e) { 3895 pageRange = e.matches ? mobilePageRange : desktopPageRange; 3896 renderPaginationList(); 3897 } 3898 paginationMql.addEventListener('change', selectPageRangeMode); 3899})('section-055f7306-112d-4d27-8914-cafe3745ec53', JSON.parse("{\"pageSize\":\"3\",\"resource\":\"properties\",\"pageRange\":1,\"variables\":{\"sort\":\"salesPrice\",\"limit\":3,\"order\":\"salesPrice\",\"offset\":0,\"sortDir\":\"DESC\",\"statusId\":\"{{variables.statusId}}\",\"companyId\":\"c1908ce5-efe4-423f-a0b8-f9e844db2413\",\"backfillMLSResults\":\"{{variables.backfillMLSResults}}\",\"statusIds\":[\"5f528253-abb7-484e-95c3-330269ac1105\"],\"propertyIds\":[],\"advancedFilters\":{\"query\":{\"statusIds\":{\"in\":[\"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\"]}}},\"websiteId\":\"e8034653-cea9-43db-b10d-f8cf56e2295a\"},\"searchFormParams\":[{\"param\":\"search\",\"global\":true,\"urlKey\":\"search\"},{\"type\":\"string\",\"param\":\"neighborhoodId\",\"global\":true,\"urlKey\":\"neighborhoodId\"},{\"type\":\"int\",\"param\":\"salesPriceGTE\",\"global\":true,\"urlKey\":\"pricemin\"},{\"type\":\"int\",\"param\":\"salesPriceLTE\",\"global\":true,\"urlKey\":\"pricemax\"},{\"type\":\"int\",\"param\":\"livingSpaceSizeGTE\",\"global\":true,\"urlKey\":\"areamin\"},{\"type\":\"int\",\"param\":\"livingSpaceSizeLTE\",\"global\":true,\"urlKey\":\"areamax\"},{\"type\":\"string\",\"param\":\"seasonalPriceId\",\"global\":true,\"urlKey\":\"seasonalPriceId\"}],\"skipScrollOnSearch\":true,\"hidePaginationOnFirstPage\":true,\"companyId\":\"c1908ce5-efe4-423f-a0b8-f9e844db2413\",\"usePageResource\":false,\"sectionIndex\":2,\"useRouterApi\":false,\"routerApiAux\":{\"testimonials\":true,\"agents\":false,\"neighborhoods\":false,\"developments\":true,\"properties\":false,\"posts\":true,\"pressReleases\":true,\"offices\":true,\"teams\":true,\"pois\":true,\"postCategories\":true}}")); 3900} catch(e) { 3901console.log(e); 3902} 3903 try { 3904(function init(sectionDomId) { 3905 const customDropdownHTML = `
3906 <div class="custom-select" role="presentation"> 3907 <button class="custom-select-toggle" type="button" aria-haspopup="true" aria-expanded="false" role="combobox"></button> 3908 <div class="custom-select-menu"><div class="custom-select-content"></div></div> 3909 </div>`; 3910 const hideOriginalSelect = originalSelect => { 3911 originalSelect.classList.remove(...originalSelect.classList); 3912 originalSelect.classList.add("sr-only"); 3913 }; 3914 const openCustomSelect = customSelectToggle => { 3915 let customSelectMenu = customSelectToggle.nextElementSibling; 3916 customSelectMenu.classList.add("open"); 3917 customSelectToggle.classList.add("open"); 3918 customSelectToggle.ariaExpanded = true; 3919 }; 3920 const closeCustomSelect = customSelectToggle => { 3921 let customSelectMenu = customSelectToggle.nextElementSibling; 3922 customSelectMenu.classList.remove("open"); 3923 customSelectToggle.classList.remove("open"); 3924 customSelectToggle.ariaExpanded = false; 3925 }; 3926 const inheritAttributes = (originalSelect, customSelectToggle, customSelectMenu) => { 3927 customSelectToggle.className = customSelectToggle.className.concat(' ', originalSelect.className); 3928 customSelectToggle.id = originalSelect.getAttribute("id") + "custom"; 3929 customSelectToggle.dataset.name = originalSelect.getAttribute("name"); 3930 customSelectMenu.setAttribute("aria-labelledby", customSelectToggle.id); 3931 }; 3932 const initiateQuerySelectors = customSelect => {
3933 let customSelectToggle = customSelect.querySelector('.custom-select-toggle'), 3934 customSelectMenu = customSelect.querySelector('.custom-select-menu'), 3935 customSelectContent = customSelect.querySelector('.custom-select-content'); 3936 return { 3937 customSelectToggle, 3938 customSelectMenu, 3939 customSelectContent 3940 }; 3941 }; 3942 const initiateToggleText = (originalSelect, customSelectToggle) => { 3943 const dataLabelOption = originalSelect.querySelector("[data-label]"); 3944 const isMultiple = originalSelect?.multiple; 3945 if (!isMultiple) { 3946 const toggleText = dataLabelOption && dataLabelOption.dataset.label || originalSelect.querySelector(":checked")?.textContent || originalSelect.querySelector("option")?.textContent; 3947 customSelectToggle.classList.add("is-placeholder"); 3948 customSelectToggle.innerHTML = toggleText; 3949 } else { 3950 const placeholderText = dataLabelOption && dataLabelOption.dataset.label || originalSelect.querySelector("option")?.textContent || "Select"; 3951 const selectedOptions = Array.from(originalSelect.querySelectorAll("option:checked")).filter(opt => opt.value !== ""); 3952 if (selectedOptions.length === 0) { 3953 customSelectToggle.innerHTML = placeholderText; 3954 customSelectToggle.classList.add("is-placeholder"); 3955 } else if (selectedOptions.length === 1) { 3956 customSelectToggle.innerHTML = selectedOptions[0].textContent; 3957 customSelectToggle.classList.remove("is-placeholder"); 3958 } else { 3959 customSelectToggle.innerHTML = `${selectedOptions[0].textContent} +${selectedOptions.length - 1}`; 3960 customSelectToggle.classList.remove("is-placeholder"); 3961 } 3962 } 3963 }; 3964 const convertOptionsToButtons = (originalSelect, customSelectContent) => { 3965 originalSelect.querySelectorAll('option').forEach(option => { 3966 const button = createButtonFromOption(option); 3967 customSelectContent.appendChild(button); 3968 }); 3969 }; 3970 const createButtonFromOption = option => { 3971 let button = document.createElement('button'); 3972 button.className = "custom-select-item"; 3973 button.setAttribute("role", "option"); 3974 button.setAttribute("type", "button"); 3975 button.textContent = option.textContent; 3976 button.setAttribute('value', option.value); 3977 if (option.disabled) { 3978 button.setAttribute("disabled", "true"); 3979 } 3980 if (option.selected && option.value !== "") { 3981 button.classList.add("is-selected"); 3982 button.setAttribute("aria-selected", "true"); 3983 } 3984 return button; 3985 }; 3986 const initiateEventListeners = (originalSelect, customSelectToggle, customSelectMenu) => { 3987 const isMultiple = originalSelect?.multiple; 3988 originalSelect.addEventListener("focus", function () { 3989 openCustomSelect(customSelectToggle); 3990 customSelectToggle.focus(); 3991 }); 3992 customSelectToggle.addEventListener("click", function () { 3993 if (customSelectToggle.getAttribute("aria-expanded") === "true") { 3994 closeCustomSelect(customSelectToggle); 3995 } else { 3996 openCustomSelect(customSelectToggle); 3997 } 3998 }); 3999 customSelectMenu.addEventListener("click", function (event) { 4000 if (event.target.classList.contains('custom-select-item')) { 4001 const clickedValue = event.target.value; 4002 const clickedOption = originalSelect.querySelector(`option[value="${clickedValue}"]`); 4003 const placeholderOption = originalSelect.querySelector("[data-label]"); 4004 const placeholderText = placeholderOption?.dataset.label || originalSelect.querySelector("option")?.textContent || "Select"; 4005 if (!isMultiple) { 4006 let opts = customSelectMenu.querySelectorAll(".is-selected"); 4007 [].forEach.call(opts, function (el) { 4008 el.classList.remove("is-selected"); 4009 }); 4010 event.target.classList.add("is-selected"); 4011 clickedOption.selected = true; 4012 customSelectToggle.innerHTML = clickedOption.textContent; 4013 if (clickedValue === "" || event.target.classList.contains("is-placeholder")) { 4014 customSelectToggle.classList.add("is-placeholder"); 4015 } else { 4016 customSelectToggle.classList.remove("is-placeholder"); 4017 } 4018 let changeEvent = new Event('change', { 4019 bubbles: true 4020 }); 4021 originalSelect.dispatchEvent(changeEvent); 4022 closeCustomSelect(customSelectToggle); 4023 } else { 4024 if (clickedValue === "") { 4025 customSelectMenu.querySelectorAll(".is-selected").forEach(el => { 4026 el.classList.remove("is-selected"); 4027 el.setAttribute("aria-selected", "false"); 4028 }); 4029 originalSelect.querySelectorAll("option").forEach(opt => opt.selected = false); 4030 customSelectToggle.innerHTML = placeholderText; 4031 customSelectToggle.classList.add("is-placeholder"); 4032 } else { 4033 const isCurrentlySelected = event.target.classList.contains("is-selected"); 4034 event.target.classList.toggle("is-selected"); 4035 event.target.setAttribute("aria-selected", (!isCurrentlySelected).toString()); 4036 clickedOption.selected = !isCurrentlySelected; 4037 const allItem = customSelectMenu.querySelector('.custom-select-item[value=""]'); 4038 if (allItem) { 4039 allItem.classList.remove("is-selected"); 4040 allItem.setAttribute("aria-selected", "false"); 4041 } 4042 const allOption = originalSelect.querySelector('option[value=""]'); 4043 if (allOption) allOption.selected = false;
4044 const selectedItems = customSelectMenu.querySelectorAll(".custom-select-item.is-selected"); 4045 if (selectedItems.length === 0) { 4046 customSelectToggle.innerHTML = placeholderText; 4047 customSelectToggle.classList.add("is-placeholder"); 4048 } else if (selectedItems.length === 1) { 4049 customSelectToggle.innerHTML = selectedItems[0].textContent; 4050 customSelectToggle.classList.remove("is-placeholder"); 4051 } else { 4052 customSelectToggle.innerHTML = `${selectedItems[0].textContent} +${selectedItems.length - 1}`; 4053 customSelectToggle.classList.remove("is-placeholder"); 4054 } 4055 } 4056 let changeEvent = new Event('change', { 4057 bubbles: true 4058 }); 4059 originalSelect.dispatchEvent(changeEvent); 4060 } 4061 } 4062 }); 4063 document.addEventListener("click", function (event) { 4064 if (!customSelectMenu.contains(event.target) && !customSelectToggle.contains(event.target)) { 4065 closeCustomSelect(customSelectToggle); 4066 } 4067 }); 4068 }; 4069 const createCustomSelect = originalSelect => { 4070 const customSelect = document.createElement('div'); 4071 customSelect.innerHTML = customDropdownHTML; 4072 const { 4073 customSelectToggle, 4074 customSelectMenu, 4075 customSelectContent 4076 } = initiateQuerySelectors(customSelect); 4077 inheritAttributes(originalSelect, customSelectToggle, customSelectMenu); 4078 hideOriginalSelect(originalSelect); 4079 initiateToggleText(originalSelect, customSelectToggle); 4080 convertOptionsToButtons(originalSelect, customSelectContent); 4081 initiateEventListeners(originalSelect, customSelectToggle, customSelectMenu); 4082 return customSelect; 4083 }; 4084 const setCustomSelectValue = (originalSelect, value) => {
4085 let customSelect = originalSelect.nextElementSibling; 4086 let customSelectToggle = customSelect.querySelector(".custom-select-toggle"); 4087 let customSelectContent = customSelect.querySelector(".custom-select-content"); 4088 if (!customSelectContent) return; 4089 let selectedOption = value ? Array.from(customSelectContent.children).find(function (b) { 4090 return b.value === value; 4091 }) : customSelectContent.firstChild; 4092 if (!selectedOption) { 4093 return; 4094 } 4095 if (selectedOption.classList.contains("is-disabled")) return; 4096 let elementNumber = Array.from(selectedOption.parentNode.children).indexOf(selectedOption); 4097 let linkedOption = originalSelect.querySelectorAll("option")[elementNumber]; 4098 linkedOption.selected = true; 4099 selectedOption.classList.add("is-selected"); 4100 selectedOption.parentNode.querySelectorAll(".custom-select-item").forEach(el => { 4101 if (el !== selectedOption) { 4102 el.classList.remove("is-selected"); 4103 } 4104 }); 4105 closeCustomSelect(customSelectToggle); 4106 customSelectToggle.innerHTML = linkedOption.innerHTML; 4107 if (linkedOption.value) { 4108 customSelectToggle.classList.remove("is-placeholder"); 4109 if (linkedOption.value !== "") { 4110 customSelect.classList.add("has-selection"); 4111 } else { 4112 customSelect.classList.remove("has-selection"); 4113 } 4114 } else { 4115 customSelect.classList.remove("has-selection"); 4116 customSelectToggle.classList.add("is-placeholder"); 4117 } 4118 }; 4119 const customSelect = originalSelect => { 4120 const customSelect = createCustomSelect(originalSelect); 4121 originalSelect.insertAdjacentElement('afterend', customSelect); 4122 return customSelect; 4123 }; 4124 const resetCustomSelect = originalSelect => { 4125 const customSelectEl = originalSelect.nextElementSibling; 4126 const customSelectToggle = customSelectEl?.querySelector('.custom-select-toggle'); 4127 const customSelectContent = customSelectEl?.querySelector('.custom-select-content'); 4128 if (!customSelectToggle || !customSelectContent) return; 4129 const placeholderOption = originalSelect.querySelector("[data-label]"); 4130 const placeholderText = placeholderOption?.dataset.label || originalSelect.querySelector("option")?.textContent || "Select"; 4131 customSelectContent.querySelectorAll('.custom-select-item').forEach(item => { 4132 item.classList.remove('is-selected'); 4133 item.setAttribute('aria-selected', 'false'); 4134 }); 4135 originalSelect.querySelectorAll('option').forEach(opt => opt.selected = false); 4136 customSelectToggle.innerHTML = placeholderText; 4137 customSelectToggle.classList.add('is-placeholder'); 4138 const customSelectWrapper = customSelectEl.querySelector('.custom-select'); 4139 if (customSelectWrapper) { 4140 customSelectWrapper.classList.remove('has-selection'); 4141 } 4142 }; 4143 const section = document.getElementById(sectionDomId); 4144 const searchContainer = section.querySelector('.search-container'); 4145 if (!searchContainer) return; 4146 const emptyResultElement = section.querySelector('.empty-result'); 4147 const dataContainer = section.querySelector('.data-container'); 4148 const areaSlider = searchContainer.querySelector('input[name="area-slider"]'); 4149 const neighborhoodSelect = searchContainer.querySelector('select[name="neighborhood-select"]'); 4150 const seasonalPriceSelect = section.querySelector('select[name="seasonal-price"]'); 4151 const searchInput = searchContainer.querySelector('input[name="search-input"]'); 4152 const resetSearchInput = section.querySelector(".js-reset"); 4153 const showFilter = section.querySelector('.js-show-filter'); 4154 const filtersCount = section.querySelector('.js-selected-filters'); 4155 const hideFilter = section.querySelector('.js-hide-filter'); 4156 const neighborhoodsSelectHolder = section.querySelector('.js-neighborhoods-select-holder'); 4157 const seasonalPriceSelectHolder = section.querySelector('.js-rental-rates-select-holder'); 4158 const _priceSlider = section.querySelector('.js-price-slider'); 4159 const _priceSliderMinLabel = section.querySelector('.js-price-slider-min'); 4160 const _priceSliderMaxLabel = section.querySelector('.js-price-slider-max');
4161 const _areaSlider = section.querySelector('.js-area-slider'); 4162 const _areaSliderMinLabel = section.querySelector('.js-area-slider-min'); 4163 const _areaSliderMaxLabel = section.querySelector('.js-area-slider-max'); 4164 const _priceMin = parseInt(_priceSlider.getAttribute("data-min"), 10); 4165 const _priceMax = parseInt(_priceSlider.getAttribute("data-max"), 10); 4166 const _priceStep = parseInt(_priceSlider.getAttribute("data-step"), 10); 4167 const _areaMin = parseInt(_areaSlider.getAttribute("data-min"), 10); 4168 const _areaMax = parseInt(_areaSlider.getAttribute("data-max"), 10); 4169 const _areaStep = parseInt(_areaSlider.getAttribute("data-step"), 10); 4170 let _currentPriceSliderMin, _currentPriceSliderMax; 4171 let _currentAreaSliderMin, _currentAreaSliderMax; 4172 showFilter.addEventListener('click', function () { 4173 searchContainer.style.display = 'block'; 4174 showFilter.style.display = 'none'; 4175 hideFilter.style.display = 'flex'; 4176 }); 4177 hideFilter.addEventListener('click', function () { 4178 searchContainer.style.display = 'none'; 4179 showFilter.style.display = 'flex'; 4180 hideFilter.style.display = 'none'; 4181 }); 4182 if (_priceSlider) { 4183 noUiSlider.create(_priceSlider, { 4184 start: [_priceMin, _priceMax], 4185 connect: true, 4186 step: _priceStep, 4187 range: { 4188 'min': _priceMin, 4189 'max': _priceMax 4190 }, 4191 format: { 4192 to: function (val) { 4193 return window.luxuryPresence.formatSliderPriceRange(val, { 4194 min: _priceMin, 4195 max: _priceMax 4196 }, "$", { 4197 lowPrefix: "<", 4198 highSuffix: "+" 4199 }); 4200 }, 4201 from: function (val) { 4202 return Number(val.replace(/[^0-9.-]+/g, "")); 4203 } 4204 } 4205 }); 4206 _priceSlider.noUiSlider.on('update', function (values) { 4207 _priceSliderMinLabel.innerHTML = `${values[0]}`; 4208 _priceSliderMaxLabel.innerHTML = `${values[1]}`; 4209 const [rawMin, rawMax] = _priceSlider.noUiSlider.get(true); 4210 _currentPriceSliderMin = rawMin; 4211 _currentPriceSliderMax = rawMax; 4212 }); 4213 _priceSlider.noUiSlider.on('end', function () { 4214 onSearch(); 4215 }); 4216 } 4217 if (_areaSlider) { 4218 noUiSlider.create(_areaSlider, { 4219 start: [_areaMin, _areaMax], 4220 connect: true, 4221 step: _areaStep, 4222 range: { 4223 'min': _areaMin, 4224 'max': _areaMax 4225 }, 4226 format: { 4227 to: function (val) { 4228 return window.luxuryPresence.formatSliderPriceRange(val, { 4229 min: _areaMin, 4230 max: _areaMax 4231 }, "", { 4232 lowPrefix: "<", 4233 highSuffix: "+" 4234 }); 4235 }, 4236 from: function (val) { 4237 return Number(val.replace(/[^0-9.-]+/g, "")); 4238 } 4239 } 4240 }); 4241 _areaSlider.noUiSlider.on('update', function (values) { 4242 _areaSliderMinLabel.innerHTML = `${values[0]}`; 4243 _areaSliderMaxLabel.innerHTML = `${values[1]}`; 4244 const [rawMin, rawMax] = _areaSlider.noUiSlider.get(true); 4245 _currentAreaSliderMin = rawMin; 4246 _currentAreaSliderMax = rawMax; 4247 }); 4248 _areaSlider.noUiSlider.on('end', function () { 4249 onSearch(); 4250 }); 4251 } 4252 function onSearch() { 4253 const params = { 4254 salesPriceGTE: _currentPriceSliderMin != _priceMin ? _currentPriceSliderMin : null, 4255 salesPriceLTE: _currentPriceSliderMax != _priceMax ? _currentPriceSliderMax : null, 4256 livingSpaceSizeGTE: _currentAreaSliderMin != _areaMin ? _currentAreaSliderMin : null, 4257 livingSpaceSizeLTE: _currentAreaSliderMax != _areaMax ? _currentAreaSliderMax : null, 4258 bedroomCountGTE: null, 4259 bathCountGTE: null, 4260 neighborhoodId: neighborhoodSelect.value || null, 4261 seasonalPriceId: seasonalPriceSelect?.value || null, 4262 search: searchInput.value || null 4263 }; 4264 const paramCount = Object.values(params).filter(value => value !== null).length; 4265 if (paramCount > 0) { 4266 filtersCount.textContent = paramCount; 4267 filtersCount.style.display = 'inline-block'; 4268 } else { 4269 filtersCount.style.display = 'none'; 4270 } 4271 const event = new CustomEvent('search', { 4272 detail: params 4273 });
4274 searchContainer.dispatchEvent(event); 4275 } 4276 searchContainer.addEventListener('neighborhoods-data', function (ev) { 4277 const neighborhoods = ev.detail; 4278 neighborhoods.data.forEach(item => { 4279 const option = document.createElement('option'); 4280 option.value = item.value; 4281 option.textContent = item.label; 4282 neighborhoodSelect.appendChild(option); 4283 }); 4284 customSelect(section.querySelector(".dropdown-select[name='neighborhood-select']")); 4285 if (neighborhoods.data.length) neighborhoodsSelectHolder.style.display = 'block'; 4286 }); 4287 if (seasonalPriceSelect) { 4288 searchContainer.addEventListener('rental-rates-data', function (ev) { 4289 const rentalRates = ev.detail; 4290 rentalRates.data.forEach(item => { 4291 const option = document.createElement('option'); 4292 option.value = item.rentalRateId; 4293 option.textContent = item.label; 4294 seasonalPriceSelect.appendChild(option); 4295 }); 4296 customSelect(section.querySelector(".dropdown-select[name='seasonal-price']")); 4297 if (rentalRates.data.length) seasonalPriceSelectHolder.style.display = 'block'; 4298 }); 4299 } 4300 searchContainer.addEventListener('sync', function (ev) { 4301 const params = ev.detail; 4302 searchInput.value = params.search || ''; 4303 if (neighborhoodSelect) setCustomSelectValue(neighborhoodSelect, params.neighborhoodId); 4304 if (seasonalPriceSelect) setCustomSelectValue(seasonalPriceSelect, params.seasonalPriceId); 4305 _priceSlider.noUiSlider.set([params.salesPriceGTE || _priceMin, params.salesPriceLTE || _priceMax]); 4306 _areaSlider.noUiSlider.set([params.livingSpaceSizeGTE || _areaMin, params.livingSpaceSizeLTE || _areaMax]); 4307 }); 4308 searchInput.addEventListener('input', window.luxuryPresence.debounce(onSearch, 1000)); 4309 resetSearchInput.addEventListener('click', function () { 4310 neighborhoodSelect.value = ''; 4311 searchInput.value = ''; 4312 if (seasonalPriceSelect) { 4313 seasonalPriceSelect.value = ''; 4314 setCustomSelectValue(seasonalPriceSelect, ''); 4315 } 4316 setCustomSelectValue(neighborhoodSelect); 4317 _priceSlider.noUiSlider.set([_priceMin, _priceMax]); 4318 _areaSlider.noUiSlider.set([_areaMin, _areaMax]); 4319 setTimeout(() => { 4320 const params = { 4321 salesPriceGTE: null, 4322 salesPriceLTE: null, 4323 livingSpaceSizeGTE: null, 4324 livingSpaceSizeLTE: null, 4325 bedroomCountGTE: null, 4326 bathCountGTE: null, 4327 neighborhoodId: null, 4328 seasonalPriceId: null, 4329 search: null 4330 }; 4331 const event = new CustomEvent('search', { 4332 detail: params 4333 }); 4334 searchContainer.dispatchEvent(event); 4335 }, 1000); 4336 }); 4337 neighborhoodSelect.addEventListener('change', onSearch); 4338 if (seasonalPriceSelect) { 4339 seasonalPriceSelect.addEventListener('change', onSearch); 4340 } 4341})('section-055f7306-112d-4d27-8914-cafe3745ec53', JSON.parse("{\"resource\":\"properties\",\"useRouterApi\":false,\"routerApiAux\":{\"testimonials\":true,\"agents\":false,\"neighborhoods\":false,\"developments\":true,\"properties\":false,\"posts\":true,\"pressReleases\":true,\"offices\":true,\"teams\":true,\"pois\":true,\"postCategories\":true},\"companyId\":\"c1908ce5-efe4-423f-a0b8-f9e844db2413\",\"usePageResource\":false,\"sectionIndex\":2}")); 4342} catch(e) { 4343console.log(e); 4344} 4345 try { 4346(function init(sectionDomId) {})('section-4510a72a-a320-4493-886b-c8947b75a60f', 'undefined'); 4347} catch(e) { 4348console.log(e); 4349} 4350 try { 4351(function init(sectionDomId, options) { 4352 let section = null; 4353 switch (sectionDomId) { 4354 case 'NAVBAR': 4355 section = document.querySelector('body > nav, #global-navbar'); 4356 break; 4357 case 'FOOTER': 4358 section = document.querySelector('body > footer, #global-footer'); 4359 break; 4360 case 'SIDEMENU': 4361 section = document.querySelector('body > div.sidemenu, #global-sidemenu'); 4362 break; 4363 case 'CONTACT': 4364 section = document.querySelector('#modal-global-contact-us'); 4365 break; 4366 case 'MOBILE_CONTACT': 4367 section = document.querySelector('body > div.mobile-contact-wrapper, #global-mobile-contact'); 4368 break; 4369 case 'SUBSCRIBE': 4370 // Subscribe Not Implemented 4371 section = null; 4372 break; 4373 case 'ACCOUNT': 4374 // Account Not Implemented 4375 section = null; 4376 break; 4377 default: 4378 section = document.querySelector('#' + sectionDomId); 4379 } 4380 if (!section) { 4381 return; 4382 } 4383 var url = window.luxuryPresence.defaults.routerUrl; 4384 var companyId = window.luxuryPresence.defaults.companyId; 4385 var limit = options.limit || 8; 4386 if (typeof limit === 'string') { 4387 limit = parseInt(limit, 10) || 8; // this NaN protection also filters out 0 - this is expected 4388 } 4389 var templateSelector = options.templateSelector || '.jsIGTemplate'; 4390 var containerSelector = options.containerSelector || '.jsIGContainer'; 4391 var hasDataClass = options.hasDataClass || 'has-data'; 4392 var hideActivateMessage = options.hasDataClass || false; 4393 var payload = { 4394 companyId: companyId, 4395 limit: limit 4396 }; 4397 if (options.resourceId && typeof options.resourceId === 'string' && !
4397options.resourceId.match(/^{{.*}}$/)) { 4398 payload.resourceId = options.resourceId; 4399 // Federated enum values are uppercase (AGENT/TEAM); element configs carry lowercase 4400 payload.resource = String(options.resource || 'agent').toUpperCase(); 4401 payload.fallbackToNoResource = options.fallbackToNoResource === 'true' || options.fallbackToNoResource === true; 4402 } 4403 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'; 4404 var templateHTML = section.querySelector(templateSelector)?.innerHTML || ''; 4405 var template = Handlebars.compile(templateHTML); 4406 var container = section.querySelector(containerSelector); 4407 if (options.variables) { 4408 Object.keys(options.variables).forEach(function (key) { 4409 if (options.variables.hasOwnProperty(key) && (typeof options.variables[key] !== 'string' || !options.variables[key].match(/^{{.*}}$/))) { 4410 payload[key] = options.variables[key]; 4411 } 4412 }); 4413 } 4414 function getData() { 4415 var feed = { 4416 error: true 4417 }; 4418 if (payload.companyId == null || payload.companyId === '') { 4419 // instagramContentFeed requires companyId (ID!) â nothing to fetch without it. 4420 // Checked after the options.variables merge, which may override the default. 4421 // Deferred so element listeners (attached after this template runs) still receive it. 4422 setTimeout(function () { 4423 section.dispatchEvent(new CustomEvent('ig-data', { 4424 detail: feed 4425 })); 4426 }, 0); 4427 return; 4428 } 4429 superagent.post(url + '/graphql').send({ 4430 query: query, 4431 variables: payload 4432 }).then(res => { 4433 try { 4434 if (!res.body.errors) { 4435 feed = res.body.data.instagramContentFeed; 4436 if (!feed.active) { 4437 if (!hideActivateMessage && sectionDomId === 'section-temp' && container) { 4438 if (payload.resourceId) { 4439 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>'; 4440 } else { 4441 container.innerHTML = '<div style="text-align: center">Instagram account is not connected.<br /> Connect it on <a href="/profile">Profile page</a></div>'; 4442 } 4443 } 4444 } else { 4445 if (feed.items.length) { 4446 if (hasDataClass) { 4447 section.classList.add(hasDataClass); 4448 } 4449 const feedName = feed.username; 4450 section.querySelectorAll('.jsIGLink').forEach(link => link.setAttribute('href', feed.feedUrl)); 4451 section.querySelectorAll('.jsIGName').forEach(name => { 4452 name.textContent = '@' + feedName; 4453 name.setAttribute('title', '@' + feedName); 4454 }); 4455 if (container && template) { 4456 container.innerHTML = template(feed); 4457 } 4458 } 4459 } 4460 } 4461 } catch (e) {} 4462 section.dispatchEvent(new CustomEvent('ig-data', { 4463 detail: feed 4464 })); 4465 }).catch(e => { 4466 console.log('err', e); 4467 section.dispatchEvent(new CustomEvent('ig-data', { 4468 detail: feed 4469 })); 4470 }); 4471 } 4472 getData(); 4473})('section-f6b2e0c9-5dd7-43a4-8086-a51ab775df71', JSON.parse("{\"limit\":11,\"resource\":\"agent\",\"resourceId\":\"{{id}}\",\"fallbackToNoResource\":\"{{{fallbackToNoResource}}}\",\"companyId\":\"c1908ce5-efe4-423f-a0b8-f9e844db2413\",\"usePageResource\":false,\"sectionIndex\":4,\"useRouterApi\":false,\"routerApiAux\":{\"testimonials\":true,\"agents\":false,\"neighborhoods\":false,\"developments\":true,\"properties\":false,\"posts\":true,\"pressReleases\":true,\"offices\":true,\"teams\":true,\"pois\":true,\"postCategories\":true}}")); 4474} catch(e) { 4475console.log(e); 4476} 4477 try { 4478(function init(sectionDomId) { 4479 const section = document.getElementById(sectionDomId); 4480 const slider = section.querySelector(".js-slider"); 4481 section.addEventListener("ig-data", function () { 4482 var splide = new Splide(slider, { 4483 rewind: true,
4484 arrows: false, 4485 type: 'loop', 4486 padding: '20%', 4487 gap: '16px', 4488 pagination: false, 4489 clones: 1, 4490 perPage: 1, 4491 perMove: 1, 4492 destroy: true, 4493 breakpoints: { 4494 768: { 4495 destroy: false 4496 } 4497 } 4498 }); 4499 splide.mount(); 4500 }); 4501})('section-f6b2e0c9-5dd7-43a4-8086-a51ab775df71', JSON.parse("{\"resource\":\"agent\",\"useRouterApi\":false,\"routerApiAux\":{\"testimonials\":true,\"agents\":false,\"neighborhoods\":false,\"developments\":true,\"properties\":false,\"posts\":true,\"pressReleases\":true,\"offices\":true,\"teams\":true,\"pois\":true,\"postCategories\":true},\"companyId\":\"c1908ce5-efe4-423f-a0b8-f9e844db2413\",\"usePageResource\":false,\"sectionIndex\":4}")); 4502} catch(e) { 4503console.log(e); 4504} 4505 4506 var { body } = document; 4507 var globalNav = body.querySelector(':scope > nav'); 4508 var globalSideMenu = body.querySelector(':scope > div.sidemenu'); 4509 4510 document.querySelectorAll('body > .modal .close').forEach(modalCloseBtn => { 4511 modalCloseBtn.addEventListener('click', function() { 4512 window.lpUI.hideClosestModal(modalCloseBtn); 4513 }); 4514 }); 4515 4516 window.addEventListener('click', function() { 4517 document.querySelectorAll('.share-popup').forEach(sharedPopup => { 4518 sharedPopup.style.display = 'none' ; 4519 }); 4520 }); 4521 4522 /* Misc Partials / Addons */ 4523 function initWOW() { 4524 if (wow) { 4525 wow.init(); 4526 wow.scrollHandler(); 4527 setTimeout(function () { 4528 const wowHideStyle = document.getElementById('wow-hide-elements'); 4529 if(wowHideStyle) { 4530 wowHideStyle.disabled = true; 4531 } 4532 }, 1); 4533 } 4534 } 4535 4536 const wowHideElements = document.getElementById('wow-hide-elements'); 4537 if (wowHideElements) { 4538 wowHideElements.disabled = false; 4539 } 4540 4541 initWOW(); 4542 4543 /* Generic Navbar Handling */ 4544 globalNav?.querySelectorAll('.hamburger-component').forEach(hamburgerComponent => { 4545 hamburgerComponent.addEventListener('click', function() { 4546 window.lpUI.sideMenuToggle(); 4547 }); 4548 }); 4549 globalSideMenu?.querySelectorAll('.toggle').forEach(toggleEl => { 4550 toggleEl.addEventListener('click', function() { 4551 window.lpUI.sideMenuToggle(); 4552 }); 4553 }); 4554 4555 document.querySelectorAll('body > nav .sub-nav-container > a, body > div.sidemenu .sub-nav-container > a').forEach(linkEl => { 4556 linkEl.addEventListener('click', function(e) { 4557 e.preventDefault(); 4558 e.stopPropagation(); 4559 var subNav = linkEl.parentElement.querySelector(':scope > .sub-nav'); 4560 if (subNav && subNav.classList.contains('visible')){ 4561 subNav.classList.remove('visible'); 4562 } else { 4563 globalNav?.querySelectorAll('.sub-nav-container .sub-nav').forEach(globalSubNav => { 4564 globalSubNav.classList.remove('visible'); 4565 }); 4566 globalSideMenu?.querySelectorAll('.sub-nav').forEach(sideMenuSubNav => { 4567 sideMenuSubNav.classList.remove('visible'); 4568 }); 4569 subNav?.classList.add('visible'); 4570 } 4571 }); 4572 }); 4573 window.addEventListener('click', function() { 4574 document.querySelectorAll('nav .sub-nav.visible, .sidemenu .sub-nav.visible').forEach(subNavEl => { 4575 subNavEl.classList.remove('visible'); 4576 }); 4577 }); 4578 4579 } 4580 4581 document.addEventListener('DOMContentLoaded', lpGlobalInit); 4582 4583 </script>
4583 4584 4585
4585<script type="module"> 4586 function selectorExists(selector) { 4587 return document.querySelector(selector) !== null; 4588 } 4589 4590 // Function to initialize the third-party library 4591 function initParoller(selector = '.my-paroller') { 4592 var $parollerElements = $(selector); 4593 if ($parollerElements.length > 0 && typeof $parollerElements.paroller === 'function') { 4594 $parollerElements.paroller(); 4595 } 4596 } 4597 4598 const parollerSelector = '.my-paroller'; 4599 4600 if (selectorExists(parollerSelector)) { 4601 window.luxuryPresence.libs.loadJs(window.luxuryPresence.libs.jsLibsMap.paroller.jsSrc, function() { 4602 initParoller(parollerSelector); 4603 window.luxuryPresence.libs.jsLibsMap.paroller.isLoaded = true; 4604 }); 4605 } 4606 </script>
4606 4607 4608 <!-- Google Tag Manager (noscript) -->
vendor: 80 bytes, lines 4608-4609
4608 4609 <noscript><iframe src="https://www.googletagmanager.com/ns.html?id=
4609GTM-T9SFQGHZ
vendor: 107 bytes, lines 4609-4611
4609" 4610 height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript> 4611
4611<!-- End Google Tag Manager --> 4612 4613
4613<script 4614 src="https://cdn.luxurypresence.com/scripts/a11y-widget/latest/widget.js" 4615 data-website-id="e8034653-cea9-43db-b10d-f8cf56e2295a" 4616 4617 defer></script>
vendor: 1 bytes, line 4617
4617
4618<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>
vendor: 1 bytes, line 4618
4618
4619<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:'a4822bf89db9c4e5',t:'MTc5MTU5OTA5Nw=='};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>
4619</body> 4620</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.