1<!DOCTYPE html> <html lang="en"> <head><meta name="description" content=""> <meta charset="utf-8"> <meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="msvalidate.01" content="52D8CD5F9EA2B1031F2D2472023A5D34"> <title>MyPortal | Collections</title>
1<script type="application/ld+json">{"@context":"https:\/\/schema.org","@type":"LocalBusiness","name":"Premier Property Solutions | Charlotte, NC","url":"https:\/\/www.mypremierproperty.com","image":"https:\/\/cdn1.brivityidx.com\/assets\/images\/agent-photos\/1\/3\/8\/13850089\/place-logo.png","telephone":"+17042860506","address":{"@type":"PostalAddress","streetAddress":"14045 Ballantyne Corporate Place Suite 500","addressLocality":"Charlotte","addressRegion":"NC","postalCode":"28277","addressCountry":"US"},"sameAs":["https:\/\/www.facebook.com\/MyPremierProperty\/","https:\/\/www.instagram.com\/premierproperty_solutions\/"]}</script>
1 <link rel="preconnect" href="https://www.google.com"> <link rel="preconnect" href="https://www.gstatic.com" crossorigin> <link rel="dns-prefetch" href="https://cdn1.brivityidx.com">
1<script> 2 var head = document.getElementsByTagName('head')[0] 3 var insertBefore = head.insertBefore; 4 head.insertBefore = function (newElement, referenceElement) { 5 // intercept style elements for IEs 6 if (newElement.tagName.toLowerCase() === 'style' 7 && newElement.styleSheet 8 && newElement.styleSheet.cssText 9 && newElement.styleSheet.cssText.replace('\r\n', '').indexOf('.gm-style') === 0) { 10 return; 11 } 12 // intercept style elements for other browsers 13 if (newElement.tagName.toLowerCase() === 'style' 14 && newElement.innerHTML 15 && newElement.innerHTML.replace('\r\n', '').indexOf('.gm-style') === 0) { 16 return; 17 } 18 insertBefore.call(head, newElement, referenceElement); 19 }; 20 </script>
20 <link rel="shortcut icon" href="https://cdn1.brivityidx.com/assets/images/uploads/10784/favicon-new.ico" type="image/x-icon"> <link href="https://cdn1.brivityidx.com/assets/css/build-site.min.css?ck=" rel="stylesheet"> <link href="https://cdn1.brivityidx.com/assets/css/build-chatbot-v1.min.css?ck=" rel="stylesheet" media="print" onload="this.media='all'"><noscript><link href="https://cdn1.brivityidx.com/assets/css/build-chatbot-v1.min.css?ck=" rel="stylesheet"></noscript> <link rel="canonical" href="https://www.mypremierproperty.com/myportal/collections">
20<script> 21 function deferScriptOnLoad(url, sleep = 0) { 22 window.addEventListener('load', function () { 23 deferScript(url, sleep); 24 }); 25 } 26 function deferScript(url, sleep = 0) { 27 if (sleep > 0) { 28 setTimeout(() => { 29 deferScript(url); 30 }, sleep); 31 return; 32 } 33 let s = document.createElement('script'); 34 s.type = 'text/javascript'; 35 s.async = true; 36 s.src = url; 37 let x = document.getElementsByTagName('head')[0]; 38 x.appendChild(s); 39 } 40 41 /* PLACE_COMPONENTS_LOADER_START */ 42 window.sitebuilderPlaceComponents = (function () { 43 var DEFAULT_URL = 'https://mobile-component-services-library-dev.brivity.com/web-components.min.js?ck=1'; 44 var BUNDLE_URLS = { default: DEFAULT_URL }; 45 var loadPromises = {}; 46 var LOAD_TIMEOUT_MS = 10000; 47 48 function urlForTag(tagName) { 49 return BUNDLE_URLS[tagName] || BUNDLE_URLS.default; 50 } 51 52 function ensureLoaded(tagName) { 53 var url = urlForTag(tagName); 54 if (loadPromises[url]) { 55 return loadPromises[url]; 56 } 57 loadPromises[url] = new Promise(function (resolve, reject) { 58 var settled = false; 59 var timer = setTimeout(function () { 60 if (settled) return; 61 settled = true; 62 reject(new Error('web-components load timeout')); 63 }, LOAD_TIMEOUT_MS); 64 var s = document.createElement('script'); 65 s.type = 'text/javascript'; 66 s.async = true; 67 s.src = url; 68 s.onerror = function () { 69 if (settled) return; 70 settled = true; 71 clearTimeout(timer); 72 reject(new Error('web-components script onerror')); 73 }; 74 document.getElementsByTagName('head')[0].appendChild(s); 75 if (window.customElements && customElements.whenDefined) { 76 customElements.whenDefined(tagName).then(function () { 77 if (settled) return; 78 settled = true; 79 clearTimeout(timer); 80 resolve(); 81 }); 82 } 83 }); 84 return loadPromises[url]; 85 } 86 87 var EAGER_SELECTOR = 'place-propertycard, place-searchpagefilter, place-bedbathfiltermodal, ' + 88 'place-listingstatusmodal, place-propertytypemodal, place-savesearchmodal, ' + 89 'place-basicmodal, place-details, place-agentbio, place-agentmessaging, ' + 90 'place-contactyouragent, place-menu, place-collectionpopup, ' + 91 'place-copycollectionmodal, place-removecollectionpopup, place-vs-accumulate'; 92 93 function warmIfEagerTagsPresent() { 94 if (document.querySelector(EAGER_SELECTOR)) { 95 ensureLoaded('place-propertycard').catch(function () {}); 96 } 97 } 98 if (document.readyState === 'loading') { 99 document.addEventListener('DOMContentLoaded', warmIfEagerTagsPresent); 100 } else { 101 warmIfEagerTagsPresent(); 102 } 103 104 var INTERACTION_SELECTOR = 'place-getyourhomecta, place-generictoast, ' + EAGER_SELECTOR + 105 ', [data-needs-place-components]'; 106 function onInteract(e) { 107 var t = e.target; 108 if (t && t.closest && t.closest(INTERACTION_SELECTOR)) { 109 ensureLoaded('place-generictoast').catch(function () {}); 110 } 111 } 112 document.addEventListener('pointerdown', onInteract, true); 113 document.addEventListener('focusin', onInteract, true); 114 115 function idleWarm() { 116 ensureLoaded('place-generictoast').catch(function () {}); 117 } 118 if ('requestIdleCallback' in window) { 119 requestIdleCallback(idleWarm, { timeout: 5000 }); 120 } else { 121 setTimeout(idleWarm, 3000); 122 } 123 124 return { ensureLoaded: ensureLoaded }; 125 })(); 126 /* PLACE_COMPONENTS_LOADER_END */ 127 128 const googleApiKey = 'AIzaSyAjpuNg6WGCMV5rzoJcIP2QmMTVto6hYmc' 129 130 /* Lazy loader for Google Maps API + turf.js. 131 * The TURF_INLINE / MAPS_API_INLINE placeholders below are emitted by 132 * Sitemodel.php only on pages whose blocks actually consume Maps/turf. 133 * On other pages those tags are stripped, and consumers call 134 * sitebuilderMapsApi.ensureLoaded() to inject them on demand. 135 * 136 * Safari fix vs. the prior reverted attempt (commit 0cef3135e): uses 137 * Google's official &callback= parameter, not setTimeout, to detect 138 * Maps readiness. 139 */ 140 window.sitebuilderMapsApi = (function () { 141 var TURF_URL = 'https://cdn.jsdelivr.net/npm/@turf/[email protected]/turf.min.js';
142 var MAPS_URL = 'https://maps.googleapis.com/maps/api/js?libraries=geocoding,places,marker,drawing&key=' + 143 googleApiKey + '&map_ids=85c127b7bf0255d9&callback=__sitebuilderMapsReady'; 144 var LOAD_TIMEOUT_MS = 15000; 145 var loadPromise = null; 146 147 function injectScript(url) { 148 var s = document.createElement('script'); 149 s.type = 'text/javascript'; 150 s.async = true; 151 s.src = url; 152 document.getElementsByTagName('head')[0].appendChild(s); 153 return s; 154 } 155 156 function loadTurf() { 157 return new Promise(function (resolve, reject) { 158 if (window.turf) { resolve(); return; } 159 var s = injectScript(TURF_URL); 160 s.onload = function () { resolve(); }; 161 s.onerror = function () { reject(new Error('turf load failed')); }; 162 }); 163 } 164 165 function loadMaps() { 166 return new Promise(function (resolve, reject) { 167 if (window.google && window.google.maps) { resolve(); return; } 168 window.__sitebuilderMapsReady = function () { resolve(); }; 169 var s = injectScript(MAPS_URL); 170 s.onerror = function () { reject(new Error('maps load failed')); }; 171 }); 172 } 173 174 function ensureLoaded() { 175 if (loadPromise) return loadPromise; 176 if (window.google && window.google.maps && window.turf) { 177 loadPromise = Promise.resolve(); 178 return loadPromise; 179 } 180 loadPromise = new Promise(function (resolve, reject) { 181 var settled = false; 182 var timer = setTimeout(function () { 183 if (settled) return; 184 settled = true; 185 reject(new Error('maps/turf load timeout')); 186 }, LOAD_TIMEOUT_MS); 187 Promise.all([loadTurf(), loadMaps()]).then(function () { 188 if (settled) return; 189 settled = true; 190 clearTimeout(timer); 191 resolve(); 192 }, function (err) { 193 if (settled) return; 194 settled = true; 195 clearTimeout(timer); 196 reject(err); 197 }); 198 }); 199 return loadPromise; 200 } 201 202 return { ensureLoaded: ensureLoaded }; 203 })(); 204 </script>
204 <link href="https://cdn1.brivityidx.com/assets/css/style-headers.min.css" rel="stylesheet"><link href="https://cdn1.brivityidx.com/assets/css/style-premium.min.css" rel="stylesheet"><link href="https://cdn1.brivityidx.com/assets/css/style-footers.css" rel="stylesheet"><link href="https://cdn1.brivityidx.com/idx-sites/1/3/5/13574/site_custom.css?v=1789579409" rel="stylesheet">
204<script type="text/javascript" src="https://cdn1.brivityidx.com/idx-sites/1/3/5/13574/global_js_variables.js?v=1789579409"></script>
204<link rel="preconnect" href="https://fonts.googleapis.com"> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <link href="https://fonts.googleapis.com/css2?family=Oswald:wght@200;500;700&display=swap" rel="stylesheet"> <link rel="stylesheet" href="https://use.typekit.net/psh7aoo.css">
204<script type="application/ld+json"> 205{"@context":"https://schema.org","@type":"RealEstateAgent","name":"Premier Property Solutions","description":"Full-service residential real estate team serving the greater Charlotte metro in NC and SC â buying and selling, from Mooresville to Clover. Premier Property Solutions has closed more than $500 million in sales volume across more than 1,300 transaction sides, per Canopy MLS agent production reports run in August 2026.","url":"https://www.mypremierproperty.com","telephone":"(704) 286-0506","email":"[email protected]","address":{"@type":"PostalAddress","streetAddress":"14045 Ballantyne Corporate Place Suite 500","addressLocality":"Charlotte","addressRegion":"NC","postalCode":"28277","addressCountry":"US"},"areaServed":["Charlotte NC","Ballantyne","SouthPark","Matthews NC","Mint Hill NC","Huntersville NC","Cornelius NC","Davidson NC","Mooresville NC","Lake Norman","Concord NC","Kannapolis NC","Gastonia NC","Belmont NC","Waxhaw NC","Weddington NC","Monroe NC","Indian Trail NC","Fort Mill SC","Tega Cay SC","Rock Hill SC","Lake Wylie SC","Clover SC","Indian Land SC"],"foundingDate":"2015", "award": "RealTrends Verified 2026 â ranked #4 among large teams in Charlotte, NC by sales volume, based on 2025 production","founder":{"@type":"Person","name":"Nicole McAlister","jobTitle":"Founder & Team Leader","url":"https://www.mypremierproperty.com/agent-profile/nicole-mcalister-13853499","description":"Founder and team leader of Premier Property Solutions, a real estate team affiliated with Ballantyne Area Market Center LLC (Keller Williams Realty; each office is independently owned and operated). Premier Property Solutions is a registered trade name of McAlisters Homes LLC, NCREC firm licence C26713. NC broker licence 279893.","identifier":[{"@type":"PropertyValue","propertyID":"NC Real Estate License","value":"279893"},{"@type":"PropertyValue","propertyID":"SC Real Estate License","value":"89383"}],"sameAs":["https://www.zillow.com/profile/NMcAlister","https://www.linkedin.com/in/nicolemcalisterrealtor/","https://www.instagram.com/nicolethecarolinasrealtor/","https://kw.com/agent/nicole-mcalister/356894"]},"sameAs":["https://www.facebook.com/MyPremierProperty/","https://www.instagram.com/premierproperty_solutions/","https://www.zillow.com/profile/MyPremierProperty/","https://www.homes.com/real-estate-agents/nicole-mcalister/jq109p5/"]} 206</script>
vendor: 64 bytes, line 206
206 <script async src="https://www.googletagmanager.com/gtag/js?id=
206G-6CDT83D19B
vendor: 12 bytes, line 206
206"></script>
206<script> 207
vendor: 134 bytes, lines 207-211
207window.dataLayer = window.dataLayer || []; 208 function gtag(){dataLayer.push(arguments);} 209 gtag('js', new Date()); 210 211 gtag('config', '
211G-6CDT83D19B
vendor: 4 bytes, line 211
211');
212</script>
212
212<script> 213var propDetailsPixelOnReady = function(){ 214 let propDetFpst = new FbRealEstatePixelTracker({"eventType": "ViewContent", "content_ids": [""]}); 215 propDetFpst.fireEvent(); 216}; 217if (document.readyState === "complete" || (document.readyState !== "loading" && !document.documentElement.doScroll)) { 218 propDetailsPixelOnReady(); 219} else { 220 document.addEventListener("DOMContentLoaded", propDetailsPixelOnReady); 221} 222 223</script>
223
223<script>
vendor: 327 bytes, lines 223-227
223(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start': 224new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0], 225j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src= 226'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f); 227})(window,document,'script','dataLayer','
227GTM-WDHHMSP
vendor: 3 bytes, line 227
227');
227</script>
227 <meta name="google-site-verification" content="xsYLKtmmfSVuInIjmlwFAx5xCQmyB7tNOHBcE26by3Y" /> <meta property="og:url" content="https://www.mypremierproperty.com/myportal/collections"> <meta property="og:image" content="http://images.brivityidx.com/assets/images/uploads/10784/dreamstead-og-new.png"> <meta property="og:image:secure_url" content="https://images.brivityidx.com/assets/images/uploads/10784/dreamstead-og-new.png"> <meta property="og:description" content=""> <meta property="og:title" content="MyPortal | Collections"> </head> <body>
vendor: 68 bytes, line 227
227 <noscript><iframe src="https://www.googletagmanager.com/ns.html?id=
227GTM-WDHHMSP
vendor: 83 bytes, line 227
227" height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
227<script> 228 window.fbAsyncInit = function() { 229 FB.init({ 230 appId : '1', 231 cookie : true, 232 xfbml : true, 233 version : 'v17.0' 234 }); 235 FB.AppEvents.logPageView(); 236 }; 237 238 setTimeout(() => {(function(d, s, id){ 239 var js, fjs = d.getElementsByTagName(s)[0]; 240 if (d.getElementById(id)) {return;} 241 js = d.createElement(s); js.id = id; 242 js.defer = true; 243 js.xfbml = false; 244 js.src = "//connect.facebook.net/en_US/sdk.js"; 245 fjs.parentNode.insertBefore(js, fjs); 246 }(document, 'script', 'facebook-jssdk'))}, 5000); 247 </script>
247<meta property="fb:app_id" content="1"><meta name="google-signin-client_id" content="1"><meta name="apple-signin-flag" content="1"><meta name="main_sitebuilder_domain" content="https://sitebuilder.brivity.com"> <div id="site-registration-bar" class="collapse"> <input type="hidden" id="huser_id" value=""> <div class="row" style="width: 100%; margin: 0;"> <div class="col-md-12" style="display: none;" id="logged-in"> <div class="topBar flex aiCenter jcBetween"> <div class="topBarLeft flex aiCenter"> <span><topbar_show_agent_name/></span> </div> <div class="topBarRight flex aiCenter"> <a class="topLink flex aiCenter thin favoritesTop" href="/myportal/collections"> <svg width="17" height="17" viewBox="0 0 17 17" fill="none" xmlns="http://www.w3.org/2000/svg"> <g clip-path="url(#clip0_16761_179132)"> <path d="M14.2659 3.57333C13.9254 3.23267 13.5211 2.96243 13.0761 2.77806C12.6312 2.59368 12.1542 2.49878 11.6726 2.49878C11.1909 2.49878 10.714 2.59368 10.269 2.77806C9.82401 2.96243 9.41973 3.23267 9.07922 3.57333L8.37256 4.28L7.66589 3.57333C6.97809 2.88554 6.04524 2.49914 5.07256 2.49914C4.09987 2.49914 3.16702 2.88554 2.47922 3.57333C1.79143 4.26113 1.40503 5.19398 1.40503 6.16667C1.40503 7.13936 1.79143 8.07221 2.47922 8.76L3.18589 9.46667L8.37256 14.6533L13.5592 9.46667L14.2659 8.76C14.6066 8.4195 14.8768 8.01521 15.0612 7.57024C15.2455 7.12526 15.3404 6.64832 15.3404 6.16667C15.3404 5.68501 15.2455 5.20807 15.0612 4.7631C14.8768 4.31812 14.6066 3.91384 14.2659 3.57333V3.57333Z" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> </g> <defs> <clipPath id="clip0_16761_179132"> <rect width="16" height="16" fill="white" transform="translate(0.372559 0.5)"/> </clipPath> </defs> </svg> <span class="ml6 topLabel">Collections </span> </a> <a class="topLink flex aiCenter thin saveSearchTop" href="/myportal/searches"> <svg width="16" height="16" viewBox="0 4 20 17" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M19 21L12 16L5 21V5C5 4.46957 5.21071 3.96086 5.58579 3.58579C5.96086 3.21071 6.46957 3 7 3H17C17.5304 3 18.0391 3.21071 18.4142 3.58579C18.7893 3.96086 19 4.46957 19 5V21Z" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" /> </svg> <span class="ml6 topLabel">Saved Searches </span> </a> <a class="topLink flex aiCenter thin market-report-top" style="display:none" href="/myportal/reports"> <svg width="17" height="17" viewBox="0 0 17 17" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M7.70589 13.1667C10.6514 13.1667 13.0392 10.7789 13.0392 7.83333C13.0392 4.88781 10.6514 2.5 7.70589 2.5C4.76037 2.5 2.37256 4.88781 2.37256 7.83333C2.37256 10.7789 4.76037 13.1667 7.70589 13.1667Z" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> <path d="M14.3725 14.5L11.4725 11.6" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> </svg> <span class="ml6 topLabel">My Reports </span> </a> <a class="aiCenter flex topBarProfile thin" href="/myportal/profile"> <span class="profileName"></span> </a> <a style="padding-right: 0px" class="aiCenter flex thin" id="topBarLogout" href="javascript:void()"> <svg width="23" height="23" viewBox="0 0 23 23" fill="none" xmlns="http://www.w3.org/2000/svg"> <g clip-path="url(#clip0_16761_179186)"> <path d="M16.4003 16.214C19.0038 13.6106 19.0038 9.38945 16.4003 6.78595C13.7968 4.18246 9.57572 4.18246 6.97222 6.78595C4.36873 9.38945 4.36873 13.6105 6.97222 16.214C9.57572 18.8175 13.7968 18.8175 16.4003 16.214Z" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> <path d="M9.80066 9.61438L13.5719 13.3856" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> <path d="M9.80066 13.3856L13.5719 9.61438" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> </g> <defs> <clipPath id="clip0_16761_179186"> <rect width="16" height="16" fill="white" transform="translate(0.372559 11.5) rotate(-45)"/> </clipPath> </defs> </svg> <span class="ml6">Log Out</span> </a> </div> </div> </div> <div id="not-logged-in"> <topbar_agent_info_not_logged_in/> <ul class="list-unstyled list-inline no-margin"> <li class="topBarSignin"><a href="#" onclick="showGoogleOneTap(true);"><svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-plus-circle mr10"><circle cx="12" cy="12" r="10"></circle><line x1="12" y1="8" x2="12" y2="16"></line>
247<line x1="8" y1="12" x2="16" y2="12"></line></svg> Sign In</a></li> </ul> </div> </div> </div> <input type="hidden" id="huser_email" value=""> <input type="hidden" id="huser_first_name" value=""> <input type="hidden" id="huser_last_name" value=""> <input type="hidden" id="huser_phone" value=""> <input type="hidden" id="huser_uuid" value=""> <div id="page" class="page"><header id="premium-navigation" class="vertical-nav" style=" outline: none; cursor: inherit;" data-selector="#premium-navigation"> <div class="main-nav"> <div class="container"> <div class="navbar-header"> <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse" style="outline: none; cursor: inherit;" data-selector="a.btn, button.btn, button"> <span class="sr-only">Toggle navigation</span> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> <a class="navbar-brand" href="/" style="outline: none; cursor: inherit;"> <img class="img-responsive site_custom_logo_dynamic" src="https://cdn1.brivityidx.com/assets/images/agent-photos/1/3/8/13850089/place-logo.png" alt="Premier Property Solutions logo" style="outline: none; cursor: inherit;" data-selector="img"> </a> </div> <div class="collapse navbar-collapse render-menu"><ul class="nav navbar-nav navbar-right"><li class="nav-item"><a class="sec-nav-link-color" href="/index">Home</a></li><li class="nav-item"><a class="sec-nav-link-color" href="/search">Search</a></li><li class="nav-item dropdown"><a class="dropdown-toggle sec-nav-link-color" data-toggle="dropdown" data-hover="dropdown" data-delay="0" data-close-others="false">Buying<i class="fa fa-angle-down"></i></a><ul class="dropdown-menu"><li class="sec-nav-drop-color"><a class="sec-nav-drop-link-color" href="/buying">Searching With Us</a></li><li class="sec-nav-drop-color"><a class="sec-nav-drop-link-color" href="/the_home_buying_process">Home Buying Process</a></li><li class="sec-nav-drop-color"><a class="sec-nav-drop-link-color" href="/prepare_an_offer_in_nc">Prepare An Offer In NC</a></li><li class="sec-nav-drop-color"><a class="sec-nav-drop-link-color" href="/prepare_an_offer_in_sc">Prepare An Offer In SC</a></li><li class="sec-nav-drop-color"><a class="sec-nav-drop-link-color" href="/financing">Financing</a></li></ul><li class="nav-item dropdown"><a class="dropdown-toggle sec-nav-link-color" data-toggle="dropdown" data-hover="dropdown" data-delay="0" data-close-others="false">Selling<i class="fa fa-angle-down"></i></a><ul class="dropdown-menu"><li class="sec-nav-drop-color"><a class="sec-nav-drop-link-color" href="/selling">Selling A Home</a></li><li class="sec-nav-drop-color"><a class="sec-nav-drop-link-color" href="/the_house_selling_process">House Selling Process</a></li><li class="sec-nav-drop-color"><a class="sec-nav-drop-link-color" href="/staging_guide">Staging Guide</a></li><li class="sec-nav-drop-color"><a class="sec-nav-drop-link-color" href="/receiving_offers">Receiving Offers</a></li><li class="sec-nav-drop-color"><a class="sec-nav-drop-link-color" href="/inspection">Inspection</a></li></ul><li class="nav-item dropdown"><a class="dropdown-toggle sec-nav-link-color" data-toggle="dropdown" data-hover="dropdown" data-delay="0" data-close-others="false">Top Areas<i class="fa fa-angle-down"></i></a><ul class="dropdown-menu"><li class="sec-nav-drop-color"><a class="sec-nav-drop-link-color" href="/search?ulti_search=Charlotte,%20NC&multi_cat=CityState&propertyType=Condo/Townhome|Multi-Family|Residential&status=1|3&mlsId=102|352&price=100000:&multi_search=Charlotte,%20NC&q_sort=createdAt-&q_offset=0">Center City</a></li><li class="sec-nav-drop-color"><a class="sec-nav-drop-link-color" href="/search?multi_search=28277&multi_cat=Zip&propertyType=Condo/Townhome|Multi-Family|Residential&status=1|3&mlsId=102|352&price=100000:&q_sort=createdAt-&q_offset=0">Ballantyne</a></li><li class="sec-nav-drop-color"><a class="sec-nav-drop-link-color" href="/search?multi_search=29715&multi_cat=Zip&propertyType=Condo/Townhome|Multi-Family|Residential&status=1|3&mlsId=102|352&price=100000:&q_sort=createdAt-&q_offset=0">Fort Mill</a></li><li class="sec-nav-drop-color">
247<a class="sec-nav-drop-link-color" href="/search?multi_search=Huntersville,%20NC&multi_cat=CityState&propertyType=Condo/Townhome|Multi-Family|Residential&status=1|3&mlsId=102|352&price=100000:&q_sort=createdAt-&q_offset=0">Huntersville</a></li><li class="sec-nav-drop-color"><a class="sec-nav-drop-link-color" href="/search?multi_search=Matthews,%20NC&multi_cat=CityState&propertyType=Condo/Townhome|Multi-Family|Residential&status=1|3&mlsId=102|352&price=100000:&q_sort=createdAt-&q_offset=0">Matthews</a></li></ul><li class="nav-item dropdown"><a class="dropdown-toggle sec-nav-link-color" data-toggle="dropdown" data-hover="dropdown" data-delay="0" data-close-others="false">Resources<i class="fa fa-angle-down"></i></a><ul class="dropdown-menu"><li class="sec-nav-drop-color"><a class="sec-nav-drop-link-color" href="/home_maintenance_tips">Home Maintenance Tips</a></li></ul><li class="nav-item"><a class="sec-nav-link-color" href="/careers">Careers</a></li><li class="nav-item"><a class="sec-nav-link-color" href="/realestateagent/search">Who We Are</a></li><li class="nav-item"><a class="sec-nav-link-color" href="/blog">Blog</a></li><li class="nav-item"><a class="sec-nav-link-color" href="/connect">Connect</a></li><li class="nav-item"><a class="sec-nav-link-color" href="/the-real-estate-momentum">The Real Estate Momentum</a></li><li class="nav-item"><a class="sec-nav-link-color" href="/homevalue">HomeValue</a></li><li class="nav-item"><a class="sec-nav-link-color" href="/referring-agents">Referring Agents</a></li><li class="nav-item"><a class="sec-nav-link-color" href="/relocating-to-charlotte">Relocating to Charlotte</a></li><li class="nav-item"><a class="sec-nav-link-color" href="/realtrends-verified">RealTrends Verified</a></li></ul></div> </div> </div> </header> <style> 248 249 .center-modal { 250 display:flex; 251 justify-content: center; 252 align-items:center; 253 position:fixed; 254 background-color:rgba(0,0,0,0.4); 255 left:0; 256 top:0; 257 right:0; 258 bottom:0; 259 z-index: 300; 260 } 261 262 .page-width-parent{ 263 max-width: 1280px; 264 margin: 0 auto; 265 } 266 267 268 .property-list-map-view { 269 display:flex; 270 flex-wrap:wrap; 271 gap:16px; 272 } 273 .property-list-map-view-parent { 274 background-color: #F9F9F9; 275 padding:16px; 276 height:710px; 277 overflow:scroll; 278 } 279 280 .property-list-list-view { 281 display:flex; 282 flex-wrap:wrap; 283 gap:24px 284 } 285 286 .property-container { 287 288 gap:24px; 289 } 290 291 .property-map-container { 292 flex:1; 293 height:710px; 294 } 295 296 .property-pagination { 297 margin-top: 26px; 298 } 299 300 .collection-saved-listings { 301 margin-bottom: 26px; 302 font-size:16px; 303 color:black; 304 } 305 306 .collection-description { 307 padding: 20px 0 18px 8px; 308 } 309 310 .my-feed-parent { 311 margin-top:32px; 312 padding-top:32px; 313 border-top: solid 1px #C4C4C4; 314 } 315 316 .collection-description-text { 317 font-size:16px; 318 margin:0; 319 color:black; 320 } 321 322 #collections { 323 display:flex; 324 flex-wrap:wrap; 325 gap:40px 24px; 326 } 327 328 #collection-pagination{ 329 margin-top: 55px 330 } 331 332 #add-listing-btn{ 333 margin-bottom: 20px 334 } 335 336 @media only screen and (min-width: 1280px) { 337 .collection-page { 338 padding:48px 48px 48px 120px; 339 } 340 .my-feed-parent { 341 width:90vw; 342 max-width: 100%; 343 overflow: hidden; 344 } 345 .property-list-map-view-parent { 346 width:500px; 347 } 348 .property-container { 349 display:flex; 350 } 351 } 352 353 @media only screen and (max-width:1280px) { 354 .collection-page { 355 padding:60px 16px 16px 16px; 356 } 357 .my-feed-parent { 358 width: unset; 359 } 360 .property-container { 361 display:flex; 362 flex-direction: column-reverse; 363 } 364 .property-list-map-view { 365 flex-wrap:nowrap; 366 overflow:scroll; 367 height:280px; 368 } 369 .property-list-map-view-parent { 370 height:unset; 371 padding:0px; 372 background-color: #FFFFFF 373 } 374 .property-map-container { 375 flex:none; 376 height:446px; 377 } 378 } 379 380 @media only screen and (max-width:768px) { 381 #collections { 382 justify-content: center; 383 } 384 .property-map-container { 385 width: calc(100% + 32px); 386 margin-left: -16px; 387 } 388 .property-list-map-view { 389 height:250px; 390 } 391 } 392 393</style>
393<script> 394 window.addEventListener("load", () => { 395 const key = localStorage.getItem('authorization'); 396 397 if( !key) { 398 $("#sign-up-modal").modal('show'); 399 400 $("#sign-up-modal").on("hidden.bs.modal", function () { 401 location.reload(); 402 }); 403 } 404 else{ 405 406 let myPortalPage = document.getElementById('myportal-page'); 407 myPortalPage.style.display = "block"; 408 409 window.location.hash = "" 410 411 function isGuid(value) { 412 var regex = /[a-f0-9]{8}(?:-[a-f0-9]{4}){3}-[a-f0-9]{12}/i; 413 var match = regex.exec(value); 414 return match != null; 415 } 416 417 let lastUrlItem = window.location.href.substring(window.location.href.lastIndexOf('/') + 1) 418 let showCollectionByUUID = false 419 420 if (isGuid(lastUrlItem)) { 421 showCollectionByUUID = true 422 } 423 424 425 class logger extends Collections.BaseLogger { 426 log(e) { 427 console.log(e); 428 } 429 } 430 431 432 class Pubsub { 433 static events = {}; 434 constructor() { 435 //this.events = {}; 436 } 437 438 static subscription (eventName, func) { 439 return { 440 subscribe: () => { 441 if (this.events[eventName]) { 442 this.events[eventName].push(func); 443 } else { 444 this.events[eventName] = [func]; 445 } 446 }, 447 unsubscribe: () => { 448 if(this.events[eventName]){ 449 this.events[eventName] = this.events[eventName].filter((subscriber) => subscriber !== func); 450 } 451 } 452 } 453 } 454 455 static publish(eventName, ...args) { 456 const funcs = this.events[eventName]; 457 if (Array.isArray(funcs)) { 458 funcs.forEach((func) => { 459 func.apply(null, args); 460 }); 461 } 462 } 463 } 464 465 class CollectionCard { 466 constructor(collection, count){ 467 468 this.element = document.createElement(`place-collectioncard`); 469 this.collection = collection 470 let _this = this; 471 let menuOpen = false; 472 var images = []; 473 474 for (let i = 0; i < collection?.propertiesImages?.length; i++) { 475 images.push(collection.propertiesImages[i].mainPhoto); 476 } 477 478 this.element.setAttribute("appearance", "regular"); 479 this.element.setAttribute("image", images); 480 this.element.setAttribute("num_properties", collection?.totalListings ?? 0) 481 this.element.setAttribute("title", collection.collectionName); 482 this.element.setAttribute("description", collection.collectionDescription ? collection.collectionDescription : collection.description ? collection.description : ""); 483 this.element.setAttribute("creator", ""); 484 this.element.setAttribute("disable_dropdown", "false"); 485 this.element.setAttribute("style", "height: 254px"); 486 this.element.setAttribute('z_index', count); 487 this.element.setAttribute("show_menu", "false"); 488 this.element.setAttribute("id", collection.collectionUUID); 489 this.element.setAttribute("container_styles", "w-[300px]"); 490 491 const collectionUUID = collection.collectionUUID; 492 493 this.element.addEventListener(`on_menu_item_pressed`, (e) => { 494 let menuItem = e.detail 495 Pubsub.publish('collection_card_menu_item_pressed', {collection,menuItem}); 496 }); 497 498 this.element.addEventListener('on_search_pressed', (e) => { 499 if (e.target.tagName != "svg" && e.target.tagName != "path") { 500 window.open('../../search.php', '_blank'); 501 e.stopPropagation(); 502 } 503 }); 504 505 this.element.addEventListener(`click`, (e) => { 506 if (e.target.tagName != "svg" && e.target.tagName != "path" && !menuOpen) { 507 Pubsub.publish('collection_card_pressed', {collection:_this.collection,e}); 508 e.stopPropagation(); 509 } 510 }); 511 512 this.element.addEventListener(`on_menu_open`, (e) => { 513 if (this.element.getAttribute("title") === "Favorites") { 514 this.element.setAttribute("disable_menu", "true"); 515 } 516 517 menuOpen = e.detail; 518 this.element.setAttribute("show_menu", menuOpen); 519 }); 520 } 521 } 522 523 class CollectionSection { 524 525 526 collectionSection = document.getElementById('collection-section') 527 collections = document.getElementById('collections') 528 529 addCollectionCard = (collection, count) => { 530 const collectionCard = new CollectionCard(collection, count); 531 532 533 534 535 this.collections.append(collectionCard.element); 536 537 } 538 539 show = () => { 540 this.collectionSection.style.display = 'block' 541 } 542 543 hide = () => { 544 this.collectionSection.style.display = 'none' 545 } 546 } 547 548 class PropertyCard { 549 constructor(collectionUUID,property){ 550 551 let _this = this; 552 this.element = document.createElement(`place-propertycard`); 553 let menuOpen = false;
554 this.property = property; 555 556 this.element.setAttribute("id", property.blossorId) 557 this.element.setAttribute("display_menu", "true"); 558 this.element.setAttribute("show_menu", "false"); 559 this.element.setAttribute("items", '[{"icon":"share-2","text":"Share Property"},{"icon":"layers","text":"Copy to Collection"},{"icon":"trash","text":"Remove from Collection"}]'); 560 561 this.element.setAttribute('appearance','small') 562 this.element.setAttribute('layout_width', '300') 563 this.element.setAttribute('display_tag', 'true') 564 this.element.setAttribute('display_favorite', 'true') 565 this.element.setAttribute('mls',`{ 566 "status":"${property.statusText}", 567 "favorite":"true", 568 "image":[{"uri":"${property?.photos[0]?.url}"}], 569 "price":"${property?.price}", 570 "address":"${property?.address?.street}", 571 "state":"${property?.address?.state}", 572 "city":"${property?.address?.city}", 573 "postalCode":"${property?.address?.zip}", 574 "beds":"${property?.bedrooms}", 575 "baths":"${property?.totalBaths}", 576 "sqft":"${property?.sqFeet}" 577 }`) 578 this.element.setAttribute('on_hover', 'true') 579 580 this.element.addEventListener('mouseenter', (e) => { 581 Pubsub.publish('property_card_mouseenter', property); 582 }) 583 584 this.element.addEventListener('mouseleave', (e) => { 585 Pubsub.publish('property_card_mouseleave', property); 586 }) 587 588 this.element.addEventListener(`on_menu_item_pressed`, (e) => { 589 let menuItem = e.detail 590 let propertyCollectionUUID = property.propertyCollectionUUID 591 let url = this.getPropertyUrl(this.property); 592 property.searchUrl = url; 593 Pubsub.publish('property_card_menu_item_pressed', {property,collectionUUID,propertyCollectionUUID,menuItem, url}); 594 }); 595 596 this.element.addEventListener(`on_menu_open`, (e) => { 597 menuOpen = e.detail; 598 this.element.setAttribute("show_menu", menuOpen); 599 }); 600 601 this.element.addEventListener('click', (e) => { 602 if (e.target.tagName != "svg" && e.target.tagName != "path" && !menuOpen) { 603 let state = _this.property.address.state; 604 let city = _this.slugify(_this.property.address.city); 605 let zip = _this.property.address.zip 606 let address = _this.slugify(_this.property.address.street); 607 let blossorId = _this.property.blossorId; 608 let url = this.getPropertyUrl(property); 609 window.open(`../../${url}`, '_blank'); 610 } 611 }); 612 613 this.element.addEventListener('on_favorite_press', (e) => { 614 let propertyCollectionUUID = property.propertyCollectionUUID; 615 Pubsub.publish('delete_property_modal_pressed', {collectionUUID, propertyCollectionUUID}); 616 }); 617 618 } 619 620 getPropertyUrl = (property) => { 621 let state = property.address.state; 622 let city = this.slugify(property.address.city); 623 let zip = property.address.zip 624 let address = this.slugify(property.address.street); 625 let blossorId = property.blossorId; 626 return `homes-for-sale/${state}/${city}/${zip}/${address}/bid-${blossorId}`; 627 } 628 629 slugify(text) { 630 // replace non letter or digits by - 631 text = text.replace(/[^\pL\d]+~u/g, '_'); 632 // transliterate 633 text = text.normalize('NFKD').replace(/[\u0300-\u036F]/g,'') 634 // remove unwanted characters 635 text = text.replace(/[^_\w]+/g, '_'); 636 // trim 637 text = text.trim(); 638 // remove duplicate - 639 text = text.replace(/_+/g, '-'); 640 // lowercase 641 text = text.toLowerCase(); 642 if (!text) { 643 return 'n-a'; 644 } 645 return text 646 } 647 } 648 649 let dateNow = new Date(); 650 dateNow.setDate(dateNow.getDate()-7); 651 dateNow.setHours(dateNow.getHours()); 652 dateNow.setMinutes(dateNow.getMinutes()); 653 dateNow.setSeconds(dateNow.getSeconds()); 654 const sevenDaysAgo = dateNow.getTime(); 655 656 class PropertySection { 657 propertySection = document.getElementById('property-section') 658 listIcon = document.getElementById('property-list-icon') 659 mapIcon = document.getElementById('property-map-icon') 660 propertyHeader = document.getElementById('property-header') 661 propertyList = document.getElementById("property-list") 662 propertyListParent = document.getElementById("property-list-parent") 663 propertyMap = document.getElementById('property-map') 664 selectedView = 'map' 665 666 collectionProperties = [] 667 668 properties = [] 669 670 671 constructor() { 672 this.listIcon.addEventListener('click', () => { 673 this.setView('list') 674 }) 675 676 this.mapIcon.addEventListener('click', () => { 677 this.setView('map') 678 }) 679 } 680 681 show = (collectionUUID, collectionProperties) => { 682 this.propertySection.style.display = 'block' 683 this.collectionProperties = collectionProperties 684 this.collectionUUID = collectionUUID 685 686 this.propertyList.innerHTML = '' 687 count = 100; 688 689 this.collectionProperties?.data?.properties?.forEach((property) => { 690 count-- 691 this.addPropertyCard(property,collectionUUID, count) 692 }); 693 } 694 695 hide = () => { 696 this.propertySection.style.display = 'none' 697 } 698 699 setPropertyCardWidth = () => { 700 let width; 701 let imageHeight; 702 let windowWidth = window.innerWidth 703 if(this.selectedView == 'map') { 704 if(windowWidth > 1279) { 705 width = `220`; 706 imageHeight = `154`; 707 } else if(windowWidth > 768) { 708 width = `325`; 709 imageHeight = `184`; 710 } else{ 711 width = `244`; 712 imageHeight = `154`; 713 } 714 } 715 else { 716 if(windowWidth > 1440 ){ 717 width = `300`; 718 imageHeight = `184`; 719 } 720 else if(windowWidth > 1279) { 721 width = `260`; 722 imageHeight = `152`; 723 } else if(windowWidth > 768) { 724 width = `218`; 725 imageHeight = `152`; 726 } else{ 727 width = `288`; 728 imageHeight = `184`; 729 } 730 } 731 732 let propertyCards = document.querySelectorAll('place-propertycard') 733 propertyCards.forEach((propertyCard) => { 734 propertyCard.setAttribute('layout_width', width) 735 propertyCard.setAttribute('image_height', imageHeight) 736 }) 737 } 738
739 setView = (view) => { 740 this.selectedView = view 741 if (view == 'list') { 742 this.listIcon.setAttribute('stroke', 'black') 743 this.mapIcon.setAttribute('stroke', 'gray') 744 745 this.propertyMap.style.display = 'none' 746 this.propertyList.classList.add('property-list-list-view') 747 this.propertyList.classList.remove('property-list-map-view') 748 this.propertyListParent.classList.remove('property-list-map-view-parent') 749 750 Pubsub.publish('property_section_show_list_view', this.collectionProperties?.data?.properties); 751 } else { 752 this.listIcon.setAttribute('stroke', 'gray') 753 this.mapIcon.setAttribute('stroke', 'black') 754 755 this.propertyMap.style.display = 'block' 756 this.propertyList.classList.remove('property-list-list-view') 757 this.propertyList.classList.add('property-list-map-view') 758 this.propertyListParent.classList.add('property-list-map-view-parent') 759 760 Pubsub.publish('property_section_show_map_view', this.collectionProperties?.data?.properties); 761 } 762 763 this.setPropertyCardWidth(); 764 } 765 766 scrollIntoView = (id) => { 767 let propertyCard = document.getElementById(id); 768 propertyCard.scrollIntoView({ behavior: 'smooth', block: 'nearest', inline: 'start' }) 769 } 770 771 addPropertyCard = (property, collectionUUID, count) => { 772 773 var propertyCardWrapperElement = document.createElement(`div`) 774 propertyCardWrapperElement.setAttribute('style', `z-index:${count}`) 775 propertyCardWrapperElement.setAttribute('class', 'property-card-wrapper') 776 propertyCardWrapperElement.setAttribute("id", property.propertyCollectionUUID); 777 778 const propertyCard = new PropertyCard(collectionUUID,property); 779 var propertyCardElement = propertyCard.element; 780 781 propertyCardWrapperElement.append(propertyCardElement) 782 783 this.propertyList.append(propertyCardWrapperElement) 784 785 } 786 787 } 788 789 790 class PageSubHeader{ 791 constructor() { 792 793 this.element = document.querySelector('place-pagesubheader') 794 795 this.element.addEventListener('button_on_press', (e) => { 796 Pubsub.publish('create_new_collection_pressed', e) 797 }) 798 799 this.element.addEventListener('top_header_on_press', (e) => { 800 Pubsub.publish('top_header_back_pressed', e) 801 }) 802 803 this.element.addEventListener('on_menu_item_pressed', (e) => { 804 Pubsub.publish('top_header_menu_item_pressed', e.detail) 805 }) 806 807 this.element.addEventListener('secondary_button_on_press', (e) => { 808 window.open('../../search.php', '_blank') 809 }) 810 } 811 812 setTitle(title) { 813 this.element.setAttribute('title', title) 814 } 815 816 setTopHeaderTitle(title){ 817 this.element.setAttribute('top_header_title', title) 818 } 819 820 showTopHeader(){ 821 this.element.setAttribute('show_top_header', true) 822 } 823 824 hideTopHeader(){ 825 this.element.setAttribute('show_top_header', false) 826 } 827 828 showPrimaryButton() { 829 this.element.setAttribute('show_button', true) 830 } 831 832 hidePrimaryButton() { 833 this.element.setAttribute('show_button', false) 834 } 835 836 showSecondaryButton(){ 837 this.element.setAttribute('show_secondary_button', true) 838 } 839 840 hideSecondaryButton(){ 841 this.element.setAttribute('show_secondary_button', false) 842 } 843 844 showMenuButton() { 845 this.element.setAttribute('show_menu_button', true) 846 } 847 848 hideMenuButton() { 849 this.element.setAttribute('show_menu_button', false) 850 } 851 } 852 853 class CollectionModal { 854 855 constructor() { 856 857 let _this = this; 858 this.element = document.querySelector('place-collectionpopup'); 859 this.collectionUUID = 0; 860 861 this.element.addEventListener("on_close_press", (e) => { 862 _this.hide(); 863 }); 864 865 this.element.addEventListener("on_save_press", (e) => { 866 this.showError(false); 867 e.detail.collectionUUID = this.collectionUUID 868 e.detail.type = this.isEditingCollection ? 'edit' : 'save' 869 Pubsub.publish('on_new_collection_saved', e.detail); 870 }); 871 872 } 873 874 setName(name) { 875 this.element.setAttribute('name_value', name) 876 } 877 878 setDescription(description) { 879 this.element.setAttribute('description_value', description ? description : "") 880 } 881 882 showError(error) { 883 this.element.setAttribute('show_error', error) 884 } 885 886 show(collectionUUID, isEditingCollection) { 887 this.isEditingCollection = isEditingCollection; 888 if(collectionUUID){ 889 this.collectionUUID = collectionUUID; 890 } 891 this.element.setAttribute('style', 'display:flex') 892 } 893 894 hide() { 895 this.element.setAttribute('style', 'display:none'); 896 897 this.showError(false) 898 899 // terrible hack.. only way i could get it to respond to prop changes 900 // to clear the input fields after closing the modal 901 this.setName('none') 902 this.setDescription('none') 903 setTimeout(() => { 904 this.setName('') 905 this.setDescription('') 906 }, 100); 907 } 908 } 909 910 class CollectionCreatedModal { 911 constructor() { 912 913 914 this.collection = "" 915 this.element = document.getElementById('collection-created-modal'); 916 let _this = this; 917 918 this.element.addEventListener("on_primary_press", (e) => { 919 this.hide(); 920 window.location.href = '../../search.php' 921 }); 922 923 this.element.addEventListener("on_tertiary_press", (e) => { 924 _this.hide(); 925 Pubsub.publish('collection_created_modal_view_collection_pressed', _this.collection); 926 }); 927 928 this.element.addEventListener("on_close_press", (e) => { 929 _this.hide(); 930 }); 931 932 this.element.setAttribute("stacked_buttons", true) 933 this.element.setAttribute("primary_button_text", "Search Listings") 934 this.element.setAttribute("tertiary_button_text", "View Collection") 935 } 936 937 show(collection) { 938 if(collection){ 939 this.collection = collection; 940 } 941 this.element.setAttribute('style', 'display:flex') 942 } 943 944 hide() { 945 this.element.setAttribute('style', 'display:none'); 946 } 947 } 948 949 class EditCollectionModal { 950 constructor() { 951 952 953 this.collection = "" 954 this.element = document.getElementById('edit-collection-modal'); 955 let _this = this; 956 957 this.element.addEventListener("on_primary_press", (e) => { 958 _this.hide(); 959 960 }); 961 962 963 964 this.element.addEventListener("on_close_press", (e) => { 965 _this.hide(); 966 }); 967 } 968 969 show() { 970 971 this.element.setAttribute('style', 'display:flex') 972 } 973 974 hide() { 975 this.element.setAttribute('style', 'display:none'); 976 } 977 } 978 979 class DeleteCollectionModal { 980 constructor() { 981 982 983 this.collection = "" 984 this.element = document.getElementById('delete-collection-modal'); 985 let _this = this; 986 987 this.element.addEventListener("on_primary_press", (e) => { 988 _this.hide(); 989 Pubsub.publish('delete_collection_modal_delete_pressed', _this.collection); 990 }); 991 992 this.element.addEventListener("on_tertiary_press", (e) => { 993 this.hide(); 994 }); 995 996 this.element.addEventListener("on_close_press", (e) => { 997 _this.hide(); 998 }); 999 } 1000 1001 show(collection) { 1002 if(collection){ 1003 this.collection = collection; 1004 } 1005 this.element.setAttribute('style', 'display:flex') 1006 } 1007 1008 hide() { 1009 this.element.setAttribute('style', 'display:none'); 1010 } 1011 } 1012 1013 class ShareSavedPropertyModal { 1014 constructor() { 1015 let _this = this; 1016 this.savedProperty = {} 1017 this.element = document.getElementById('share-saved-property-modal'); 1018 1019 this.element.addEventListener("on_primary_press", (e) => { 1020 1021 1022 1023 navigator.clipboard.writeText(this.link) 1024 _this.hide(); 1025 Pubsub.publish('share_saved_property_modal_share_pressed'); 1026 1027 }); 1028 1029 this.element.addEventListener("on_close_press", (e) => { 1030 _this.hide(); 1031 }); 1032 } 1033 1034 show = (savedProperty) => { 1035 1036 1037 this.savedProperty = savedProperty; 1038 1039 this.link = document.location.origin + "/" + this.savedProperty.searchUrl 1040 this.element.setAttribute('share_link_text', this.link) 1041 this.element.setAttribute('style', 'display:flex') 1042 } 1043 1044 hide = () => { 1045 this.element.setAttribute('style', 'display:none'); 1046 } 1047 } 1048 1049 class DeletePropertyModal { 1050 constructor() { 1051 1052 1053 this.collectionUUID = "" 1054 this.propertyCollectionUUID = "" 1055 this.element = document.getElementById('delete-property-modal'); 1056 let _this = this; 1057 1058 this.element.addEventListener("on_primary_press", (e) => { 1059 _this.hide(); 1060 Pubsub.publish('delete_property_modal_delete_pressed', {"collectionUUID":_this.collectionUUID, "propertyCollectionUUID":_this.propertyCollectionUUID}); 1061 }); 1062 1063 this.element.addEventListener("on_tertiary_press", (e) => { 1064 this.hide(); 1065 }); 1066 1067 this.element.addEventListener("on_close_press", (e) => { 1068 _this.hide(); 1069 }); 1070 } 1071 1072 show(collectionUUID, propertyCollectionUUID) { 1073 if(collectionUUID){ 1074 this.collectionUUID = collectionUUID; 1075 } 1076 if(propertyCollectionUUID){ 1077 this.propertyCollectionUUID = propertyCollectionUUID; 1078 } 1079 this.element.setAttribute('style', 'display:flex') 1080 } 1081 1082 hide() { 1083 this.element.setAttribute('style', 'display:none'); 1084 } 1085 } 1086 1087 class CopyPropertyToCollectionModal { 1088 constructor(){ 1089 1090 this.element = document.querySelector('place-copycollectionmodal'); 1091 this.collections = []; 1092 this.property = {} 1093 this.isVisible = false;
1094 1095 1096 1097 this.element.addEventListener('close_button', (e) => { 1098 this.hide(); 1099 }); 1100 1101 this.element.addEventListener('cancel_button', (e) => { 1102 this.hide(); 1103 }); 1104 1105 this.element.addEventListener('on_save', (e) => { 1106 Pubsub.publish('copy_property_to_collection_modal_save_pressed', {'collectionUUID':e.detail, 'property':this.property}); 1107 }); 1108 1109 this.element.addEventListener('set_selected_collection', (e) => { 1110 console.log('set_selected_collection', e) 1111 }); 1112 1113 this.element.addEventListener('on_link_press', (e) => { 1114 Pubsub.publish('show_new_collection_modal'); 1115 }); 1116 1117 } 1118 1119 getCollectionData(){ 1120 return JSON.parse(this.element.getAttribute("collections")); 1121 } 1122 1123 setCollectionData(collections){ 1124 this.element.setAttribute('collections', JSON.stringify(collections)) 1125 } 1126 1127 getCollectionList(collections, currentCollectionName) { 1128 let collectionList = []; 1129 collections.forEach(collection => { 1130 if (currentCollectionName && (collection.collectionName == currentCollectionName)) return; 1131 collectionList.push({ 1132 collection_title: collection.collectionName, 1133 id: collection.collectionUUID, 1134 propertiesImages: collection?.propertiesImages?.length > 0 ? collection?.propertiesImages : [], 1135 }) 1136 }); 1137 this.setCollectionData(collectionList); 1138 1139 } 1140 1141 setIsAddingToCollection(isAddingToCollection){ 1142 this.element.setAttribute('is_add_to_collection', isAddingToCollection); 1143 } 1144 1145 show(property) { 1146 1147 if(property){ 1148 this.property = property; 1149 } 1150 1151 this.isVisible = true; 1152 1153 let mls = { 1154 status: property?.status || property?.standardStatus || "", 1155 image: this.getPropertyImageUrl(property), 1156 price: property?.price || "0", 1157 address: ( typeof property?.address === "string") ? property?.address : (property?.address?.street || property?.streetAddress || ""), 1158 state: property?.state || property?.address?.state || "", 1159 city: property?.city || property?.address?.city || "", 1160 postal_code: property?.postal_code || property?.address?.zip || "", 1161 beds: property?.beds || property?.bedrooms || 0, 1162 baths: property?.baths || property?.fullBaths || property?.bathsTotalDecimal || 0, 1163 sqft: property?.sqft || property?.squareFeet || property?.sqFeet || 0, 1164 creator: property?.creator || "", 1165 } 1166 1167 this.element.setAttribute('mls', JSON.stringify(mls)) 1168 this.element.setAttribute('image_url',mls?.image || "") 1169 this.element.setAttribute('style', 'display:flex') 1170 } 1171 1172 getPropertyImageUrl(property){ 1173 // property?.image[0]?.uri || property?.photos[0]?.url || "", 1174 1175 if(property.image && property.image.length > 0){ 1176 return property.image[0].uri 1177 } else if (property.photos && property.photos.length > 0){ 1178 return property.photos[0].url 1179 } else { 1180 return "" 1181 } 1182 } 1183 1184 hide() { 1185 this.isVisible = false;
1186 this.element.setAttribute('style', 'display:none'); 1187 } 1188 } 1189 1190 class CollectionPaging { 1191 constructor(collectionsPerPage){ 1192 1193 1194 this.element = document.getElementById('collection-pagination'); 1195 this.collectionsPerPage = collectionsPerPage; 1196 1197 this.element.addEventListener('page_changed', (e) => { 1198 Pubsub.publish('collection_page_changed', e.detail); 1199 }); 1200 } 1201 1202 setPageCount(pageCount){ 1203 this.element.setAttribute('page_count', pageCount); 1204 } 1205 1206 show() { 1207 this.element.setAttribute('style', 'display:flex') 1208 } 1209 1210 hide() { 1211 this.element.setAttribute('style', 'display:none') 1212 } 1213 } 1214 1215 class PropertyPaging { 1216 constructor(propertiesPerPage){ 1217 1218 1219 this.element = document.getElementById('property-pagination'); 1220 this.propertiesPerPage = propertiesPerPage; 1221 1222 this.element.addEventListener('page_changed', (e) => { 1223 Pubsub.publish('property_page_changed', e.detail); 1224 }); 1225 } 1226 1227 setPageCount(pageCount){ 1228 this.element.setAttribute('page_count', pageCount); 1229 } 1230 1231 setCurrentPage(currentPage){ 1232 this.element.setAttribute('current_page', currentPage); 1233 } 1234 1235 show() { 1236 this.element.setAttribute('style', 'display:flex') 1237 } 1238 1239 hide() { 1240 this.element.setAttribute('style', 'display:none') 1241 } 1242 } 1243 1244 class NewCollectionBlock { 1245 constructor(){ 1246 1247 this.element = document.getElementById('new-collection-block'); 1248 1249 this.element.addEventListener('on_main_press', (e) => { 1250 Pubsub.publish('new_collection_block_create_collection_pressed', e.detail); 1251 }); 1252 } 1253 show(collectionUUID, propertyCollectionUUID) { 1254 this.element.setAttribute('style', 'display:flex') 1255 } 1256 1257 hide() { 1258 this.element.setAttribute('style', 'display:none'); 1259 } 1260 } 1261 1262 class AddListingsBlock { 1263 constructor() { 1264 1265 this.element = document.getElementById('add-listings-block'); 1266 1267 this.element.addEventListener('on_main_press', (e) => { 1268 window.open('../../search.php', '_blank') 1269 }); 1270 1271 this.element.addEventListener("on_tertiary_press", (e) => { 1272 1273 }); 1274 } 1275 1276 show() { 1277 this.element.setAttribute('style', 'display:flex') 1278 } 1279 1280 hide() { 1281 this.element.setAttribute('style', 'display:none'); 1282 } 1283 } 1284 1285 class MyFeed { 1286 constructor(blueroofMiddlewareApi, collectionsService) { 1287 this.blueroofMiddlewareApi = blueroofMiddlewareApi; 1288 this.collectionsService = collectionsService; 1289 this.element = document.querySelector('place-myfeedblock'); 1290 1291 this.element.addEventListener('on_menu_open', (e) => { 1292 this.element.setAttribute('show_menu', e.detail.e); 1293 this.element.setAttribute('show_menu_index', e.detail.index); 1294 }); 1295 1296 this.element.addEventListener('on_view_all_pressed', (e) => { 1297 window.open('../../search.php', '_blank'); 1298 }); 1299 1300 this.element.addEventListener('on_add_collection', (e) => { 1301 1302 let property = e.detail; 1303 Pubsub.publish('my_feed_add_collection_pressed', {property}); 1304 1305 }); 1306 1307 this.element.addEventListener('on_share_pressed', (e) => { 1308 1309 let property = e.detail 1310 1311 let url = this.getPropertyUrl(property); 1312 property.searchUrl = url; 1313 1314 Pubsub.publish('my_feed_share_pressed', {property}); 1315 }); 1316 1317 this.element.addEventListener('on_favorite_pressed', (e) => { 1318 let property = e.detail.property; 1319 let isAddingFavorite = e.detail.isAddingFavorite; 1320 1321 if(isAddingFavorite){ 1322 Pubsub.publish('my_feed_on_favorite_pressed', {property}); 1323 } 1324 else{ 1325 Pubsub.publish('my_feed_on_unfavorite_pressed', {property}); 1326 } 1327 }); 1328 1329 this.element.addEventListener('on_property_pressed', (e) => { 1330 let property = e.detail 1331 1332 let url = this.getPropertyUrl(property); 1333 property.searchUrl = url; 1334 window.open('../../' + url, '_blank'); 1335 }); 1336 1337 1338 this.blueroofMiddlewareApi.getMyFeed().then((data) => { 1339 1340 let myFeedBlossorIds = data.map(property => property.blossorId); 1341 1342 1343 this.collectionsService.checkIfInCollection(myFeedBlossorIds).then((propertiesInCollections) => { 1344 1345 let feed = [] 1346 data.forEach((item) => { 1347 feed.push({ 1348 image: [ 1349 { 1350 title: "", 1351 id: 0, 1352 uri: item?.photos[0].url, 1353 }, 1354 ], 1355 price: item?.price, 1356 favorite: propertiesInCollections?.data[item?.blossorId] != null || false, 1357 address: item?.streetAddress, 1358 city: item?.city, 1359 state: item?.state, 1360 postal_code: item?.postalCode, 1361 beds: item?.bedrooms, 1362 status: item?.standardStatus, 1363 baths: item?.bathsTotalDecimal, 1364 sqft: item?.squareFeet, 1365 creator: "", 1366 mls_price_history: item?.history[item.history.length-1]?.price, 1367 blossorId: item?.blossorId, 1368 open_house : item?.openhouses?.length > 0 ? true : false, 1369 open_house_date : item?.openhouses[0]?.startDate, 1370 open_house_end_time : item?.openhouses[0]?.endDate, 1371 property_created_at : item?.listDate, 1372 lastStatusChangeDate : item?.lastStatusChangeDate, 1373 }) 1374 }) 1375 1376 if(feed && feed?.length > 0){ 1377 this.show(); 1378 this.element.setAttribute('mls_data', JSON.stringify(feed)); 1379 } 1380 }); 1381 }); 1382 1383 } 1384 1385 getPropertyUrl = (property) => { 1386 let state = property.state; 1387 let city = this.slugify(property.city); 1388 let zip = property.postal_code 1389 let address = this.slugify(property.address); 1390 let blossorId = property.blossorId; 1391 return `homes-for-sale/${state}/${city}/${zip}/${address}/bid-${blossorId}`; 1392 } 1393 1394 slugify(text) { 1395 // replace non letter or digits by - 1396 text = text.replace(/[^\pL\d]+~u/g, '_'); 1397 // transliterate 1398 text = text.normalize('NFKD').replace(/[\u0300-\u036F]/g,'') 1399 // remove unwanted characters 1400 text = text.replace(/[^_\w]+/g, '_'); 1401 // trim 1402 text = text.trim(); 1403 // remove duplicate - 1404 text = text.replace(/_+/g, '-'); 1405 // lowercase 1406 text = text.toLowerCase(); 1407 if (!text) { 1408 return 'n-a'; 1409 } 1410 return text 1411 } 1412 1413 getMlsData = () => { 1414 return JSON.parse(this.element.getAttribute('mls_data')); 1415 } 1416 1417 setMlsData = (data) => { 1418 this.element.setAttribute('mls_data', JSON.stringify(data)); 1419 } 1420 1421 show() { 1422 this.element.setAttribute('style', 'display:flex') 1423 } 1424 1425 hide() { 1426 this.element.setAttribute('style', 'display:none') 1427 } 1428 } 1429 1430 class BlueroofMiddlewareApi { 1431 constructor() { 1432 this.baseUrl = "https://brivity-home-middleware.production.brivity.com"; 1433 this.apiKey = localStorage.getItem('authorization'); 1434 } 1435 1436 getMyFeed = async () => { 1437 const response = await fetch(`${this.baseUrl}/listings/voltron`, { 1438 method: 'POST', 1439 headers: { 1440 'Content-Type': 'application/json', 1441 'Authorization': `${this.apiKey}` 1442 }, 1443 body: JSON.stringify([]) 1444 }); 1445 1446 const data = await response.json(); 1447 return data; 1448 } 1449 1450 getLeadBasicInfo = async () => { 1451 const response = await fetch(`${this.baseUrl}/blueroofleads/basicinfo`, { 1452 method: 'GET', 1453 headers: { 1454 'Content-Type': 'application/json', 1455 'Authorization': `${this.apiKey}` 1456 }, 1457 1458 }); 1459 1460 const data = await response.json(); 1461 return data; 1462 } 1463 1464 getAgentProfile = async (brivityUserId) => { 1465 const response = await fetch(`${this.baseUrl}/blueroofagents/profile`, { 1466 method: 'POST', 1467 headers: { 1468 'Content-Type': 'application/json', 1469 'Authorization': `${this.apiKey}` 1470 }, 1471 body: `{"brivityUserId": ${brivityUserId}}` 1472 1473 }); 1474 1475 const data = await response.json(); 1476 return data; 1477 } 1478 1479 } 1480 1481 class Map { 1482 constructor(){ 1483 this.element = document.querySelector('place-map'); 1484 this.properties = []; 1485 1486 this.element.addEventListener('on_marker_clicked', (e) => { 1487 Pubsub.publish('map_marker_clicked', e.detail.id) 1488 }); 1489 } 1490 1491 setMarkers = (properties) => { 1492 let markers = []; 1493 let color = 'black' 1494 1495 let dateNow = new Date(); 1496 dateNow.setDate(dateNow.getDate()-7); 1497 dateNow.setHours(dateNow.getHours()); 1498 dateNow.setMinutes(dateNow.getMinutes()); 1499 dateNow.setSeconds(dateNow.getSeconds()); 1500 const sevenDaysAgo = dateNow.getTime(); 1501 1502 this.properties = properties; 1503 properties?.forEach(property => { 1504 1505 if(property.statusText == 'Active'){ 1506 color = '#1FA6E8' 1507 }else if(property.statusText == 'Pending'){ 1508 color = '#FFC82C' 1509 }else if(property.statusText == 'Sold'){ 1510 color = '#FF7343' 1511 } 1512 1513 let listDate = new Date(property.listDate); 1514 1515 1516 if(listDate.getTime() > sevenDaysAgo){ 1517 color = '#24D0BC' 1518 } 1519 1520 markers.push({ 1521 id: `${property.blossorId}`, 1522 location: property.location, 1523 price: property.price, 1524 color : color 1525 }) 1526 }); 1527 1528 this.element.setAttribute('markers', JSON.stringify(markers)); 1529 } 1530 1531 setSelectedMarker = (property) => { 1532 let markerIndex = this.properties.findIndex((p) => p.blossorId == property.blossorId) 1533 if(markerIndex > -1){ 1534 this.element.setAttribute('selected_property_index', markerIndex); 1535 } 1536 } 1537 1538 clearSelectedMarker = () => { 1539 this.element.setAttribute('selected_property_index', -1); 1540 } 1541 1542 } 1543 1544 class SavedListings { 1545 constructor(){ 1546 this.element = document.getElementById('collection-saved-listings'); 1547 } 1548 1549 setCount(count) { 1550 this.element.innerText = `Saved Listings (${count})`; 1551 } 1552 1553 hide() { 1554 this.element.style.display = `none`; 1555 } 1556 show() { 1557 this.element.style.display = `block`; 1558 } 1559 } 1560 1561 class AddListingBtn { 1562 constructor(){ 1563 this.element = document.getElementById('add-listing-btn'); 1564 this.element.setAttribute('button_style', JSON.stringify({paddingLeft: '0px'})); 1565 this.element.addEventListener('on_press', (e) => { 1566 window.open('../../search.php', '_blank') 1567 }) 1568 } 1569 1570 hide() { 1571 this.element.style.display = `none`; 1572 } 1573 show() { 1574 this.element.style.display = `block`; 1575 } 1576 } 1577 1578 class Page { 1579 constructor(blueroofMiddlewareApi) { 1580 this.selectedCollection = {}; 1581 this.inPropertyView = false;
1582 this.lead = {} 1583 this.agent = {} 1584 this.isInMapView = false; 1585 this.isInListView = true; 1586 1587 this.authorizationData = JSON.parse(atob(blueroofMiddlewareApi.apiKey.split('.')[1])); 1588 this.is_blueroof_person = this.authorizationData?.is_blueroof_person; 1589 1590 1591 } 1592 1593 setSelectedCollection(collection) { 1594 this.selectedCollection = collection; 1595 } 1596 1597 setInPropertyView(inPropertyView) { 1598 this.inPropertyView = inPropertyView; 1599 } 1600 } 1601 1602 1603 class messagingEmitter extends Messaging.BaseEmitter { 1604 1605 newMessage(message) { 1606 Pubsub.publish('messaging_emitter_new_message', message); 1607 } 1608 } 1609 1610 1611 1612 (async () => { 1613 1614 const blueroofMiddlewareApi = new BlueroofMiddlewareApi(); 1615 const page = new Page(blueroofMiddlewareApi); 1616 1617 let url = 'https://messaging.brivity.com' 1618 const messaging = new Messaging.Service(url, blueroofMiddlewareApi.apiKey, new messagingEmitter()); 1619 1620 let lead = await blueroofMiddlewareApi.getLeadBasicInfo(); 1621 let agent = await blueroofMiddlewareApi.getAgentProfile(lead.data?.brivity_agent_id); 1622 1623 page.lead = lead.data; 1624 page.agent = agent.data; 1625 1626 const collectionsService = new Collections.Service(window?.globalSiteVariables?.options?.apis?.collections?.url ?? '',blueroofMiddlewareApi.apiKey, "sitebuilder", new logger()); 1627 1628 1629 const menu = new Menu(page?.is_blueroof_person || false, page?.agent, blueroofMiddlewareApi.baseUrl, blueroofMiddlewareApi.apiKey); 1630 const collectionSection = new CollectionSection() 1631 const propertySection = new PropertySection() 1632 const collectionModal = new CollectionModal(); 1633 const collectionCreatedModal = new CollectionCreatedModal(); 1634 const deleteCollectionModal = new DeleteCollectionModal();
1635 const editCollectionModal = new EditCollectionModal(); 1636 const shareSavedPropertyModal = new ShareSavedPropertyModal(); 1637 const deletePropertyModal = new DeletePropertyModal(); 1638 const copyPropertyToCollectionModal = new CopyPropertyToCollectionModal(); 1639 const pageSubHeader = new PageSubHeader(); 1640 const collectionPaging = new CollectionPaging(8) 1641 const propertyPaging = new PropertyPaging(8) 1642 const newCollectionBlock = new NewCollectionBlock(); 1643 const addListingsBlock = new AddListingsBlock(); 1644 const myFeed = new MyFeed(blueroofMiddlewareApi, collectionsService); 1645 const map = new Map(); 1646 const savedListings = new SavedListings(); 1647 const addListingBtn = new AddListingBtn(); 1648 1649 collectionPaging.hide(); 1650 propertySection.hide(); 1651 1652 let collections = []; 1653 let extraCollections = 0; 1654 let createCopyCollection = false; 1655 1656 if(!showCollectionByUUID){ 1657 const collectionDescription = document.getElementById("collectionDescription"); 1658 1659 collectionsService.getCollections(0, collectionPaging.collectionsPerPage).then((e) => { 1660 1661 extraCollections = e?.data?.totalCollections 1662 1663 if(e.data.TotalPages > 1) { 1664 collectionPaging.show() 1665 collectionPaging.setPageCount(e.data.TotalPages); 1666 } else { 1667 collectionPaging.setPageCount(1); 1668 } 1669 1670 1671 if(e?.data?.Items){ 1672 collections = e.data.Items; 1673 count = 100; 1674 e.data.Items.forEach((collection) => { 1675 count-- 1676 1677 collectionSection.addCollectionCard(collection, count) 1678 }); 1679 } 1680 1681 copyPropertyToCollectionModal.getCollectionList(collections) 1682 1683 if(collections.length == 0){ 1684 newCollectionBlock.show(); 1685 } 1686 1687 }).catch((e) => { 1688 if(collections.length == 0){ 1689 newCollectionBlock.show(); 1690 } 1691 }); 1692 } 1693 else{ 1694 collectionsService.getCollections(0, collectionPaging.collectionsPerPage).then((e) => { 1695 1696 if(e?.data?.Items){ 1697 collections = e.data.Items; 1698 } 1699 1700 }); 1701 } 1702 1703 Pubsub.subscription('property_card_mouseenter', (property) => { 1704 1705 document.querySelectorAll('place-propertycard').forEach((propertyCard) => { 1706 propertyCard.setAttribute('show_border', false); 1707 }) 1708 1709 if(page.isInMapView){ 1710 map.setSelectedMarker(property) 1711 } 1712 }).subscribe(); 1713 1714 Pubsub.subscription('property_card_mouseleave', () => { 1715 if(page.isInMapView){ 1716 map.clearSelectedMarker() 1717 } 1718 }).subscribe(); 1719 1720 Pubsub.subscription('messaging_emitter_new_message', (message) => { 1721 toast.show('New message from ' + message.createdByAlias) 1722 }).subscribe(); 1723 1724 Pubsub.subscription('property_section_show_map_view', (properties) => { 1725 map.setMarkers(properties); 1726 page.isInMapView = true; 1727 page.isInListView = false; 1728 1729 document.querySelectorAll('place-propertycard').forEach((propertyCard) => { 1730 propertyCard.setAttribute('show_border_on_hover', true); 1731 }) 1732 }).subscribe(); 1733 1734 Pubsub.subscription('property_section_show_list_view', (properties) => { 1735 page.isInMapView = false;
1736 page.isInListView = true; 1737 1738 document.querySelectorAll('place-propertycard').forEach((propertyCard) => { 1739 propertyCard.setAttribute('show_border_on_hover', false); 1740 }) 1741 1742 }).subscribe(); 1743 1744 Pubsub.subscription('property_page_changed', (page) => { 1745 collectionsService.getCollectionProperties(propertySection.collectionUUID, page, propertyPaging.propertiesPerPage).then((collectionProperties) => { 1746 map.setMarkers(collectionProperties?.data?.properties); 1747 savedListings.setCount(collectionProperties?.data?.totalListings || 0); 1748 propertySection.show(propertySection.collectionUUID,collectionProperties) 1749 propertySection.setPropertyCardWidth(); 1750 propertyPaging.setCurrentPage(page); 1751 }); 1752 }).subscribe(); 1753 1754 Pubsub.subscription("top_header_menu_item_pressed", (menuItemPressed) => { 1755 1756 if(menuItemPressed == 'Edit Collection'){ 1757 collectionModal.setName(page.selectedCollection.collectionName); 1758 collectionModal.setDescription(page.selectedCollection.collectionDescription); 1759 collectionModal.show(page.selectedCollection.collectionUUID, true); 1760 } 1761 else if(menuItemPressed == 'Delete Collection'){ 1762 deleteCollectionModal.show(page.selectedCollection); 1763 } 1764 }).subscribe(); 1765 1766 Pubsub.subscription('new_collection_block_create_collection_pressed', (e) => { 1767 collectionModal.show(0, false); 1768 }).subscribe(); 1769 1770 Pubsub.subscription('collection_card_pressed', (e) => { 1771 1772 window.location.hash = e.collection.collectionUUID; 1773 1774 page.setSelectedCollection(e.collection); 1775 1776 collectionsService.getCollectionProperties(e.collection.collectionUUID,1, propertyPaging.propertiesPerPage).then((collectionProperties) => { 1777 1778 1779 savedListings.setCount(collectionProperties?.data?.totalListings || 0); 1780 propertyPaging.setPageCount(collectionProperties.data.totalPages); 1781 1782 1783 if(collectionProperties?.data?.properties == null){ 1784 addListingsBlock.show(); 1785 } 1786 propertySection.show(e.collection.collectionUUID,collectionProperties) 1787 propertySection.setPropertyCardWidth(); 1788 1789 if(collectionProperties.data.totalPages > 1){ 1790 propertyPaging.show(); 1791 } 1792 1793 }); 1794 1795 1796 collectionSection.hide(); 1797 1798 let collectionList = []; 1799 1800 collections.forEach(collection => { 1801 if (collection.collectionName == e.collection.collectionName) return; 1802 1803 collectionList.push({ 1804 collection_title: collection.collectionName, 1805 id: collection.collectionUUID, 1806 propertiesImages: collection?.propertiesImages?.length > 0 ? collection?.propertiesImages : [], 1807 }) 1808 }); 1809 1810 copyPropertyToCollectionModal.getCollectionList(collections, e.collection.collectionName); 1811 1812 pageSubHeader.showTopHeader(); 1813 pageSubHeader.setTopHeaderTitle("Collections"); 1814 pageSubHeader.setTitle(e.collection.collectionName); 1815 pageSubHeader.hidePrimaryButton(); 1816 pageSubHeader.showMenuButton(); 1817 1818 if(window.innerWidth > 768 ){ 1819 pageSubHeader.showSecondaryButton(); 1820 } 1821 1822 page.setInPropertyView(true) 1823 1824 propertyPaging.setCurrentPage(1); 1825 propertySection.setView('list') 1826 1827 1828 const collectionDescription = document.getElementById('collection-description') 1829 collectionDescription.style.display="flex" 1830 collectionDescription.children[0].innerText = e?.collection.collectionDescription || "" 1831 }).subscribe(); 1832 1833 Pubsub.subscription('collection_card_menu_item_pressed', (e) => { 1834 if (e.menuItem == "Delete Collection") { 1835 1836 deleteCollectionModal.show(e.collection); 1837 1838 } else { 1839 1840 1841 collectionModal.setName(e.collection.collectionName); 1842 collectionModal.setDescription(e.collection.collectionDescription); 1843 collectionModal.show(e.collection.collectionUUID, true); 1844 } 1845 }).subscribe(); 1846 1847 Pubsub.subscription('property_card_menu_item_pressed', (e) => { 1848 if(e.menuItem == 'Remove from Collection') { 1849 deletePropertyModal.show(e.collectionUUID, e.propertyCollectionUUID); 1850 } 1851 else if(e.menuItem == 'Copy to Collection') { 1852 copyPropertyToCollectionModal.show(e.property); 1853 } 1854 else if(e.menuItem == 'Share Property') { 1855 1856 shareSavedPropertyModal.show(e.property); 1857 } 1858 }).subscribe(); 1859 1860 Pubsub.subscription('delete_property_modal_pressed', (e) => { 1861 deletePropertyModal.show(e.collectionUUID, e.propertyCollectionUUID); 1862 }).subscribe(); 1863 1864 Pubsub.subscription('show_new_collection_modal', (e) => { 1865 collectionModal.show(); 1866 copyPropertyToCollectionModal.hide(); 1867 createCopyCollection = true; 1868 }).subscribe(); 1869 1870 Pubsub.subscription('top_header_back_pressed', () => { 1871 window.location.hash = ''; 1872 pageSubHeader.hideTopHeader(); 1873 page.selectedCollection = {}; 1874 pageSubHeader.setTitle("COLLECTIONS"); 1875 pageSubHeader.showPrimaryButton(); 1876 pageSubHeader.hideSecondaryButton(); 1877 pageSubHeader.hideMenuButton(); 1878 1879 page.setInPropertyView(false) 1880 1881 collectionSection.show(); 1882 propertySection.hide() 1883 1884 propertyPaging.setCurrentPage(1); 1885 1886 copyPropertyToCollectionModal.getCollectionList(collections) 1887 1888 const collectionDescription = document.getElementById('collection-description') 1889 collectionDescription.style.display="none" 1890 collectionDescription.children[0].innerText = ""; 1891 addListingsBlock.hide(); 1892 }).subscribe() 1893 1894 Pubsub.subscription('create_new_collection_pressed', (e) => { 1895 collectionModal.show(0, false); 1896 }).subscribe(); 1897 1898 Pubsub.subscription('on_new_collection_saved', (e) => { 1899 if(e.type == 'save'){ 1900 1901 let people = [{ personUUID: page.lead.brivity_uuid, role: "lead" }]; 1902 let properties = [""]; 1903 collectionsService.createCollection(e.name, e.description, page.lead.brivity_uuid, people, properties).then((e) => { 1904 1905 collections.unshift(e.data); 1906 1907 extraCollections++ 1908 if(collections.length > 8) { 1909 collections.pop(); 1910 collectionPaging.show() 1911 collectionPaging.setPageCount(Math.ceil(extraCollections / 8)); 1912 } 1913 1914 count = 100; 1915 collectionSection.collections.innerHTML = ""; 1916 collections.forEach((collection) => { 1917 count-- 1918 collectionSection.addCollectionCard(collection, count) 1919 }); 1920 1921 let collectionsList = copyPropertyToCollectionModal.getCollectionData(); 1922 let newCollection = { 1923 collection_title: e.data.collectionName, 1924 id: e.data.collectionUUID, 1925 propertiesImages: [], 1926 } 1927 collectionsList.unshift(newCollection); 1928 copyPropertyToCollectionModal.setCollectionData(collectionsList); 1929 1930 if(!copyPropertyToCollectionModal.isVisible){ 1931 if (createCopyCollection) { 1932 copyPropertyToCollectionModal.isVisible = true; 1933 copyPropertyToCollectionModal.element.setAttribute('style', 'display:flex'); 1934 createCopyCollection = false;
1935 } else { 1936 collectionCreatedModal.show(e.data); 1937 } 1938 } 1939 1940 collectionModal.hide(); 1941 1942 newCollectionBlock.hide(); 1943 }).catch((e) => { 1944 collectionModal.showError(true) 1945 }); 1946 } 1947 else{ 1948 collectionsService.updateCollection(e.collectionUUID, e.name, e.description).then((collection) => { 1949 let element = document.getElementById(e.collectionUUID); 1950 element.setAttribute('title', e.name); 1951 element.setAttribute('description', e.description); 1952 if(Object.keys(page.selectedCollection).length !== 0){ 1953 pageSubHeader.setTitle(e.name); 1954 } 1955 const collectionDescription = document.getElementById('collection-description') 1956 collectionDescription.children[0].innerText = e.description; 1957 let updatedCollection = collections.findIndex((c) => c.collectionUUID == e.collectionUUID) 1958 if(updatedCollection != -1){ 1959 collections[updatedCollection].collectionName = e.name; 1960 collections[updatedCollection].collectionDescription = e.description; 1961 } 1962 collectionModal.hide(); 1963 editCollectionModal.show(); 1964 }); 1965 } 1966 }).subscribe(); 1967 1968 Pubsub.subscription('collection_created_modal_view_collection_pressed', (collection) => { 1969 Pubsub.publish('collection_card_pressed', {"collection": collection}) 1970 }).subscribe(); 1971 1972 Pubsub.subscription('delete_collection_modal_delete_pressed', (collection) => { 1973 collectionsService.deleteCollection(collection.collectionUUID).then((e) => { 1974 document.getElementById(collection.collectionUUID).remove(); 1975 toast.show('Collection was Deleted') 1976 1977 extraCollections-- 1978 1979 if(extraCollections.length < 9) { 1980 collectionPaging.hide() 1981 }else{ 1982 collectionPaging.setPageCount(Math.ceil(extraCollections / 8)); 1983 } 1984 1985 if(page.inPropertyView){ 1986 Pubsub.publish('top_header_back_pressed'); 1987 } 1988 }); 1989 }).subscribe(); 1990 1991 Pubsub.subscription('delete_property_modal_delete_pressed', (e) => { 1992 const currentPage = $("#property-pagination").find("#info-parent").filter( 1993 function() { 1994 return $(this).css("color") === "rgb(196, 196, 196)" 1995 } 1996 ).text(); 1997 1998 const propertiesPerPage = 8; 1999 const numOfProperties = $("#property-list .property-card-wrapper").length; 2000 const setPage = numOfProperties === 1 ? currentPage - 1 : currentPage; 2001 2002 collectionsService.removePropertyFromCollection(e.collectionUUID, e.propertyCollectionUUID) 2003 .then(() => { 2004 toast.show('Property removed from collection'); 2005 2006 return collectionsService.getCollectionProperties(e.collectionUUID, setPage, propertiesPerPage); 2007 }) 2008 .then((collectionProperties) => { 2009 const totalListingsCount = collectionProperties?.data?.totalListings; 2010 const properties = collectionProperties?.data?.properties; 2011 const totalPages = collectionProperties?.data?.totalPages; 2012 const currentCollection = $(`#${e.collectionUUID}`); 2013 2014 currentCollection.attr("num_properties", totalListingsCount); 2015 2016 map.setMarkers(properties); 2017 savedListings.setCount(totalListingsCount || 0); 2018 propertySection.show(propertySection.collectionUUID, collectionProperties); 2019 propertySection.setPropertyCardWidth(); 2020 2021 propertyPaging.setCurrentPage(setPage); 2022 propertyPaging.setPageCount(totalPages); 2023 2024 if (totalListingsCount <= 8) { 2025 propertyPaging.hide(); 2026 } 2027 }) 2028 .catch(error => { 2029 console.error("Error in collection operations:", error); 2030 }); 2031 }).subscribe(); 2032 2033 Pubsub.subscription('copy_property_to_collection_modal_save_pressed', (e) => { 2034 2035 let collectionUUID = e.collectionUUID; 2036 let blossorId = e.property.blossorId; 2037 collectionsService.addPropertyToCollection(collectionUUID, [blossorId]).then(() => { 2038 2039 2040 let data = copyPropertyToCollectionModal.getCollectionData(); 2041 let myFeedData = myFeed.getMlsData(); 2042 2043 collectionsService.getCollectionProperties(collectionUUID,1,1).then((e) => { 2044 2045 // update photos in add property to collection modal 2046 let collectionIndex = data.findIndex((x) => x.id == collectionUUID); 2047 let collection = data[collectionIndex]; 2048 let photo = e?.data?.properties[0]?.photos[0]?.url; 2049 2050 collection.propertiesImages = []; 2051 if(e?.data?.properties?.length > 0){ 2052 collection.propertiesImages.push({mainPhoto: photo}); 2053 } 2054 2055 data[collectionIndex] = collection; 2056 2057 copyPropertyToCollectionModal.setCollectionData(data); 2058 2059 2060 // update collection card if in collection view 2061 pageCollectionIndex = collections.findIndex((x) => x.collectionUUID == collectionUUID) 2062 2063 if(pageCollectionIndex > -1){ 2064 2065 let collectionCard = document.getElementById(collectionUUID); 2066 let numProperties = parseInt(collectionCard.getAttribute('num_properties')); 2067 numProperties++; 2068 collectionCard.setAttribute('num_properties', numProperties); 2069 2070 let images = collectionCard.getAttribute('image'); 2071 if(images){ 2072 images += "," + photo; 2073 } 2074 else{ 2075 images = photo; 2076 } 2077 2078 collectionCard.setAttribute('image', images); 2079 } 2080 2081 //update my feed to set property heart as favorited 2082 let myFeedPropertyIndex = myFeedData.findIndex((x) => x.blossorId == blossorId); 2083 if(myFeedPropertyIndex > -1){ 2084 myFeedData[myFeedPropertyIndex].favorite = true; 2085 myFeed.setMlsData(myFeedData); 2086 } 2087 2088 }) 2089 2090 copyPropertyToCollectionModal.hide(); 2091 toast.show('Property added to collection') 2092 2093 }).catch((e) => { 2094 toast.show('Error adding property to collection', true) 2095 }); 2096 }).subscribe(); 2097 2098 Pubsub.subscription('collection_page_changed', (e) => { 2099 collectionsService.getCollections(e, collectionPaging.collectionsPerPage).then((e) => { 2100 if(e?.data?.Items){ 2101 collections = e.data.Items; 2102 2103 collectionSection.collections.innerHTML = ""; 2104 count = 100;
2105 e.data.Items.forEach((collection) => { 2106 count-- 2107 2108 collectionSection.addCollectionCard(collection, count) 2109 }); 2110 } 2111 }); 2112 }).subscribe(); 2113 2114 Pubsub.subscription('share_saved_property_modal_share_pressed', (e) => { 2115 toast.show('Link Copied!') 2116 }).subscribe(); 2117 2118 Pubsub.subscription('my_feed_share_pressed', (e) => { 2119 shareSavedPropertyModal.show(e.property); 2120 }).subscribe(); 2121 2122 Pubsub.subscription('my_feed_add_collection_pressed', (e) => { 2123 copyPropertyToCollectionModal.setIsAddingToCollection(true); 2124 copyPropertyToCollectionModal.show(e.property); 2125 }).subscribe(); 2126 2127 Pubsub.subscription('map_marker_clicked', (id) => { 2128 propertySection.scrollIntoView(id); 2129 2130 document.querySelectorAll('place-propertycard').forEach((propertyCard) => { 2131 if(propertyCard.id == id) { 2132 propertyCard.setAttribute('show_border', true) 2133 } 2134 else { 2135 propertyCard.setAttribute('show_border', false) 2136 } 2137 }) 2138 }).subscribe(); 2139 2140 Pubsub.subscription('my_feed_on_favorite_pressed', (e) => { 2141 copyPropertyToCollectionModal.setIsAddingToCollection(true); 2142 copyPropertyToCollectionModal.show(e.property); 2143 }).subscribe(); 2144 2145 Pubsub.subscription('my_feed_on_unfavorite_pressed', (e) => { 2146 let blossorId = e.property.blossorId; 2147 let myFeedData = myFeed.getMlsData(); 2148 collectionsService.checkIfInCollection([blossorId]).then((propertiesInCollections) => { 2149 if(propertiesInCollections.data[blossorId]){ 2150 propertiesInCollections.data[blossorId].forEac
2150h((collection) => { 2151 collectionsService.removePropertyFromCollection(collection.collectionUUID, collection.propertyUUID).then(() => { 2152 2153 let data = copyPropertyToCollectionModal.getCollectionData(); 2154 let collectionUUID = collection.collectionUUID; 2155 collectionsService.getCollectionProperties(collectionUUID,1,1).then((e) => { 2156 2157 // update photos in add property to collection modal 2158 let collectionIndex = data.findIndex((x) => x.id == collectionUUID); 2159 let collection = data[collectionIndex]; 2160 let photo = e?.data?.properties?.length > 0 ? e?.data?.properties[0]?.photos[0]?.url : ''; 2161 2162 collection.propertiesImages = []; 2163 if(e?.data?.properties?.length > 0){ 2164 collection.propertiesImages.push({mainPhoto: photo}); 2165 } 2166 2167 data[collectionIndex] = collection; 2168 2169 copyPropertyToCollectionModal.setCollectionData(data); 2170 2171 2172 // update collection card if in collection view 2173 pageCollectionIndex = collections.findIndex((x) => x.collectionUUID == collectionUUID) 2174 2175 if(pageCollectionIndex > -1){ 2176 2177 let collectionCard = document.getElementById(collectionUUID); 2178 let numProperties = parseInt(collectionCard.getAttribute('num_properties')); 2179 numProperties--; 2180 collectionCard.setAttribute('num_properties', numProperties); 2181 2182 let images = collectionCard.getAttribute('image'); 2183 let newImages = images.split(',').filter((x) => x == photo).join(','); 2184 collectionCard.setAttribute('image', newImages); 2185 } 2186 2187 //update my feed to set property heart as not favorited 2188 let myFeedPropertyIndex = myFeedData.findIndex((x) => x.blossorId == blossorId); 2189 if(myFeedPropertyIndex > -1){ 2190 myFeedData[myFeedPropertyIndex].favorite = false; 2191 myFeed.setMlsData(myFeedData); 2192 } 2193 }) 2194 toast.show('Property removed from collection'); 2195 }).catch((e) => { 2196 toast.show('Error removing from collection', true); 2197 }); 2198 }); 2199 } 2200 }); 2201 }).subscribe(); 2202 2203 let modalBackdrop = document.getElementsByClassName('center-modal'); 2204 for(let i = 0; i < modalBackdrop.length; i++){ 2205 modalBackdrop[i].addEventListener('click', (e) => { 2206 if(e.target == modalBackdrop[i]){ 2207 modalBackdrop[i].style.display = 'none'; 2208 } 2209 }); 2210 } 2211 2212 window.addEventListener( "hashchange", function( event ) { 2213 if(window.location.hash == ''){ 2214 Pubsub.publish("top_header_back_pressed"); 2215 } 2216 }); 2217 2218 2219 document.addEventListener("click", (e) => { 2220 2221 const elements = document.querySelectorAll("[show_menu]");
2222 elements.forEach((el) => { 2223 el.setAttribute("show_menu", "false"); 2224 }); 2225 2226 document.getElementById("c2dfac72-6233-4e8d-b0d2-f44e4240ebb4")?.setAttribute("show_menu", "false"); 2227 }); 2228 if(window.innerWidth < 768 ){ 2229 savedListings.hide(); 2230 pageSubHeader.hideSecondaryButton(); 2231 } else{ 2232 addListingBtn.hide(); 2233 } 2234 })(); 2235 } 2236 }) 2237 2238</script>
2238 <div id="myportal-page" style="display:none"> <div style="position:relative; width:100%;"> <div style="position:absolute;z-index:110; top:0; bottom:0; "> <place-menu></place-menu> </div> <div class="collection-page" style="flex:1;"> <div class="page-width-parent"> <place-pagesubheader title="COLLECTIONS" show_top_header="false" button_title="Create New" button_icon="plus" secondary_button_icon="plus" secondary_button_title="Add Listings" show_secondary_button="false" show_menu="false" menu_items='[{ "icon": "edit-2", "text": "Edit Collection" },{ "icon": "trash", "text": "Delete Collection" }]' ></place-pagesubheader> <div id="collection-description" class="collection-description" style="display:none;"> <p class="collection-description-text" style="" ></p> </div> <div id="collection-section" style="margin-top:24px;"> <div id="collections" style="display:flex; flex-wrap:wrap"> <place-actioncard id="new-collection-block" style="display:none;" title="Create A Collection" sub_title="You can create a collection to save and keep track of your favorite properties." button_text="Create New" button_icon="plus" button_icon_fill="white" card_width="300" /> </div> <place-pagination id="collection-pagination" style="display:none"></place-pagination> <div class="my-feed-parent"> <place-myfeedblock style="display:none" display_menu="false"></place-myfeedblock> </div> </div> <div id="property-section"> <div id="property-header" style="display:flex; justify-content: space-between"> <p id="collection-saved-listings" class="collection-saved-listings"></p> <place-button icon="plus" ghost="true" btn_text_styles="text-[#5386E4]" icon_stroke="#5386E4" id="add-listing-btn" title="Add Listing"></place-button> <div style="padding: 0 5px; display:flex"> <place-icon id="property-list-icon" style="margin-right:10px" name="list" size="24" fill="none" stroke="black"></place-icon> <place-icon id="property-map-icon" name="map" size="24" fill="none" stroke="gray"></place-icon> </div> </div> <div class="property-container" style=""> <div id="property-list-parent"> <div id="property-list" class="property-list-list-view"> </div> <div> <place-actioncard id="add-listings-block" style="display:none;" title="Add Listings" sub_title="You can search and add properties to a collection to keep track of your favorite homes using the heart icon." button_text="Search Listings" button_icon="search" button_icon_fill="white" card_width="300" /> </div> </div> <div id="property-map" class="property-map-container" style="display:none" > <place-map map_type_control="true" zoom_control="true"> </place-map> </div> </div> <place-pagination id="property-pagination" class="property-pagination" style="display:none"></place-pagination> </div> </div> </div> </div> <place-basicmodal id="collection-created-modal" class="center-modal" style="display:none" title="Collection Created" sub_title="Would you like to add listings to your new collection? You can search for new listings or copy them from an existing collection." title_icon="heart" primary_button_text="View Collection" tertiary_button_text="Search" stacked_buttons="true" ></place-basicmodal> <place-basicmodal id="delete-collection-modal" class="center-modal" style="display:none" title="Delete Collection" sub_title="Deleting a collection will permanently remove it from your account. Your saved properties will only be visible in your Favorites collection." description="Are you sure you would like to delete this collection?" title_icon="trash" primary_button_text="Delete" tertiary_button_text="Cancel" no_stack_buttons="true" ></place-basicmodal> <place-basicmodal id="edit-collection-modal" class="center-modal" style="display:none" title="Changes Saved" sub_title="The changes to your collection have been saved." title_icon="check" primary_button_text="Close" ></place-basicmodal> <place-basicmodal id="delete-property-modal" class="center-modal" style="display:none" title="Remove Property" sub_title="Deleting this property will remove it from the current collection. Are you sure you would like to delete this property from your collection?" title_icon="trash" primary_button_text="Delete" tertiary_button_text="Cancel" no_stack_buttons="true" ></place-basicmodal> <place-basicmodal id="share-saved-property-modal" class="center-modal" style="display:none" title="Share Property" sub_title="Copy link to share property." title_icon="share" primary_button_text="Copy Link" ></place-basicmodal> <place-copycollectionmodal class="center-modal" style="display:none" collections='[]' ></place-copycollectionmodal> <place-collectionpopup class="center-modal" style="display:none"></place-collectionpopup> </div> <footer id="footer-9n" data-selector="footer" style="outline: none; cursor: inherit;"> <div class="container"> <div class="row"> <div class="col-md-2"> <div class="render-menu hot-nav"> <ul class="" style="outline: none; cursor: inherit;"><li class="nav-item" data-selector="li" style="outline: none; cursor: inherit;"> <a href="/index" style="outline: none; cursor: inherit;">Home</a> </li> <li class="nav-item" data-selector="li" style="outline: none; cursor: inherit;"> <a href="/search" style="outline: none; cursor: inherit;">Listings</a> </li> <li class="nav-item" data-selector="li" style="outline: none; cursor: inherit;"> <a href="/buying" style="outline: none; cursor: inherit;">Buying</a> </li> <li class="nav-item" data-selector="li" style="outline: none; cursor: inherit;"> <a class="white" href="/selling" style="outline: none; cursor: inherit;">Selling</a> </li> <li class="nav-item" data-selector="li" style="outline: none; cursor: inherit;"> <a href="/financing" style="outline: none; cursor: inherit;">Financing</a> </li> <li class="nav-item" data-selector="li" style="outline: none; cursor: inherit;"> <a href="/homevalue" style="outline: none; cursor: inherit;">Home Value</a> </li> <li class="nav-item" data-selector="li" style="outline: none; cursor: inherit;"> <a href="/realestateagent/search" style="outline: none; cursor: inherit;">Who We Are</a> </li> <li class="nav-item" data-selector="li" style="outline: none; cursor: inherit;"> <a href="/connect" style="outline: none; cursor: inherit;">Connect</a> </li> </ul></div> </div>
2238 <div class="col-md-7 col-md-offset-1"> <form id="form-contact1" action="" class="form-contact"> <div class="row margin-bottom-0"> <div class="col-sm-6" style="margin-bottom: 20px;"> <div class="form-group"> <input name="contact1_fname" id="contact1_fname" placeholder="First Name" class="form-control contact_fname" type="text" required="" style='background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAAAfBJREFUWAntVk1OwkAUZkoDKza4Utm61iP0AqyIDXahN2BjwiHYGU+gizap4QDuegWN7lyCbMSlCQjU7yO0TOlAi6GwgJc0fT/fzPfmzet0crmD7HsFBAvQbrcrw+Gw5fu+AfOYvgylJ4TwCoVCs1ardYTruqfj8fgV5OUMSVVT93VdP9dAzpVvm5wJHZFbg2LQ2pEYOlZ/oiDvwNcsFoseY4PBwMCrhaeCJyKWZU37KOJcYdi27QdhcuuBIb073BvTNL8ln4NeeR6NRi/wxZKQcGurQs5oNhqLshzVTMBewW/LMU3TTNlO0ieTiStjYhUIyi6DAp0xbEdgTt+LE0aCKQw24U4llsCs4ZRJrYopB6RwqnpA1YQ5NGFZ1YQ41Z5S8IQQdP5laEBRJcD4Vj5DEsW2gE6s6g3d/YP/g+BDnT7GNi2qCjTwGd6riBzHaaCEd3Js01vwCPIbmWBRx1nwAN/1ov+/drgFWIlfKpVukyYihtgkXNp4mABK+1GtVr+SBhJDbBIubVw+Cd/TDgKO2DPiN3YUo6y/nDCNEIsqTKH1en2tcwA9FKEItyDi3aIh8Gl1sRrVnSDzNFDJT1bAy5xpOYGn5fP5JuL95ZjMIn1ya7j5dPGfv0A5eAnpZUY3n5jXcoec5J67D9q+VuAPM47D3XaSeL4AAAAASUVORK5CYII="); background-repeat: no-repeat; background-attachment: scroll; background-size: 16px 18px; background-position: 98% 50%;'></div> </div> <div class="col-sm-6" style="margin-bottom: 20px;"> <div class="form-group"> <input name="contact1_lname" id="contact1_lname" placeholder="Last Name" class="form-control contact_lname" type="text" required=""></div> </div> </div> <div class="row margin-bottom-0"> <div class="col-sm-6" style="margin-bottom: 20px;"> <div class="form-group"> <input name="contact1_email" id="contact1_email" placeholder="Email Address" class="form-control contact_email" type="email" required=""></div> </div> <div class="col-sm-6" style="margin-bottom: 20px;"> <div class="form-group"> <input name="contact1_phone" id="contact1_phone" placeholder="Phone Number" class="form-control contact_phone" type="tel" required=""></div> </div> </div> <div class="row margin-bottom-0"> <div class="col-sm-12" style="margin-bottom: 20px;"> <i class="fa fa-caret-down" style="position: absolute; top: 13px; right: 30px; font-size: 14px; outline: none; cursor: inherit;" data-selector=".fa"></i> <select name="lead_type" style="width: 100%; height: 40px; padding-left: 12px; font-size: 14px; border-radius: 0; -webkit-appearance: none; -webkit-border-radius: 0px;"><option value="buyer">I'm interested in buying a home</option><option value="seller">I'm interested in selling a home</option><option value="seller/buyer">I'm interested in buying and selling</option><option value="tenant">I'm interested in finding a home to rent</option><option value="recruit">I'm interested in a real estate career</option><option value="n/a">Other reason to contact an agent</option></select></div> </div> <div class="row margin-bottom-0"> <div class="col-sm-12" style="margin-bottom: 20px;"> <textarea name="contact1_message" id="contact1_message" class="form-control contact_message" rows="3" placeholder="Your Message"></textarea></div> </div> <div class="text-right"> <input type="text" id="contact1_robot_field" name="contact1_robot_field" style="display: none;"><button type="submit" class="btn btn-primary squared" data-selector="a.btn, button.btn, button" style="outline: none; cursor: inherit;">Send Us A Message</button> </div> <div id="honeypot-div"> <input name="age_required" id="age_required" value="" type="text" style="display: none;"></div></form> </div> <div class="col-md-2 col-md-offset-1"> <img class="ftr-logo" src="https://images.brivityidx.com/assets/images/uploads/10784/footer-place-logo.png" alt="Buy and Sell Homes Real Estate" data-selector="img" style="border-style: none !important; outline: none; cursor: inherit;"><h3 class="text-left margin-top-40" data-selector="h1, h2, h3, h4, h5, h6" style="outline: none; cursor: inherit;">Reach Out</h3> <div class="text-left" style="outline: medium none; cursor: inherit;"> <ul style="list-style-type: none; outline: none; cursor: inherit;"> <li data-selector="li" style="outline: none; cursor: inherit;"> <span class="agent_address">14045 Ballantyne Corporate Place Suite 500</span> <span class="agent_city">Charlotte</span>, <span class="agent_state">North Carolina</span> <span class="agent_zip">28277</span> </li> <li data-selector="li" style="outline: none; cursor: inherit;"> <a class="agent_phone_dynamic dynamic_loading dynamic_loading dynamic_loading dynamic_loading" href="tel:9807040299" src="tel:" style="outline: none; cursor: inherit;"></a> </li> </ul></div> </div> </div> <div class="row ftr-anchor"> <div class="col-sm-6 anchor-col no-padding editContent" style="outline: none; cursor: inherit;" data-selector=".editContent"> <p class="no-margin" style="outline: none; cursor: inherit;" data-selector="p"><span class="get_this_year">2022</span> © <b>Premier Property Solutions | <a href="https://www.place.com/" target="_blank">PLACE</a></b></p> <p style="margin: 10px 0px; outline: none; cursor: inherit;" data-selector="p"> <img src="https://images.brivityidx.com/assets/images/uploads/1428/Equal-Housing-Realtor_gray50.png" alt="Equal Housing | Realtor" style="width: 50px; outline: none; cursor: inherit;" data-selector="img">  Each office is independently owned and operated. </p> </div> <div class="col-sm-6 anchor-col no-padding"> <ul class="list-inline social" style="outline: none; cursor: inherit;"><li data-selector="li" style="outline: none; cursor: inherit;"> <a class="" href="https://www.facebook.com/MyPremierProperty/" target="_blank" style="outline: none; cursor: inherit;"> <svg viewbox="0 0 24 24" width="24" height="24" stroke="currentColor" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round" class="css-i6dzq1"><path d="M18 2h-3a5 5 0 0 0-5 5v3H7v4h3v8h4v-8h3l1-4h-4V7a1 1 0 0 1 1-1h3z"></path></svg></a> </li> <li data-selector="li" style="outline: none; cursor: inherit;"> <a class="" href="https://www.instagram.com/premierproperty_solutions/" target="_blank" style="outline: none; cursor: inherit;"> <svg viewbox="0 0 24 24" width="24" height="24" stroke="currentColor" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round" class="css-i6dzq1"><rect x="2" y="2" width="20" height="20" rx="5" ry="5"></rect><path d="M16 11.37A4 4 0 1 1 12.63 8 4 4 0 0 1 16 11.37z"></path><line x1="17.5" y1="6.5" x2="17.5" y2="6.5"></line></svg></a> </li> </ul></div> </div> </div> </footer> </div> <section id="seo-anchor"> <div class="container"> <ul class="powered-by"> <li>Powered by <a class="pb-vendor" href="https://www.brivity.com/"> Brivity</a></li> <li class="pb-admin-login"><a href="https://login.brivityidx.com/login"><span class='pb-admin-login-text'>Admin Log In</span></a></li> </ul> <ul class="seo-anchor-links"> <li><a href="/privacy_policy">Privacy Policy</a></li> <li><a href="/tos">DMCA & Terms of Service</a></li> <li><a id='sitemapUrl' href='/sitemap' style='display: inline;'>Sitemap</a></li> </ul> </div> </section> <input type="hidden" id="hchatbot_settings" data-chatbot-version="1" value="{"chat_position":"right","call_to_action_text":"Hi there! Please let us know if you have any questions and an agent will reach out to you as soon as possible.","initial_message":"Enter your question below and an agent will be in touch with you.","tags":"IDX Chat","version":"1"}"> 2239<!-- chatbot v1 --> 2240<!-- Chatbot drawer container --> 2241<div class="chatbot-drawer-container loading"> 2242 <div class="chatbot-content-wrapper"> 2243 <div class="chatbot-outside-content"> 2244 <div class="chatbot-bubble-message-container cb-hide"> 2245 <img src="https://cdn.brivity.com/images/people/28863551/2b37c1e1cc67758023a8060b11ff9814e79e4cf8-original.png?1756463957" class="chatbot-agent-img" alt="Agent profile image in chat bubble"/> 2246 <div id="call-to-action" class="bubble-message"></div> 2247 <button type="button" class="chatbox-bubble-close" data-dismiss="modal" aria-label="Close">
2248 <span aria-hidden="true">×</span> 2249 </button> 2250 </div> 2251 <button id="chatbot-open-btn" class="chatbot-open-btn bg-prmry" aria-label="Chatbot Open Button"> 2252 <svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg"> 2253 <path d="M20.8 6.35501V16C20.8 17.765 19.365 19.195 17.6 19.195L11.2 19.2L5.755 22.28C5.645 22.365 5.52 22.4 5.4 22.4C5.09 22.4 4.8 22.155 4.8 21.8V19.2H3.2C1.4375 19.2 0 17.765 0 16V6.35501C0 4.63751 1.4375 3.20001 3.2 3.20001H17.6C19.365 3.20001 20.8 4.63751 20.8 6.35501ZM7.2 18.705L10.57 16.8H17.6C18.035 16.8 18.4 16.44 18.4 16V6.40001C18.4 5.96251 18.035 5.60001 17.6 5.60001H3.2C2.7625 5.60001 2.4 5.96251 2.4 6.40001V16C2.4 16.44 2.7625 16.8 3.2 16.8H7.2V18.705ZM12.8 22.4V20.8H15.2V22.4C15.2 22.835 15.56 23.2 16 23.2H21.43L24.8 25.105V23.2H28.8C29.235 23.2 29.6 22.835 29.6 22.4V12.8C29.6 12.365 29.235 12 28.8 12H22.4V9.60001H28.8C30.565 9.60001 32 11.035 32 12.755V22.4C32 24.165 30.565 25.6 28.8 25.6H27.2V28.2C27.2 28.555 26.91 28.8 26.6 28.8C26.48 28.8 26.355 28.765 26.245 28.68L20.8 25.6L16 25.595C14.24 25.595 12.8 24.165 12.8 22.4Z" fill="white"/> 2254 </svg> 2255 </button> 2256 </div> 2257 <div class="chatbot-drawer"> 2258 <div class="chatbot-header bg-prmry"> 2259 <div class="chatbot-agent-info"> 2260 <img src="https://cdn.brivity.com/images/people/28863551/2b37c1e1cc67758023a8060b11ff9814e79e4cf8-original.png?1756463957" class="chatbot-agent-img" alt="Agent profile image in chat header"/> 2261 <div class="chatbot-agent"> 2262 <h3 class="chatbot-agent-name">Premier Property Solutions Team</h3> 2263 <h4><span class="chatbot-agent-title"></span> | <span class="chatbot-agent-company">Premier Property Solutions | Charlotte, NC</span></h4> 2264 </div> 2265 <a id="chatbot-agent-phone" style="display: none;">(704) 286-0506</a> 2266 </div> 2267 <button id="close-chatbot-drawer" type="button" class="chatbox-modal-close" data-dismiss="modal" aria-label="Close"> 2268 <span aria-hidden="true">×</span> 2269 </button> 2270 </div> 2271 <div class="chatbot-body"> 2272 <div class="chatbot-message-container"> 2273 <img src="https://cdn.brivity.com/images/people/28863551/2b37c1e1cc67758023a8060b11ff9814e79e4cf8-original.png?1756463957" class="chatbot-agent-img" alt="Agent profile image in message"/> 2274 <h4 id="initial_message" class="chatbot-chat-messages not-loaded"></h4> 2275 <div class="chatbot-chat-messages loading"> 2276 <span class="typing-indicator"> 2277 <span></span> 2278 <span></span> 2279 <span></span> 2280 </span> 2281 </div> 2282 </div> 2283 <form id="chatbotForm" class="chatbot-form"> 2284 <input type="name" id="chatbot_fullname" class="chatbox-form-control no-native-focus" placeholder="Full Name" 2285 pattern="^[A-Za-z'\- ]+ [A-Za-z'\- ]+$" 2286 required /> 2287 <input type="tel" id="chatbot_phone" class="chatbox-form-control no-native-focus" placeholder="Phone" required /> 2288 <input type="email" id="chatbot_email" class="chatbox-form-control no-native-focus" placeholder="Email" 2289 pattern="^[^@\s]+@[^@\s]+\.[^@\s]+$" 2290 required /> 2291 <textarea id="chatbot_message" class="chatbox-form-control chatbot-message" rows="5" name="notes" placeholder="Any Comments or Questions"></textarea> 2292 <div class="chatbot-consent-container"> 2293 <div class="chatbot-toggle"> 2294 By proceeding and clicking the sign up button, you consent to receive calls and texts (SMS/MMS) including marketing and promotional communications, from <span class="agent_name_dynamic"></span>, its affiliates, and agents or vendors acting on their behalf. These
2294communications may be delivered using an automatic telephone dialing system or by using an artificial or prerecorded voice. Message and data rates may apply. To opt out of text messages, reply STOP. Your consent is not required as a condition of any purchase. By continuing, you also agree to our <a class="opt-out-href" href="/tos">Terms of Use</a> and <a class="opt-out-href" href="/privacy_policy">Privacy Policy</a>. 2295 </div> 2296 </div> 2297 <input type="hidden" id="chatbot_tags"> 2298 </form> 2299 </div> 2300 <div class="chatbot-footer"> 2301 <button type="submit" form="chatbotForm" class="chatbot-send bg-prmry chatbot-btn-disabled" data-dismiss="modal" aria-label="Close" disabled> 2302 Send 2303 <span aria-hidden="true"> 2304 <svg class="chatbot-btn-icon" width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg"> 2305 <g clip-path="url(#clip0_2435_997)"> 2306 <path d="M14.6667 1.33331L7.33337 8.66665" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> 2307 <path d="M14.6667 1.33331L10 14.6666L7.33337 8.66665L1.33337 5.99998L14.6667 1.33331Z" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> 2308 </g> 2309 <defs> 2310 <clipPath id="clip0_2435_997"> 2311 <rect width="16" height="16" fill="white"/> 2312 </clipPath> 2313 </defs> 2314 </svg> 2315 </span> 2316 </button> 2317 </div> 2318 </div> 2319 </div> 2320</div> <style> 2321 .signup-consent-checkbox-section { 2322 display: none; 2323 flex-direction:column; 2324 align-items:flex-start; 2325 padding: 6px 0; 2326 } 2327 2328 .signup-consent-checkbox-section .checkbox { 2329 display:flex; 2330 align-items:flex-start; 2331 justify-content:center; 2332 gap:8px; 2333 padding:0 !important; 2334 } 2335 2336 .signup-consent-checkbox-section .checkbox input { 2337 position:unset; 2338 margin:2px 0 0 0 !important; 2339 } 2340 2341 .signup-consent-checkbox-section .checkbox span { 2342 color: #666666; 2343 font-size: 14px; 2344 font-weight: 400; 2345 line-height:16px; 2346 } 2347 2348 .signup-verbage { 2349 text-align:center; 2350 font-size:10px; 2351 line-height:16px; 2352 } 2353 2354 .signup-verbage span { 2355 color: #8C8C8C; 2356 font-weight:600; 2357 } 2358 2359 .signup-verbage a { 2360 color:#5386E4 !important; 2361 font-weight:400; 2362 } 2363 2364 .signup-verbage .twilio-enabled-verbage { 2365 display:none; 2366 } 2367 2368 2369 2370 </style> <div id="modal-mount" data-modal-bundle="https://cdn1.brivityidx.com/assets/modals/v1/all.html?ck=1789512948"></div>
2370 <div id="credential_picker_container_centered"> <div id="credential_picker_header_bar"> <p><button class="signOrLogBtn" onclick="showSignupModal();">Sign up</button> or <button class="signOrLogBtn" onclick="showLoginModal();">Login</button> another way</p> </div> <div id="credential_picker_header_bar_separator"></div> </div> <place-getyourhomecta id="contact_modal" style="display:none; justify-content: center; align-items: center; position:fixed; background-color:rgba(0,0,0,0.4); left:0; top:0; right:0; bottom:0; z-index: 100;" interest_items='[{"text":"Looking to sell ASAP"},{"text":"Looking to sell (1-3 months)"},{"text":"Looking to sell (3-6 months)"}, {"text":"Looking to sell (6-12 months)"},{"text":"Looking to sell (12+ months)"}, {"text":"Just curious"}]' > </place-getyourhomecta> <place-generictoast appear_from_both="true" container_style="right-1/2 z-200"></place-generictoast>
2370<script> 2371 document.addEventListener("DOMContentLoaded", () => { 2372 class Toast { 2373 constructor() { 2374 this.element = document.querySelector('place-generictoast'); 2375 } 2376 2377 show(message, error = false, link) { 2378 var dispatch = function () { 2379 window.dispatchEvent( 2380 new CustomEvent("ShowToast", { 2381 detail: { 2382 text: message, 2383 error: error, 2384 link: link, 2385 }, 2386 }) 2387 ); 2388 }; 2389 if (window.sitebuilderPlaceComponents && window.sitebuilderPlaceComponents.ensureLoaded) { 2390 window.sitebuilderPlaceComponents 2391 .ensureLoaded('place-generictoast') 2392 .then(dispatch) 2393 .catch(function (err) { 2394 console.warn('toast.show fallback (web-components unavailable):', message, err); 2395 }); 2396 } else { 2397 dispatch(); 2398 } 2399 } 2400 } 2401 2402 window.toast = new Toast(); 2403 }); 2404 </script>
2404
2404<script src="https://cdn.jsdelivr.net/npm/@turf/[email protected]/turf.min.js"></script>
2404
2404<script src="https://maps.googleapis.com/maps/api/js?libraries=geocoding,places,marker,drawing&key=AIzaSyAjpuNg6WGCMV5rzoJcIP2QmMTVto6hYmc&map_ids=85c127b7bf0255d9"></script>
2404
2404<script src="https://cdn1.brivityidx.com/assets/js/build.min.js?ck="></script>
2404
2404<script src="https://cdn1.brivityidx.com/assets/js/top_bar_v2.min.js?ck="></script>
2404
2404<script src="https://cdn1.brivityidx.com/assets/js/global_js.min.js?ck=1789512947"></script>
2404
2404<script>deferScript("https://cdn1.brivityidx.com/assets/js/global_js_defer.min.js?ck=1789512947", 5000);</script>
2404
2404<script> 2405 function shouldLoadChatbotImmediately() { 2406 const settingsEl = document.getElementById('hchatbot_settings'); 2407 if (!settingsEl) return false; 2408 2409 const version = Number(settingsEl.dataset.chatbotVersion); 2410 let isInitialized = false; 2411 2412 try { 2413 const session = JSON.parse(sessionStorage.getItem('cbSession') || '{}'); 2414 isInitialized = session.chatbotInitialized === true; 2415 } catch (e) {} 2416 2417 return version > 1 && isInitialized; 2418 } 2419 </script>
2419
2419<script>document.getElementById('hchatbot_settings') && Number(document.getElementById('hchatbot_settings').dataset.chatbotVersion) > 1 && deferScript("https://cdnjs.cloudflare.com/ajax/libs/microsoft-signalr/9.0.6/signalr.min.js", 0);</script>
2419
2419<script>document.getElementById('hchatbot_settings') && deferScript(Number(document.getElementById('hchatbot_settings').dataset.chatbotVersion) > 1 ? "https://cdn1.brivityidx.com/assets/js/chatbot_v2.min.js?ck=1789512945" : "https://cdn1.brivityidx.com/assets/js/chatbot.min.js?ck=1789512945", shouldLoadChatbotImmediately() ? 50 : 5000);</script>
2419
2419<script type="text/javascript" src="https://cdn1.brivityidx.com/assets/js/jquery.geocomplete.min.js"></script>
2419<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery.bootstrapvalidator/0.5.3/js/bootstrapValidator.min.js"></script>
2419<script type="text/javascript" src="https://cdn1.brivityidx.com/assets/js/member_area_components.js"></script>
2419<script type="text/javascript" src="https://cdn1.brivityidx.com/assets/js/update_agent_info.js"></script>
2419
2419<script src="https://mobile-component-services-library.s3.amazonaws.com/collections_service.min.js?ck=1"></script>
2419
2419<script src="https://mobile-component-services-library.s3.amazonaws.com/messaging_service.min.js?ck=1"></script>
2419
2419<script>$(document).ready(function(){$("#sitemap-listings > div.container > div > div.col-xs-12.col-md-12.col-lg-4.col-lg-push-8.seo-intro > a").attr("href","/search")});$(document).ready(function(){$("#sitemap-listings > div.container > div > div.col-xs-12.col-md-12.col-lg-4.col-lg-push-8.seo-intro > a").attr("href","/search")});$(document).ready(function(){$("ul.seo-anchor-links li:nth-of-type(4) a").attr("href","/search")})</script>
2419
2419<script>(function($){$.fn.countTo=function(options){options=options||{};return $(this).each(function(){var settings=$.extend({},$.fn.countTo.defaults,{from:$(this).data('from'),to:$(this).data('to'),speed:$(this).data('speed'),refreshInterval:$(this).data('refresh-interval'),decimals:$(this).data('decimals')},options);var loops=Math.ceil(settings.speed/settings.refreshInterval),increment=(settings.to-settings.from)/loops;var self=this,$self=$(this),loopCount=0,value=settings.from,data=$self.data('countTo')||{};$self.data('countTo',data);if(data.interval){clearInterval(data.interval)} 2420data.interval=setInterval(updateTimer,settings.refreshInterval);render(value);function updateTimer(){value+=increment;loopCount++;render(value);if(typeof(settings.onUpdate)=='function'){settings.onUpdate.call(self,value)} 2421if(loopCount>=loops){$self.removeData('countTo');clearInterval(data.interval);value=settings.to;if(typeof(settings.onComplete)=='function'){settings.onComplete.call(self,value)}}} 2422function render(value){var formattedValue=settings.formatter.call(self,value,settings);$self.html(formattedValue)}})};$.fn.countTo.defaults={from:0,to:0,speed:1000,refreshInterval:100,decimals:0,formatter:formatter,onUpdate:null,onComplete:null};function formatter(value,settings){return value.toFixed(settings.decimals)}}(jQuery));jQuery(function($){$('.count-number').data('countToOptions',{formatter:function(value,options){return value.toFixed(options.decimals).replace(/\B(?=(?:\d{3})+(?!\d))/g,',')}});$('.timer').each(count);function count(options){var $this=$(this);options=$.extend({},options||{},$this.data('countToOptions')||{});$this.countTo(options)}})</script>
2422
2422<script>$(document).ready(function(){const navIcons={"Home":`<svg class="nav-icon" id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 21.61 24"><path d="M21.09,8.28L11.76.35c-.55-.47-1.36-.47-1.91,0L.52,8.27c-.33.28-.52.69-.52,1.13v13.12c0,.82.66,1.48,1.48,1.48h18.65c.82,0,1.48-.66,1.48-1.48v-13.12c0-.43-.19-.85-.52-1.13ZM17.73,12.58l-3.1,3.05c-.07.07-.1.16-.08.26l.73,4.3c.04.24-.21.42-.42.31l-3.89-2.02c-.08-.04-.18-.04-.27,0l-3.88,2c-.21.11-.46-.07-.42-.31l.7-4.31c.02-.09-.02-.19-.08-.26l-3.13-3.07c-.17-.17-.08-.46.16-.5l4.32-.64c.09-.01.18-.07.22-.16l1.94-3.89c.11-.22.42-.22.52,0l1.97,3.91c.04.08.12.14.22.16l4.33.67c.24.04.33.33.16.5Z"></path></svg>`,"Search":`<i class="nav-icon fa fa-search"></i>`,"Buying":`<i class="nav-icon fa fa-key"></i>`,"Selling":`<i class="nav-icon fa fa-truck"></i>`,"Top Areas":`<i class="nav-icon fa fa-map-marker"></i>`,"Resources":`<i class="nav-icon fa fa-pencil"></i>`,"Neighborhood Heighlights":`<i class="nav-icon fa fa-sun-o"></i>`,"Careers":`<i class="nav-icon fa fa-briefcase"></i>`,"Financing":`<i class="nav-icon fa fa-usd"></i>`,"Who We Are":`<i class="nav-icon fa fa-user"></i>`,"Reviews":`<i class="nav-icon fa fa-star"></i>`,"Blog":`<i class="nav-icon fa fa-newspaper-o"></i>`,"Connect":`<i class="nav-icon fa fa-comment"></i>`,"Google Verification":`<i class="nav-icon fa fa-google"></i>`,};const defaultIcon=`<i class="nav-icon fa fa-circle"></i>`;$('#premium-navigation .main-nav .render-menu ul li a.sec-nav-link-color, #premium-navigation .main-nav .render-menu ul li a.dropdown-toggle').each(function(){const $link=$(this);if($link.find('svg, i.fa').not('.fa-angle-down').length===0){const linkText=$link.clone().children().remove().end().text().trim();const icon=navIcons[linkText]||defaultIcon;$link.prepend(icon)}});$('#premium-navigation.vertical-nav .navbar-nav > li > a').css('opacity','1')})</script>
2422
2422<script>$('a[class$="propClone"]').attr('target','_blank')</script>
2422
2422<script>var acc=document.getElementsByClassName("accordion");var i;for(i=0;i<acc.length;i++){acc[i].addEventListener("click",function(){this.classList.toggle("active");var panel=this.nextElementSibling;if(panel.style.display==="block"){panel.style.display="none"}else{panel.style.display="block"}})} 2423var acc=document.getElementsByClassName("accordion");var i;for(i=0;i<acc.length;i++){acc[i].addEventListener("click",function(){this.classList.toggle("active");var panel=this.nextElementSibling;if(panel.style.maxHeight){panel.style.maxHeight=null}else{panel.style.maxHeight=panel.scrollHeight+"px"}})}</script>
2423
2423<script>function moveleftOne(){var element=document.getElementById("leftOne");element.classList.toggle("moveleftOne")}</script>
2423
2423<script>function moveleftTwo(){var element=document.getElementById("leftTwo");element.classList.toggle("moveleftOne")}</script>
2423
2423<script>function moveleftThree(){var element=document.getElementById("leftThree");element.classList.toggle("moveleftTwo")}</script>
2423
2423<script>function moveleftFour(){var element=document.getElementById("leftFour");element.classList.toggle("moveleftOne")}</script>
2423
2423<script>function moveleftFive(){var element=document.getElementById("leftFive");element.classList.toggle("moveleftOne")}</script>
2423
2423<script>function moveleftSix(){var element=document.getElementById("leftSix");element.classList.toggle("moveleftTwo")}</script>
2423 </body> </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.