1(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[7177],{13673:()=>{},14831:(e,t,r)=>{Promise.resolve().then(r.t.bind(r,81013,23)),Promise.resolve().then(r.t.bind(r,35574,23)),Promise.resolve().then(r.t.bind(r,13673,23)),Promise.resolve().then(r.bind(r,40649)),Promise.resolve().then(r.bind(r,80370))},20063:(e,t,r)=>{"use strict";var a=r(47260);r.o(a,"permanentRedirect")&&r.d(t,{permanentRedirect:function(){return a.permanentRedirect}}),r.o(a,"redirect")&&r.d(t,{redirect:function(){return a.redirect}}),r.o(a,"useParams")&&r.d(t,{useParams:function(){return a.useParams}}),r.o(a,"usePathname")&&r.d(t,{usePathname:function(){return a.usePathname}}),r.o(a,"useRouter")&&r.d(t,{useRouter:function(){return a.useRouter}}),r.o(a,"useSearchParams")&&r.d(t,{useSearchParams:function(){return a.useSearchParams}})},35574:e=>{e.exports={style:{fontFamily:"'Cormorant Garamond', 'Cormorant Garamond Fallback'"},className:"__className_2b785a",variable:"__variable_2b785a"}},40649:(e,t,r)=>{"use strict";r.d(t,{default:()=>n});var a=r(12115),i=r(20063),s=r(62890);function n(){let e=(0,i.useRouter)(),t=(0,a.useRef)(!1);return(0,a.useEffect)(()=>{let{data:r}=s.ND.auth.onAuthStateChange(async(r,a)=>{if(!t.current&&["SIGNED_IN","SIGNED_OUT","TOKEN_REFRESHED"].includes(r)){t.current=!0;try{if("SIGNED_OUT"===r)await fetch("/api/auth/callback",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({event:r,session:null})}),e.refresh();else if(a&&("SIGNED_IN"===r||"TOKEN_REFRESHED"===r)){let{data:{user:t},error:i}=await s.ND.auth.getUser();if(i||!t)return void console.error("Session verification failed:",i);await fetch("/api/auth/callback",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({event:r,session:a})}),"SIGNED_IN"===r&&e.refresh()}}catch(e){console.error("Failed to sync auth to server cookies",e)}finally{t.current=!1}}});return()=>{var e;return null==r||null==(e=r.subscription)?void 0:e.unsubscribe()}},[e]),null}},62890:(e,t,r)=>{"use strict";r.d(t,{ND:()=>a.ND});var a=r(64767)},64767:(e,t,r)=>{"use strict";r.d(t,{ND:()=>n});var a=r(16620);let i="https://msuxzpdyjhwvhlbksrlz.supabase.co",s="sb_publishable_KaYACQLLAtPbOOdiIo0-bA_ix0iG_MY";if(!i||!s)throw Error("Missing Supabase environment variables. Please check your .env.local file and ensure NEXT_PUBLIC_SUPABASE_URL and NEXT_PUBLIC_SUPABASE_PUBLISHABLE_DEFAULT_KEY are set.");let n=(0,a.createBrowserClient)(i,s,{cookieOptions:{maxAge:172800}})},80370:(e,t,r)=>{"use strict";r.d(t,{FavouritesProvider:()=>l,G:()=>o});var a=r(95155),i=r(12115),s=r(62890);let n=(0,i.createContext)(null);function l(e){let{children:t}=e,[r,l]=(0,i.useState)(new Set),[o,u]=(0,i.useState)([]),[c,d]=(0,i.useState)(!0),[f,h]=(0,i.useState)(null),[_,g]=(0,i.useState)(null),m=(0,i.useCallback)(async()=>{try{let{data:e}=await s.ND.auth.getUser(),t=(null==e?void 0:e.user)||null;if(!t)return void u([]);let{data:r,error:a}=await s.ND.from("saved_listings").select("listing_id").eq("user_id",t.id);if(a){console.error("Error fetching saved_listings:",a),g("Failed to load saved listings.");return}let i=(r||[]).map(e=>"object"==typeof e&&null!==e&&"listing_id"in e?String(e.listing_id):null).filter(Boolean);if(0===i.length){l(new Set),u([]);return}l(new Set(i.map(String)));let{data:n,error:o}=await s.ND.from("listings").select("*, listing_images(*)").in("id",i).eq("status","active").order("created_at",{ascending:!1});if(o){console.error("Error fetching listing details:",o),g("Failed to load listings.");return}let c=(Array.isArray(n)?n:[]).map(e=>{let t="object"==typeof e&&null!==e?e:{},r=Array.isArray(t.listing_images)?t.listing_images:[],a=r.find(e=>"object"==typeof e&&null!==e&&e.is_primary),i=r[0];return{...t,image_url:(null==a?void 0:a.image_url)||(null==i?void 0:i.image_url)||null}});u(c)}catch(e){console.error("Error fetching favourite listings (client):",e),g("Failed to load favourite listings.")}},[]),v=(0,i.useCallback)(async e=>{if(!e)return void d(!1);try{d(!0),g(null),await m()}catch(e){console.error("Error fetching initial saved listings:",e),g("Could not fetch your saved properties.")}finally{d(!1)}},[m]);(0,i.useEffect)(()=>{let e=!0;d(!0),(async()=>{try{let{data:{user:t}}=await s.ND.auth.getUser(),r=t||null;if(!e)return;h(r),r?await v(r.id):(l(new Set),u([]),d(!1))}catch(t){if(console.error("Failed to get initial session:",t),!e)return;d(!1)}})();let{data:{subscription:t}}=s.ND.auth.onAuthStateChange(async(t,r)=>{let{data:{user:a}}=await s.ND.auth.getUser(),i=a||null;e&&(h(i),i?await v(i.id):(l(new Set),u([]),d(!1)))});return()=>{e=!1,t.unsubscribe()}},[v]);let b=(0,i.useCallback)(async(e,t)=>{if(!(await s.ND.auth.getUser()).data.user){window.location.href="/auth";return}let a=r.has(e),i=new Set(r);a?(i.delete(e),t&&u(t=>t.filter(t=>t.id!==e))):(i.add(e),t&&u(e=>[...e,t])),l(i);try{let{data:{user:t}}=await s.ND.auth.getUser();if(!t){window.location.href="/auth";return}if(a){let{error:r}=await s.ND.from("saved_listings").delete().match({user_id:t.id,listing_id:e});if(r)throw r}else{let{error:r}=await s.ND.from("saved_listings").insert([{user_id:t.id,listing_id:e}]);if(r)throw r}await m()}catch(e){console.error("Error toggling saved listing (client):",e),l(r),t&&m(),g("Failed to update favourite status. Please try again.")}},[r,m]),y=(0,i.useCallback)(e=>r.has(e),[r]),S=(0,i.useMemo)(()=>({savedListingIds:r,favouriteListings:o,loading:c,user:f,error:_,isSaved:y,toggleSavedListing:b,savedListings:Array.from(r)}),[r,o,c,f,_,y,b]);return(0,a.jsx)(n.Provider,{value:S,children:t})}function o(){let e=(0,i.useContext)(n);if(!e)throw Error("useFavourites must be used within a FavouritesProvi
1der");return e}},81013:e=>{e.exports={style:{fontFamily:"'Playfair Display', 'Playfair Display Fallback'",fontStyle:"normal"},className:"__className_0a80b4",variable:"__variable_0a80b4"}}},e=>{e.O(0,[3994,2978,6620,8441,1255,7358],()=>e(e.s=14831)),_N_E=e.O()}]);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.