diff --git a/wp-content/plugins/mls-by-hansonxyz/includes/class-mls-query.php b/wp-content/plugins/mls-by-hansonxyz/includes/class-mls-query.php index a000d0b1..91bd4e18 100755 --- a/wp-content/plugins/mls-by-hansonxyz/includes/class-mls-query.php +++ b/wp-content/plugins/mls-by-hansonxyz/includes/class-mls-query.php @@ -209,40 +209,13 @@ class MLS_Query { // City and postal_code are mutually exclusive - city takes priority if ($args['city']) { - // Look up city coordinates for radius search - $city_coords = $this->get_city_coordinates($args['city']); - if ($city_coords) { - // Match exact city OR within 15 miles of city center - $distance_filter = $this->get_distance_filter_sql( - $city_coords['latitude'], - $city_coords['longitude'], - 15 // miles - ); - $where[] = "(city = %s OR ({$distance_filter}))"; - $values[] = $args['city']; - } else { - // Fallback to exact match if city not in geo table - $where[] = 'city = %s'; - $values[] = $args['city']; - } + // Exact city match + $where[] = 'city = %s'; + $values[] = $args['city']; } elseif ($args['postal_code']) { - // Only apply postal_code filter if city is not set - // Look up zip code coordinates for radius search - $zip_coords = $this->get_zipcode_coordinates($args['postal_code']); - if ($zip_coords) { - // Match exact zip code OR within 20 miles of zip code center - $distance_filter = $this->get_distance_filter_sql( - $zip_coords['latitude'], - $zip_coords['longitude'], - 20 // miles - ); - $where[] = "(postal_code = %s OR ({$distance_filter}))"; - $values[] = $args['postal_code']; - } else { - // Fallback to exact match if zip code not in geo table - $where[] = 'postal_code = %s'; - $values[] = $args['postal_code']; - } + // Exact postal code match + $where[] = 'postal_code = %s'; + $values[] = $args['postal_code']; } elseif ($args['center_lat'] && $args['center_lng']) { // Direct lat/lng radius search (from homepage location search) $distance_filter = $this->get_distance_filter_sql( @@ -548,40 +521,13 @@ class MLS_Query { // City and postal_code are mutually exclusive - city takes priority if (!empty($args['city'])) { - // Look up city coordinates for radius search - $city_coords = $this->get_city_coordinates($args['city']); - if ($city_coords) { - // Match exact city OR within 15 miles of city center - $distance_filter = $this->get_distance_filter_sql( - $city_coords['latitude'], - $city_coords['longitude'], - 15 // miles - ); - $where[] = "(city = %s OR ({$distance_filter}))"; - $values[] = $args['city']; - } else { - // Fallback to exact match if city not in geo table - $where[] = 'city = %s'; - $values[] = $args['city']; - } + // Exact city match + $where[] = 'city = %s'; + $values[] = $args['city']; } elseif (!empty($args['postal_code'])) { - // Only apply postal_code filter if city is not set - // Look up zip code coordinates for radius search - $zip_coords = $this->get_zipcode_coordinates($args['postal_code']); - if ($zip_coords) { - // Match exact zip code OR within 20 miles of zip code center - $distance_filter = $this->get_distance_filter_sql( - $zip_coords['latitude'], - $zip_coords['longitude'], - 20 // miles - ); - $where[] = "(postal_code = %s OR ({$distance_filter}))"; - $values[] = $args['postal_code']; - } else { - // Fallback to exact match if zip code not in geo table - $where[] = 'postal_code = %s'; - $values[] = $args['postal_code']; - } + // Exact postal code match + $where[] = 'postal_code = %s'; + $values[] = $args['postal_code']; } elseif (!empty($args['center_lat']) && !empty($args['center_lng'])) { // Direct lat/lng radius search (from homepage location search) $radius = !empty($args['radius']) ? (int) $args['radius'] : 30; @@ -806,40 +752,13 @@ class MLS_Query { // City and postal_code are mutually exclusive - city takes priority if (!empty($args['city'])) { - // Look up city coordinates for radius search - $city_coords = $this->get_city_coordinates($args['city']); - if ($city_coords) { - // Match exact city OR within 15 miles of city center - $distance_filter = $this->get_distance_filter_sql( - $city_coords['latitude'], - $city_coords['longitude'], - 15 // miles - ); - $where[] = "(city = %s OR ({$distance_filter}))"; - $values[] = $args['city']; - } else { - // Fallback to exact match if city not in geo table - $where[] = 'city = %s'; - $values[] = $args['city']; - } + // Exact city match + $where[] = 'city = %s'; + $values[] = $args['city']; } elseif (!empty($args['postal_code'])) { - // Only apply postal_code filter if city is not set - // Look up zip code coordinates for radius search - $zip_coords = $this->get_zipcode_coordinates($args['postal_code']); - if ($zip_coords) { - // Match exact zip code OR within 20 miles of zip code center - $distance_filter = $this->get_distance_filter_sql( - $zip_coords['latitude'], - $zip_coords['longitude'], - 20 // miles - ); - $where[] = "(postal_code = %s OR ({$distance_filter}))"; - $values[] = $args['postal_code']; - } else { - // Fallback to exact match if zip code not in geo table - $where[] = 'postal_code = %s'; - $values[] = $args['postal_code']; - } + // Exact postal code match + $where[] = 'postal_code = %s'; + $values[] = $args['postal_code']; } if (!empty($args['min_price'])) { diff --git a/wp-content/plugins/mls-by-hansonxyz/mls-by-hansonxyz.php b/wp-content/plugins/mls-by-hansonxyz/mls-by-hansonxyz.php old mode 100644 new mode 100755 index 7598aca9..9df8fa1e --- a/wp-content/plugins/mls-by-hansonxyz/mls-by-hansonxyz.php +++ b/wp-content/plugins/mls-by-hansonxyz/mls-by-hansonxyz.php @@ -256,6 +256,10 @@ final class MLS_Plugin { $status = isset($_REQUEST['status']) ? sanitize_text_field($_REQUEST['status']) : 'Active'; $property_type = isset($_REQUEST['property_type']) ? sanitize_text_field($_REQUEST['property_type']) : null; $city = isset($_REQUEST['city']) ? sanitize_text_field($_REQUEST['city']) : null; + // Parse "City, SS" format - extract just the city name + if ($city && preg_match('/^(.+),\s*([A-Z]{2})$/', $city, $matches)) { + $city = $matches[1]; + } $min_price = isset($_REQUEST['min_price']) ? (int) $_REQUEST['min_price'] : null; $max_price = isset($_REQUEST['max_price']) ? (int) $_REQUEST['max_price'] : null; $min_beds = isset($_REQUEST['min_beds']) ? (int) $_REQUEST['min_beds'] : null; diff --git a/wp-content/themes/homeproz/dist/assets/main.js b/wp-content/themes/homeproz/dist/assets/main.js index 21997a13..fa0077b1 100644 --- a/wp-content/themes/homeproz/dist/assets/main.js +++ b/wp-content/themes/homeproz/dist/assets/main.js @@ -1 +1 @@ -(function(r){var I=r(".menu-toggle"),n=r(".mobile-navigation");I.length&&(I.on("click",function(){var s=r(this).attr("aria-expanded")==="true";r(this).attr("aria-expanded",!s),n.toggleClass("is-open"),s?r("body").removeClass("mobile-menu-open"):r("body").addClass("mobile-menu-open")}),r(document).on("keydown",function(s){s.key==="Escape"&&n.hasClass("is-open")&&(I.attr("aria-expanded","false"),n.removeClass("is-open"),r("body").removeClass("mobile-menu-open"))}),r(document).on("click",function(s){n.hasClass("is-open")&&!r(s.target).closest(".mobile-navigation").length&&!r(s.target).closest(".menu-toggle").length&&(I.attr("aria-expanded","false"),n.removeClass("is-open"),r("body").removeClass("mobile-menu-open"))}))})(jQuery);(function(r){var I=6e3,n=1450,s=1e3,h=[],c=0,g=null,m=!1,u=!1,y=null;function v(){if(r(".Home_Page").length&&(y=r(".hero-split-image"),!!y.length)){var p=y.data("gallery-images");!p||!p.length||(h=p,t(),r(window).on("resize",l(t,150)))}}function t(){var p=r(window).width();p>=n?m||e():m&&i()}function e(){m=!0,u||(a(),u=!0),g=setInterval(o,I)}function i(){m=!1,g&&(clearInterval(g),g=null)}function a(){r.each(h,function(p,d){var f=new Image;f.src=d})}function o(){c=(c+1)%h.length;var p=h[c],d=r('
');d.css({position:"absolute",top:0,left:0,right:0,bottom:0,"background-image":"url("+p+")","background-size":"cover","background-position":"center center","background-repeat":"no-repeat",opacity:0,transform:"scale(1.02)",transition:"opacity "+s+"ms ease-in-out, transform "+s+"ms ease-in-out","z-index":1}),y.css("position","relative"),y.append(d),d[0].offsetHeight,d.css({opacity:1,transform:"scale(1)"}),setTimeout(function(){y.css("background-image","url("+p+")"),d.remove()},s)}function l(p,d){var f;return function(){var P=this,x=arguments;clearTimeout(f),f=setTimeout(function(){p.apply(P,x)},d)}}r(document).ready(v)})(jQuery);(function(r){var I=2,n=null,s=!1;function h(){var v=r(".hero-location-search");v.length&&(m(),v.each(function(){c(r(this))}))}function c(v){var t=v.find(".hero-location-input"),e=v.find('input[name="lat"]'),i=v.find('input[name="lng"]'),a=v.find(".hero-geolocation-btn"),o=r('');t.after(o),g(t,o);var l=null;function p(b){if(!n||b.length=I){var w=b,C=l.label.substring(w.length),_=''+y(w)+''+y(C)+"";o.html(_).show()}else o.empty().hide(),l=null}function f(){return l?(t.val(l.label),e.val(l.lat),i.val(l.lng),o.empty().hide(),l=null,!0):!1}function P(){var b=t.val().trim();if(e.val()&&i.val())return!0;var w=x(b);if(w)return t.val(w.label),e.val(w.lat),i.val(w.lng),!0;if(l)return t.val(l.label),e.val(l.lat),i.val(l.lng),!0;var C=p(b);return C?(t.val(C.label),e.val(C.lat),i.val(C.lng),!0):!1}function x(b){if(!n||!b)return null;for(var w=b.toLowerCase(),C=0;C0;h--){var c=Math.floor(Math.random()*(h+1)),g=s[h];s[h]=s[c],s[c]=g}return s},renderListings:function(){if(!this.listings||this.listings.length===0){this.grid.hide(),this.emptyMessage.show();return}for(var n=[],s=[],h=0;h',n.bedrooms&&(c+='
  • '+n.bedrooms+" "+s+"
  • "),n.bathrooms&&(c+='
  • '+n.bathrooms+" "+h+"
  • "),n.sqft&&(c+='
  • '+n.sqft.toLocaleString()+" sqft
  • "),c+=""),'
    Active
    '+this.escapeHtml(n.price_formatted)+'

    '+this.escapeHtml(n.address)+"

    "+c+'View Details
    '},escapeHtml:function(n){if(!n)return"";var s=document.createElement("div");return s.textContent=n,s.innerHTML}};r(document).ready(function(){I.init()})}})(jQuery);(function(r){var I={PREFIX:"HOMEPROZ_AJAX_",EXPIRY_MS:3e5,init:function(){this.cleanExpired()},cleanExpired:function(){try{for(var t=Date.now(),e=[],i=0;ithis.EXPIRY_MS&&e.push(a)}catch{e.push(a)}}e.forEach(function(l){sessionStorage.removeItem(l)})}catch{}},normalizeData:function(t){var e={};for(var i in t)if(i!=="nonce"){var a=t[i];Array.isArray(a)?e[i]=a.map(function(o){return typeof o=="number"?Math.round(o*1e4)/1e4:o}):e[i]=a}return e},getKey:function(t){for(var e=this.normalizeData(t),i=JSON.stringify(e),a=0,o=0;othis.EXPIRY_MS?(sessionStorage.removeItem(e),null):a.data}catch{return null}},set:function(t,e){try{var i=this.getKey(t),a={time:Date.now(),data:e};sessionStorage.setItem(i,JSON.stringify(a))}catch{}}};I.init();var n={pending:{clusters:null,properties:null},timeouts:{clusters:null,properties:null},requestIds:{clusters:0,properties:0},debounceDelay:200,queue:function(t,e,i,a,o){var l=this;this.timeouts[t]&&(clearTimeout(this.timeouts[t]),this.timeouts[t]=null),this.pending[t]&&(this.pending[t].abort(),this.pending[t]=null),this.requestIds[t]++;var p=this.requestIds[t];this.timeouts[t]=setTimeout(function(){l.timeouts[t]=null;var d=e(p);d&&d.then&&(l.pending[t]=d,d.done(function(f){p===l.requestIds[t]&&i(f,p)}),d.fail(function(f,P,x){o&&p===l.requestIds[t]&&P!=="abort"&&o(f,P,x)}),d.always(function(){l.pending[t]===d&&(l.pending[t]=null),a&&p===l.requestIds[t]&&a()}))},this.debounceDelay)},cancel:function(t){var e=t?[t]:["clusters","properties"],i=this;e.forEach(function(a){i.timeouts[a]&&(clearTimeout(i.timeouts[a]),i.timeouts[a]=null),i.pending[a]&&(i.pending[a].abort(),i.pending[a]=null)})},isLoading:function(t){return!!(this.pending[t]||this.timeouts[t])}},s={map:null,markers:{},markerData:{},densityLayer:null,clusterLayer:null,markerCluster:null,markerLayer:null,selectedPropertyId:null,isPinClickPan:!1,hoveredPropertyId:null,temporaryHoverMarker:null,baseZIndex:400,currentFilters:{},currentMode:null,initialCenter:[45,-93.5],initialZoom:7,init:function(t){var e=r("#property-map");if(!(!e.length||typeof L>"u")){this.currentFilters=t||{},this.map=L.map("property-map").setView([45,-93.5],7),L.tileLayer("https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png",{attribution:'© OpenStreetMap'}).addTo(this.map),this.densityLayer=L.layerGroup().addTo(this.map),this.clusterLayer=L.layerGroup().addTo(this.map),this.markerLayer=L.layerGroup().addTo(this.map),this.markerCluster=L.markerClusterGroup({maxClusterRadius:50,spiderfyOnMaxZoom:!0,showCoverageOnHover:!1,zoomToBoundsOnClick:!0,disableClusteringAtZoom:18,chunkedLoading:!0,chunkInterval:200,chunkDelay:50,iconCreateFunction:function(a){var o=a.getChildCount(),l="small";return o>=100?l="large":o>=10&&(l="medium"),L.divIcon({html:"
    "+o+"
    ",className:"marker-cluster marker-cluster-"+l,iconSize:L.point(40,40)})}}),this.map.addLayer(this.markerCluster);var i=this;this.map.on("moveend zoomend",function(){i.loadClusters(),setTimeout(function(){c.updateUrlState()},400)}),this.bindCardHoverEvents(),this.loadClusters()}},loadClusters:function(){if(this.map){var t=this,e=this.map.getBounds(),i=this.map.getCenter(),a=this.map.getZoom(),o=[e.getSouthWest().lat,e.getSouthWest().lng,e.getNorthEast().lat,e.getNorthEast().lng],l=[i.lat,i.lng],p={action:"mls_get_clusters",zoom:a,bounds:o,status:this.currentFilters.status||"Active",property_type:this.currentFilters.property_type||"",city:this.currentFilters.city||"",min_price:this.currentFilters.min_price||"",max_price:this.currentFilters.max_price||"",min_beds:this.currentFilters.min_beds||""};c.updateFromMap(o,l);var d=I.get(p);if(d&&d.success){var f=d.data;switch(this.currentMode=f.type,f.type){case"density":this.renderDensity(f.dots);break;case"clusters":this.renderClusters(f.clusters);break;case"markers":this.renderMarkers(f.markers);break}return}n.queue("clusters",function(P){return r.ajax({url:homeprozMapData.clusterEndpoint,type:"GET",data:p})},function(P,x){if(P.success){I.set(p,P);var b=P.data;switch(t.currentMode=b.type,b.type){case"density":t.renderDensity(b.dots);break;case"clusters":t.renderClusters(b.clusters);break;case"markers":t.renderMarkers(b.markers);break}}})}},clearAllLayers:function(){this.densityLayer.clearLayers(),this.clusterLayer.clearLayers(),this.markerCluster.clearLayers(),this.markerLayer.clearLayers(),this.markers={},this.temporaryHoverMarker&&(this.map.removeLayer(this.temporaryHoverMarker),this.temporaryHoverMarker=null)},renderDensity:function(t){this.clearAllLayers(),this.selectedPropertyId=null,this.isPinClickPan=!1,r(".property-card").removeClass("property-card-highlighted");var e=this,i=this.map.getZoom();t.forEach(function(a){var o=e.getDensityColor(a.count,i),l=e.getDensitySize(a.count,i),p=L.divIcon({html:'
    ',className:"density-dot-container",iconSize:[l,l],iconAnchor:[l/2,l/2]}),d=L.marker([a.lat,a.lng],{icon:p});d.on("click",function(){e.map.setView([a.lat,a.lng],e.map.getZoom()+2)}),d.bindTooltip(a.count+" properties",{className:"density-tooltip"}),e.densityLayer.addLayer(d)})},getDensityThreshold:function(t){return Math.max(40,Math.round(600/Math.pow(1.4,t-3)))},getDensityColor:function(t,e){var i=this.getDensityThreshold(e),a=t/i;return a>=1.5?"rgba(180, 83, 9, 0.8)":a>=1?"rgba(217, 119, 6, 0.8)":a>=.6?"rgba(245, 158, 11, 0.8)":a>=.3?"rgba(234, 179, 8, 0.8)":a>=.15?"rgba(132, 204, 22, 0.8)":"rgba(34, 197, 94, 0.8)"},getDensitySize:function(t,e){var i=this.getDensityThreshold(e),a=t/i;return a>=1.5?11:a>=1?10:a>=.6?8:a>=.3?7:6},renderClusters:function(t){this.clearAllLayers(),this.selectedPropertyId=null,this.isPinClickPan=!1,r(".property-card").removeClass("property-card-highlighted");var e=this;t.forEach(function(i){var a="small";i.count>=100?a="large":i.count>=10&&(a="medium");var o=L.divIcon({html:"
    "+i.count+"
    ",className:"marker-cluster marker-cluster-"+a+" server-cluster",iconSize:L.point(40,40)}),l=L.marker([i.lat,i.lng],{icon:o});l.on("click",function(){e.map.setView([i.lat,i.lng],e.map.getZoom()+2)});var p="$"+e.formatNumber(i.min_price);i.max_price!==i.min_price&&(p+=" - $"+e.formatNumber(i.max_price)),l.bindTooltip(i.count+" properties
    "+p,{className:"cluster-tooltip"}),e.clusterLayer.addLayer(l)})},renderMarkers:function(t){var e=this.selectedPropertyId;this.clearAllLayers(),this.hoveredPropertyId=null;var i=this,a=[];t.forEach(function(o,l){if(o.lat&&o.lng){var p=o.id===e,d=p?"amber":"red",f=L.marker([o.lat,o.lng],{icon:i.createIcon(d),zIndexOffset:p?1e4:i.baseZIndex+l});f.propertyId=o.id,f.defaultZIndex=i.baseZIndex+l,i.markerData[o.id]={lat:o.lat,lng:o.lng,price:o.price,address:o.address},f.bindPopup('
    '+o.price+"
    "+o.address+'
    View Details
    '),f.on("click",function(P){i.onMarkerClick(o.id)}),a.push(f),i.markers[o.id]=f}}),a.length<=30?a.forEach(function(o){i.markerLayer.addLayer(o)}):this.markerCluster.addLayers(a),this.isPinClickPan=!1,e&&this.markers[e]?this.selectedPropertyId=e:(this.selectedPropertyId=null,r(".property-card").removeClass("property-card-highlighted"))},updateFilters:function(t){this.currentFilters=t||{},this.loadClusters()},resetToInitialPosition:function(){this.map&&this.map.setView(this.initialCenter,this.initialZoom)},formatNumber:function(t){return t.toString().replace(/\B(?=(\d{3})+(?!\d))/g,",")},createIcon:function(t){return t=t||"red",L.divIcon({className:"property-marker property-marker-"+t,html:'
    ',iconSize:[17,22],iconAnchor:[8,22],popupAnchor:[0,-22]})},onMarkerClick:function(t){var e=this;if(this.selectedPropertyId!==t){this.selectedPropertyId&&(this.setMarkerColor(this.selectedPropertyId,"red"),this.resetMarkerZIndex(this.selectedPropertyId),r("#property-"+this.selectedPropertyId).removeClass("property-card-highlighted"));var i=this.markerData[t];if(i){this.selectedPropertyId=t,this.setMarkerColor(t,"amber"),this.setMarkerZIndex(t,1e4);var a=r("#property-"+t);a.length?(a.addClass("property-card-highlighted"),this.isCardScroll=!0,r("html, body").animate({scrollTop:a.offset().top-120},300,function(){setTimeout(function(){e.isCardScroll=!1},100)})):(this.isPinClickPan=!0,this.map.panTo([i.lat,i.lng]))}}},flashCard:function(t){t.removeClass("property-card-highlighted"),setTimeout(function(){t.addClass("property-card-highlighted"),setTimeout(function(){t.removeClass("property-card-highlighted"),setTimeout(function(){t.addClass("property-card-highlighted")},150)},150)},50)},setMarkerColor:function(t,e){var i=this.markers[t];i&&i.setIcon(this.createIcon(e))},setMarkerZIndex:function(t,e){var i=this.markers[t];i&&i.setZIndexOffset(e)},resetMarkerZIndex:function(t){var e=this.markers[t];e&&e.setZIndexOffset(e.defaultZIndex)},bindCardHoverEvents:function(){var t=this;r(document).on("mouseenter",".property-card[data-property-id]",function(){var e=r(this),i=e.data("property-id");if(i!==t.selectedPropertyId)if(t.hoveredPropertyId=i,t.markers[i])t.setMarkerColor(i,"blue"),t.setMarkerZIndex(i,9e3);else{var a=e.data("lat"),o=e.data("lng");a&&o&&t.map&&(t.temporaryHoverMarker&&t.map.removeLayer(t.temporaryHoverMarker),t.temporaryHoverMarker=L.marker([a,o],{icon:t.createIcon("blue"),zIndexOffset:15e3}),t.temporaryHoverMarker.addTo(t.map))}}),r(document).on("mouseleave",".property-card[data-property-id]",function(){var e=r(this).data("property-id");e!==t.selectedPropertyId&&(t.hoveredPropertyId===e&&(t.hoveredPropertyId=null),t.temporaryHoverMarker&&(t.map.removeLayer(t.temporaryHoverMarker),t.temporaryHoverMarker=null),t.markers[e]&&(t.setMarkerColor(e,"red"),t.resetMarkerZIndex(e)))})}},h={$mainFilter:null,$stickyFilter:null,$mainForm:null,$stickyForm:null,$resetButton:null,$masthead:null,scrollTimeout:null,isVisible:!1,init:function(){window.innerWidth<1024||!r(".is-map-view").length||(this.$mainFilter=r("#property-filters"),this.$stickyFilter=r("#property-filters-sticky"),this.$mainForm=this.$mainFilter.find(".filters-form"),this.$stickyForm=this.$stickyFilter.find(".filters-form-sticky"),this.$resetButton=this.$mainFilter.find(".filter-item-button .btn"),this.$masthead=r("#masthead"),!(!this.$mainFilter.length||!this.$stickyFilter.length||!this.$resetButton.length)&&(this.setupScrollHandler(),this.bindEvents(),this.checkVisibility()))},setupScrollHandler:function(){var t=this;r(window).on("scroll.stickyFilters",function(){clearTimeout(t.scrollTimeout),t.scrollTimeout=setTimeout(function(){t.checkVisibility()},50)})},checkVisibility:function(){var t=this.$masthead.length?this.$masthead.outerHeight():0,e=t+10,i=this.$resetButton[0].getBoundingClientRect();i.bottom1)&&(this.pendingRestoreState=t))},restoreState:function(){var t=this.pendingRestoreState;if(t){this.pendingRestoreState=null;var e=this.getFormData();if(s.currentFilters={status:"Active",property_type:e.property_type||"",city:e.property_location||"",min_price:e.min_price||"",max_price:e.max_price||"",min_beds:e.beds||""},t.lat!==null&&t.lng!==null&&t.zoom!==null&&s.map){s.map.off("moveend zoomend"),s.map.setView([t.lat,t.lng],t.zoom);var i=s.map.getBounds(),a=s.map.getCenter();this.mapBounds=[i.getSouthWest().lat,i.getSouthWest().lng,i.getNorthEast().lat,i.getNorthEast().lng],this.mapCenter=[a.lat,a.lng],s.loadClusters(),setTimeout(function(){s.map.on("moveend zoomend",function(){s.loadClusters(),setTimeout(function(){c.updateUrlState()},400)})},100)}t.page>1?this.bulkLoadPages(t.page,t.scroll):t.scroll>0&&(window.scrollTo({top:t.scroll,behavior:"instant"}),r(window).trigger("scroll"))}},bulkLoadPages:function(t,e){var i=this,a=this.getFormData();u.isRestoring=!0;for(var o=[],l=1;l<=t+1;l++)o.push(l);var p={action:"homeproz_filter_properties",nonce:homeprozAjax.nonce,property_type:a.property_type,property_location:a.property_location,zip:a.zip,min_price:a.min_price,max_price:a.max_price,beds:a.beds,cards_only:"true"};this.mapBounds&&(p.bounds=this.mapBounds),this.mapCenter&&(p.center=this.mapCenter);var d=[],f=[];if(o.forEach(function(x){var b=r.extend({},p,{paged:x}),w=I.get(b);w&&w.success&&w.data&&w.data.html?d.push({page:x,html:w.data.html,max_pages:w.data.max_pages||1}):f.push(x)}),f.length===0){this.renderBulkResults(d,t,e);return}this.$results.html('
    ');var P=f.map(function(x){var b=r.extend({},p,{paged:x});return r.ajax({url:homeprozAjax.ajaxUrl,type:"POST",data:b}).then(function(w){var C={page:x,html:w.success?w.data.html:"",max_pages:w.success?w.data.max_pages:0};return w.success&&I.set(b,w),C})});r.when.apply(r,P).done(function(){var x=P.length===1?[arguments[0]]:Array.prototype.slice.call(arguments),b=d.concat(x);i.renderBulkResults(b,t,e)}).fail(function(){u.isRestoring=!1,i.filterProperties(1,!1)})},renderBulkResults:function(t,e,i){t.sort(function(l,p){return l.page-p.page});var a=t[0]?t[0].max_pages:1,o='

    Loading...

    ';o+='
    ',t.forEach(function(l){l.html&&l.page<=a&&(o+='
    ',o+=l.html,o+="
    ")}),o+="
    ",this.$results.html(o),u.currentPage=Math.min(e+1,a),u.maxPages=a,u.pages={},t.forEach(function(l){l.page<=a&&(u.pages[l.page]={state:"populated"})}),i>0&&window.scrollTo({top:i,behavior:"instant"}),u.isRestoring=!1,r(window).trigger("scroll"),typeof v<"u"&&v.process()},updateFromMap:function(t,e){s.isCardScroll||(this.mapBounds=t,this.mapCenter=e,this.isMapUpdate=!0,s.isPinClickPan||this.clearPinSelection(),this.$results.html('
    '),u.isEnabled&&y.reset(s.isPinClickPan),u.currentPage=1,this._scrollBlocked=!0,this.clearScrollFromUrl(),this.filterProperties(1,!1))},clearScrollFromUrl:function(){var t=window.location.hash.replace("#","");if(t){var e=t.split("&").filter(function(a){return!a.startsWith("scroll=")}),i=e.length?"#"+e.join("&"):"";history.replaceState(null,"",window.location.pathname+window.location.search+i)}},clearPinSelection:function(){s.selectedPropertyId&&(s.setMarkerColor(s.selectedPropertyId,"red"),s.resetMarkerZIndex(s.selectedPropertyId),r("#property-"+s.selectedPropertyId).removeClass("property-card-highlighted"),s.selectedPropertyId=null)},getPageFromHash:function(){var t=this.getStateFromHash();return t?t.page:1},filterProperties:function(t,e){e=e!==!1,t=t||1;var i=this,a=this.getFormData();this.$filters.addClass("is-loading"),this.isFirstLoad&&this.$results.html('
    ');var o={action:"homeproz_filter_properties",nonce:homeprozAjax.nonce,property_type:a.property_type,property_location:a.property_location,zip:a.zip,min_price:a.min_price,max_price:a.max_price,beds:a.beds,paged:t};this.mapBounds&&(o.bounds=this.mapBounds),this.mapCenter&&(o.center=this.mapCenter);var l=this.isMapUpdate;this.isMapUpdate=!1;var p=this.isResetTriggered;this.isResetTriggered=!1,n.queue("properties",function(d){return r.ajax({url:homeprozAjax.ajaxUrl,type:"POST",data:o})},function(d,f){d.success&&(i.$results.html(d.data.html),i.isFirstLoad=!1,p&&d.data.found_posts===0&&s.map&&s.resetToInitialPosition(),d.data.filters&&!l&&s.updateFilters(d.data.filters),typeof m<"u"&&m.calculate(),y.destroy(),setTimeout(function(){y.init()},100),e&&i.updateUrl(a,t),s.selectedPropertyId?setTimeout(function(){var P=r("#property-"+s.selectedPropertyId);P.length&&(window.scrollTo({top:P.offset().top-120,behavior:"instant"}),P.addClass("property-card-highlighted"))},150):t>1&&window.scrollTo({top:i.$filters.offset().top-100,behavior:"instant"}))},function(){i.$filters.removeClass("is-loading")},function(){i.$results.html('

    Error

    Something went wrong. Please try again.

    ')})},getFormData:function(){return{property_type:this.$form.find('[name="property_type"]').val()||"",property_location:this.$form.find('[name="property_location"]').val()||"",zip:this.$form.find('[name="zip"]').val()||"",min_price:this.$form.find('[name="min_price"]').val()||"",max_price:this.$form.find('[name="max_price"]').val()||"",beds:this.$form.find('[name="beds"]').val()||""}},getFormState:function(){return this.getFormData()},setFormFromState:function(t){for(var e in t)this.$form.find('[name="'+e+'"]').val(t[e])},updateUrl:function(t,e){var i=[];for(var a in t)t[a]&&i.push(a+"="+encodeURIComponent(t[a]));if(e>1&&i.push("page="+e),!this._scrollBlocked){var o=window.pageYOffset||document.documentElement.scrollTop;o>0&&i.push("scroll="+Math.round(o))}if(s.map){var l=s.map.getCenter(),p=s.map.getZoom();i.push("lat="+l.lat.toFixed(6)),i.push("lng="+l.lng.toFixed(6)),i.push("zoom="+p)}var d=homeprozAjax.archiveUrl+(i.length?"#"+i.join("&"):"");history.replaceState(null,"",d)},updateUrlState:function(){var t=this;clearTimeout(this._urlUpdateTimeout),this._urlUpdateTimeout=setTimeout(function(){var e=u.currentPage||1,i=t.getFormData();t.updateUrl(i,e)},300)},getStateFromHash:function(){var t=window.location.hash.replace("#","");if(!t)return null;var e={};return t.split("&").forEach(function(i){var a=i.split("=");a.length===2&&(e[a[0]]=decodeURIComponent(a[1]))}),{property_type:e.property_type||"",property_location:e.property_location||"",zip:e.zip||"",min_price:e.min_price||"",max_price:e.max_price||"",beds:e.beds||"",page:e.page?parseInt(e.page):1,scroll:e.scroll?parseInt(e.scroll):0,lat:e.lat?parseFloat(e.lat):null,lng:e.lng?parseFloat(e.lng):null,zoom:e.zoom?parseInt(e.zoom):null}},getPageFromUrl:function(t){var e=t.match(/#page=(\d+)/);if(e)return parseInt(e[1]);var i=t.match(/[?&]paged=(\d+)/);return i?parseInt(i[1]):1},resetFilters:function(){this.$form.find("select").val(""),this.$form.find('input[name="zip"]').val(""),h&&h.$stickyForm&&(h.$stickyForm.find("select").val(""),h.$stickyForm.find('input[name="zip"]').val("")),this.isResetTriggered=!0,this.onFilterChange()},onFilterChange:function(){var t=this.getFormData();if(s.map&&(s.currentFilters={status:"Active",property_type:t.property_type||"",city:t.property_location||"",min_price:t.min_price||"",max_price:t.max_price||"",min_beds:t.beds||""}),!s.map){this.filterProperties(1);return}r.ajax({url:homeprozAjax.ajaxUrl,type:"GET",data:{action:"homeproz_get_filter_bounds",property_type:t.property_type,city:t.property_location,min_price:t.min_price,max_price:t.max_price,min_beds:t.beds},success:function(e){if(e.success&&e.data){var i=e.data,a=s.map.getBounds(),o=L.latLngBounds([i.sw_lat,i.sw_lng],[i.ne_lat,i.ne_lng]),l=a.intersects(o);if(l)s.loadClusters();else{var p=(i.ne_lat-i.sw_lat)*.1,d=(i.ne_lng-i.sw_lng)*.1,f=L.latLngBounds([i.sw_lat-p,i.sw_lng-d],[i.ne_lat+p,i.ne_lng+d]);s.map.fitBounds(f)}}else s.loadClusters()},error:function(){s.loadClusters()}})}},g={breakpoint:1024,isMapView:!0,isAboveBreakpoint:!0,mapInitialized:!1,init:function(){var t=this;if(typeof homeprozMapData<"u"&&(this.isMapView=homeprozMapData.isMapView!==!1),this.isAboveBreakpoint=window.innerWidth>=this.breakpoint,this.isAboveBreakpoint&&this.isMapView&&typeof homeprozMapData<"u"){var e=c.getFormData(),i={status:"Active",property_type:e.property_type||"",city:e.property_location||"",min_price:e.min_price||"",max_price:e.max_price||"",min_beds:e.beds||""};s.init(i),this.mapInitialized=!0,c.pendingRestoreState&&c.restoreState()}var a;r(window).on("resize",function(){clearTimeout(a),a=setTimeout(function(){t.handleResize()},150)})},handleResize:function(){var t=this.isAboveBreakpoint;this.isAboveBreakpoint=window.innerWidth>=this.breakpoint;var e=r(".property-archive-main");if(t&&!this.isAboveBreakpoint&&u.isEnabled&&y.destroy(),!t&&this.isAboveBreakpoint){if(this.isMapView){if(e.removeClass("is-grid-view").addClass("is-map-view"),!this.mapInitialized&&typeof homeprozMapData<"u"){var i=c.getFormData(),a={status:"Active",property_type:i.property_type||"",city:i.property_location||"",min_price:i.min_price||"",max_price:i.max_price||"",min_beds:i.beds||""};s.init(a),this.mapInitialized=!0,c.pendingRestoreState&&c.restoreState()}else s.map&&setTimeout(function(){s.map.invalidateSize()},100);setTimeout(function(){y.init()},200)}else e.removeClass("is-map-view").addClass("is-grid-view");typeof m<"u"&&setTimeout(function(){m.calculate()},150)}},setMapView:function(t){this.isMapView=t}},m={cardWidth:400,cardGap:24,mapGap:32,mapRatio:.33,breakpoint:1024,containerPadding:24,init:function(){this.calculate();var t=this,e;r(window).on("resize",function(){clearTimeout(e),e=setTimeout(function(){t.calculate()},100)})},calculate:function(){if(window.innerWidth .container"),i=t.hasClass("is-map-view"),a=e.width();i?this.calculateMapLayout(a):this.calculateGridLayout(a)},calculateMapLayout:function(t){for(var e=5;e>=1;e--){var i=e*this.cardWidth+(e-1)*this.cardGap,a=(this.mapGap+i)/(1-this.mapRatio);if(a<=t){this.setProperties(a,e,".property-map-layout"),this.setProperties(a,e,".property-list-container");return}}var i=this.cardWidth,a=(this.mapGap+i)/(1-this.mapRatio);this.setProperties(Math.min(a,t),1,".property-map-layout"),this.setProperties(Math.min(a,t),1,".property-list-container")},calculateGridLayout:function(t){for(var e=6;e>=1;e--){var i=e*this.cardWidth+(e-1)*this.cardGap;if(i<=t){this.setProperties(i,e,".grid-view-container");return}}this.setProperties(this.cardWidth,1,".grid-view-container")},setProperties:function(t,e,i){var a=r(i);a.length&&(a.css("--layout-width",t+"px"),a.css("--card-columns",e))},clearProperties:function(){r(".property-map-layout, .grid-view-container, .property-list-container").css({"--layout-width":"","--card-columns":""})}},u={pages:{},totalPages:0,totalPosts:0,currentPage:1,pendingPage:null,isEnabled:!1,isRestoring:!1,cardsPerPage:12},y={$container:null,$grid:null,scrollTimeout:null,init:function(){if(window.innerWidth>=1024&&r(".is-map-view").length?this.$container=r(".property-list-container"):this.$container=r("#property-results"),this.$grid=this.$container.find(".properties-grid"),!(!this.$container.length||!this.$grid.length)){var t=this.$container.find(".properties-meta"),e=t.find(".properties-count strong").text().replace(/,/g,"");u.totalPosts=parseInt(e)||0,u.totalPages=Math.ceil(u.totalPosts/u.cardsPerPage),!(u.totalPages<=1)&&(u.pages={},u.pendingPage=null,this.wrapInitialCards(),this.bindScrollHandler(),u.isEnabled=!0,this.$container.addClass("infinite-scroll-enabled"),this.syncPages())}},wrapInitialCards:function(){var t=this.$grid.find(".property-card");if(t.length){var e=r('
    ');t.wrapAll(e),u.pages[1]={state:"populated"}}},bindScrollHandler:function(){var t=this;r(window).on("scroll.infiniteScroll",function(){clearTimeout(t.scrollTimeout),t.scrollTimeout=setTimeout(function(){t.syncPages(),c.updateUrlState()},100)}),r(window).on("wheel.infiniteScroll",function(){c._scrollBlocked=!1})},syncPages:function(){if(!(!this.$grid||!u.isEnabled)&&!u.isRestoring){var t=u.totalPages,e=this.calculateCurrentPage();e>t-2&&(e=t-2),e<1&&(e=1),u.currentPage=e;var i=[e-2,e-1,e,e+1,e+2];i=i.filter(function(o){return o>=1&&o<=t});var a=this.getReferenceCardDimensions();this.ensurePagesExist(i),this.loadFirstUnloaded(i),this.syncPageStates(i,a)}},calculateCurrentPage:function(){var t=window.scrollY||window.pageYOffset,e=t+window.innerHeight,i=this.$grid.find(".infinite-scroll-page");if(!i.length)return 1;var a=1,o=1/0;return i.each(function(){var l=r(this),p=parseInt(l.data("page")),d=l.find(".property-card").first();if(d.length){var f=d[0].getBoundingClientRect(),P=f.top+t;if(P<=e){var x=e-P;x');e.insertPageInOrder(o,i),u.pages[i]||(u.pages[i]={state:"empty"})}})},insertPageInOrder:function(t,e){var i=this.$grid.find(".infinite-scroll-page"),a=!1;i.each(function(){var o=parseInt(r(this).data("page"));if(eo&&window.scrollTo({top:o,behavior:"instant"})}}},destroy:function(){u.isEnabled&&(r(window).off("scroll.infiniteScroll"),clearTimeout(this.scrollTimeout),this.$container&&this.$container.removeClass("infinite-scroll-enabled"),this.$grid&&(this.$grid.find('.infinite-scroll-page[data-state="populated"]').children().unwrap(),this.$grid.find('.infinite-scroll-page[data-state="placeholder"]').remove()),u.pages={},u.pendingPage=null,u.isEnabled=!1)}},v={_isRunning:!1,_activeLoads:0,MAX_PARALLEL:2,LOAD_DISTANCE:1e3,init:function(){this.process(),this.bindScrollEvent()},bindScrollEvent:function(){var t=this,e;r(window).on("scroll",function(){clearTimeout(e),e=setTimeout(function(){t.process()},50)})},process:function(){this._isRunning||(this._isRunning=!0,this._activeLoads=0,this._processNext())},_getNextElement:function(){var t=r(".property-card-image[data-bg]");if(!t.length)return null;var e=window.pageYOffset||document.documentElement.scrollTop,i=e,a=e+window.innerHeight,o=this.LOAD_DISTANCE,l=[],p=[];return t.each(function(){var d=this.getBoundingClientRect(),f=d.top+e,P=f+d.height;if(P>=i&&f<=a)l.push({el:this,position:f});else{var x;f>a?x=f-a:x=i-P,x<=o&&p.push({el:this,distance:x})}}),l.sort(function(d,f){return d.position-f.position}),p.sort(function(d,f){return d.distance-f.distance}),l.length?l[0].el:p.length?p[0].el:null},_processNext:function(){for(var t=this;this._activeLoads1&&this.startAutoplay())}},calculateThumbnailsPerPage:function(){r(window).width()<=640?this.thumbnailsPerPage=4:this.thumbnailsPerPage=5},bindEvents:function(){var n=this;this.$thumbnails.on("click",function(s){s.stopPropagation();var h=parseInt(r(this).data("index"));n.stopAutoplay(),n.setMainImage(h,!1)}),this.$playbackBtn.on("click",function(s){s.stopPropagation(),s.preventDefault(),n.isPlaying?n.stopAutoplay():n.startAutoplay()}),this.$prevBtn.on("click",function(){n.stopAutoplay(),n.prevThumbnailPage()}),this.$nextBtn.on("click",function(){n.stopAutoplay(),n.nextThumbnailPage()}),this.$gallery.find("[data-lightbox-trigger]").on("click",function(s){if(n.isSwiping){n.isSwiping=!1;return}n.stopAutoplay(),n.openLightbox(n.currentIndex)}),this.$lightbox.find(".lightbox-close, .lightbox-overlay").on("click",function(){n.closeLightbox()}),this.$lightbox.find(".lightbox-prev").on("click",function(){n.slideLightboxImage("prev")}),this.$lightbox.find(".lightbox-next").on("click",function(){n.slideLightboxImage("next")}),r(document).on("keydown",function(s){if(n.$lightbox.is('[aria-hidden="false"]'))switch(s.key){case"Escape":n.closeLightbox();break;case"ArrowLeft":n.slideLightboxImage("prev");break;case"ArrowRight":n.slideLightboxImage("next");break}}),r(window).on("resize",function(){n.calculateThumbnailsPerPage(),n.updateThumbnailNavigation()})},bindSwipeEvents:function(){var n=this;this.$mainImageContainer[0].addEventListener("touchstart",function(s){n.handleSwipeStart(s)},{passive:!0}),this.$mainImageContainer[0].addEventListener("touchend",function(s){n.handleMainGallerySwipeEnd(s)},{passive:!0}),this.$lightboxImageContainer[0].addEventListener("touchstart",function(s){n.handleSwipeStart(s)},{passive:!0}),this.$lightboxImageContainer[0].addEventListener("touchend",function(s){n.handleLightboxSwipeEnd(s)},{passive:!0})},handleSwipeStart:function(n){n.touches.length===1&&(this.swipeStartX=n.touches[0].clientX,this.swipeStartY=n.touches[0].clientY)},handleMainGallerySwipeEnd:function(n){if(n.changedTouches.length===1){var s=n.changedTouches[0].clientX-this.swipeStartX,h=n.changedTouches[0].clientY-this.swipeStartY;Math.abs(s)>Math.abs(h)&&Math.abs(s)>this.swipeThreshold&&(this.isSwiping=!0,this.stopAutoplay(),s>0?this.slideMainImage("prev"):this.slideMainImage("next"))}},handleLightboxSwipeEnd:function(n){if(n.changedTouches.length===1){var s=n.changedTouches[0].clientX-this.swipeStartX,h=n.changedTouches[0].clientY-this.swipeStartY;Math.abs(s)>Math.abs(h)&&Math.abs(s)>this.swipeThreshold&&(s>0?this.slideLightboxImage("prev"):this.slideLightboxImage("next"))}},startAutoplay:function(){var n=this;this.images.length<=1||(this.isPlaying=!0,this.$playbackBtn.addClass("is-playing"),this.$playbackBtn.attr("aria-label","Pause slideshow"),this.autoplayInterval=setInterval(function(){n.advanceImage()},this.autoplayDelay))},stopAutoplay:function(){this.isPlaying=!1,this.$playbackBtn.removeClass("is-playing"),this.$playbackBtn.attr("aria-label","Play slideshow"),this.autoplayInterval&&(clearInterval(this.autoplayInterval),this.autoplayInterval=null)},advanceImage:function(){if(!this.isTransitioning){var n=this.currentIndex+1;n>=this.images.length&&(n=0),this.setMainImage(n,!0)}},slideMainImage:function(n){var s=this;if(!(this.isTransitioning||this.images.length<=1)){var h;n==="prev"?(h=this.currentIndex-1,h<0&&(h=this.images.length-1)):(h=this.currentIndex+1,h>=this.images.length&&(h=0)),this.isTransitioning=!0;var c=this.images[h],g=n==="next"?"100%":"-100%",m=n==="next"?"-100%":"100%",u=r('');u.attr("src",c.url),u.attr("alt",c.alt||"Property photo"),u.css({position:"absolute",top:0,left:0,width:"100%",height:"100%","object-fit":"cover",transform:"translateX("+g+")","z-index":2,"border-radius":"0.5rem"}),this.$mainImageContainer.css({position:"relative",overflow:"hidden"}),this.$mainImageContainer.append(u),this.$mainImage.css({transition:"transform "+this.slideDuration+"ms ease-out"}),u.css({transition:"transform "+this.slideDuration+"ms ease-out"}),u[0].offsetHeight,this.$mainImage.css("transform","translateX("+m+")"),u.css("transform","translateX(0)"),setTimeout(function(){s.$mainImage.attr("src",c.url),s.$mainImage.attr("alt",c.alt||"Property photo"),s.$mainImage.css({transition:"",transform:""}),u.remove(),s.isTransitioning=!1},this.slideDuration),this.currentIndex=h,this.$thumbnails.removeClass("is-active"),this.$thumbnails.filter('[data-index="'+h+'"]').addClass("is-active"),this.scrollToThumbnail(h)}},setMainImage:function(n,s){var h=this;if(!(n<0||n>=this.images.length)&&!this.isTransitioning){var c=this.images[n];if(s){this.isTransitioning=!0;var g=r('');g.attr("src",c.url),g.attr("alt",c.alt||"Property photo"),g.css({position:"absolute",top:0,left:0,width:"100%",height:"100%","object-fit":"cover",opacity:0,transform:"scale(1.02)",transition:"opacity "+this.fadeDuration+"ms ease-in-out, transform "+this.fadeDuration+"ms ease-in-out","z-index":2,"border-radius":"0.5rem"}),this.$mainImageContainer.css("position","relative"),this.$mainImageContainer.append(g),g[0].offsetHeight,g.css({opacity:1,transform:"scale(1)"}),setTimeout(function(){h.$mainImage.attr("src",c.url),h.$mainImage.attr("alt",c.alt||"Property photo"),g.remove(),h.isTransitioning=!1},this.fadeDuration)}else this.$mainImage.attr("src",c.url),this.$mainImage.attr("alt",c.alt||"Property photo");this.currentIndex=n,this.$thumbnails.removeClass("is-active"),this.$thumbnails.filter('[data-index="'+n+'"]').addClass("is-active"),this.scrollToThumbnail(n)}},scrollToThumbnail:function(n){var s=Math.floor(n/this.thumbnailsPerPage);s!==this.thumbnailPage&&(this.thumbnailPage=s,this.scrollThumbnails())},scrollThumbnails:function(){var n=this.$gallery.find(".gallery-thumbnails"),s=this.$thumbnails.first().outerWidth(!0),h=this.thumbnailPage*this.thumbnailsPerPage*s;n.css("transform","translateX(-"+h+"px)"),this.updateThumbnailNavigation()},updateThumbnailNavigation:function(){var n=Math.ceil(this.images.length/this.thumbnailsPerPage);this.$prevBtn.prop("disabled",this.thumbnailPage===0),this.$nextBtn.prop("disabled",this.thumbnailPage>=n-1),n<=1?(this.$prevBtn.hide(),this.$nextBtn.hide()):(this.$prevBtn.show(),this.$nextBtn.show())},prevThumbnailPage:function(){this.thumbnailPage>0&&(this.thumbnailPage--,this.scrollThumbnails(),this.preloadPrevThumbnailPage())},nextThumbnailPage:function(){var n=Math.ceil(this.images.length/this.thumbnailsPerPage);this.thumbnailPage=this.images.length&&(h=0)),this.isTransitioning=!0;var c=this.images[h],g=n==="next"?"100%":"-100%",m=n==="next"?"-100%":"100%",u=r('');u.attr("src",c.url),u.attr("alt",c.alt||"Property photo"),u.css({position:"absolute","max-width":"100%","max-height":"calc(100vh - 8rem)","object-fit":"contain",transform:"translateX("+g+")",left:"50%",top:"50%","margin-left":"-45vw","margin-top":"calc(-50vh + 4rem)"}),this.$lightboxImageContainer.css({position:"relative",overflow:"hidden"}),this.$lightboxImageContainer.append(u),this.$lightboxImage.css({transition:"transform "+this.slideDuration+"ms ease-out"}),u.css({transition:"transform "+this.slideDuration+"ms ease-out"}),u[0].offsetHeight,this.$lightboxImage.css("transform","translateX("+m+")"),u.css("transform","translateX(0)"),setTimeout(function(){s.$lightboxImage.attr("src",c.url),s.$lightboxImage.attr("alt",c.alt||"Property photo"),s.$lightboxImage.css({transition:"",transform:""}),u.remove(),s.isTransitioning=!1,s.$lightboxCounter.text(h+1)},this.slideDuration),this.currentIndex=h}},prevImage:function(){this.slideLightboxImage("prev")},nextImage:function(){this.slideLightboxImage("next")},updateLightboxImage:function(){var n=this.images[this.currentIndex];this.$lightboxImage.attr("src",n.url),this.$lightboxImage.attr("alt",n.alt||"Property photo"),this.$lightboxCounter.text(this.currentIndex+1)},setupThumbnailLoading:function(){this.$thumbnails.each(function(){var n=r(this),s=n.find("img");n.addClass("is-loading"),n.find(".thumbnail-spinner").length||n.append('
    '),s[0].complete?n.removeClass("is-loading"):(s.on("load",function(){n.removeClass("is-loading")}),s.on("error",function(){n.removeClass("is-loading")}))})},preloadThumbnailPages:function(n,s){for(var h=this,c=n*this.thumbnailsPerPage,g=Math.min((n+s)*this.thumbnailsPerPage,this.images.length),m=c;m=0&&this.preloadThumbnailPages(n,1)}};r(function(){I.init()})})(jQuery);(function(r){if(!r(".mortgage-calculator-main").length)return;let I=!1;r.fn.currencyInput=function(s=!0){return this.data("ci_show_symbol",s),I||(I=!0,r.fn._CIOriginalVal=r.fn.val,r.fn.val=function(c){if(r(this).data("_currencyInput"))if(arguments.length===0){var g=r(this)._CIOriginalVal();if(g=="")return"";var m=parseInt(g.replace(/[^0-9]/g,""));return m}else{if(c=String(c).replace(/[^0-9]/g,""),c!=""){var u=parseInt(c).toLocaleString("en-US",{style:"currency",currency:"USD",minimumFractionDigits:0,maximumFractionDigits:0});return r(this).data("ci_show_symbol")||(u=u.replace("$","")),r(this)._CIOriginalVal(u)}return r(this)._CIOriginalVal(c)}else if(r(this).data("_percentInput"))if(arguments.length===0){var g=r(this)._CIOriginalVal();if(g=="")return"";var m=parseFloat(g.replace(/[^0-9.]/g,""));return isNaN(m)?"":m}else{c=String(c).replace(/[^0-9.]/g,"");var y=c.split(".");return y.length>2&&(c=y[0]+"."+y.slice(1).join("")),r(this)._CIOriginalVal(c)}else return arguments.length===0?r(this)._CIOriginalVal():r(this)._CIOriginalVal(c)}),this.data("_currencyInput")?this:(this.data("_currencyInput",!0),this.on("focus",function(){r(this).select()}),this.on("input",function(c){var g=this.selectionStart,m=r(this)._CIOriginalVal(),u=m.length;r(this).val(m);var y=r(this)._CIOriginalVal().length;y>u?g+=y-u:y2&&(m=u[0]+"."+u.slice(1).join("")),r(this)._CIOriginalVal(m);var y=m.length;y0){var c=h/s*100;this.$downPaymentPercent._CIOriginalVal(c.toFixed(1))}},syncDownPaymentFromPercent:function(){var s=this.$homePrice.val(),h=this.$downPaymentPercent.val();if(s&&s>0&&h!==""&&h>=0){var c=Math.round(s*h/100);this.$downPayment.val(c)}},calculate:function(){var s=this.$homePrice.val()||0,h=this.$downPayment.val()||0,c=parseInt(this.$loanTerm.val(),10),g=this.$interestRate.val()||0,m=s-h;m<0&&(m=0);var u=g/100/12,y=c*12,v=0,t=0;if(m>0&&u>0&&y>0){var e=Math.pow(1+u,y);v=m*(u*e)/(e-1),t=v*y-m}else m>0&&u===0&&(v=m/y,t=0);this.$monthlyPayment.text(this.formatCurrencyDisplay(v)),this.$principalInterest.text(this.formatCurrencyDisplay(v)),this.$loanAmount.text(this.formatCurrencyDisplay(m)),this.$totalInterest.text(this.formatCurrencyDisplay(t))}};r(document).ready(function(){n.init()})})(jQuery);(function(r){r(function(){})})(jQuery); +(function(r){var x=r(".menu-toggle"),n=r(".mobile-navigation");x.length&&(x.on("click",function(){var s=r(this).attr("aria-expanded")==="true";r(this).attr("aria-expanded",!s),n.toggleClass("is-open"),s?r("body").removeClass("mobile-menu-open"):r("body").addClass("mobile-menu-open")}),r(document).on("keydown",function(s){s.key==="Escape"&&n.hasClass("is-open")&&(x.attr("aria-expanded","false"),n.removeClass("is-open"),r("body").removeClass("mobile-menu-open"))}),r(document).on("click",function(s){n.hasClass("is-open")&&!r(s.target).closest(".mobile-navigation").length&&!r(s.target).closest(".menu-toggle").length&&(x.attr("aria-expanded","false"),n.removeClass("is-open"),r("body").removeClass("mobile-menu-open"))}))})(jQuery);(function(r){var x=6e3,n=1450,s=1e3,l=[],h=0,b=null,y=!1,c=!1,f=null;function m(){if(r(".Home_Page").length&&(f=r(".hero-split-image"),!!f.length)){var p=f.data("gallery-images");!p||!p.length||(l=p,t(),r(window).on("resize",u(t,150)))}}function t(){var p=r(window).width();p>=n?y||e():y&&i()}function e(){y=!0,c||(a(),c=!0),b=setInterval(o,x)}function i(){y=!1,b&&(clearInterval(b),b=null)}function a(){r.each(l,function(p,d){var g=new Image;g.src=d})}function o(){h=(h+1)%l.length;var p=l[h],d=r('
    ');d.css({position:"absolute",top:0,left:0,right:0,bottom:0,"background-image":"url("+p+")","background-size":"cover","background-position":"center center","background-repeat":"no-repeat",opacity:0,transform:"scale(1.02)",transition:"opacity "+s+"ms ease-in-out, transform "+s+"ms ease-in-out","z-index":1}),f.css("position","relative"),f.append(d),d[0].offsetHeight,d.css({opacity:1,transform:"scale(1)"}),setTimeout(function(){f.css("background-image","url("+p+")"),d.remove()},s)}function u(p,d){var g;return function(){var P=this,v=arguments;clearTimeout(g),g=setTimeout(function(){p.apply(P,v)},d)}}r(document).ready(m)})(jQuery);(function(r){var x=2,n=null,s=!1;function l(){var f=r(".hero-location-search");f.length&&(y(),f.each(function(){h(r(this))}))}function h(f){var m=f.find(".hero-location-input"),t=f.find('input[name="city"]'),e=f.find('input[name="zip"]'),i=f.find(".hero-geolocation-btn"),a=r('');m.after(a),b(m,a);var o=null;function u(v){if(!n||v.length=x){var I=v,w=o.label.substring(I.length),C=''+c(I)+''+c(w)+"";a.html(C).show()}else a.empty().hide(),o=null}function d(){return o?(m.val(o.label),o.type==="city"?(t.val(o.label),e.val("")):(e.val(o.value),t.val("")),a.empty().hide(),o=null,!0):!1}function g(){var v=m.val().trim();if(t.val()||e.val())return!0;var I=P(v);if(I)return m.val(I.label),I.type==="city"?(t.val(I.label),e.val("")):(e.val(I.value),t.val("")),!0;if(o)return m.val(o.label),o.type==="city"?(t.val(o.label),e.val("")):(e.val(o.value),t.val("")),!0;var w=u(v);return w?(m.val(w.label),w.type==="city"?(t.val(w.label),e.val("")):(e.val(w.value),t.val("")),!0):!1}function P(v){if(!n||!v)return null;for(var I=v.toLowerCase(),w=0;w0;l--){var h=Math.floor(Math.random()*(l+1)),b=s[l];s[l]=s[h],s[h]=b}return s},renderListings:function(){if(!this.listings||this.listings.length===0){this.grid.hide(),this.emptyMessage.show();return}for(var n=[],s=[],l=0;l',n.bedrooms&&(h+='
  • '+n.bedrooms+" "+s+"
  • "),n.bathrooms&&(h+='
  • '+n.bathrooms+" "+l+"
  • "),n.sqft&&(h+='
  • '+n.sqft.toLocaleString()+" sqft
  • "),h+=""),'
    Active
    '+this.escapeHtml(n.price_formatted)+'

    '+this.escapeHtml(n.address)+"

    "+h+'View Details
    '},escapeHtml:function(n){if(!n)return"";var s=document.createElement("div");return s.textContent=n,s.innerHTML}};r(document).ready(function(){x.init()})}})(jQuery);(function(r){var x={PREFIX:"HOMEPROZ_AJAX_",EXPIRY_MS:3e5,init:function(){this.cleanExpired()},cleanExpired:function(){try{for(var t=Date.now(),e=[],i=0;ithis.EXPIRY_MS&&e.push(a)}catch{e.push(a)}}e.forEach(function(u){sessionStorage.removeItem(u)})}catch{}},normalizeData:function(t){var e={};for(var i in t)if(i!=="nonce"){var a=t[i];Array.isArray(a)?e[i]=a.map(function(o){return typeof o=="number"?Math.round(o*1e4)/1e4:o}):e[i]=a}return e},getKey:function(t){for(var e=this.normalizeData(t),i=JSON.stringify(e),a=0,o=0;othis.EXPIRY_MS?(sessionStorage.removeItem(e),null):a.data}catch{return null}},set:function(t,e){try{var i=this.getKey(t),a={time:Date.now(),data:e};sessionStorage.setItem(i,JSON.stringify(a))}catch{}}};x.init();var n={pending:{clusters:null,properties:null},timeouts:{clusters:null,properties:null},requestIds:{clusters:0,properties:0},debounceDelay:200,queue:function(t,e,i,a,o){var u=this;this.timeouts[t]&&(clearTimeout(this.timeouts[t]),this.timeouts[t]=null),this.pending[t]&&(this.pending[t].abort(),this.pending[t]=null),this.requestIds[t]++;var p=this.requestIds[t];this.timeouts[t]=setTimeout(function(){u.timeouts[t]=null;var d=e(p);d&&d.then&&(u.pending[t]=d,d.done(function(g){p===u.requestIds[t]&&i(g,p)}),d.fail(function(g,P,v){o&&p===u.requestIds[t]&&P!=="abort"&&o(g,P,v)}),d.always(function(){u.pending[t]===d&&(u.pending[t]=null),a&&p===u.requestIds[t]&&a()}))},this.debounceDelay)},cancel:function(t){var e=t?[t]:["clusters","properties"],i=this;e.forEach(function(a){i.timeouts[a]&&(clearTimeout(i.timeouts[a]),i.timeouts[a]=null),i.pending[a]&&(i.pending[a].abort(),i.pending[a]=null)})},isLoading:function(t){return!!(this.pending[t]||this.timeouts[t])}},s={map:null,markers:{},markerData:{},densityLayer:null,clusterLayer:null,markerCluster:null,markerLayer:null,selectedPropertyId:null,isPinClickPan:!1,hoveredPropertyId:null,temporaryHoverMarker:null,baseZIndex:400,currentFilters:{},currentMode:null,initialCenter:[45,-93.5],initialZoom:7,init:function(t){var e=r("#property-map");if(!(!e.length||typeof L>"u")){this.currentFilters=t||{},this.map=L.map("property-map").setView([45,-93.5],7),L.tileLayer("https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png",{attribution:'© OpenStreetMap'}).addTo(this.map),this.densityLayer=L.layerGroup().addTo(this.map),this.clusterLayer=L.layerGroup().addTo(this.map),this.markerLayer=L.layerGroup().addTo(this.map),this.markerCluster=L.markerClusterGroup({maxClusterRadius:50,spiderfyOnMaxZoom:!0,showCoverageOnHover:!1,zoomToBoundsOnClick:!0,disableClusteringAtZoom:18,chunkedLoading:!0,chunkInterval:200,chunkDelay:50,iconCreateFunction:function(a){var o=a.getChildCount(),u="small";return o>=100?u="large":o>=10&&(u="medium"),L.divIcon({html:"
    "+o+"
    ",className:"marker-cluster marker-cluster-"+u,iconSize:L.point(40,40)})}}),this.map.addLayer(this.markerCluster);var i=this;this.map.on("moveend zoomend",function(){i.loadClusters(),setTimeout(function(){h.updateUrlState()},400)}),this.bindCardHoverEvents(),this.loadClusters()}},loadClusters:function(){if(this.map){var t=this,e=this.map.getBounds(),i=this.map.getCenter(),a=this.map.getZoom(),o=[e.getSouthWest().lat,e.getSouthWest().lng,e.getNorthEast().lat,e.getNorthEast().lng],u=[i.lat,i.lng],p={action:"mls_get_clusters",zoom:a,bounds:o,status:this.currentFilters.status||"Active",property_type:this.currentFilters.property_type||"",city:this.currentFilters.city||"",min_price:this.currentFilters.min_price||"",max_price:this.currentFilters.max_price||"",min_beds:this.currentFilters.min_beds||""};h.updateFromMap(o,u);var d=x.get(p);if(d&&d.success){var g=d.data;switch(this.currentMode=g.type,g.type){case"density":this.renderDensity(g.dots);break;case"clusters":this.renderClusters(g.clusters);break;case"markers":this.renderMarkers(g.markers);break}return}n.queue("clusters",function(P){return r.ajax({url:homeprozMapData.clusterEndpoint,type:"GET",data:p})},function(P,v){if(P.success){x.set(p,P);var I=P.data;switch(t.currentMode=I.type,I.type){case"density":t.renderDensity(I.dots);break;case"clusters":t.renderClusters(I.clusters);break;case"markers":t.renderMarkers(I.markers);break}}})}},clearAllLayers:function(){this.densityLayer.clearLayers(),this.clusterLayer.clearLayers(),this.markerCluster.clearLayers(),this.markerLayer.clearLayers(),this.markers={},this.temporaryHoverMarker&&(this.map.removeLayer(this.temporaryHoverMarker),this.temporaryHoverMarker=null)},renderDensity:function(t){this.clearAllLayers(),this.selectedPropertyId=null,this.isPinClickPan=!1,r(".property-card").removeClass("property-card-highlighted");var e=this,i=this.map.getZoom();t.forEach(function(a){var o=e.getDensityColor(a.count,i),u=e.getDensitySize(a.count,i),p=L.divIcon({html:'
    ',className:"density-dot-container",iconSize:[u,u],iconAnchor:[u/2,u/2]}),d=L.marker([a.lat,a.lng],{icon:p});d.on("click",function(){e.map.setView([a.lat,a.lng],e.map.getZoom()+2)}),d.bindTooltip(a.count+" properties",{className:"density-tooltip"}),e.densityLayer.addLayer(d)})},getDensityThreshold:function(t){return Math.max(40,Math.round(600/Math.pow(1.4,t-3)))},getDensityColor:function(t,e){var i=this.getDensityThreshold(e),a=t/i;return a>=1.5?"rgba(180, 83, 9, 0.8)":a>=1?"rgba(217, 119, 6, 0.8)":a>=.6?"rgba(245, 158, 11, 0.8)":a>=.3?"rgba(234, 179, 8, 0.8)":a>=.15?"rgba(132, 204, 22, 0.8)":"rgba(34, 197, 94, 0.8)"},getDensitySize:function(t,e){var i=this.getDensityThreshold(e),a=t/i;return a>=1.5?11:a>=1?10:a>=.6?8:a>=.3?7:6},renderClusters:function(t){this.clearAllLayers(),this.selectedPropertyId=null,this.isPinClickPan=!1,r(".property-card").removeClass("property-card-highlighted");var e=this;t.forEach(function(i){var a="small";i.count>=100?a="large":i.count>=10&&(a="medium");var o=L.divIcon({html:"
    "+i.count+"
    ",className:"marker-cluster marker-cluster-"+a+" server-cluster",iconSize:L.point(40,40)}),u=L.marker([i.lat,i.lng],{icon:o});u.on("click",function(){e.map.setView([i.lat,i.lng],e.map.getZoom()+2)});var p="$"+e.formatNumber(i.min_price);i.max_price!==i.min_price&&(p+=" - $"+e.formatNumber(i.max_price)),u.bindTooltip(i.count+" properties
    "+p,{className:"cluster-tooltip"}),e.clusterLayer.addLayer(u)})},renderMarkers:function(t){var e=this.selectedPropertyId;this.clearAllLayers(),this.hoveredPropertyId=null;var i=this,a=[];t.forEach(function(o,u){if(o.lat&&o.lng){var p=o.id===e,d=p?"amber":"red",g=L.marker([o.lat,o.lng],{icon:i.createIcon(d),zIndexOffset:p?1e4:i.baseZIndex+u});g.propertyId=o.id,g.defaultZIndex=i.baseZIndex+u,i.markerData[o.id]={lat:o.lat,lng:o.lng,price:o.price,address:o.address},g.bindPopup('
    '+o.price+"
    "+o.address+'
    View Details
    '),g.on("click",function(P){i.onMarkerClick(o.id)}),a.push(g),i.markers[o.id]=g}}),a.length<=30?a.forEach(function(o){i.markerLayer.addLayer(o)}):this.markerCluster.addLayers(a),this.isPinClickPan=!1,e&&this.markers[e]?this.selectedPropertyId=e:(this.selectedPropertyId=null,r(".property-card").removeClass("property-card-highlighted"))},updateFilters:function(t){this.currentFilters=t||{},this.loadClusters()},resetToInitialPosition:function(){this.map&&this.map.setView(this.initialCenter,this.initialZoom)},formatNumber:function(t){return t.toString().replace(/\B(?=(\d{3})+(?!\d))/g,",")},createIcon:function(t){return t=t||"red",L.divIcon({className:"property-marker property-marker-"+t,html:'
    ',iconSize:[17,22],iconAnchor:[8,22],popupAnchor:[0,-22]})},onMarkerClick:function(t){var e=this;if(this.selectedPropertyId!==t){this.selectedPropertyId&&(this.setMarkerColor(this.selectedPropertyId,"red"),this.resetMarkerZIndex(this.selectedPropertyId),r("#property-"+this.selectedPropertyId).removeClass("property-card-highlighted"));var i=this.markerData[t];if(i){this.selectedPropertyId=t,this.setMarkerColor(t,"amber"),this.setMarkerZIndex(t,1e4);var a=r("#property-"+t);a.length?(a.addClass("property-card-highlighted"),this.isCardScroll=!0,r("html, body").animate({scrollTop:a.offset().top-120},300,function(){setTimeout(function(){e.isCardScroll=!1},100)})):(this.isPinClickPan=!0,this.map.panTo([i.lat,i.lng]))}}},flashCard:function(t){t.removeClass("property-card-highlighted"),setTimeout(function(){t.addClass("property-card-highlighted"),setTimeout(function(){t.removeClass("property-card-highlighted"),setTimeout(function(){t.addClass("property-card-highlighted")},150)},150)},50)},setMarkerColor:function(t,e){var i=this.markers[t];i&&i.setIcon(this.createIcon(e))},setMarkerZIndex:function(t,e){var i=this.markers[t];i&&i.setZIndexOffset(e)},resetMarkerZIndex:function(t){var e=this.markers[t];e&&e.setZIndexOffset(e.defaultZIndex)},bindCardHoverEvents:function(){var t=this;r(document).on("mouseenter",".property-card[data-property-id]",function(){var e=r(this),i=e.data("property-id");if(i!==t.selectedPropertyId){t.hoveredPropertyId=i;var a=t.markers[i],o=!1;if(a){var u=a.getLatLng(),p=t.map.getBounds().contains(u),d=!1;if(t.markerCluster&&t.markerCluster.hasLayer(a)){var g=t.markerCluster.getVisibleParent(a);d=g&&g!==a}!d&&p?(t.setMarkerColor(i,"blue"),t.setMarkerZIndex(i,9e3)):o=!0}else o=!0;if(o){var P=e.data("lat"),v=e.data("lng");P&&v&&t.map&&(t.temporaryHoverMarker&&t.map.removeLayer(t.temporaryHoverMarker),t.temporaryHoverMarker=L.marker([P,v],{icon:t.createIcon("blue"),zIndexOffset:15e3}),t.temporaryHoverMarker.addTo(t.map))}}}),r(document).on("mouseleave",".property-card[data-property-id]",function(){var e=r(this).data("property-id");e!==t.selectedPropertyId&&(t.hoveredPropertyId===e&&(t.hoveredPropertyId=null),t.temporaryHoverMarker&&(t.map.removeLayer(t.temporaryHoverMarker),t.temporaryHoverMarker=null),t.markers[e]&&(t.setMarkerColor(e,"red"),t.resetMarkerZIndex(e)))})}},l={$mainFilter:null,$stickyFilter:null,$mainForm:null,$stickyForm:null,$resetButton:null,$masthead:null,scrollTimeout:null,isVisible:!1,init:function(){window.innerWidth<1024||!r(".is-map-view").length||(this.$mainFilter=r("#property-filters"),this.$stickyFilter=r("#property-filters-sticky"),this.$mainForm=this.$mainFilter.find(".filters-form"),this.$stickyForm=this.$stickyFilter.find(".filters-form-sticky"),this.$resetButton=this.$mainFilter.find(".filter-item-button .btn"),this.$masthead=r("#masthead"),!(!this.$mainFilter.length||!this.$stickyFilter.length||!this.$resetButton.length)&&(this.setupScrollHandler(),this.bindEvents(),this.checkVisibility()))},setupScrollHandler:function(){var t=this;r(window).on("scroll.stickyFilters",function(){clearTimeout(t.scrollTimeout),t.scrollTimeout=setTimeout(function(){t.checkVisibility()},50)})},checkVisibility:function(){var t=this.$masthead.length?this.$masthead.outerHeight():0,e=t+10,i=this.$resetButton[0].getBoundingClientRect();i.bottom1)&&(this.pendingRestoreState=t))},restoreState:function(){var t=this.pendingRestoreState;if(t){this.pendingRestoreState=null;var e=this.getFormData();if(s.currentFilters={status:"Active",property_type:e.property_type||"",city:e.city||"",min_price:e.min_price||"",max_price:e.max_price||"",min_beds:e.beds||""},t.lat!==null&&t.lng!==null&&t.zoom!==null&&s.map){s.map.off("moveend zoomend"),s.map.setView([t.lat,t.lng],t.zoom);var i=s.map.getBounds(),a=s.map.getCenter();this.mapBounds=[i.getSouthWest().lat,i.getSouthWest().lng,i.getNorthEast().lat,i.getNorthEast().lng],this.mapCenter=[a.lat,a.lng],s.loadClusters(),setTimeout(function(){s.map.on("moveend zoomend",function(){s.loadClusters(),setTimeout(function(){h.updateUrlState()},400)})},100)}t.page>1?this.bulkLoadPages(t.page,t.scroll):t.scroll>0&&(window.scrollTo({top:t.scroll,behavior:"instant"}),r(window).trigger("scroll"))}},bulkLoadPages:function(t,e){var i=this,a=this.getFormData();c.isRestoring=!0;for(var o=[],u=1;u<=t+1;u++)o.push(u);var p={action:"homeproz_filter_properties",nonce:homeprozAjax.nonce,property_type:a.property_type,city:a.city,zip:a.zip,min_price:a.min_price,max_price:a.max_price,beds:a.beds,cards_only:"true"};this.mapBounds&&(p.bounds=this.mapBounds),this.mapCenter&&(p.center=this.mapCenter);var d=[],g=[];if(o.forEach(function(v){var I=r.extend({},p,{paged:v}),w=x.get(I);w&&w.success&&w.data&&w.data.html?d.push({page:v,html:w.data.html,max_pages:w.data.max_pages||1}):g.push(v)}),g.length===0){this.renderBulkResults(d,t,e);return}this.$results.html('
    ');var P=g.map(function(v){var I=r.extend({},p,{paged:v});return r.ajax({url:homeprozAjax.ajaxUrl,type:"POST",data:I}).then(function(w){var C={page:v,html:w.success?w.data.html:"",max_pages:w.success?w.data.max_pages:0};return w.success&&x.set(I,w),C})});r.when.apply(r,P).done(function(){var v=P.length===1?[arguments[0]]:Array.prototype.slice.call(arguments),I=d.concat(v);i.renderBulkResults(I,t,e)}).fail(function(){c.isRestoring=!1,i.filterProperties(1,!1)})},renderBulkResults:function(t,e,i){t.sort(function(u,p){return u.page-p.page});var a=t[0]?t[0].max_pages:1,o='

    Loading...

    ';o+='
    ',t.forEach(function(u){u.html&&u.page<=a&&(o+='
    ',o+=u.html,o+="
    ")}),o+="
    ",this.$results.html(o),c.currentPage=Math.min(e+1,a),c.maxPages=a,c.pages={},t.forEach(function(u){u.page<=a&&(c.pages[u.page]={state:"populated"})}),i>0&&window.scrollTo({top:i,behavior:"instant"}),c.isRestoring=!1,r(window).trigger("scroll"),typeof m<"u"&&m.process()},updateFromMap:function(t,e){s.isCardScroll||(this.mapBounds=t,this.mapCenter=e,this.isMapUpdate=!0,s.isPinClickPan||this.clearPinSelection(),this.$results.html('
    '),c.isEnabled&&f.reset(s.isPinClickPan),c.currentPage=1,this._scrollBlocked=!0,this.clearScrollFromUrl(),this.filterProperties(1,!1))},clearScrollFromUrl:function(){var t=window.location.hash.replace("#","");if(t){var e=t.split("&").filter(function(a){return!a.startsWith("scroll=")}),i=e.length?"#"+e.join("&"):"";history.replaceState(null,"",window.location.pathname+window.location.search+i)}},clearPinSelection:function(){s.selectedPropertyId&&(s.setMarkerColor(s.selectedPropertyId,"red"),s.resetMarkerZIndex(s.selectedPropertyId),r("#property-"+s.selectedPropertyId).removeClass("property-card-highlighted"),s.selectedPropertyId=null)},getPageFromHash:function(){var t=this.getStateFromHash();return t?t.page:1},filterProperties:function(t,e){e=e!==!1,t=t||1;var i=this,a=this.getFormData();this.$filters.addClass("is-loading"),this.isFirstLoad&&this.$results.html('
    ');var o={action:"homeproz_filter_properties",nonce:homeprozAjax.nonce,property_type:a.property_type,city:a.city,zip:a.zip,min_price:a.min_price,max_price:a.max_price,beds:a.beds,paged:t};this.mapBounds&&(o.bounds=this.mapBounds),this.mapCenter&&(o.center=this.mapCenter);var u=this.isMapUpdate;this.isMapUpdate=!1;var p=this.isResetTriggered;this.isResetTriggered=!1,n.queue("properties",function(d){return r.ajax({url:homeprozAjax.ajaxUrl,type:"POST",data:o})},function(d,g){d.success&&(i.$results.html(d.data.html),i.isFirstLoad=!1,p&&d.data.found_posts===0&&s.map&&s.resetToInitialPosition(),d.data.filters&&!u&&s.updateFilters(d.data.filters),typeof y<"u"&&y.calculate(),f.destroy(),setTimeout(function(){f.init()},100),e&&i.updateUrl(a,t),s.selectedPropertyId?setTimeout(function(){var P=r("#property-"+s.selectedPropertyId);P.length&&(window.scrollTo({top:P.offset().top-120,behavior:"instant"}),P.addClass("property-card-highlighted"))},150):t>1&&window.scrollTo({top:i.$filters.offset().top-100,behavior:"instant"}))},function(){i.$filters.removeClass("is-loading")},function(){i.$results.html('

    Error

    Something went wrong. Please try again.

    ')})},getFormData:function(){return{property_type:this.$form.find('[name="property_type"]').val()||"",city:this.$form.find('[name="city"]').val()||"",zip:this.$form.find('[name="zip"]').val()||"",min_price:this.$form.find('[name="min_price"]').val()||"",max_price:this.$form.find('[name="max_price"]').val()||"",beds:this.$form.find('[name="beds"]').val()||""}},getFormState:function(){return this.getFormData()},setFormFromState:function(t){for(var e in t)this.$form.find('[name="'+e+'"]').val(t[e])},updateUrl:function(t,e){var i=[];for(var a in t)t[a]&&i.push(a+"="+encodeURIComponent(t[a]));if(e>1&&i.push("page="+e),!this._scrollBlocked){var o=window.pageYOffset||document.documentElement.scrollTop;o>0&&i.push("scroll="+Math.round(o))}if(s.map){var u=s.map.getCenter(),p=s.map.getZoom();i.push("lat="+u.lat.toFixed(6)),i.push("lng="+u.lng.toFixed(6)),i.push("zoom="+p)}var d=homeprozAjax.archiveUrl+(i.length?"#"+i.join("&"):"");history.replaceState(null,"",d)},updateUrlState:function(){var t=this;clearTimeout(this._urlUpdateTimeout),this._urlUpdateTimeout=setTimeout(function(){var e=c.currentPage||1,i=t.getFormData();t.updateUrl(i,e)},300)},getStateFromHash:function(){var t=window.location.hash.replace("#","");if(!t)return null;var e={};return t.split("&").forEach(function(i){var a=i.split("=");a.length===2&&(e[a[0]]=decodeURIComponent(a[1]))}),{property_type:e.property_type||"",city:e.city||"",zip:e.zip||"",min_price:e.min_price||"",max_price:e.max_price||"",beds:e.beds||"",page:e.page?parseInt(e.page):1,scroll:e.scroll?parseInt(e.scroll):0,lat:e.lat?parseFloat(e.lat):null,lng:e.lng?parseFloat(e.lng):null,zoom:e.zoom?parseInt(e.zoom):null}},getPageFromUrl:function(t){var e=t.match(/#page=(\d+)/);if(e)return parseInt(e[1]);var i=t.match(/[?&]paged=(\d+)/);return i?parseInt(i[1]):1},resetFilters:function(){this.$form.find("select").val(""),this.$form.find('input[name="zip"]').val(""),l&&l.$stickyForm&&(l.$stickyForm.find("select").val(""),l.$stickyForm.find('input[name="zip"]').val("")),this.isResetTriggered=!0,this.onFilterChange()},onFilterChange:function(){var t=this.getFormData();if(s.map&&(s.currentFilters={status:"Active",property_type:t.property_type||"",city:t.city||"",min_price:t.min_price||"",max_price:t.max_price||"",min_beds:t.beds||""}),!s.map){this.filterProperties(1);return}r.ajax({url:homeprozAjax.ajaxUrl,type:"GET",data:{action:"homeproz_get_filter_bounds",property_type:t.property_type,city:t.city,min_price:t.min_price,max_price:t.max_price,min_beds:t.beds},success:function(e){if(e.success&&e.data){var i=e.data,a=(i.ne_lat-i.sw_lat)*.1,o=(i.ne_lng-i.sw_lng)*.1,u=L.latLngBounds([i.sw_lat-a,i.sw_lng-o],[i.ne_lat+a,i.ne_lng+o]);s.map.fitBounds(u)}else s.loadClusters()},error:function(){s.loadClusters()}})}},b={breakpoint:1024,isMapView:!0,isAboveBreakpoint:!0,mapInitialized:!1,init:function(){var t=this;if(typeof homeprozMapData<"u"&&(this.isMapView=homeprozMapData.isMapView!==!1),this.isAboveBreakpoint=window.innerWidth>=this.breakpoint,this.isAboveBreakpoint&&this.isMapView&&typeof homeprozMapData<"u"){var e=h.getFormData(),i={status:"Active",property_type:e.property_type||"",city:e.city||"",min_price:e.min_price||"",max_price:e.max_price||"",min_beds:e.beds||""};s.init(i),this.mapInitialized=!0,h.pendingRestoreState?h.restoreState():(e.city||e.zip||e.property_type||e.min_price||e.max_price||e.beds)&&h.onFilterChange()}var a;r(window).on("resize",function(){clearTimeout(a),a=setTimeout(function(){t.handleResize()},150)})},handleResize:function(){var t=this.isAboveBreakpoint;this.isAboveBreakpoint=window.innerWidth>=this.breakpoint;var e=r(".property-archive-main");if(t&&!this.isAboveBreakpoint&&c.isEnabled&&f.destroy(),!t&&this.isAboveBreakpoint){if(this.isMapView){if(e.removeClass("is-grid-view").addClass("is-map-view"),!this.mapInitialized&&typeof homeprozMapData<"u"){var i=h.getFormData(),a={status:"Active",property_type:i.property_type||"",city:i.city||"",min_price:i.min_price||"",max_price:i.max_price||"",min_beds:i.beds||""};s.init(a),this.mapInitialized=!0,h.pendingRestoreState&&h.restoreState()}else s.map&&setTimeout(function(){s.map.invalidateSize()},100);setTimeout(function(){f.init()},200)}else e.removeClass("is-map-view").addClass("is-grid-view");typeof y<"u"&&setTimeout(function(){y.calculate()},150)}},setMapView:function(t){this.isMapView=t}},y={cardWidth:400,cardGap:24,mapGap:32,mapRatio:.33,breakpoint:1024,containerPadding:24,init:function(){this.calculate();var t=this,e;r(window).on("resize",function(){clearTimeout(e),e=setTimeout(function(){t.calculate()},100)})},calculate:function(){if(window.innerWidth .container"),i=t.hasClass("is-map-view"),a=e.width();i?this.calculateMapLayout(a):this.calculateGridLayout(a)},calculateMapLayout:function(t){for(var e=5;e>=1;e--){var i=e*this.cardWidth+(e-1)*this.cardGap,a=(this.mapGap+i)/(1-this.mapRatio);if(a<=t){this.setProperties(a,e,".property-map-layout"),this.setProperties(a,e,".property-list-container");return}}var i=this.cardWidth,a=(this.mapGap+i)/(1-this.mapRatio);this.setProperties(Math.min(a,t),1,".property-map-layout"),this.setProperties(Math.min(a,t),1,".property-list-container")},calculateGridLayout:function(t){for(var e=6;e>=1;e--){var i=e*this.cardWidth+(e-1)*this.cardGap;if(i<=t){this.setProperties(i,e,".grid-view-container");return}}this.setProperties(this.cardWidth,1,".grid-view-container")},setProperties:function(t,e,i){var a=r(i);a.length&&(a.css("--layout-width",t+"px"),a.css("--card-columns",e))},clearProperties:function(){r(".property-map-layout, .grid-view-container, .property-list-container").css({"--layout-width":"","--card-columns":""})}},c={pages:{},totalPages:0,totalPosts:0,currentPage:1,pendingPage:null,isEnabled:!1,isRestoring:!1,cardsPerPage:12},f={$container:null,$grid:null,scrollTimeout:null,init:function(){if(window.innerWidth>=1024&&r(".is-map-view").length?this.$container=r(".property-list-container"):this.$container=r("#property-results"),this.$grid=this.$container.find(".properties-grid"),!(!this.$container.length||!this.$grid.length)){var t=this.$container.find(".properties-meta"),e=t.find(".properties-count strong").text().replace(/,/g,"");c.totalPosts=parseInt(e)||0,c.totalPages=Math.ceil(c.totalPosts/c.cardsPerPage),!(c.totalPages<=1)&&(c.pages={},c.pendingPage=null,this.wrapInitialCards(),this.bindScrollHandler(),c.isEnabled=!0,this.$container.addClass("infinite-scroll-enabled"),this.syncPages())}},wrapInitialCards:function(){var t=this.$grid.find(".property-card");if(t.length){var e=r('
    ');t.wrapAll(e),c.pages[1]={state:"populated"}}},bindScrollHandler:function(){var t=this;r(window).on("scroll.infiniteScroll",function(){clearTimeout(t.scrollTimeout),t.scrollTimeout=setTimeout(function(){t.syncPages(),h.updateUrlState()},100)}),r(window).on("wheel.infiniteScroll",function(){h._scrollBlocked=!1})},syncPages:function(){if(!(!this.$grid||!c.isEnabled)&&!c.isRestoring){var t=c.totalPages,e=this.calculateCurrentPage();e>t-2&&(e=t-2),e<1&&(e=1),c.currentPage=e;var i=[e-2,e-1,e,e+1,e+2];i=i.filter(function(o){return o>=1&&o<=t});var a=this.getReferenceCardDimensions();this.ensurePagesExist(i),this.loadFirstUnloaded(i),this.syncPageStates(i,a)}},calculateCurrentPage:function(){var t=window.scrollY||window.pageYOffset,e=t+window.innerHeight,i=this.$grid.find(".infinite-scroll-page");if(!i.length)return 1;var a=1,o=1/0;return i.each(function(){var u=r(this),p=parseInt(u.data("page")),d=u.find(".property-card").first();if(d.length){var g=d[0].getBoundingClientRect(),P=g.top+t;if(P<=e){var v=e-P;v');e.insertPageInOrder(o,i),c.pages[i]||(c.pages[i]={state:"empty"})}})},insertPageInOrder:function(t,e){var i=this.$grid.find(".infinite-scroll-page"),a=!1;i.each(function(){var o=parseInt(r(this).data("page"));if(eo&&window.scrollTo({top:o,behavior:"instant"})}}},destroy:function(){c.isEnabled&&(r(window).off("scroll.infiniteScroll"),clearTimeout(this.scrollTimeout),this.$container&&this.$container.removeClass("infinite-scroll-enabled"),this.$grid&&(this.$grid.find('.infinite-scroll-page[data-state="populated"]').children().unwrap(),this.$grid.find('.infinite-scroll-page[data-state="placeholder"]').remove()),c.pages={},c.pendingPage=null,c.isEnabled=!1)}},m={_isRunning:!1,_activeLoads:0,MAX_PARALLEL:2,LOAD_DISTANCE:1e3,init:function(){this.process(),this.bindScrollEvent()},bindScrollEvent:function(){var t=this,e;r(window).on("scroll",function(){clearTimeout(e),e=setTimeout(function(){t.process()},50)})},process:function(){this._isRunning||(this._isRunning=!0,this._activeLoads=0,this._processNext())},_getNextElement:function(){var t=r(".property-card-image[data-bg]");if(!t.length)return null;var e=window.pageYOffset||document.documentElement.scrollTop,i=e,a=e+window.innerHeight,o=this.LOAD_DISTANCE,u=[],p=[];return t.each(function(){var d=this.getBoundingClientRect(),g=d.top+e,P=g+d.height;if(P>=i&&g<=a)u.push({el:this,position:g});else{var v;g>a?v=g-a:v=i-P,v<=o&&p.push({el:this,distance:v})}}),u.sort(function(d,g){return d.position-g.position}),p.sort(function(d,g){return d.distance-g.distance}),u.length?u[0].el:p.length?p[0].el:null},_processNext:function(){for(var t=this;this._activeLoads1&&this.startAutoplay())}},calculateThumbnailsPerPage:function(){r(window).width()<=640?this.thumbnailsPerPage=4:this.thumbnailsPerPage=5},bindEvents:function(){var n=this;this.$thumbnails.on("click",function(s){s.stopPropagation();var l=parseInt(r(this).data("index"));n.stopAutoplay(),n.setMainImage(l,!1)}),this.$playbackBtn.on("click",function(s){s.stopPropagation(),s.preventDefault(),n.isPlaying?n.stopAutoplay():n.startAutoplay()}),this.$prevBtn.on("click",function(){n.stopAutoplay(),n.prevThumbnailPage()}),this.$nextBtn.on("click",function(){n.stopAutoplay(),n.nextThumbnailPage()}),this.$gallery.find("[data-lightbox-trigger]").on("click",function(s){if(n.isSwiping){n.isSwiping=!1;return}n.stopAutoplay(),n.openLightbox(n.currentIndex)}),this.$lightbox.find(".lightbox-close, .lightbox-overlay").on("click",function(){n.closeLightbox()}),this.$lightbox.find(".lightbox-prev").on("click",function(){n.slideLightboxImage("prev")}),this.$lightbox.find(".lightbox-next").on("click",function(){n.slideLightboxImage("next")}),r(document).on("keydown",function(s){if(n.$lightbox.is('[aria-hidden="false"]'))switch(s.key){case"Escape":n.closeLightbox();break;case"ArrowLeft":n.slideLightboxImage("prev");break;case"ArrowRight":n.slideLightboxImage("next");break}}),r(window).on("resize",function(){n.calculateThumbnailsPerPage(),n.updateThumbnailNavigation()})},bindSwipeEvents:function(){var n=this;this.$mainImageContainer[0].addEventListener("touchstart",function(s){n.handleSwipeStart(s)},{passive:!0}),this.$mainImageContainer[0].addEventListener("touchend",function(s){n.handleMainGallerySwipeEnd(s)},{passive:!0}),this.$lightboxImageContainer[0].addEventListener("touchstart",function(s){n.handleSwipeStart(s)},{passive:!0}),this.$lightboxImageContainer[0].addEventListener("touchend",function(s){n.handleLightboxSwipeEnd(s)},{passive:!0})},handleSwipeStart:function(n){n.touches.length===1&&(this.swipeStartX=n.touches[0].clientX,this.swipeStartY=n.touches[0].clientY)},handleMainGallerySwipeEnd:function(n){if(n.changedTouches.length===1){var s=n.changedTouches[0].clientX-this.swipeStartX,l=n.changedTouches[0].clientY-this.swipeStartY;Math.abs(s)>Math.abs(l)&&Math.abs(s)>this.swipeThreshold&&(this.isSwiping=!0,this.stopAutoplay(),s>0?this.slideMainImage("prev"):this.slideMainImage("next"))}},handleLightboxSwipeEnd:function(n){if(n.changedTouches.length===1){var s=n.changedTouches[0].clientX-this.swipeStartX,l=n.changedTouches[0].clientY-this.swipeStartY;Math.abs(s)>Math.abs(l)&&Math.abs(s)>this.swipeThreshold&&(s>0?this.slideLightboxImage("prev"):this.slideLightboxImage("next"))}},startAutoplay:function(){var n=this;this.images.length<=1||(this.isPlaying=!0,this.$playbackBtn.addClass("is-playing"),this.$playbackBtn.attr("aria-label","Pause slideshow"),this.autoplayInterval=setInterval(function(){n.advanceImage()},this.autoplayDelay))},stopAutoplay:function(){this.isPlaying=!1,this.$playbackBtn.removeClass("is-playing"),this.$playbackBtn.attr("aria-label","Play slideshow"),this.autoplayInterval&&(clearInterval(this.autoplayInterval),this.autoplayInterval=null)},advanceImage:function(){if(!this.isTransitioning){var n=this.currentIndex+1;n>=this.images.length&&(n=0),this.setMainImage(n,!0)}},slideMainImage:function(n){var s=this;if(!(this.isTransitioning||this.images.length<=1)){var l;n==="prev"?(l=this.currentIndex-1,l<0&&(l=this.images.length-1)):(l=this.currentIndex+1,l>=this.images.length&&(l=0)),this.isTransitioning=!0;var h=this.images[l],b=n==="next"?"100%":"-100%",y=n==="next"?"-100%":"100%",c=r('');c.attr("src",h.url),c.attr("alt",h.alt||"Property photo"),c.css({position:"absolute",top:0,left:0,width:"100%",height:"100%","object-fit":"cover",transform:"translateX("+b+")","z-index":2,"border-radius":"0.5rem"}),this.$mainImageContainer.css({position:"relative",overflow:"hidden"}),this.$mainImageContainer.append(c),this.$mainImage.css({transition:"transform "+this.slideDuration+"ms ease-out"}),c.css({transition:"transform "+this.slideDuration+"ms ease-out"}),c[0].offsetHeight,this.$mainImage.css("transform","translateX("+y+")"),c.css("transform","translateX(0)"),setTimeout(function(){s.$mainImage.attr("src",h.url),s.$mainImage.attr("alt",h.alt||"Property photo"),s.$mainImage.css({transition:"",transform:""}),c.remove(),s.isTransitioning=!1},this.slideDuration),this.currentIndex=l,this.$thumbnails.removeClass("is-active"),this.$thumbnails.filter('[data-index="'+l+'"]').addClass("is-active"),this.scrollToThumbnail(l)}},setMainImage:function(n,s){var l=this;if(!(n<0||n>=this.images.length)&&!this.isTransitioning){var h=this.images[n];if(s){this.isTransitioning=!0;var b=r('');b.attr("src",h.url),b.attr("alt",h.alt||"Property photo"),b.css({position:"absolute",top:0,left:0,width:"100%",height:"100%","object-fit":"cover",opacity:0,transform:"scale(1.02)",transition:"opacity "+this.fadeDuration+"ms ease-in-out, transform "+this.fadeDuration+"ms ease-in-out","z-index":2,"border-radius":"0.5rem"}),this.$mainImageContainer.css("position","relative"),this.$mainImageContainer.append(b),b[0].offsetHeight,b.css({opacity:1,transform:"scale(1)"}),setTimeout(function(){l.$mainImage.attr("src",h.url),l.$mainImage.attr("alt",h.alt||"Property photo"),b.remove(),l.isTransitioning=!1},this.fadeDuration)}else this.$mainImage.attr("src",h.url),this.$mainImage.attr("alt",h.alt||"Property photo");this.currentIndex=n,this.$thumbnails.removeClass("is-active"),this.$thumbnails.filter('[data-index="'+n+'"]').addClass("is-active"),this.scrollToThumbnail(n)}},scrollToThumbnail:function(n){var s=Math.floor(n/this.thumbnailsPerPage);s!==this.thumbnailPage&&(this.thumbnailPage=s,this.scrollThumbnails())},scrollThumbnails:function(){var n=this.$gallery.find(".gallery-thumbnails"),s=this.$thumbnails.first().outerWidth(!0),l=this.thumbnailPage*this.thumbnailsPerPage*s;n.css("transform","translateX(-"+l+"px)"),this.updateThumbnailNavigation()},updateThumbnailNavigation:function(){var n=Math.ceil(this.images.length/this.thumbnailsPerPage);this.$prevBtn.prop("disabled",this.thumbnailPage===0),this.$nextBtn.prop("disabled",this.thumbnailPage>=n-1),n<=1?(this.$prevBtn.hide(),this.$nextBtn.hide()):(this.$prevBtn.show(),this.$nextBtn.show())},prevThumbnailPage:function(){this.thumbnailPage>0&&(this.thumbnailPage--,this.scrollThumbnails(),this.preloadPrevThumbnailPage())},nextThumbnailPage:function(){var n=Math.ceil(this.images.length/this.thumbnailsPerPage);this.thumbnailPage=this.images.length&&(l=0)),this.isTransitioning=!0;var h=this.images[l],b=n==="next"?"100%":"-100%",y=n==="next"?"-100%":"100%",c=r('');c.attr("src",h.url),c.attr("alt",h.alt||"Property photo"),c.css({position:"absolute","max-width":"100%","max-height":"calc(100vh - 8rem)","object-fit":"contain",transform:"translateX("+b+")",left:"50%",top:"50%","margin-left":"-45vw","margin-top":"calc(-50vh + 4rem)"}),this.$lightboxImageContainer.css({position:"relative",overflow:"hidden"}),this.$lightboxImageContainer.append(c),this.$lightboxImage.css({transition:"transform "+this.slideDuration+"ms ease-out"}),c.css({transition:"transform "+this.slideDuration+"ms ease-out"}),c[0].offsetHeight,this.$lightboxImage.css("transform","translateX("+y+")"),c.css("transform","translateX(0)"),setTimeout(function(){s.$lightboxImage.attr("src",h.url),s.$lightboxImage.attr("alt",h.alt||"Property photo"),s.$lightboxImage.css({transition:"",transform:""}),c.remove(),s.isTransitioning=!1,s.$lightboxCounter.text(l+1)},this.slideDuration),this.currentIndex=l}},prevImage:function(){this.slideLightboxImage("prev")},nextImage:function(){this.slideLightboxImage("next")},updateLightboxImage:function(){var n=this.images[this.currentIndex];this.$lightboxImage.attr("src",n.url),this.$lightboxImage.attr("alt",n.alt||"Property photo"),this.$lightboxCounter.text(this.currentIndex+1)},setupThumbnailLoading:function(){this.$thumbnails.each(function(){var n=r(this),s=n.find("img");n.addClass("is-loading"),n.find(".thumbnail-spinner").length||n.append('
    '),s[0].complete?n.removeClass("is-loading"):(s.on("load",function(){n.removeClass("is-loading")}),s.on("error",function(){n.removeClass("is-loading")}))})},preloadThumbnailPages:function(n,s){for(var l=this,h=n*this.thumbnailsPerPage,b=Math.min((n+s)*this.thumbnailsPerPage,this.images.length),y=h;y=0&&this.preloadThumbnailPages(n,1)}};r(function(){x.init()})})(jQuery);(function(r){if(!r(".mortgage-calculator-main").length)return;let x=!1;r.fn.currencyInput=function(s=!0){return this.data("ci_show_symbol",s),x||(x=!0,r.fn._CIOriginalVal=r.fn.val,r.fn.val=function(h){if(r(this).data("_currencyInput"))if(arguments.length===0){var b=r(this)._CIOriginalVal();if(b=="")return"";var y=parseInt(b.replace(/[^0-9]/g,""));return y}else{if(h=String(h).replace(/[^0-9]/g,""),h!=""){var c=parseInt(h).toLocaleString("en-US",{style:"currency",currency:"USD",minimumFractionDigits:0,maximumFractionDigits:0});return r(this).data("ci_show_symbol")||(c=c.replace("$","")),r(this)._CIOriginalVal(c)}return r(this)._CIOriginalVal(h)}else if(r(this).data("_percentInput"))if(arguments.length===0){var b=r(this)._CIOriginalVal();if(b=="")return"";var y=parseFloat(b.replace(/[^0-9.]/g,""));return isNaN(y)?"":y}else{h=String(h).replace(/[^0-9.]/g,"");var f=h.split(".");return f.length>2&&(h=f[0]+"."+f.slice(1).join("")),r(this)._CIOriginalVal(h)}else return arguments.length===0?r(this)._CIOriginalVal():r(this)._CIOriginalVal(h)}),this.data("_currencyInput")?this:(this.data("_currencyInput",!0),this.on("focus",function(){r(this).select()}),this.on("input",function(h){var b=this.selectionStart,y=r(this)._CIOriginalVal(),c=y.length;r(this).val(y);var f=r(this)._CIOriginalVal().length;f>c?b+=f-c:f2&&(y=c[0]+"."+c.slice(1).join("")),r(this)._CIOriginalVal(y);var f=y.length;f0){var h=l/s*100;this.$downPaymentPercent._CIOriginalVal(h.toFixed(1))}},syncDownPaymentFromPercent:function(){var s=this.$homePrice.val(),l=this.$downPaymentPercent.val();if(s&&s>0&&l!==""&&l>=0){var h=Math.round(s*l/100);this.$downPayment.val(h)}},calculate:function(){var s=this.$homePrice.val()||0,l=this.$downPayment.val()||0,h=parseInt(this.$loanTerm.val(),10),b=this.$interestRate.val()||0,y=s-l;y<0&&(y=0);var c=b/100/12,f=h*12,m=0,t=0;if(y>0&&c>0&&f>0){var e=Math.pow(1+c,f);m=y*(c*e)/(e-1),t=m*f-y}else y>0&&c===0&&(m=y/f,t=0);this.$monthlyPayment.text(this.formatCurrencyDisplay(m)),this.$principalInterest.text(this.formatCurrencyDisplay(m)),this.$loanAmount.text(this.formatCurrencyDisplay(y)),this.$totalInterest.text(this.formatCurrencyDisplay(t))}};r(document).ready(function(){n.init()})})(jQuery);(function(r){r(function(){})})(jQuery); diff --git a/wp-content/themes/homeproz/template-parts/property/property-filters.js b/wp-content/themes/homeproz/template-parts/property/property-filters.js index bcceb6fc..65581f90 100755 --- a/wp-content/themes/homeproz/template-parts/property/property-filters.js +++ b/wp-content/themes/homeproz/template-parts/property/property-filters.js @@ -840,13 +840,36 @@ self.hoveredPropertyId = propertyId; - // Check if marker exists on map - if (self.markers[propertyId]) { - // Marker exists - highlight it - self.setMarkerColor(propertyId, 'blue'); - self.setMarkerZIndex(propertyId, 9000); // Blue below amber but above red + var marker = self.markers[propertyId]; + var needsTemporaryMarker = false; + + if (marker) { + // Marker exists - check if it's visible (not clustered and in viewport) + var markerLatLng = marker.getLatLng(); + var inViewport = self.map.getBounds().contains(markerLatLng); + + // Check if marker is clustered (part of a cluster group) + var isClustered = false; + if (self.markerCluster && self.markerCluster.hasLayer(marker)) { + var visibleParent = self.markerCluster.getVisibleParent(marker); + isClustered = visibleParent && visibleParent !== marker; + } + + if (!isClustered && inViewport) { + // Marker is visible as individual pin - highlight it + self.setMarkerColor(propertyId, 'blue'); + self.setMarkerZIndex(propertyId, 9000); + } else { + // Marker is clustered or outside viewport - need temporary marker + needsTemporaryMarker = true; + } } else { - // Marker is clustered - create temporary pin at property location + // Marker doesn't exist in current dataset - need temporary marker + needsTemporaryMarker = true; + } + + // Create temporary marker if needed + if (needsTemporaryMarker) { var lat = $card.data('lat'); var lng = $card.data('lng'); @@ -981,7 +1004,7 @@ }); // City/Zip mutual exclusivity in sticky form - city clears zip - this.$stickyForm.find('select[name="property_location"]').on('change', function() { + this.$stickyForm.find('select[name="city"]').on('change', function() { if ($(this).val()) { self.$stickyForm.find('input[name="zip"]').val(''); self.$mainForm.find('input[name="zip"]').val(''); @@ -991,8 +1014,8 @@ // City/Zip mutual exclusivity in sticky form - zip clears city this.$stickyForm.find('input[name="zip"]').on('input', function() { if ($(this).val()) { - self.$stickyForm.find('select[name="property_location"]').val(''); - self.$mainForm.find('select[name="property_location"]').val(''); + self.$stickyForm.find('select[name="city"]').val(''); + self.$mainForm.find('select[name="city"]').val(''); } }); @@ -1118,7 +1141,7 @@ }); // City/Zip mutual exclusivity - city clears zip - this.$form.find('select[name="property_location"]').on('change', function() { + this.$form.find('select[name="city"]').on('change', function() { if ($(this).val()) { self.$form.find('input[name="zip"]').val(''); // Also sync to sticky form if it exists @@ -1131,10 +1154,10 @@ // City/Zip mutual exclusivity - zip clears city this.$form.find('input[name="zip"]').on('input', function() { if ($(this).val()) { - self.$form.find('select[name="property_location"]').val(''); + self.$form.find('select[name="city"]').val(''); // Also sync to sticky form if it exists if (StickyFilters && StickyFilters.$stickyForm) { - StickyFilters.$stickyForm.find('select[name="property_location"]').val(''); + StickyFilters.$stickyForm.find('select[name="city"]').val(''); } } }); @@ -1220,7 +1243,7 @@ PropertyMap.currentFilters = { status: 'Active', property_type: formData.property_type || '', - city: formData.property_location || '', + city: formData.city || '', min_price: formData.min_price || '', max_price: formData.max_price || '', min_beds: formData.beds || '' @@ -1291,7 +1314,7 @@ action: 'homeproz_filter_properties', nonce: homeprozAjax.nonce, property_type: formData.property_type, - property_location: formData.property_location, + city: formData.city, zip: formData.zip, min_price: formData.min_price, max_price: formData.max_price, @@ -1529,7 +1552,7 @@ action: 'homeproz_filter_properties', nonce: homeprozAjax.nonce, property_type: formData.property_type, - property_location: formData.property_location, + city: formData.city, zip: formData.zip, min_price: formData.min_price, max_price: formData.max_price, @@ -1628,7 +1651,7 @@ getFormData: function() { return { property_type: this.$form.find('[name="property_type"]').val() || '', - property_location: this.$form.find('[name="property_location"]').val() || '', + city: this.$form.find('[name="city"]').val() || '', zip: this.$form.find('[name="zip"]').val() || '', min_price: this.$form.find('[name="min_price"]').val() || '', max_price: this.$form.find('[name="max_price"]').val() || '', @@ -1729,7 +1752,7 @@ return { // Filters property_type: raw.property_type || '', - property_location: raw.property_location || '', + city: raw.city || '', zip: raw.zip || '', min_price: raw.min_price || '', max_price: raw.max_price || '', @@ -1792,7 +1815,7 @@ PropertyMap.currentFilters = { status: 'Active', property_type: formData.property_type || '', - city: formData.property_location || '', + city: formData.city || '', min_price: formData.min_price || '', max_price: formData.max_price || '', min_beds: formData.beds || '' @@ -1812,7 +1835,7 @@ data: { action: 'homeproz_get_filter_bounds', property_type: formData.property_type, - city: formData.property_location, + city: formData.city, min_price: formData.min_price, max_price: formData.max_price, min_beds: formData.beds @@ -1820,35 +1843,19 @@ success: function(response) { if (response.success && response.data) { var filterBounds = response.data; - var mapBounds = PropertyMap.map.getBounds(); - // Check if map view intersects with filter bounds - var filterLatLngBounds = L.latLngBounds( - [filterBounds.sw_lat, filterBounds.sw_lng], - [filterBounds.ne_lat, filterBounds.ne_lng] + // Add 10% padding to bounds + var latPadding = (filterBounds.ne_lat - filterBounds.sw_lat) * 0.1; + var lngPadding = (filterBounds.ne_lng - filterBounds.sw_lng) * 0.1; + + var paddedBounds = L.latLngBounds( + [filterBounds.sw_lat - latPadding, filterBounds.sw_lng - lngPadding], + [filterBounds.ne_lat + latPadding, filterBounds.ne_lng + lngPadding] ); - // Check if ANY of the filter bounds corners are visible in the map - // OR if the map view is fully contained within the filter bounds - var mapIntersects = mapBounds.intersects(filterLatLngBounds); - - if (!mapIntersects) { - // Add 10% padding to bounds - var latPadding = (filterBounds.ne_lat - filterBounds.sw_lat) * 0.1; - var lngPadding = (filterBounds.ne_lng - filterBounds.sw_lng) * 0.1; - - var paddedBounds = L.latLngBounds( - [filterBounds.sw_lat - latPadding, filterBounds.sw_lng - lngPadding], - [filterBounds.ne_lat + latPadding, filterBounds.ne_lng + lngPadding] - ); - - // Reposition map to show filtered properties - PropertyMap.map.fitBounds(paddedBounds); - // The moveend event will trigger loadClusters and updateFromMap - } else { - // Map already shows relevant area, just reload clusters and properties - PropertyMap.loadClusters(); - } + // Always fit map to show all filtered properties + PropertyMap.map.fitBounds(paddedBounds); + // The moveend event will trigger loadClusters and updateFromMap } else { // No properties found with these filters, just reload PropertyMap.loadClusters(); @@ -1890,7 +1897,7 @@ var mapFilters = { status: 'Active', property_type: formData.property_type || '', - city: formData.property_location || '', + city: formData.city || '', min_price: formData.min_price || '', max_price: formData.max_price || '', min_beds: formData.beds || '' @@ -1901,6 +1908,9 @@ // Restore state if we have pending state to restore if (PropertyFilters.pendingRestoreState) { PropertyFilters.restoreState(); + } else if (formData.city || formData.zip || formData.property_type || formData.min_price || formData.max_price || formData.beds) { + // Filters present from URL but no saved map state - fit to filter bounds + PropertyFilters.onFilterChange(); } } @@ -1940,7 +1950,7 @@ var mapFilters = { status: 'Active', property_type: formData.property_type || '', - city: formData.property_location || '', + city: formData.city || '', min_price: formData.min_price || '', max_price: formData.max_price || '', min_beds: formData.beds || '' @@ -2480,7 +2490,7 @@ action: 'homeproz_filter_properties', nonce: homeprozAjax.nonce, property_type: formData.property_type, - property_location: formData.property_location, + city: formData.city, zip: formData.zip, min_price: formData.min_price, max_price: formData.max_price, diff --git a/wp-content/themes/homeproz/template-parts/property/property-results.php b/wp-content/themes/homeproz/template-parts/property/property-results.php index 57c31cdb..35d0c5f8 100755 --- a/wp-content/themes/homeproz/template-parts/property/property-results.php +++ b/wp-content/themes/homeproz/template-parts/property/property-results.php @@ -26,7 +26,8 @@ if (!function_exists('mls_get_properties')) { // Get filter values from URL $current_type = isset($_GET['property_type']) ? sanitize_text_field($_GET['property_type']) : ''; $current_status = isset($_GET['property_status']) ? sanitize_text_field($_GET['property_status']) : 'Active'; -$current_location = isset($_GET['property_location']) ? sanitize_text_field($_GET['property_location']) : ''; +$current_location = isset($_GET['city']) ? sanitize_text_field($_GET['city']) : ''; +$current_zip = isset($_GET['zip']) ? sanitize_text_field($_GET['zip']) : ''; $current_min_price = isset($_GET['min_price']) ? intval($_GET['min_price']) : ''; $current_max_price = isset($_GET['max_price']) ? intval($_GET['max_price']) : ''; $current_beds = isset($_GET['beds']) ? intval($_GET['beds']) : ''; @@ -49,7 +50,15 @@ if ($current_type) { $filter_args['property_type'] = $current_type; } if ($current_location) { - $filter_args['city'] = $current_location; + // Parse "City, SS" format - extract just the city name + $city_name = $current_location; + if (preg_match('/^(.+),\s*([A-Z]{2})$/', $current_location, $matches)) { + $city_name = $matches[1]; + } + $filter_args['city'] = $city_name; +} elseif ($current_zip) { + // Zip code filter (only if city not set) + $filter_args['postal_code'] = $current_zip; } // Use lat/lng radius search if provided (takes precedence over location) if ($center_lat && $center_lng) {