1"use strict";(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[4860],{20371:(e,t,a)=>{a.d(t,{VX:()=>r});let r=[{slug:"best-cities-for-digital-nomads",kind:"topic",name:"Best Cities for Digital Nomads",intro:"The cities that make remote work feel effortless â reliable connectivity, an established nomad scene, and the everyday infrastructure that lets you stay productive far from home. We rank destinations with a proven internet score, then surface the highest-rated overall so you can settle in fast and get to work.",filter:{internet_score:{$gte:3}},sort:{ranking_score:-1,population:-1},badgeLabel:e=>`#${e} for digital nomads`},{slug:"cheapest-cities-for-nomads",kind:"topic",name:"Cheapest Cities for Nomads",intro:"Stretch your budget without giving up the essentials. These destinations carry the lowest monthly cost of living for a remote worker, sorted strictly from least to most expensive so the most affordable bases rise to the top. Ideal for long stays where every dollar of runway counts.",filter:{cost_for_nomad_in_usd:{$ne:null}},sort:{cost_for_nomad_in_usd:1},badgeLabel:e=>`#${e} cheapest for nomads`},{slug:"safest-cities-to-travel",kind:"topic",name:"Safest Cities to Travel",intro:"Peace of mind comes first when you are far from home. We rank cities by their measured safety level â from petty-crime risk to overall personal security â surfacing the places where solo travelers and families alike can relax and explore with confidence.",filter:{safety_level:{$ne:null}},sort:{safety_level:-1,ranking_score:-1},badgeLabel:e=>`#${e} safest to travel`},{slug:"best-internet-cities",kind:"topic",name:"Best Internet Cities",intro:"Fast, dependable connectivity changes what a city is good for â video calls, large uploads, and streaming all just work. This list ranks destinations by raw connection speed and a strong connectivity score, so latency and dropouts never derail a workday.",filter:{$or:[{internet_speed:{$gte:50}},{internet_score:{$gte:4}}]},sort:{internet_speed:-1,internet_score:-1},badgeLabel:e=>`#${e} for internet`},{slug:"best-overall-cities",kind:"topic",name:"Best Overall Cities",intro:'When you want the all-rounders â places that score well across the board rather than excelling at one thing â start here. This is our composite "best places" ranking, blending the headline ranking signal with each destination\'s overall quality-of-life score.',filter:{overall_score:{$ne:null}},sort:{ranking_score:-1,overall_score:-1},badgeLabel:e=>`#${e} overall`},{slug:"best-value-cities",kind:"topic",name:"Best Value Cities",intro:"Great value is more than cheap â it is what you get back for what you spend. These cities earn a high value score, meaning the cost of everyday life lines up favorably against the lifestyle on offer. Comfortable living that does not quietly drain your account.",filter:{cost_score:{$gte:3}},sort:{cost_score:-1,ranking_score:-1},badgeLabel:e=>`#${e} for value`},{slug:"best-cities-for-nightlife-and-leisure",kind:"topic",name:"Best Cities for Nightlife and Leisure",intro:"For the travelers who measure a city by what happens after dark and on the weekend. We rank destinations by their leisure quality â the density and energy of bars, restaurants, music, and culture â so you land somewhere that stays interesting long after the workday ends.",filter:{leisure_quality:{$gte:3}},sort:{leisure_quality:-1,ranking_score:-1},badgeLabel:e=>`#${e} for nightlife & leisure`},{slug:"cleanest-air-cities",kind:"topic",name:"Cleanest Air Cities",intro:"Air quality shapes how a place actually feels to live in â energy levels, sleep, and how much you want to be outside. These cities post the strongest air-quality scores, ranking the destinations where you can breathe easy and spend your days outdoors without a second thought.",filter:{air_quality_score:{$gte:3}},sort:{air_quality_score:-1,ranking_score:-1},badgeLabel:e=>`#${e} for clean air`},{slug:"most-affordable-safe-cities",kind:"topic",name:"Most Affordable Safe Cities",intro:"The rare combination travelers actually want: low cost of living without compromising on personal safety. Every city here clears both a solid value score and a solid safety level, so you never have to trade your budget against your peace of mind.",filter:{cost_score:{$gte:3},safety_level:{$gte:3}},sort:{ranking_score:-1},badgeLabel:e=>`#${e} affordable & safe`},{slug:"best-cities-for-remote-work",kind:"topic",name:"Best Cities for Remote Work",intro:"Remote work demands more than fast Wi-Fi â it needs a stable, secure base you can build a routine around. These cities pair an excellent connectivity score with a dependable safety level, the foundation for focused weeks and a sustainable long-term setup.",filter:{internet_score:{$gte:4},safety_level:{$gte:3}},sort:{ranking_score:-1},badgeLabel:e=>`#${e} for remote work`},{slug:"best-big-cities",kind:"topic",name:"Best Big Cities",intro:"The metropolises â million-
1plus-population hubs with the scale that brings world-class food, transit, culture, and opportunity. We filter to genuinely large cities and rank them by overall standing, for travelers who want the energy and depth only a big city delivers.",filter:{population:{$gte:1e6}},sort:{ranking_score:-1,population:-1},badgeLabel:e=>`#${e} big city`},{slug:"best-affordable-european-cities",kind:"topic",name:"Best Affordable European Cities",intro:"Europe on a budget that actually works. This is a single curated cut â European destinations that also earn a strong value score â ranked by overall quality. From the Balkans to the Baltics, these are the cities where the continent rewards you without the price tag.",filter:{region:"Europe",cost_score:{$gte:3}},sort:{ranking_score:-1},badgeLabel:e=>`#${e} affordable in Europe`},{slug:"best-cities-in-asia-for-nomads",kind:"topic",name:"Best Cities in Asia for Nomads",intro:"Asia remains the heartland of the nomad world, and this curated list ranks its strongest bases â destinations across the region with a proven internet score, ordered by overall standing. Vibrant, affordable, and built for remote work, these cities draw nomads back year after year.",filter:{region:"Asia",internet_score:{$gte:3}},sort:{ranking_score:-1},badgeLabel:e=>`#${e} in Asia for nomads`},{slug:"top-rated-cities-overall",kind:"topic",name:"Top-Rated Cities Overall",intro:"Our editorial top tier â the destinations that clear the highest ranking-score bar across every signal we track. If you simply want the best places we cover, with no other constraint, this is the shortlist. Consistently excellent, no caveats required.",filter:{ranking_score:{$gte:7}},sort:{ranking_score:-1},badgeLabel:e=>`#${e} top-rated`}]},26335:(e,t,a)=>{a.d(t,{NEWSLETTER_OPT_OUT_TEXT:()=>l,NewsletterSignupCTA:()=>c});var r=a(95155),o=a(12115),i=a(42023),s=a(97200);let n=e=>e?.name||e?.fullName||e?.displayName||e?.data?.name||e?.data?.fullName||e?.data?.profile?.name||e?.data?.profile?.fullName||"",l=`No spam. To unsubscribe, email ${s.$P}.`;function c({user:e,source:t="footer",variant:a="default",className:s="",eyebrow:d="The Wanderlust newsletter",title:u="Trip ideas worth opening",description:p="City spotlights, trip ideas and what's new in Wanderlust â sent when there's something worth reading, not on a schedule.",helperText:h=l,inputLabel:m="Email address",inputId:f="newsletter-email",submitLabel:g="Subscribe",successMessage:y="Youâre on the list! Weâll email you when thereâs something worth reading."}){let[b,w]=(0,o.useState)("idle"),[x,_]=(0,o.useState)(""),v=(0,o.useMemo)(()=>e?.email||e?.contactEmail||e?.data?.email||e?.data?.contactEmail||e?.data?.profile?.email||e?.data?.profile?.contactEmail||e?.data?.contact?.email||"",[e]),k=(0,o.useMemo)(()=>(e=>{let t=e?.firstName||e?.data?.firstName||e?.data?.profile?.firstName;if(t)return t;let a=n(e);return a?a.split(" ")[0]:""})(e),[e]),N=(0,o.useMemo)(()=>(e=>{let t=e?.lastName||e?.surname||e?.data?.lastName||e?.data?.surname||e?.data?.profile?.lastName||e?.data?.profile?.surname;if(t)return t;let a=n(e)?.trim();if(!a)return"";let r=a.split(/\s+/);return r.length<=1?"":r.slice(1).join(" ")})(e),[e]),[E,T]=(0,o.useState)(null),I=E??v,S=async e=>{e.preventDefault();let a=I?.trim();if(!a){w("error"),_("Please add the email you want Wanderlust updates sent to.");return}w("loading"),_("");try{let e=await fetch("/api/newsletter",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({email:a,firstName:k,lastName:N,source:t})});if(!e.ok){let t=await e.json().catch(()=>({}));throw Error(t?.message||t?.error||"We couldnât save your subscription. Try again in a moment.")}w("success"),_(y),(0,i.c5)("newsletter_subscribe",{source:t})}catch(e){console.error("Newsletter subscription failed",e),w("error"),_(e.message||"We couldnât save your subscription. Try again in a moment.")}},C="loading"===b,L="editorial"===a?{wrapper:"relative overflow-hidden rounded-[14px] border border-[oklch(0.85_0.012_70)] bg-[oklch(0.99_0.006_80)] px-6 py-7 text-[oklch(0.18_0.02_60)] shadow-[0_1px_0_rgba(0,0,0,0.02),0_30px_60px_-40px_rgba(0,0,0,0.25)] sm:px-7",overlay:"pointer-events-none absolute inset-0 opacity-60 [background:radial-gradient(circle_at_top_right,color-mix(in_oklab,oklch(0.62_0.15_40)_14%,transparent),transparent_55%)]",layout:"relative flex flex-col gap-5",eyebrow:"block text-[11.5px] uppercase tracking-[0.14em] text-[oklch(0.58_0.015_60)]",title:"m-0 text-[clamp(22px,2.4vw,28px)] leading-[1.05] tracking-[-0.02em] text-[oklch(0.18_0.02_60)]",description:"m-0 text-[14px] leading-[1.55] text-[oklch(0.36_0.02_60)] max-w-[44ch]",form:"relative w-full space-y-3",label:"sr-only",controls:"flex flex-col gap-2 rounded-2xl border border-[oklch(0.85_0.012_70)] bg-[oklch(0.975_0.008_80)] p-1.5 transition focus-within:border-[oklch(0.18_0.02_60)] sm:flex-row sm:items-center sm:gap-1 sm:rounded-full",input:"w-full flex-1 rounded-xl border-0 bg-transparent px-4 py-2.5 text-[14px] text-[oklch(0.18_0.02_60)] placeholder:text-[oklch(0.58_0.015_60)] focus:outline-none focus:ring-0 sm:rounded-full",button:"inline-flex items-center justify-center gap-1.5 rounded-xl bg-[oklch(0.18_0.02_60)] px-5 py-2.5 text-[13.5px] font-medium text-[oklch(0.975_0.008_80)] transition hover:-translate-y-[1px] hover:bg-[oklch(0.38_0.09_40)] disabled:cursor-not-allowed disabled:opacity-60 sm:rounded-full",helper:"text-[10.5px] uppercase tracking-[0.12em] text-[oklch(0.58_0.015_60)]",success:"text-[13px] text-[oklch(0.36_0.02_60)]",error:"text-[13px] text-[oklch(0.48_0.15_25)]"}:"journal"===a?{wrapper:"relative w-full",overlay:"",layout:"relative flex flex-col gap-4",eyebrow:"text-[10.5px] uppercase tracking-[0.18em] text-[color-mix(in_oklab,var(--wl-bg)_62%,transparent)]",title:"m-0 text-[clamp(20px,2vw,26px)] font-normal leading-[1.12] tracking-[-0.02em] text-[var(--wl-bg)]",description:"m-0 max-w-[46ch] text-[15px] leading-[1.6] text-[color-mix(in_oklab,var(--wl-bg)_72%,transparent)]",form:"relative w-full space-y-3",label:"sr-only",controls:"flex items-center gap-2 rounded-full border border-[color-mix(in_oklab,var(--wl-bg)_25%,transparent)] bg-[
1color-mix(in_oklab,var(--wl-bg)_10%,transparent)] p-1.5 transition focus-within:border-[color-mix(in_oklab,var(--wl-bg)_45%,transparent)]",input:"min-w-0 flex-1 border-0 bg-transparent px-4 py-2 text-[14.5px] text-[var(--wl-bg)] placeholder:text-[color-mix(in_oklab,var(--wl-bg)_45%,transparent)] focus:outline-none focus:ring-0",button:"shrink-0 rounded-full !bg-[var(--wl-accent)] px-5 py-2.5 text-[14px] font-medium text-white transition hover:!bg-[var(--wl-accent-ink)] disabled:cursor-not-allowed disabled:opacity-60",helper:"text-[10.5px] uppercase tracking-[0.12em] text-[color-mix(in_oklab,var(--wl-bg)_55%,transparent)]",success:"text-[13px] text-[color-mix(in_oklab,var(--wl-bg)_75%,transparent)]",error:"text-[13px] text-[oklch(0.72_0.14_25)]"}:{wrapper:"relative overflow-hidden rounded-3xl bg-gradient-to-br from-sky-500 via-indigo-500 to-purple-600 px-8 py-12 text-white shadow-2xl sm:px-12",overlay:"absolute inset-0 opacity-40 mix-blend-screen",layout:"relative flex flex-col gap-8 lg:flex-row lg:items-center lg:justify-between",eyebrow:"text-xs font-semibold uppercase tracking-[0.35em] text-white/70",title:"mt-4 text-3xl font-semibold leading-tight sm:text-4xl",description:"mt-3 text-base text-white/80",form:"relative w-full max-w-lg space-y-3 rounded-2xl border border-white/30 bg-white/10 p-6 shadow-lg backdrop-blur-sm",label:"text-xs font-semibold uppercase tracking-[0.3em] text-white/70",controls:"space-y-3",input:"w-full rounded-xl border border-white/40 bg-white/95 px-4 py-3 text-base text-slate-900 shadow-lg transition focus:border-white focus:outline-none focus:ring-2 focus:ring-white/80",button:"inline-flex w-full items-center justify-center rounded-xl bg-slate-900 px-4 py-3 text-sm font-semibold text-white shadow-lg transition hover:bg-slate-800 disabled:cursor-not-allowed disabled:opacity-60",helper:"text-xs text-white/70",success:"text-sm text-white/80",error:"text-sm text-rose-100"},$="error"===b?L.error:L.success,O="editorial"===a,A="journal"===a,j={fontFamily:"var(--font-jetbrains-mono), ui-monospace, monospace"};return(0,r.jsxs)("div",{className:`${L.wrapper} ${s}`.trim(),children:[O||A?L.overlay?(0,r.jsx)("div",{className:L.overlay,"aria-hidden":"true"}):null:(0,r.jsxs)("div",{className:L.overlay,children:[(0,r.jsx)("div",{className:"absolute -left-24 top-1/3 h-48 w-48 rounded-full bg-white/40 blur-3xl"}),(0,r.jsx)("div",{className:"absolute -right-16 bottom-0 h-40 w-40 rounded-full bg-amber-200/50 blur-3xl"})]}),(0,r.jsxs)("div",{className:L.layout,children:[d||u||p?(0,r.jsxs)("div",{className:O||A?"":"max-w-2xl",children:[d?(0,r.jsx)("p",{className:L.eyebrow,style:O?j:void 0,children:d}):null,u?(0,r.jsx)("h2",{className:L.title,style:O?{fontFamily:"var(--font-fraunces), Georgia, serif"}:void 0,children:u}):null,p?(0,r.jsx)("p",{className:O&&(u||d)?`${L.description} mt-2`:L.description,children:p}):null]}):null,(0,r.jsxs)("form",{onSubmit:S,className:L.form,children:[(0,r.jsx)("label",{htmlFor:f,className:L.label,children:m}),(0,r.jsxs)("div",{className:L.controls,children:[(0,r.jsx)("input",{id:f,type:"email",name:"email",value:I,onChange:e=>{T(e.target.value),"idle"!==b&&(w("idle"),_(""))},placeholder:"[email protected]",className:L.input,autoComplete:"email","aria-label":m}),(0,r.jsxs)("button",{type:"submit",className:L.button,disabled:C,children:[C?"Subscribing...":g,O&&!C?(0,r.jsx)("span",{"aria-hidden":"true",className:"-mr-0.5",children:"â"}):null]})]}),(0,r.jsx)("p",{className:L.helper,style:O?j:void 0,children:h}),x&&(0,r.jsx)("p",{className:$,role:"status","aria-live":"polite",children:x})]})]})]})}},29480:(e,t,a)=>{a.d(t,{AuthProvider:()=>d,A:()=>u});var r=a(95155),o=a(12115);let i={isLoggedIn:!1,user:null,loading:!0},s=(e,t)=>{switch(t.type){case"LOGIN":return{...e,user:t.payload.user,isLoggedIn:!0,loading:!1};case"SET_USER":return{...e,user:t.payload};case"LOGOUT":return{...e,user:null,isLoggedIn:!1,loading:!1};case"SET_LOADING":return{...e,loading:t.payload};default:throw Error(`Unknown action type: ${t.type}`)}};var n=a(22113);let l=(0,o.createContext)();function c(){try{localStorage.removeItem("authToken"),localStorage.removeItem("authTokenExpires"),localStorage.removeItem("refreshToken"),localStorage.removeItem("refreshTokenExpires"),localStorage.removeItem("accessToken")}catch{}}function d({children:e}
1){let[t,a]=(0,o.useReducer)(s,i),[u,p]=(0,o.useState)(!0),[h,m]=(0,o.useState)(!1);(0,o.useEffect)(()=>{m(!0)},[]),(0,o.useEffect)(()=>{h&&(async()=>{p(!0),c();let e=null;try{let t=localStorage.getItem("user");t&&(e=JSON.parse(t))}catch{e=null}if(e)a({type:"LOGIN",payload:{user:e}});else{a({type:"LOGOUT"}),p(!1);return}try{let t=await (0,n.Sk)();if(t){a({type:"SET_USER",payload:t});try{localStorage.setItem("user",JSON.stringify(t))}catch{}}else e||a({type:"LOGOUT"})}catch(t){let e=t?.status??t?.response?.status;if(401===e||403===e){try{localStorage.removeItem("user")}catch{}a({type:"LOGOUT"})}else console.warn("Failed to refresh user data:",t)}finally{p(!1)}})()},[h]);let f=(0,o.useCallback)((e,t)=>{a({type:"LOGIN",payload:{user:e}}),t&&window.dispatchEvent(new CustomEvent("auth:login",{detail:{token:t}}))},[a]),g=(0,o.useCallback)(()=>{try{localStorage.removeItem("user"),c()}catch{}a({type:"LOGOUT"})},[a]),y=(0,o.useCallback)(async()=>{try{await fetch("/api/auth/logout",{method:"POST",credentials:"include"})}catch{}g(),window.dispatchEvent(new Event("auth:logout"))},[g]),b=(0,o.useCallback)(async()=>{try{let e=await (0,n.Sk)();if(!e)return null;a({type:"LOGIN",payload:{user:e}});try{localStorage.setItem("user",JSON.stringify(e))}catch{}return e}catch(t){let e=t?.status??t?.response?.status;return 401===e||403===e?g():console.warn("Failed to refresh user data:",t),null}},[a,g]);(0,o.useEffect)(()=>{let e=()=>g();return window.addEventListener("auth:logout",e),()=>{window.removeEventListener("auth:logout",e)}},[g]);let w=(0,o.useMemo)(()=>({...t,dispatch:a,login:f,logout:y,refreshUser:b,isLoading:u}),[t,a,f,y,b,u]);return(0,r.jsx)(l.Provider,{value:w,children:e})}function u(){return(0,o.useContext)(l)}},42023:(e,t,a)=>{a.d(t,{Ck:()=>l,c5:()=>c,qY:()=>i,sx:()=>d});var r=a(78314),o=a(41463);let i=Object.freeze({VISIT:"visit",SIGNUP:"signup",AI_GENERATION_START:"ai_generation_start",AI_GENERATION_COMPLETE:"ai_generation_complete",JOURNEY_SAVED:"journey_saved",SHARE_CREATED:"share_created",INVITED_USER_SIGNUP:"invited_user_signup",AFFILIATE_CLICK:"affiliate_click",BOOKING_IMPORTED:"booking_imported",PAYWALL_VIEW:"paywall_view",UPGRADE_CTA_CLICK:"upgrade_cta_click",BEGIN_CHECKOUT:"begin_checkout",PURCHASE:"purchase"}),s="wl_anon",n=o.env.NEXT_PUBLIC_GOOGLE_ANALYTICS||"G-XWSBN43968";function l(){var e;let t=null;try{t=window.localStorage.getItem(s)}catch(e){}t||(t=function(){if("u"<typeof document)return null;let e=document.cookie.match(/(?:^|;\s*)wl_anon=([^;]+)/);return e?decodeURIComponent(e[1]):null}()),t||(t="u">typeof crypto&&crypto.randomUUID?crypto.randomUUID():`wl_${Date.now()}_${Math.random().toString(36).slice(2)}`);try{window.localStorage.setItem(s,t)}catch(e){}return e=t,"u"<typeof document||(document.cookie=`${s}=${encodeURIComponent(e)}; path=/; max-age=31536000; SameSite=Lax`),t}function c(e,t={}){try{(window.dataLayer=window.dataLayer||[],window.gtag=window.gtag||function(){window.dataLayer.push(arguments)},window.gtag)?.("event",e,{...t,send_to:n})}catch(e){}}function d(e,t={},a={}){c(e,t);try{(0,r.u4)(e,t)}catch(e){}try{!1!==a.serverPost&&fetch("/api/analytics/track",{method:"POST",keepalive:!0,headers:{"Content-Type":"application/json"},body:JSON.stringify({name:e,anonId:l(),props:t,path:window.location.pathname,referrer:document.referrer})}).catch(()=>{})}catch(e){}}},97200:(e,t,a)=>{a.d(t,{$P:()=>h,$V:()=>l,Ai:()=>f,I3:()=>m,Jz:()=>r,ME:()=>u,OE:()=>s,Oy:()=>c,W:()=>o,c$:()=>g,e6:()=>d,ge:()=>p,qU:()=>n,qf:()=>i});let r="1,300+",o="190+",i="https://apps.apple.com/app/id6762548388",s=6.99,n=59.99,l=240,c=3.99,d=39.99,u="Wanderlust App LLC",p="Export, PA",h="[email protected]",m=5,f="Generous daily AI chat + 3 AI-built itineraries every 30 days",g=[{description:"Track the countries you've visited",key:"track"},{description:`City guides for ${r} cities`,key:"city"},{description:"New-tab browser extension with a new destination photo on every tab",key:"ext"},{description:"Generous AI chat â an assistant that plans with you, adds stops to your trip and surfaces what to book",key:"chat"},{description:"3 AI-built itineraries every 30 days",key:"itineraries"},{description:"Offline Trip Mode in the iOS app",key:"offline"},{description:"Unlimited AI itineraries",disabled:!0,key:"ai"},{description:"Invite travel companions to plan with you",disabled:!0,key:"invite"},{description:"Insider tips on every city page",disabled:!0,key:"tips"}]}}]);
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.