{"id":505,"date":"2026-02-26T16:59:31","date_gmt":"2026-02-26T16:59:31","guid":{"rendered":"https:\/\/buddyupapi-staging.us35.cdn-alpha.com\/?page_id=505"},"modified":"2026-02-26T16:59:31","modified_gmt":"2026-02-26T16:59:31","slug":"explore","status":"publish","type":"page","link":"https:\/\/buddyupapi-staging.us35.cdn-alpha.com\/explore\/","title":{"rendered":"Explore"},"content":{"rendered":"<div class=\"buddyUpPjaxContainer\" data-buddyup-pjax-container=\"1\"><style>.buddyUpExploreLayout {\n    display: block;\n}\n\n.buddyUpExploreMapShell {\n    position: relative;\n    padding: .25rem;\n    background: var(--buddyup-background);\n}\n\n.buddyUpExploreStatusBar {\n    position: relative;\n    z-index: 520;\n    margin: 0 0 .45rem 0;\n    padding: .5rem .65rem;\n    border-radius: var(--buddyup-panel-radius, 12px);\n    background: rgba(255,255,255,.92);\n    border: 1px solid rgba(67, 126, 146, .2);\n}\n\n.buddyUpExploreTopTabs {\n    position: relative;\n    z-index: 520;\n    margin: 0 0 .45rem 0;\n    padding: .5rem .65rem;\n    border-radius: var(--buddyup-panel-radius, 12px);\n    background: rgba(255,255,255,.92);\n    border: 1px solid rgba(67, 126, 146, .2);\n}\n\n.buddyUpExploreTopTabsLabel {\n    font-weight: 700;\n    margin-bottom: .35rem;\n    color: #1f3656;\n}\n\n.buddyUpExploreTopTabsList {\n    display: flex;\n    flex-wrap: wrap;\n    gap: .35rem;\n}\n\n\/* Side tab: uses shared .buddyUpSideTab from global styles.css *\/\n#buddyUpExploreSidebarToggle {\n    display: none;\n}\n\naside.buddyUpExploreSidebar {\n    position: absolute;\n    top: 8.2rem;\n    left: .85rem;\n    width: min(320px, 85vw);\n    max-height: calc(100% - 14.6rem);\n    z-index: 10001;\n    margin: 0;\n    padding: .95rem .8rem;\n    border-radius: var(--buddyup-panel-radius, 12px);\n    background: var(--buddyup-background);\n    box-shadow: 0 12px 28px rgba(0,0,0,.22);\n    overflow: auto;\n    border: 1px solid rgba(67, 126, 146, .22);\n    gap: .85rem;\n}\n\naside.buddyUpExploreSidebar.buddyUpSearchSidebar > .buddyUpSearchSidebarSection {\n    margin: 0;\n}\n\n.buddyUpExploreMapFocusSection {\n    margin-bottom: .55rem;\n}\n\n.buddyUpExploreFocusToggle {\n    display: grid;\n    grid-template-columns: 1fr 1fr;\n    gap: .35rem;\n}\n\n.buddyUpExploreFocusBtn {\n    min-height: 2rem;\n    border-radius: 999px;\n    border: 1px solid var(--secondary-color);\n    background: #fff;\n    color: var(--secondary-color);\n    font-weight: 700;\n}\n\n.buddyUpExploreFocusBtn.isActive {\n    background: var(--secondary-color);\n    color: #fff;\n}\n\n.buddyUpExploreSearchNearRow {\n    display: grid;\n    grid-template-columns: 1fr auto;\n    gap: .35rem;\n    align-items: start;\n}\n\n.buddyUpExploreSearchNearRow .buddyUpButton3 {\n    margin: 0;\n    min-height: 2.2rem;\n}\n\n.buddyUpExploreSearch {\n    margin: 0;\n}\n\n.buddyUpExploreSection {\n    margin-bottom: .7rem;\n}\n\n.buddyUpExploreSection:last-child {\n    margin-bottom: 0;\n}\n\n.buddyUpExploreSectionToggle {\n    width: 100%;\n    border: 0;\n    background: transparent;\n    display: flex;\n    align-items: center;\n    justify-content: space-between;\n    font-weight: 700;\n    color: #1f3656;\n    padding: .1rem 0 .4rem 0;\n    cursor: pointer;\n}\n\n.buddyUpExploreSectionChevron {\n    font-size: .9rem;\n    opacity: .8;\n    transition: transform .18s ease;\n}\n\n.buddyUpExploreSectionBody {\n    display: block;\n}\n\n.buddyUpExploreSectionCollapsible.isCollapsed .buddyUpExploreSectionBody {\n    display: none;\n}\n\n.buddyUpExploreSectionCollapsible.isCollapsed .buddyUpExploreSectionChevron {\n    transform: rotate(-90deg);\n}\n\n.buddyUpExploreSectionTitle {\n    font-weight: 700;\n    margin-bottom: .45rem;\n    color: #1f3656;\n}\n\n.buddyUpExploreToggleList {\n    display: flex;\n    flex-direction: column;\n    gap: .35rem;\n}\n\n.buddyUpExploreToggle {\n    width: 100%;\n    margin: 0;\n    text-align: left;\n    min-height: 2.15rem;\n    border-radius: var(--buddyup-control-radius, 10px);\n    background: var(--secondary-color);\n    color: #fff;\n    border: 1px solid transparent;\n}\n\n.buddyUpExploreTopTabsList .buddyUpExploreToggle {\n    width: auto;\n    min-height: 2rem;\n    border-radius: 999px;\n    padding: .4rem .8rem;\n}\n\n.buddyUpExploreToggle.isActive {\n    border-color: var(--secondary-color);\n    background: var(--secondary-color);\n    color: #fff;\n}\n\n.buddyUpExploreCategoryToggle.buddyUpButton3 {\n    background: #fff !important;\n    border: 1px solid rgba(67, 126, 146, 0.35) !important;\n    color: #1f3656 !important;\n    font-weight: 600;\n    transition: background-color .18s ease, color .18s ease, border-color .18s ease, box-shadow .18s ease;\n}\n\n.buddyUpExploreCategoryToggle.buddyUpButton3.isActive {\n    background: var(--secondary-color) !important;\n    border-color: var(--secondary-color) !important;\n    color: #fff !important;\n    box-shadow: 0 0 0 2px rgba(67, 126, 146, 0.2);\n}\n\n.buddyUpExploreLock {\n    margin-top: .45rem;\n}\n\n.buddyUpExploreRadiusRow {\n    margin-bottom: .4rem;\n}\n\n.buddyUpExploreRadiusSlider {\n    width: 100%;\n    accent-color: var(--buddyup-color1);\n}\n\n.buddyUpExploreRadiusValue {\n    margin-top: .2rem;\n    font-size: .85rem;\n    font-weight: 600;\n    color: #1f3656;\n}\n\n.buddyUpExploreApplyRadius {\n    margin-top: .35rem;\n    width: 100%;\n}\n\n.buddyUpExploreRadiusHint {\n    margin-top: .35rem;\n    opacity: .8;\n}\n\n.buddyUpExploreNearbySignedOut {\n    padding-top: .1rem;\n}\n\n.buddyUpExploreNearbyRange {\n    width: 100%;\n    margin: .15rem 0 .45rem 0;\n    accent-color: var(--buddyup-color1);\n}\n\n.buddyUpExploreNearbyLockCard {\n    border-radius: var(--buddyup-control-radius, 10px);\n    border: 1px solid rgba(0,0,0,.08);\n    background: rgba(67, 126, 146, .08);\n    padding: .55rem .65rem;\n}\n\n.buddyUpExploreNearbyLockTitle {\n    font-weight: 700;\n    margin-bottom: .2rem;\n}\n\n.buddyUpExploreMapCard {\n    position: relative;\n    border-radius: var(--buddyup-panel-radius, 12px);\n    overflow: hidden;\n}\n\n.buddyUpExploreMapLoading {\n    position: absolute;\n    inset: 0;\n    background: rgba(255,255,255,.74);\n    display: flex;\n    align-items: center;\n    justify-content: center;\n    z-index: 540;\n}\n\n.buddyUpExploreMapLoadingInner {\n    display: inline-flex;\n    align-items: center;\n    gap: .55rem;\n    background: rgba(255,255,255,.96);\n    border: 1px solid rgba(67, 126, 146, .25);\n    border-radius: 999px;\n    padding: .45rem .75rem;\n    color: #1f3656;\n    font-weight: 600;\n}\n\n.buddyUpExploreSpinner {\n    width: 16px;\n    height: 16px;\n    border-radius: 50%;\n    border: 2px solid rgba(31, 54, 86, .25);\n    border-top-color: var(--secondary-color);\n    animation: buddyUpExploreSpin .7s linear infinite;\n}\n\n@keyframes buddyUpExploreSpin {\n    to { transform: rotate(360deg); }\n}\n\n.buddyUpExploreMap {\n    width: 100%;\n    min-height: 82vh;\n    border-radius: var(--buddyup-panel-radius, 12px);\n    border: 1px solid rgba(67, 126, 146, .22);\n}\n\n.buddyUpExploreSignedOutTease {\n    position: relative;\n    margin-top: .55rem;\n    width: min(360px, 100%);\n    background: rgba(255,255,255,.98);\n    border: 1px solid rgba(0,0,0,.08);\n    border-radius: var(--buddyup-panel-radius, 12px);\n    padding: .65rem;\n    box-shadow: 0 8px 20px rgba(0,0,0,.18);\n    z-index: 530;\n}\n\n.buddyUpExploreTeaseClose {\n    position: absolute;\n    right: .35rem;\n    top: .2rem;\n    border: 0;\n    background: transparent;\n    font-size: 1.2rem;\n    line-height: 1;\n    cursor: pointer;\n    opacity: .6;\n}\n\n.buddyUpExploreTeaseTitle {\n    font-weight: 700;\n    margin: 0 1rem .45rem 0;\n}\n\n.buddyUpExploreTeaseThumbs {\n    display: grid;\n    grid-template-columns: repeat(3, 1fr);\n    gap: .3rem;\n    margin-bottom: .45rem;\n}\n\n.buddyUpExploreTeaseThumbs span {\n    display: block;\n    height: 44px;\n    border-radius: 6px;\n    background: linear-gradient(135deg, rgba(0,0,0,.12), rgba(0,0,0,.04));\n}\n\n.buddyUpExploreTeaseThumbs img {\n    width: 100%;\n    height: 44px;\n    border-radius: 6px;\n    object-fit: cover;\n    display: block;\n}\n\n.buddyUpExploreTeaseCopy {\n    font-size: .92rem;\n    line-height: 1.3;\n    margin-bottom: .5rem;\n}\n\n.buddyUpExploreTeaseCta {\n    width: 100%;\n    text-align: center;\n    margin: 0;\n}\n\n.buddyUpExploreSignedOutBottomCta {\n    margin-top: .55rem;\n    border-radius: var(--buddyup-panel-radius, 12px);\n    background: rgba(255,255,255,.94);\n    border: 1px solid rgba(0,0,0,.08);\n    padding: .6rem .75rem;\n    display: flex;\n    align-items: center;\n    justify-content: space-between;\n    gap: .6rem;\n    border: 1px solid rgba(67, 126, 146, .22);\n}\n\n.buddyUpExploreFiltersOverlay {\n    position: absolute;\n    inset: 0;\n    border-radius: 12px;\n    background: rgba(67, 126, 146, .2);\n    display: flex;\n    align-items: center;\n    justify-content: center;\n    padding: .65rem;\n    z-index: 7;\n}\n\n.buddyUpExploreSidebar.isLoggedOut .buddyUpExploreFiltersOverlay {\n    display: none;\n}\n\n.buddyUpExploreFiltersOverlayCard {\n    border-radius: var(--buddyup-control-radius, 10px);\n    background: #fff;\n    border: 1px solid rgba(67, 126, 146, .25);\n    padding: .65rem;\n    text-align: center;\n    max-width: 260px;\n}\n\n.buddyUpExploreSidebar.isLoggedOut:hover .buddyUpExploreFiltersOverlay {\n    display: flex;\n}\n\n.buddyUpExploreSignedOutBottomCta .buddyUpButton1 {\n    margin: 0;\n    white-space: nowrap;\n}\n\n\/* Adventure pin marker treatment *\/\n.buddyUpExplorePin {\n    width: 64px;\n    height: 64px;\n    border-radius: 18px;\n    overflow: hidden;\n    border: 3px solid #fff;\n    box-shadow: 0 8px 22px rgba(0,0,0,.22);\n    background: #f4f4f4;\n    position: relative;\n    transform: translateY(-2px);\n}\n\n.buddyUpExplorePin img {\n    width: 100%;\n    height: 100%;\n    object-fit: cover;\n}\n\n.buddyUpExplorePinDot {\n    position: absolute;\n    left: 50%;\n    bottom: -10px;\n    transform: translateX(-50%);\n    width: 14px;\n    height: 14px;\n    border-radius: 50%;\n    background: var(--buddyup-color1);\n    border: 2px solid #fff;\n    box-shadow: 0 3px 8px rgba(0,0,0,.22);\n}\n\n.buddyUpExplorePinWrap {\n    background: transparent;\n    border: 0;\n}\n\n\/* Expanded popup card treatment *\/\n.buddyUpExplorePopup .leaflet-popup-content-wrapper {\n    border-radius: 16px;\n    box-shadow: 0 14px 32px rgba(0,0,0,.22);\n    padding: 0;\n}\n\n.buddyUpExplorePopup .leaflet-popup-content {\n    margin: 0;\n}\n\n.buddyUpExplorePopupCard {\n    max-width: 380px;\n    padding: .75rem;\n}\n\n.buddyUpExplorePopupBadge {\n    display: inline-block;\n    font-size: .72rem;\n    font-weight: 700;\n    letter-spacing: .02em;\n    padding: .2rem .5rem;\n    border-radius: 999px;\n    background: rgba(0,0,0,.06);\n    margin-bottom: .45rem;\n}\n\n.buddyUpExplorePopupTitle {\n    font-size: 1rem;\n    font-weight: 700;\n    line-height: 1.25;\n}\n\n.buddyUpExplorePopupSubtitle {\n    font-size: .82rem;\n    opacity: .78;\n    margin-top: .15rem;\n}\n\n.buddyUpExplorePopupDescription {\n    margin-top: .55rem;\n    font-size: .86rem;\n    line-height: 1.4;\n}\n\n.buddyUpExplorePopupHero {\n    margin-top: .55rem;\n    width: 100%;\n    max-height: 190px;\n    object-fit: cover;\n    border-radius: 12px;\n}\n\n.buddyUpExplorePopupGallery {\n    margin-top: .6rem;\n    display: flex;\n    flex-direction: column;\n    gap: .5rem;\n    max-height: 320px;\n    overflow: auto;\n    padding-right: .15rem;\n}\n\n.buddyUpExplorePopupMediaItem {\n    border-radius: 12px;\n    overflow: hidden;\n    background: rgba(0,0,0,.03);\n}\n\n.buddyUpExplorePopupMedia {\n    width: 100%;\n    max-height: 210px;\n    display: block;\n    object-fit: cover;\n    background: #000;\n}\n\n.buddyUpExplorePopupMediaCaption {\n    padding: .45rem .55rem;\n    font-size: .78rem;\n    line-height: 1.35;\n    opacity: .86;\n}\n\n.buddyUpExplorePopupLink {\n    margin: .6rem 0 0 0;\n    width: 100%;\n    text-align: center;\n}\n\n@media (max-width: 980px) {\n    .buddyUpExploreMapShell {\n        padding: 0;\n    }\n\n    .buddyUpExploreStatusBar {\n        position: relative;\n        padding: .42rem .55rem;\n        margin-bottom: .4rem;\n    }\n\n    .buddyUpExploreTopTabs {\n        padding: .42rem .55rem;\n        margin-bottom: .4rem;\n    }\n\n    .buddyUpExploreMap {\n        min-height: 72vh;\n        border-radius: 0;\n    }\n\n    #buddyUpExploreSidebarToggle {\n        display: inline-flex;\n    }\n\n    .buddyUpExploreMapShell aside.buddyUpExploreSidebar.buddyUpSearchSidebar.buddyUpFiltersShelf {\n        position: fixed;\n        top: calc(var(--buddyup-mobile-header-height, 56px) + var(--buddyup-mobile-safe-top, 0px) + 8px);\n        left: 0;\n        width: min(360px, calc(100vw - 18%));\n        max-width: calc(100vw - 18%);\n        height: calc(100dvh - var(--buddyup-mobile-header-height, 56px) - var(--buddyup-mobile-nav-offset, 70px) - var(--buddyup-mobile-safe-top, 0px) - 16px);\n        max-height: calc(100dvh - var(--buddyup-mobile-header-height, 56px) - var(--buddyup-mobile-nav-offset, 70px) - var(--buddyup-mobile-safe-top, 0px) - 16px);\n        border-radius: 0 14px 14px 0;\n        z-index: 10001;\n        box-shadow: 0 12px 28px rgba(0, 0, 0, 0.25);\n        background: #fff;\n        padding: .95rem .8rem;\n        overflow-y: auto;\n        transition: transform .24s ease, opacity .24s ease;\n        transform: translateX(-105%);\n        opacity: 1;\n        touch-action: pan-y;\n    }\n\n    .buddyUpExploreMapShell aside.buddyUpExploreSidebar.buddyUpSearchSidebar.buddyUpFiltersShelf.isOpen,\n    .buddyUpExploreMapShell aside.buddyUpExploreSidebar.buddyUpSearchSidebar.buddyUpFiltersShelf.activeMobileMenu {\n        transform: translateX(0);\n    }\n\n    .buddyUpExploreMapShell aside.buddyUpExploreSidebar.buddyUpSearchSidebar.buddyUpFiltersShelf.isCollapsed {\n        transform: translateX(-105%);\n        opacity: 0;\n        pointer-events: none;\n    }\n\n    .buddyUpExploreSignedOutTease {\n        width: 100%;\n        border-radius: 10px;\n        padding: .55rem;\n        margin-top: .45rem;\n    }\n\n    .buddyUpExploreTeaseThumbs img,\n    .buddyUpExploreTeaseThumbs span {\n        height: 40px;\n    }\n\n    .buddyUpExploreSignedOutBottomCta.hidden {\n        display: none;\n    }\n\n    .buddyUpExploreSignedOutBottomCta {\n        display: none;\n    }\n\n    .buddyUpExploreSidebar.isLoggedOut .buddyUpExploreFiltersOverlay {\n        display: flex;\n    }\n\n    .buddyUpExploreSignedOutBottomCta .buddyUpButton1 {\n        width: auto;\n        text-align: center;\n        font-size: .9rem;\n        padding: .42rem .62rem;\n    }\n}\n\n@media (min-width: 1024px) {\n    .buddyUpExploreMapShell {\n        padding: .35rem;\n    }\n\n    .buddyUpExploreSidebar {\n        width: min(320px, 32vw);\n        max-height: calc(100% - 14.6rem);\n    }\n\n    .buddyUpExploreMap {\n        min-height: 83vh;\n    }\n}\n<\/style><script>\nwindow.buddyUpExploreSSR = {\"status\":\"success\",\"adventures\":[{\"id\":10,\"user_id\":195,\"title\":\"Great North Slopes\",\"body\":\"Mini adventure for a day on the slopes\",\"categories\":[\"Snow Skiing\",\"Snow Tubing\"],\"location_label\":\"\",\"city\":\"\",\"state\":\"\",\"postal_code\":\"\",\"latitude\":39.1616527,\"longitude\":-84.8664722,\"point_source\":\"media_location_fallback\",\"preview_url\":\"https:\\\/\\\/buddyupapi-staging.us35.cdn-alpha.com\\\/wp-content\\\/uploads\\\/buddyup_83a0680f0a80f005.jpg\",\"media\":[{\"url\":\"https:\\\/\\\/buddyupapi-staging.us35.cdn-alpha.com\\\/wp-content\\\/uploads\\\/buddyup_83a0680f0a80f005.jpg\",\"type\":\"image\",\"description\":\"Skiing Hill\"}],\"created_at\":\"2026-03-05 17:45:47\"},{\"id\":9,\"user_id\":195,\"title\":\"Fishing On The Licking River\",\"body\":\"Fishing and caught a golden horse fish\",\"categories\":[\"Fishing\"],\"location_label\":\"\",\"city\":\"\",\"state\":\"\",\"postal_code\":\"\",\"latitude\":38.1264242,\"longitude\":-83.6102318,\"point_source\":\"media_location_fallback\",\"preview_url\":\"https:\\\/\\\/buddyupapi-staging.us35.cdn-alpha.com\\\/wp-content\\\/uploads\\\/buddyup_ea32b3ad58f23bcf.jpg\",\"media\":[{\"url\":\"https:\\\/\\\/buddyupapi-staging.us35.cdn-alpha.com\\\/wp-content\\\/uploads\\\/buddyup_ea32b3ad58f23bcf.jpg\",\"type\":\"image\",\"description\":\"front view golden horse fish\"}],\"created_at\":\"2026-03-05 17:37:15\"},{\"id\":8,\"user_id\":159,\"title\":\"testing geo location\",\"body\":\"this is a test post\",\"categories\":[\"BBQ\\\/Cookout\"],\"location_label\":\"\",\"city\":\"\",\"state\":\"\",\"postal_code\":\"\",\"latitude\":38.0540248,\"longitude\":-83.9372774,\"point_source\":\"media_location_fallback\",\"preview_url\":\"https:\\\/\\\/buddyupapi-staging.us35.cdn-alpha.com\\\/wp-content\\\/uploads\\\/buddyup_c420c8b6ef87484c.png\",\"media\":[{\"url\":\"https:\\\/\\\/buddyupapi-staging.us35.cdn-alpha.com\\\/wp-content\\\/uploads\\\/buddyup_c420c8b6ef87484c.png\",\"type\":\"image\",\"description\":\"Just a white screen\"}],\"created_at\":\"2026-03-03 20:31:13\"},{\"id\":6,\"user_id\":104,\"title\":\"test 5\",\"body\":\"This is a test of notifications, new Adventure single page, new pin links, photo gallery styling\",\"categories\":[\"Biking\",\"Beach Volleyball\"],\"location_label\":\"\",\"city\":\"\",\"state\":\"\",\"postal_code\":\"\",\"latitude\":40.3553915,\"longitude\":-105.7176957,\"point_source\":\"media_location_fallback\",\"preview_url\":\"https:\\\/\\\/buddyupapi-staging.us35.cdn-alpha.com\\\/wp-content\\\/uploads\\\/buddyup_c97c3d6079f5d205.jpg\",\"media\":[{\"url\":\"https:\\\/\\\/buddyupapi-staging.us35.cdn-alpha.com\\\/wp-content\\\/uploads\\\/buddyup_c97c3d6079f5d205.jpg\",\"type\":\"image\",\"description\":\"road\"}],\"created_at\":\"2026-03-02 21:18:06\"}],\"events\":[{\"event_id\":75,\"event_name\":\"Hike-a-thon(test)\",\"location_name\":\"Harding Icefield Trail - Exit Glacier Nature Center\",\"address\":\"24620 Herman Leirer Rd\",\"city\":\"Seward\",\"state\":\"Alaska\",\"location_label\":\"Harding Icefield Trail - Exit Glacier Nature Center, 24620 Herman Leirer Rd, Seward, Alaska\",\"latitude\":null,\"longitude\":null,\"point_source\":\"\",\"event_image\":\"https:\\\/\\\/buddyupapi-staging.us35.cdn-alpha.com\\\/wp-content\\\/uploads\\\/buddyup_a132a2e4f4436f83.jpg\",\"zip\":\"\",\"event_categories\":[\"Hiking\",\"Snow Skiing\",\"cross-country skiing\",\"Rock Climbing\",\"mountain climbing\"]}],\"groups\":[{\"id\":8,\"name\":\"Cliff Watching Enthusiasts\",\"address_1\":\"\",\"city\":\"a cliff\",\"state\":\"KS\",\"location_label\":\"a cliff, KS\",\"latitude\":37.6829546,\"longitude\":-97.4679657,\"point_source\":\"geocoded\",\"image\":\"https:\\\/\\\/buddyupapi-staging.us35.cdn-alpha.com\\\/wp-content\\\/uploads\\\/buddyup_b21c583f58ad273c.jpg\",\"categories\":[\"cliffs\"]},{\"id\":4,\"name\":\"Test Group\",\"address_1\":\"123 Main Street\",\"city\":\"Orlando\",\"state\":\"Florida\",\"location_label\":\"123 Main Street, Orlando, Florida\",\"latitude\":28.5438863,\"longitude\":-81.3773901,\"point_source\":\"geocoded\",\"image\":\"\",\"categories\":[\"hiking\",\"fishing\"]},{\"id\":6,\"name\":\"Test Group New\",\"address_1\":\"567 Main Street\",\"city\":\"Tampa\",\"state\":\"Florida\",\"location_label\":\"567 Main Street, Tampa, Florida\",\"latitude\":27.9572266,\"longitude\":-82.489102,\"point_source\":\"geocoded\",\"image\":\"\",\"categories\":[\"hiking\",\"camping\"]},{\"id\":10,\"name\":\"video test group 1\",\"address_1\":\"\",\"city\":\"Boston\",\"state\":\"Massachusetts\",\"location_label\":\"Boston, Massachusetts\",\"latitude\":42.3588336,\"longitude\":-71.0578303,\"point_source\":\"geocoded\",\"image\":\"https:\\\/\\\/buddyupapi-staging.us35.cdn-alpha.com\\\/wp-content\\\/uploads\\\/buddyup_112f569cd8658513.jpg\",\"categories\":[\"Archery\",\"BBQ\\\/Cookout\",\"Beachcombing\",\"Bird Watching\"]}],\"generated_at\":1776640918};\n<\/script>\n\n<section id=\"buddyUpExploreWrapper\" class=\"buddyUpContainer buddyUp\">\n    <div class=\"buddyUpExploreLayout\">\n        <div class=\"buddyUpElWrapper buddyUpExploreMapShell\">\n            <button type=\"button\" id=\"buddyUpExploreSidebarToggle\" class=\"buddyUpSideTab\" aria-expanded=\"false\" aria-controls=\"buddyUpExploreSidebar\" data-target=\"buddyUpExploreSidebar\" data-local-toggle=\"true\">\n                <i class=\"fa-solid fa-sliders\" aria-hidden=\"true\"><\/i>\n                <span>Filters<\/span>\n            <\/button>\n\n            <aside class=\"buddyUpElWrapper buddyUpExploreSidebar buddyUpSearchSidebar buddyUpFiltersShelf\" id=\"buddyUpExploreSidebar\" aria-hidden=\"true\">\n\n                <div class=\"buddyUpSearchSidebarSection buddyUpExploreSection buddyUpExploreSectionCollapsible\" id=\"buddyUpExploreMapFocusSection\">\n                    <button type=\"button\" class=\"buddyUpExploreSectionToggle\" data-target=\"buddyUpExploreMapFocusBody\" aria-expanded=\"true\">\n                        Map Focus\n                        <span class=\"buddyUpExploreSectionChevron\" aria-hidden=\"true\">\u25be<\/span>\n                    <\/button>\n                    <div id=\"buddyUpExploreMapFocusBody\" class=\"buddyUpExploreSectionBody\">\n                        <div class=\"buddyUpExploreFocusToggle\" id=\"buddyUpExploreFocusToggle\">\n                            <button type=\"button\" id=\"buddyUpExploreFocusAll\" class=\"buddyUpExploreFocusBtn isActive\">All<\/button>\n                            <button type=\"button\" id=\"buddyUpExploreFocusNearMe\" class=\"buddyUpExploreFocusBtn\">Near Me<\/button>\n                        <\/div>\n                    <\/div>\n                <\/div>\n\n                <div id=\"buddyUpExploreRadiusSection\" class=\"buddyUpSearchSidebarSection buddyUpExploreSection buddyUpExploreSectionCollapsible hidden\">\n                    <button type=\"button\" class=\"buddyUpExploreSectionToggle\" data-target=\"buddyUpExploreRadiusBody\" aria-expanded=\"true\">\n                        Radius\n                        <span class=\"buddyUpExploreSectionChevron\" aria-hidden=\"true\">\u25be<\/span>\n                    <\/button>\n                    <div id=\"buddyUpExploreRadiusBody\" class=\"buddyUpExploreSectionBody\">\n                        <div class=\"buddyUpExploreRadiusRow\">\n                            <input id=\"buddyUpExploreZip\" class=\"buddyUpInput\" type=\"text\" placeholder=\"Zip code\" maxlength=\"10\" \/>\n                        <\/div>\n                        <div class=\"buddyUpExploreRadiusRow\">\n                            <input id=\"buddyUpExploreRadiusMiles\" class=\"buddyUpExploreRadiusSlider\" type=\"range\" min=\"5\" max=\"100\" step=\"5\" value=\"25\" \/>\n                            <div id=\"buddyUpExploreRadiusValue\" class=\"buddyUpExploreRadiusValue\">25 miles<\/div>\n                        <\/div>\n                        <button id=\"buddyUpExploreApplyRadius\" type=\"button\" class=\"buddyUpButton3 buddyUpExploreApplyRadius\">Apply Radius<\/button>\n                        <div id=\"buddyUpExploreRadiusHint\" class=\"textSmall buddyUpExploreRadiusHint\"><\/div>\n                    <\/div>\n                <\/div>\n\n                <div class=\"buddyUpSearchSidebarSection buddyUpExploreSection buddyUpExploreSectionCollapsible\" id=\"buddyUpExploreCategorySection\">\n                    <button type=\"button\" class=\"buddyUpExploreSectionToggle\" data-target=\"buddyUpExploreCategoryBody\" aria-expanded=\"true\">\n                        Categories\n                        <span class=\"buddyUpExploreSectionChevron\" aria-hidden=\"true\">\u25be<\/span>\n                    <\/button>\n                    <div id=\"buddyUpExploreCategoryBody\" class=\"buddyUpExploreSectionBody\">\n                        <div id=\"buddyUpExploreCategoryFilters\" class=\"buddyUpExploreToggleList\"><\/div>\n                    <\/div>\n                <\/div>\n\n                <div class=\"buddyUpSearchSidebarSection buddyUpExploreSection buddyUpExploreNearbySignedOut\" id=\"buddyUpExploreNearbySignedOut\">\n                    <div class=\"buddyUpExploreSectionTitle\">Nearby<\/div>\n                    <input id=\"buddyUpExploreNearbyRange\" class=\"buddyUpExploreNearbyRange\" type=\"range\" min=\"5\" max=\"100\" value=\"25\" disabled=\"disabled\" \/>\n                    <div class=\"buddyUpExploreNearbyLockCard\">\n                        <div class=\"buddyUpExploreNearbyLockTitle\">See Who\u2019s Out There<\/div>\n                        <div class=\"textSmall\">Join to See Buddies<\/div>\n                    <\/div>\n                <\/div>\n\n                <div id=\"buddyUpExploreFiltersOverlay\" class=\"buddyUpExploreFiltersOverlay hidden\">\n                    <div class=\"buddyUpExploreFiltersOverlayCard\">\n                        <strong>Unlock Full Explore<\/strong>\n                        <div class=\"textSmall\">Sign up or log in to discover nearby people, groups, and events.<\/div>\n                    <\/div>\n                <\/div>\n            <\/aside>\n\n            <div class=\"buddyUpExploreStatusBar\">\n                <div class=\"textSmall\" id=\"buddyUpExploreStatus\">Loading map...<\/div>\n            <\/div>\n\n            <div class=\"buddyUpExploreTopTabs\" id=\"buddyUpExploreTopTabs\">\n                <div class=\"buddyUpExploreTopTabsLabel\">View<\/div>\n                <div id=\"buddyUpExploreDatasetToggles\" class=\"buddyUpExploreTopTabsList\"><\/div>\n                <div id=\"buddyUpExploreLockMessage\" class=\"textSmall buddyUpExploreLock hidden\"><\/div>\n            <\/div>\n\n            <div class=\"buddyUpExploreMapCard\">\n                <div id=\"buddyUpExploreMap\" class=\"buddyUpExploreMap\"><\/div>\n                <div id=\"buddyUpExploreMapLoading\" class=\"buddyUpExploreMapLoading hidden\" aria-live=\"polite\" aria-busy=\"true\">\n                    <div class=\"buddyUpExploreMapLoadingInner\">\n                        <span class=\"buddyUpExploreSpinner\" aria-hidden=\"true\"><\/span>\n                        <span id=\"buddyUpExploreMapLoadingText\">Loading map data...<\/span>\n                    <\/div>\n                <\/div>\n            <\/div>\n\n            <div id=\"buddyUpExploreSignedOutTease\" class=\"buddyUpExploreSignedOutTease hidden\">\n                <button type=\"button\" id=\"buddyUpExploreTeaseClose\" class=\"buddyUpExploreTeaseClose\" aria-label=\"Close\">\u00d7<\/button>\n                <div class=\"buddyUpExploreTeaseTitle\">Join to see who shared this!<\/div>\n                <div class=\"buddyUpExploreTeaseThumbs\" id=\"buddyUpExploreTeaseThumbs\">\n                    <span><\/span><span><\/span><span><\/span><span><\/span><span><\/span><span><\/span>\n                <\/div>\n                <div class=\"buddyUpExploreTeaseCopy\">Join BuddyUpGo to connect with people who share your interests<\/div>\n                <a href=\"https:\/\/buddyupapi-staging.us35.cdn-alpha.com\/register\/\" class=\"buddyUpButton1 buddyUpExploreTeaseCta\">Join FREE to Connect<\/a>\n            <\/div>\n\n            <div id=\"buddyUpExploreSignedOutBottomCta\" class=\"buddyUpExploreSignedOutBottomCta hidden\">\n                <span>Explore is better with Buddies.<\/span>\n                <a href=\"https:\/\/buddyupapi-staging.us35.cdn-alpha.com\/register\/\" class=\"buddyUpButton1\">Join FREE to Connect<\/a>\n            <\/div>\n        <\/div>\n    <\/div>\n<\/section>\n<script>(async function(){\n    const wrapper = document.getElementById('buddyUpExploreWrapper');\n    if (!wrapper) return;\n\n    const statusEl = document.getElementById('buddyUpExploreStatus');\n    const mapEl = document.getElementById('buddyUpExploreMap');\n    const mapLoadingEl = document.getElementById('buddyUpExploreMapLoading');\n    const mapLoadingTextEl = document.getElementById('buddyUpExploreMapLoadingText');\n    const datasetTogglesEl = document.getElementById('buddyUpExploreDatasetToggles');\n    const categoryFiltersEl = document.getElementById('buddyUpExploreCategoryFilters');\n    const lockMessageEl = document.getElementById('buddyUpExploreLockMessage');\n    const nearbySignedOutEl = document.getElementById('buddyUpExploreNearbySignedOut');\n    const signedOutTeaseEl = document.getElementById('buddyUpExploreSignedOutTease');\n    const signedOutTeaseThumbsEl = document.getElementById('buddyUpExploreTeaseThumbs');\n    const teaseCloseBtn = document.getElementById('buddyUpExploreTeaseClose');\n    const signedOutBottomCtaEl = document.getElementById('buddyUpExploreSignedOutBottomCta');\n    const sidebarEl = document.getElementById('buddyUpExploreSidebar');\n    const sidebarToggleBtn = document.getElementById('buddyUpExploreSidebarToggle');\n    const filtersOverlayEl = document.getElementById('buddyUpExploreFiltersOverlay');\n    const focusSectionEl = document.getElementById('buddyUpExploreMapFocusSection');\n    const focusAllBtn = document.getElementById('buddyUpExploreFocusAll');\n    const focusNearMeBtn = document.getElementById('buddyUpExploreFocusNearMe');\n    const searchNearSectionEl = document.getElementById('buddyUpExploreSearchNearSection');\n    const searchNearInput = document.getElementById('buddyUpExploreSearchNear');\n    const searchNearOptions = document.getElementById('buddyUpExploreSearchNearOptions');\n    const searchNearApplyBtn = document.getElementById('buddyUpExploreSearchNearApply');\n    const searchNearHint = document.getElementById('buddyUpExploreSearchNearHint');\n    const categorySectionEl = document.getElementById('buddyUpExploreCategorySection');\n    const radiusSectionEl = document.getElementById('buddyUpExploreRadiusSection');\n    const zipInput = document.getElementById('buddyUpExploreZip');\n    const radiusInput = document.getElementById('buddyUpExploreRadiusMiles');\n    const radiusValueEl = document.getElementById('buddyUpExploreRadiusValue');\n    const applyRadiusBtn = document.getElementById('buddyUpExploreApplyRadius');\n    const radiusHint = document.getElementById('buddyUpExploreRadiusHint');\n\n    const currentUser = (typeof BUDDYUP !== 'undefined' && typeof BUDDYUP.getCurrentUser === 'function')\n        ? BUDDYUP.getCurrentUser()\n        : null;\n    const ssrAuth = (typeof BUDDYUP !== 'undefined' && typeof BUDDYUP.getSsrAuthState === 'function')\n        ? BUDDYUP.getSsrAuthState()\n        : { logged_in: 0, user_id: 0, subscription_tier: 0 };\n    const isLoggedIn = !!(\n        (currentUser && currentUser.id) ||\n        (typeof BUDDYUP.isLoggedInFast === 'function' && BUDDYUP.isLoggedInFast()) ||\n        Number(ssrAuth.logged_in || 0) === 1\n    );\n    const currentUserId = Number((currentUser && currentUser.id) || ssrAuth.user_id || 0);\n\n    let tier = 0;\n    if (isLoggedIn) {\n        if (currentUser && typeof BUDDYUP.getSubscriptionTier === 'function') {\n            tier = Number(await BUDDYUP.getSubscriptionTier());\n        } else {\n            tier = Number(ssrAuth.subscription_tier || 0);\n        }\n    }\n    if (typeof BUDDYUP.normalizeSubscriptionTier === 'function') {\n        tier = BUDDYUP.normalizeSubscriptionTier(tier);\n    } else if (![0, 1, 2].includes(tier)) {\n        tier = 0;\n    }\n\n    if (!isLoggedIn && typeof BUDDYUP.syncAuthStateWithServer === 'function') {\n        BUDDYUP.syncAuthStateWithServer(false);\n    }\n\n    const state = {\n        mode: 'adventures',\n        categories: new Set(),\n        allByMode: {\n            adventures: [],\n            events: [],\n            groups: [],\n            buddies: [],\n            users: [],\n        },\n        loadedModes: {\n            adventures: false,\n            events: false,\n            groups: false,\n            buddies: false,\n            users: false,\n        },\n        zipCenter: null,\n        radiusMiles: 25,\n        buddyIds: new Set(),\n        sidebarCollapsed: false,\n        mapFocus: 'all',\n        userNearCenter: null,\n        searchNearCenter: null,\n        searchNearSuggestions: [],\n        searchNearDebounceTimer: null,\n    };\n\n    const exploreSSR = window.buddyUpExploreSSR && typeof window.buddyUpExploreSSR === 'object'\n        ? window.buddyUpExploreSSR\n        : null;\n    let usedExploreSSR = false;\n\n    const getExploreAggregatePayload = async () => {\n        if (exploreSSR && String(exploreSSR.status || '').toLowerCase() === 'success') {\n            return exploreSSR;\n        }\n\n        const resp = await BUDDYUP.apiRequest('explore-aggregate', {\n            limit_adventures: 350,\n            limit_events: 80,\n            limit_groups: 40,\n            include_events: 1,\n            include_groups: 1,\n        });\n\n        if (!resp || String(resp.status || '').toLowerCase() !== 'success') return null;\n        return resp;\n    };\n\n    const GEO_CACHE_KEY = 'buddyupExploreGeoCacheV1';\n    const GEO_CACHE_MAX_AGE_MS = 1000 * 60 * 60 * 24 * 30;\n    const GEO_CACHE = {};\n    const GEO_IN_FLIGHT = {};\n    let map = null;\n    let markersLayer = null;\n    let mapLoadingToken = 0;\n\n    const safe = (v) => String(v || '').replace(\/[&<>\\\"]\/g, (m) => ({ '&': '&amp;', '<': '&lt;', '>': '&gt;', '\"': '&quot;' }[m]));\n    const isMobile = () => window.matchMedia('(max-width: 980px)').matches;\n\n    const loadLeaflet = async () => {\n        if (window.L && typeof window.L.map === 'function') return true;\n        if (!document.getElementById('buddyupLeafletCss')) {\n            const css = document.createElement('link');\n            css.id = 'buddyupLeafletCss';\n            css.rel = 'stylesheet';\n            css.href = 'https:\/\/unpkg.com\/leaflet@1.9.4\/dist\/leaflet.css';\n            document.head.appendChild(css);\n        }\n        await new Promise((resolve, reject) => {\n            if (document.getElementById('buddyupLeafletJs')) return resolve();\n            const js = document.createElement('script');\n            js.id = 'buddyupLeafletJs';\n            js.src = 'https:\/\/unpkg.com\/leaflet@1.9.4\/dist\/leaflet.js';\n            js.onload = resolve;\n            js.onerror = reject;\n            document.body.appendChild(js);\n        });\n        return !!(window.L && typeof window.L.map === 'function');\n    };\n\n    const loadGeoCacheFromStorage = () => {\n        try {\n            const raw = window.localStorage ? window.localStorage.getItem(GEO_CACHE_KEY) : '';\n            if (!raw) return;\n            const parsed = JSON.parse(raw);\n            if (!parsed || typeof parsed !== 'object') return;\n            const now = Date.now();\n\n            Object.keys(parsed).forEach((key) => {\n                const entry = parsed[key];\n                if (!entry || typeof entry !== 'object') return;\n                const ts = Number(entry.ts || 0);\n                if (!isFinite(ts) || (now - ts) > GEO_CACHE_MAX_AGE_MS) return;\n                if (!isFinite(Number(entry.latitude)) || !isFinite(Number(entry.longitude))) return;\n\n                GEO_CACHE[key] = {\n                    latitude: Number(entry.latitude),\n                    longitude: Number(entry.longitude),\n                    city: String(entry.city || ''),\n                    state: String(entry.state || ''),\n                    label: String(entry.label || key),\n                };\n            });\n        } catch (e) {}\n    };\n\n    const persistGeoCacheToStorage = () => {\n        try {\n            if (!window.localStorage) return;\n            const payload = {};\n            const now = Date.now();\n            Object.keys(GEO_CACHE).forEach((key) => {\n                const item = GEO_CACHE[key];\n                if (!item || !isFinite(item.latitude) || !isFinite(item.longitude)) return;\n                payload[key] = {\n                    latitude: Number(item.latitude),\n                    longitude: Number(item.longitude),\n                    city: String(item.city || ''),\n                    state: String(item.state || ''),\n                    label: String(item.label || ''),\n                    ts: now,\n                };\n            });\n            window.localStorage.setItem(GEO_CACHE_KEY, JSON.stringify(payload));\n        } catch (e) {}\n    };\n\n    const cacheGeo = (cacheKey, geo) => {\n        GEO_CACHE[cacheKey] = geo;\n        persistGeoCacheToStorage();\n        return geo;\n    };\n\n    const geocodeText = async (text) => {\n        const q = String(text || '').trim();\n        if (!q) return null;\n\n        const cacheKey = q.toLowerCase();\n        if (GEO_CACHE[cacheKey]) return GEO_CACHE[cacheKey];\n        if (GEO_IN_FLIGHT[cacheKey]) return GEO_IN_FLIGHT[cacheKey];\n\n        GEO_IN_FLIGHT[cacheKey] = (async () => {\n            const found = await BUDDYUP.locationAutocompleteSearch(q);\n            if (!Array.isArray(found) || found.length === 0) return null;\n            const first = found[0];\n            if (!first || !isFinite(first.latitude) || !isFinite(first.longitude)) return null;\n            return cacheGeo(cacheKey, {\n                latitude: Number(first.latitude),\n                longitude: Number(first.longitude),\n                city: first.city || '',\n                state: first.state || '',\n                label: first.label || q,\n            });\n        })();\n\n        try {\n            return await GEO_IN_FLIGHT[cacheKey];\n        } finally {\n            delete GEO_IN_FLIGHT[cacheKey];\n        }\n    };\n\n    const mapWithConcurrency = async (items, limit, run) => {\n        const arr = Array.isArray(items) ? items : [];\n        if (!arr.length) return [];\n\n        const cap = Math.max(1, Number(limit || 1));\n        const out = new Array(arr.length);\n        let index = 0;\n\n        const workers = Array.from({ length: Math.min(cap, arr.length) }, async () => {\n            while (true) {\n                const i = index;\n                index += 1;\n                if (i >= arr.length) return;\n                out[i] = await run(arr[i], i);\n            }\n        });\n\n        await Promise.all(workers);\n        return out;\n    };\n\n    const buildRowLocationText = (row) => [row && row.city ? row.city : '', row && row.state ? row.state : '']\n        .filter(Boolean)\n        .join(', ')\n        .trim();\n\n    const resolveGeoLookupForTexts = async (texts, statusPrefix) => {\n        const uniqueTexts = Array.from(new Set((texts || []).map((x) => String(x || '').trim()).filter(Boolean)));\n        const lookup = {};\n        if (!uniqueTexts.length) return lookup;\n\n        if (statusEl && statusPrefix) {\n            statusEl.innerText = `${statusPrefix} (${uniqueTexts.length} locations)...`;\n        }\n\n        const pairs = await mapWithConcurrency(uniqueTexts, 8, async (text) => {\n            const geo = await geocodeText(text);\n            return [text, geo];\n        });\n\n        pairs.forEach((pair) => {\n            if (!Array.isArray(pair) || pair.length < 2) return;\n            const key = String(pair[0] || '').trim();\n            const geo = pair[1];\n            if (!key || !geo) return;\n            lookup[key] = geo;\n        });\n\n        return lookup;\n    };\n\n    const haversineMiles = (lat1, lon1, lat2, lon2) => {\n        const toRad = (d) => d * (Math.PI \/ 180);\n        const R = 3958.8;\n        const dLat = toRad(lat2 - lat1);\n        const dLon = toRad(lon2 - lon1);\n        const a = Math.sin(dLat\/2) * Math.sin(dLat\/2) + Math.cos(toRad(lat1)) * Math.cos(toRad(lat2)) * Math.sin(dLon\/2) * Math.sin(dLon\/2);\n        const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));\n        return R * c;\n    };\n\n    const modeRules = {\n        adventures: { label: 'Adventures', locked: false },\n        events: { label: 'Events', locked: !isLoggedIn || tier === 0 },\n        groups: { label: 'Groups', locked: !isLoggedIn || tier === 0 },\n        buddies: { label: 'Buddies', locked: !isLoggedIn },\n        users: { label: 'Users', locked: !isLoggedIn },\n    };\n\n    const renderSignedOutState = () => {\n        if (signedOutTeaseEl) signedOutTeaseEl.classList.toggle('hidden', isLoggedIn);\n        if (signedOutBottomCtaEl) signedOutBottomCtaEl.classList.toggle('hidden', isLoggedIn);\n        if (nearbySignedOutEl) nearbySignedOutEl.classList.toggle('hidden', isLoggedIn);\n\n        if (sidebarEl) sidebarEl.classList.toggle('isLoggedOut', !isLoggedIn);\n        if (filtersOverlayEl) {\n            filtersOverlayEl.classList.toggle('hidden', isLoggedIn);\n        }\n\n        [searchNearInput, searchNearApplyBtn, focusNearMeBtn, focusAllBtn].forEach((el) => {\n            if (!el) return;\n            if (!isLoggedIn) el.setAttribute('disabled', 'disabled');\n            else el.removeAttribute('disabled');\n        });\n\n        if (teaseCloseBtn && signedOutTeaseEl) {\n            teaseCloseBtn.addEventListener('click', () => signedOutTeaseEl.classList.add('hidden'));\n        }\n\n        if (!isLoggedIn) {\n            if (radiusSectionEl) radiusSectionEl.classList.add('hidden');\n            if (categorySectionEl) categorySectionEl.classList.add('hidden');\n        } else {\n            if (categorySectionEl) categorySectionEl.classList.remove('hidden');\n        }\n\n        if (!isLoggedIn) {\n            if (focusSectionEl) focusSectionEl.classList.add('hidden');\n            if (searchNearSectionEl) searchNearSectionEl.classList.add('hidden');\n        } else {\n            if (focusSectionEl) focusSectionEl.classList.remove('hidden');\n            if (searchNearSectionEl) searchNearSectionEl.classList.remove('hidden');\n        }\n    };\n\n    const renderFocusToggle = () => {\n        if (focusAllBtn) focusAllBtn.classList.toggle('isActive', state.mapFocus === 'all');\n        if (focusNearMeBtn) focusNearMeBtn.classList.toggle('isActive', state.mapFocus === 'nearme');\n    };\n\n    const resolveNearMeCenterFromUser = async () => {\n        if (!isLoggedIn || !isFinite(currentUserId) || currentUserId <= 0) return null;\n        if (state.userNearCenter) return state.userNearCenter;\n\n        let searchText = '';\n        const zipCandidate = currentUser.zip_code || currentUser.zip || currentUser.postal_code || '';\n        if (zipCandidate) {\n            searchText = String(zipCandidate).trim();\n        }\n\n        if (!searchText) {\n            const account = await BUDDYUP.apiRequest('account-get', {\n                id: currentUserId,\n                fields: 'id,postal_code,zip,zip_code,city,state'\n            });\n            if (account && account.status === 'success') {\n                const zip = account.zip_code || account.zip || account.postal_code || '';\n                if (zip) searchText = String(zip).trim();\n                if (!searchText) {\n                    const city = account.city || '';\n                    const stateName = account.state || '';\n                    searchText = [city, stateName].filter(Boolean).join(', ');\n                }\n            }\n        }\n\n        if (!searchText) return null;\n\n        const center = await geocodeText(searchText);\n        if (!center) return null;\n        state.userNearCenter = {\n            latitude: Number(center.latitude),\n            longitude: Number(center.longitude),\n        };\n        return state.userNearCenter;\n    };\n\n    const renderSearchNearSuggestions = () => {\n        if (!searchNearOptions) return;\n        const options = Array.isArray(state.searchNearSuggestions) ? state.searchNearSuggestions : [];\n        searchNearOptions.innerHTML = options.map((x) => {\n            const label = x && x.label ? String(x.label) : '';\n            return label ? `<option value=\"${safe(label)}\"><\/option>` : '';\n        }).join('');\n    };\n\n    const applySearchNearCenter = async () => {\n        if (!isLoggedIn || !searchNearInput) return;\n        const query = String(searchNearInput.value || '').trim();\n        if (!query) {\n            state.searchNearCenter = null;\n            if (searchNearHint) searchNearHint.innerText = '';\n            renderMap();\n            return;\n        }\n\n        const center = await geocodeText(query);\n        if (!center) {\n            if (searchNearHint) searchNearHint.innerText = 'Could not locate that place.';\n            return;\n        }\n\n        state.searchNearCenter = {\n            latitude: Number(center.latitude),\n            longitude: Number(center.longitude),\n            label: String(center.label || query),\n        };\n        if (searchNearHint) searchNearHint.innerText = `Centered near ${state.searchNearCenter.label}.`;\n        renderMap();\n        closeSidebarOnMobile();\n    };\n\n    const syncSidebarUi = () => {\n        if (!sidebarEl || !sidebarToggleBtn) return;\n\n        const mobileLayout = isMobile();\n        if (!mobileLayout) {\n            state.sidebarCollapsed = false;\n\n            if (typeof BUDDYUP.closeFiltersShelf === 'function') {\n                BUDDYUP.closeFiltersShelf();\n            }\n\n            sidebarEl.classList.remove('isCollapsed');\n            sidebarEl.classList.remove('isOpen');\n            sidebarEl.classList.remove('activeMobileMenu');\n            sidebarEl.setAttribute('aria-hidden', 'false');\n            sidebarToggleBtn.classList.add('hidden');\n            sidebarToggleBtn.setAttribute('aria-expanded', 'true');\n            return;\n        }\n\n        const isOpen = !state.sidebarCollapsed;\n        sidebarToggleBtn.classList.remove('hidden');\n        sidebarEl.classList.toggle('isCollapsed', !isOpen);\n        sidebarToggleBtn.setAttribute('aria-expanded', isOpen ? 'true' : 'false');\n\n        if (isOpen) {\n            if (typeof BUDDYUP.openFiltersShelf === 'function') {\n                BUDDYUP.openFiltersShelf(sidebarEl);\n            } else {\n                sidebarEl.classList.add('isOpen');\n                sidebarEl.classList.add('activeMobileMenu');\n                sidebarEl.setAttribute('aria-hidden', 'false');\n            }\n            return;\n        }\n\n        if (typeof BUDDYUP.closeFiltersShelf === 'function') {\n            BUDDYUP.closeFiltersShelf();\n        } else {\n            sidebarEl.classList.remove('isOpen');\n            sidebarEl.classList.remove('activeMobileMenu');\n            sidebarEl.setAttribute('aria-hidden', 'true');\n        }\n    };\n\n    const closeSidebarOnMobile = () => {\n        if (!isMobile()) return;\n        state.sidebarCollapsed = true;\n        syncSidebarUi();\n    };\n\n    const sampleTeaseAdventureImages = () => {\n        const adventures = Array.isArray(state.allByMode.adventures) ? state.allByMode.adventures : [];\n        const all = adventures\n            .flatMap((adv) => {\n                const lead = adv && adv.image ? [String(adv.image)] : [];\n                const media = Array.isArray(adv && adv.media)\n                    ? adv.media.map((m) => m && m.url ? String(m.url) : '').filter(Boolean)\n                    : [];\n                return lead.concat(media);\n            })\n            .filter(Boolean);\n\n        const unique = Array.from(new Set(all));\n        for (let i = unique.length - 1; i > 0; i--) {\n            const j = Math.floor(Math.random() * (i + 1));\n            const t = unique[i];\n            unique[i] = unique[j];\n            unique[j] = t;\n        }\n        return unique.slice(0, 6);\n    };\n\n    const renderSignedOutTeaseThumbs = () => {\n        if (!signedOutTeaseThumbsEl) return;\n        const images = sampleTeaseAdventureImages();\n        if (!images.length) return;\n\n        signedOutTeaseThumbsEl.innerHTML = images.map((url, i) => (\n            `<img decoding=\"async\" src=\"${safe(url)}\" alt=\"Adventure preview ${i + 1}\" \/>`\n        )).join('');\n    };\n\n    const setMapLoading = (isLoading, message) => {\n        if (mapLoadingTextEl && message) {\n            mapLoadingTextEl.innerText = String(message);\n        }\n\n        if (!mapLoadingEl) return;\n\n        if (isLoading) {\n            mapLoadingEl.classList.remove('hidden');\n            if (markersLayer) {\n                markersLayer.clearLayers();\n            }\n            return;\n        }\n\n        mapLoadingEl.classList.add('hidden');\n    };\n\n    const renderModeToggles = () => {\n        datasetTogglesEl.innerHTML = '';\n\n        if (!isLoggedIn) {\n            const signedOutInterests = ['Fishing', 'Canoeing', 'Boating', 'Hiking'];\n            signedOutInterests.forEach((label, i) => {\n                const id = `buddyUpExploreSignedOutInterest_${i}`;\n                datasetTogglesEl.insertAdjacentHTML('beforeend', `\n                    <button id=\"${id}\" type=\"button\" class=\"buddyUpButton3 buddyUpExploreToggle isActive\" disabled=\"disabled\">\u2713 ${safe(label)}<\/button>\n                `);\n            });\n            lockMessageEl.classList.add('hidden');\n            lockMessageEl.innerHTML = '';\n            return;\n        }\n\n        Object.keys(modeRules).forEach((mode) => {\n            const rule = modeRules[mode];\n            const id = `buddyUpExploreMode_${mode}`;\n            datasetTogglesEl.insertAdjacentHTML('beforeend', `\n                <button id=\"${id}\" type=\"button\" class=\"buddyUpButton3 buddyUpExploreToggle ${state.mode === mode ? 'isActive' : ''}\" ${rule.locked ? 'disabled=\"disabled\"' : ''}>\n                    ${rule.locked ? '\ud83d\udd12 ' : ''}${rule.label}\n                <\/button>\n            `);\n            const btn = document.getElementById(id);\n            if (btn) {\n                btn.addEventListener('click', async () => {\n                    if (state.mode === mode) return;\n\n                    const loadToken = ++mapLoadingToken;\n                    setMapLoading(true, `Loading ${rule.label}...`);\n\n                    state.mode = mode;\n                    state.categories = new Set();\n\n                    try {\n                        await ensureModeLoaded(mode);\n                        renderModeToggles();\n                        renderCategories();\n                        toggleRadiusSection();\n                        renderMap();\n                    } finally {\n                        if (loadToken === mapLoadingToken) {\n                            setMapLoading(false);\n                        }\n                    }\n                });\n            }\n        });\n\n        if (!isLoggedIn) {\n            lockMessageEl.classList.add('hidden');\n            lockMessageEl.innerHTML = '';\n        } else if (tier === 0) {\n            lockMessageEl.classList.remove('hidden');\n            lockMessageEl.innerHTML = 'Free tier can use Adventures, Buddies, and Users. Upgrade to unlock Events and Groups on Explore.';\n        } else {\n            lockMessageEl.classList.add('hidden');\n            lockMessageEl.innerHTML = '';\n        }\n    };\n\n    const getCategoriesForMode = () => {\n        const items = state.allByMode[state.mode] || [];\n        const catMap = {};\n        items.forEach((item) => {\n            const cats = Array.isArray(item.categories) ? item.categories : [];\n            cats.forEach((cat) => {\n                const c = String(cat || '').trim();\n                if (!c) return;\n                const key = c.toLowerCase();\n                catMap[key] = c;\n            });\n        });\n        return Object.keys(catMap).sort().map((key) => catMap[key]);\n    };\n\n    const renderCategories = () => {\n        categoryFiltersEl.innerHTML = '';\n        const categories = getCategoriesForMode();\n        if (!categories.length) {\n            categoryFiltersEl.innerHTML = '<div class=\"textSmall\" style=\"opacity:.75;\">No categories found.<\/div>';\n            return;\n        }\n\n        categories.forEach((cat, i) => {\n            const id = `buddyUpExploreCat_${i}`;\n            const active = state.categories.has(cat.toLowerCase());\n            categoryFiltersEl.insertAdjacentHTML('beforeend', `\n                <button id=\"${id}\" type=\"button\" class=\"buddyUpButton3 buddyUpExploreToggle buddyUpExploreCategoryToggle ${active ? 'isActive' : ''}\">${safe(cat)}<\/button>\n            `);\n            const btn = document.getElementById(id);\n            if (btn) {\n                btn.addEventListener('click', () => {\n                    const key = cat.toLowerCase();\n                    if (state.categories.has(key)) {\n                        state.categories = new Set();\n                    } else {\n                        state.categories = new Set([key]);\n                    }\n                    renderCategories();\n                    renderMap();\n                    closeSidebarOnMobile();\n                });\n            }\n        });\n    };\n\n    const toggleRadiusSection = () => {\n        const show = isLoggedIn;\n        if (show) radiusSectionEl.classList.remove('hidden');\n        else radiusSectionEl.classList.add('hidden');\n    };\n\n    const updateRadiusLabel = () => {\n        if (!radiusInput || !radiusValueEl) return;\n        const miles = Number(radiusInput.value || state.radiusMiles || 25);\n        radiusValueEl.innerText = `${miles} miles`;\n    };\n\n    const initCollapsibleSections = () => {\n        if (!sidebarEl) return;\n\n        const toggles = sidebarEl.querySelectorAll('.buddyUpExploreSectionToggle[data-target]');\n        toggles.forEach((btn) => {\n            if (!btn || btn.dataset.bound === '1') return;\n\n            const targetId = String(btn.getAttribute('data-target') || '').trim();\n            if (!targetId) return;\n\n            const body = document.getElementById(targetId);\n            const section = btn.closest('.buddyUpExploreSectionCollapsible');\n            if (!body || !section) return;\n\n            btn.dataset.bound = '1';\n            btn.addEventListener('click', () => {\n                const isCollapsed = section.classList.toggle('isCollapsed');\n                btn.setAttribute('aria-expanded', isCollapsed ? 'false' : 'true');\n            });\n        });\n    };\n\n    const normalizeAdventureItems = (rows) => {\n        return (rows || []).filter((row) => row && isFinite(Number(row.latitude)) && isFinite(Number(row.longitude))).map((row) => ({\n            type: 'adventure',\n            id: Number(row.id),\n            title: row.title || 'Adventure',\n            subtitle: [row.city, row.state].filter(Boolean).join(', ') || row.location_label || '',\n            description: row.body || '',\n            latitude: Number(row.latitude),\n            longitude: Number(row.longitude),\n            categories: Array.isArray(row.categories) ? row.categories : [],\n            image: row.preview_url || '',\n            media: Array.isArray(row.media) ? row.media : [],\n        }));\n    };\n\n    const normalizeEvents = async (seedRows) => {\n        let rows = Array.isArray(seedRows) ? seedRows : null;\n        if (!rows) {\n            const resp = await BUDDYUP.apiRequest('events-search', {});\n            rows = resp && Array.isArray(resp.upcoming) ? resp.upcoming : [];\n        }\n        const sourceRows = rows.slice(0, 60);\n\n        \/\/ Build a location string for each event, using all available address fields\n        const buildEventLocText = (ev) => {\n            const cityState = [ev.city, ev.state].filter(Boolean).join(', ');\n            if (cityState) return cityState;\n            if (ev.zip) return String(ev.zip);\n            if (ev.location_name) return String(ev.location_name);\n            if (ev.location_label) return String(ev.location_label);\n            const addr = [ev.address, ev.address2, ev.city, ev.state, ev.zip].filter(Boolean).join(', ');\n            if (addr) return addr;\n            return '';\n        };\n\n        const unresolvedTexts = sourceRows\n            .filter((ev) => !isFinite(Number(ev && ev.latitude)) || !isFinite(Number(ev && ev.longitude)))\n            .map((ev) => buildEventLocText(ev));\n\n        const geoLookup = await resolveGeoLookupForTexts(unresolvedTexts, 'Resolving event locations');\n\n        const out = [];\n        for (const ev of sourceRows) {\n            const locText = buildEventLocText(ev);\n            const rowLat = Number(ev && ev.latitude);\n            const rowLng = Number(ev && ev.longitude);\n\n            let latitude = null;\n            let longitude = null;\n\n            if (isFinite(rowLat) && isFinite(rowLng) && !(rowLat === 0 && rowLng === 0)) {\n                latitude = rowLat;\n                longitude = rowLng;\n            } else {\n                const geo = geoLookup[locText] || null;\n                if (!geo) continue;\n                latitude = Number(geo.latitude);\n                longitude = Number(geo.longitude);\n            }\n\n            out.push({\n                type: 'event',\n                id: Number(ev.event_id || ev.id || 0),\n                title: ev.event_name || ev.name || 'Event',\n                subtitle: [ev.city, ev.state].filter(Boolean).join(', ') || locText,\n                latitude,\n                longitude,\n                categories: Array.isArray(ev.event_categories) ? ev.event_categories : (Array.isArray(ev.categories) ? ev.categories : []),\n                image: ev.event_image || ev.image || '',\n            });\n        }\n        return out;\n    };\n\n    const normalizeGroups = async (seedRows) => {\n        let rows = Array.isArray(seedRows) ? seedRows : null;\n        if (!rows) {\n            const resp = await BUDDYUP.apiRequest('groups-search', {});\n            rows = resp && Array.isArray(resp.groups) ? resp.groups : [];\n        }\n        const sourceRows = rows.slice(0, 30);\n        const fullRows = sourceRows.map((group) => {\n            const locText = [group.city, group.state].filter(Boolean).join(', ') || group.location_label || group.address_1 || group.address || '';\n            return { group, locText };\n        });\n\n        const unresolvedTexts = fullRows\n            .filter((x) => !isFinite(Number(x && x.group && x.group.latitude)) || !isFinite(Number(x && x.group && x.group.longitude)))\n            .map((x) => x.locText);\n\n        const geoLookup = await resolveGeoLookupForTexts(unresolvedTexts, 'Resolving group locations');\n\n        const out = [];\n        for (const row of fullRows) {\n            const group = row.group;\n            const locText = row.locText || '';\n            const rowLat = Number(group && group.latitude);\n            const rowLng = Number(group && group.longitude);\n\n            let latitude = null;\n            let longitude = null;\n\n            if (isFinite(rowLat) && isFinite(rowLng) && !(rowLat === 0 && rowLng === 0)) {\n                latitude = rowLat;\n                longitude = rowLng;\n            } else {\n                const geo = geoLookup[locText] || null;\n                if (!geo) continue;\n                latitude = Number(geo.latitude);\n                longitude = Number(geo.longitude);\n            }\n\n            out.push({\n                type: 'group',\n                id: Number(group.id || 0),\n                title: group.name || 'Group',\n                subtitle: locText,\n                latitude,\n                longitude,\n                categories: Array.isArray(group.categories) ? group.categories : [],\n                image: group.image || '',\n            });\n        }\n        return out;\n    };\n\n    const resolveBuddyIds = async () => {\n        if (!isLoggedIn || !isFinite(currentUserId) || currentUserId <= 0) return;\n        const account = await BUDDYUP.apiRequest('account-get', {\n            id: currentUserId,\n            include: 'buddies',\n            fields: 'id,buddies'\n        });\n        const buddies = account && Array.isArray(account.buddies) ? account.buddies : [];\n        buddies.forEach((b) => {\n            if (b && b.id) state.buddyIds.add(Number(b.id));\n        });\n    };\n\n    const normalizeUsers = async () => {\n        const resp = await BUDDYUP.apiRequest('users-search', { location: '', categories: [] });\n        const rows = resp && Array.isArray(resp.users) ? resp.users : [];\n        const sourceRows = rows.slice(0, 250).filter((user) => {\n            if (!user || !user.id) return false;\n            if (isFinite(currentUserId) && currentUserId > 0) {\n                return Number(user.id) !== currentUserId;\n            }\n            return true;\n        });\n        const geoLookup = await resolveGeoLookupForTexts(\n            sourceRows.map((user) => buildRowLocationText(user)),\n            'Resolving buddies and users locations'\n        );\n        const out = [];\n        for (const user of sourceRows) {\n            const locText = buildRowLocationText(user);\n            const geo = geoLookup[locText] || null;\n            if (!geo) continue;\n            out.push({\n                type: state.buddyIds.has(Number(user.id)) ? 'buddy' : 'user',\n                id: Number(user.id),\n                title: (user.username || '').trim() || (user.full_name || '').trim() || `${user.first_name || ''} ${user.last_name || ''}`.trim() || 'User',\n                subtitle: locText,\n                latitude: Number(geo.latitude),\n                longitude: Number(geo.longitude),\n                categories: Array.isArray(user.interests) ? user.interests : [],\n                image: user.profile_image ? BUDDYUP.profileImageSrc(user.profile_image) : '',\n            });\n        }\n        state.allByMode.buddies = out.filter((x) => x.type === 'buddy');\n        state.allByMode.users = out.filter((x) => x.type === 'user');\n    };\n\n    const ensureModeLoaded = async (mode) => {\n        if (!mode || state.loadedModes[mode] === true) return;\n\n        if (mode === 'adventures') {\n            statusEl.innerText = 'Loading Adventures...';\n\n            let adventuresRows = [];\n            if (!usedExploreSSR && exploreSSR && String(exploreSSR.status || '').toLowerCase() === 'success' && Array.isArray(exploreSSR.adventures)) {\n                adventuresRows = exploreSSR.adventures;\n                usedExploreSSR = true;\n            } else {\n                const adv = await BUDDYUP.apiRequest('adventures-explore-map', { limit: 350 });\n                adventuresRows = adv && adv.status === 'success' && Array.isArray(adv.adventures) ? adv.adventures : [];\n            }\n\n            state.allByMode.adventures = normalizeAdventureItems(adventuresRows);\n            state.loadedModes.adventures = true;\n            renderSignedOutTeaseThumbs();\n            return;\n        }\n\n        if (!isLoggedIn) return;\n\n        if (mode === 'events') {\n            statusEl.innerText = 'Loading Events...';\n            const aggregate = await getExploreAggregatePayload();\n            const seed = aggregate && Array.isArray(aggregate.events) ? aggregate.events : null;\n            state.allByMode.events = await normalizeEvents(seed);\n            state.loadedModes.events = true;\n            return;\n        }\n\n        if (mode === 'groups') {\n            statusEl.innerText = 'Loading Groups...';\n            const aggregate = await getExploreAggregatePayload();\n            const seed = aggregate && Array.isArray(aggregate.groups) ? aggregate.groups : null;\n            state.allByMode.groups = await normalizeGroups(seed);\n            state.loadedModes.groups = true;\n            return;\n        }\n\n        if (mode === 'users' || mode === 'buddies') {\n            statusEl.innerText = 'Loading Buddies and Users...';\n            await resolveBuddyIds();\n            await normalizeUsers();\n            state.loadedModes.users = true;\n            state.loadedModes.buddies = true;\n            return;\n        }\n    };\n\n    const getActiveCenter = () => {\n        if (state.searchNearCenter) {\n            return {\n                latitude: Number(state.searchNearCenter.latitude),\n                longitude: Number(state.searchNearCenter.longitude),\n            };\n        }\n\n        if (state.mapFocus === 'nearme' && state.userNearCenter) {\n            return {\n                latitude: Number(state.userNearCenter.latitude),\n                longitude: Number(state.userNearCenter.longitude),\n            };\n        }\n\n        return null;\n    };\n\n    const getFilteredItems = () => {\n        let items = state.allByMode[state.mode] || [];\n\n        if (state.categories.size > 0) {\n            items = items.filter((item) => {\n                const itemCats = Array.isArray(item.categories) ? item.categories.map((c) => String(c).toLowerCase()) : [];\n                return itemCats.some((c) => state.categories.has(c));\n            });\n        }\n\n        const center = getActiveCenter();\n        if (center && state.mapFocus === 'nearme' && isFinite(state.radiusMiles)) {\n            items = items.filter((item) => {\n                const d = haversineMiles(center.latitude, center.longitude, Number(item.latitude), Number(item.longitude));\n                return d <= state.radiusMiles;\n            });\n        }\n\n        return items;\n    };\n\n    const buildIcon = (item) => {\n        if (item.type === 'adventure' && item.image) {\n            return L.divIcon({\n                className: 'buddyUpExplorePinWrap',\n                html: `<div class=\"buddyUpExplorePin\"><img decoding=\"async\" src=\"${safe(item.image)}\" alt=\"Adventure\" \/><span class=\"buddyUpExplorePinDot\"><\/span><\/div>`,\n                iconSize: [64, 72],\n                iconAnchor: [32, 60],\n                popupAnchor: [0, -56],\n            });\n        }\n        return null;\n    };\n\n    \/\/ Build deep links into the matching single-detail pages.\n    const buildDetailLink = (item) => {\n        if (!item || !item.id) return '';\n        const id = Number(item.id);\n        if (!isFinite(id) || id <= 0) return '';\n\n        const addPathId = (base, paramName) => {\n            const url = String(base || '').trim();\n            if (!url) return '';\n            if (url.indexOf('?') >= 0) {\n                return `${url}${url.endsWith('?') || url.endsWith('&') ? '' : '&'}${paramName}=${id}`;\n            }\n            return `${url}${url.endsWith('\/') ? '' : '\/'}${id}`;\n        };\n\n        if (item.type === 'adventure') {\n            if (!isLoggedIn) return '';\n            return addPathId(buddyUpVariables && buddyUpVariables.adventure_link ? buddyUpVariables.adventure_link : '', 'adventure_id');\n        }\n        if (item.type === 'event') {\n            return addPathId(buddyUpVariables && buddyUpVariables.event_link ? buddyUpVariables.event_link : '', 'event_id');\n        }\n        if (item.type === 'group') {\n            return addPathId(buddyUpVariables && buddyUpVariables.group_link ? buddyUpVariables.group_link : '', 'group_id');\n        }\n        if (item.type === 'user' || item.type === 'buddy') {\n            return addPathId(buddyUpVariables && buddyUpVariables.account_link ? buddyUpVariables.account_link : '', 'user_id');\n        }\n\n        return '';\n    };\n\n    \/\/ Adventure popups render richer media cards; other types use compact cards.\n    const buildPopupHtml = (item) => {\n        const detailLink = buildDetailLink(item);\n        if (item.type !== 'adventure') {\n            return `\n                <div class=\"buddyUpExplorePopupCard\">\n                    <div class=\"buddyUpExplorePopupTitle\">${safe(item.title)}<\/div>\n                    ${item.subtitle ? `<div class=\"buddyUpExplorePopupSubtitle\">${safe(item.subtitle)}<\/div>` : ''}\n                    ${item.image ? `<img decoding=\"async\" class=\"buddyUpExplorePopupHero\" src=\"${safe(item.image)}\" alt=\"${safe(item.title)}\" \/>` : ''}\n                    ${detailLink ? `<a href=\"${safe(detailLink)}\" class=\"buddyUpButton1 buddyUpExplorePopupLink\">Open ${safe(item.type === 'buddy' ? 'Buddy' : item.type.charAt(0).toUpperCase() + item.type.slice(1))}<\/a>` : ''}\n                <\/div>\n            `;\n        }\n\n        const descriptionRaw = String(item.description || '').replace(\/<[^>]*>\/g, ' ').trim();\n        const description = descriptionRaw.length > 0 ? descriptionRaw : '';\n        const media = Array.isArray(item.media) ? item.media : [];\n\n        const mediaHtml = media.length > 0\n            ? `<div class=\"buddyUpExplorePopupGallery\">${media.map((m, i) => {\n                const mUrl = m && m.url ? safe(m.url) : '';\n                const mType = m && String(m.type || '').toLowerCase() === 'video' ? 'video' : 'image';\n                const mDesc = m && m.description ? safe(m.description) : '';\n                if (!mUrl) return '';\n\n                return `\n                    <div class=\"buddyUpExplorePopupMediaItem\">\n                        ${mType === 'video'\n                            ? BUDDYUP.renderVideoMediaHtml(m.url, { className: 'buddyUpExplorePopupMedia', title: `${item && item.title ? item.title : 'Adventure'} video ${i + 1}` })\n                            : `<img decoding=\"async\" src=\"${mUrl}\" alt=\"${safe((m && m.description) ? m.description : `Adventure media ${i + 1}`)}\" class=\"buddyUpExplorePopupMedia\" \/>`\n                        }\n                        ${mDesc ? `<div class=\"buddyUpExplorePopupMediaCaption\">${mDesc}<\/div>` : ''}\n                    <\/div>\n                `;\n            }).join('')}<\/div>`\n            : (item.image ? `<img decoding=\"async\" class=\"buddyUpExplorePopupHero\" src=\"${safe(item.image)}\" alt=\"${safe(item.title)}\" \/>` : '');\n\n        return `\n            <div class=\"buddyUpExplorePopupCard\">\n                <div class=\"buddyUpExplorePopupHeader\">\n                    <div class=\"buddyUpExplorePopupBadge\">Adventure<\/div>\n                    <div class=\"buddyUpExplorePopupTitle\">${safe(item.title)}<\/div>\n                    ${item.subtitle ? `<div class=\"buddyUpExplorePopupSubtitle\">${safe(item.subtitle)}<\/div>` : ''}\n                <\/div>\n                ${description ? `<div class=\"buddyUpExplorePopupDescription\">${safe(description)}<\/div>` : ''}\n                ${mediaHtml}\n                ${detailLink ? `<a href=\"${safe(detailLink)}\" class=\"buddyUpButton1 buddyUpExplorePopupLink\">Open Adventure<\/a>` : ''}\n            <\/div>\n        `;\n    };\n\n    const renderMap = () => {\n        if (!map || !markersLayer) return;\n\n        const items = getFilteredItems();\n        markersLayer.clearLayers();\n\n        if (items.length === 0) {\n            statusEl.innerText = 'No map results match the current filters.';\n            return;\n        }\n\n        statusEl.innerText = `Showing ${items.length} ${state.mode}.`;\n\n        const markerRefs = [];\n        items.forEach((item) => {\n            const lat = Number(item.latitude);\n            const lng = Number(item.longitude);\n            if (!isFinite(lat) || !isFinite(lng)) return;\n\n            const opts = {};\n            const icon = buildIcon(item);\n            if (icon) opts.icon = icon;\n            const marker = L.marker([lat, lng], opts);\n\n            marker.bindPopup(() => buildPopupHtml(item), {\n                maxWidth: 420,\n                minWidth: 280,\n                className: 'buddyUpExplorePopup'\n            });\n\n            markersLayer.addLayer(marker);\n            markerRefs.push(marker);\n        });\n\n        if (markerRefs.length === 1) {\n            map.setView(markerRefs[0].getLatLng(), 11);\n        } else if (markerRefs.length > 1) {\n            const center = getActiveCenter();\n\n            if (center) {\n                if (state.mapFocus === 'nearme') {\n                    map.setView([center.latitude, center.longitude], 10);\n                } else {\n                    map.setView([center.latitude, center.longitude], 9);\n                }\n                return;\n            }\n\n            const group = L.featureGroup(markerRefs);\n            const bounds = group.getBounds();\n            const sw = bounds.getSouthWest();\n            const ne = bounds.getNorthEast();\n            const centerLat = (Number(sw.lat) + Number(ne.lat)) \/ 2;\n            const centerLng = (Number(sw.lng) + Number(ne.lng)) \/ 2;\n            map.fitBounds(bounds.pad(0.16));\n            map.panTo([centerLat, centerLng]);\n        }\n    };\n\n    const okLeaflet = await loadLeaflet();\n    if (!okLeaflet) {\n        statusEl.innerText = 'Map library failed to load.';\n        return;\n    }\n\n    loadGeoCacheFromStorage();\n\n    map = L.map(mapEl, { scrollWheelZoom: true });\n    L.tileLayer('https:\/\/{s}.tile.openstreetmap.org\/{z}\/{x}\/{y}.png', {\n        maxZoom: 19,\n        attribution: '&copy; OpenStreetMap contributors'\n    }).addTo(map);\n    markersLayer = L.layerGroup().addTo(map);\n\n    setMapLoading(true, 'Loading Adventures...');\n    await ensureModeLoaded('adventures');\n\n    state.sidebarCollapsed = isMobile();\n    renderSignedOutState();\n    renderSignedOutTeaseThumbs();\n    renderFocusToggle();\n    renderModeToggles();\n    renderCategories();\n    toggleRadiusSection();\n    initCollapsibleSections();\n    updateRadiusLabel();\n    renderMap();\n    setMapLoading(false);\n    syncSidebarUi();\n\n    if (focusAllBtn) {\n        focusAllBtn.addEventListener('click', () => {\n            if (!isLoggedIn) return;\n            state.mapFocus = 'all';\n            renderFocusToggle();\n            renderMap();\n            closeSidebarOnMobile();\n        });\n    }\n\n    if (focusNearMeBtn) {\n        focusNearMeBtn.addEventListener('click', async () => {\n            if (!isLoggedIn) return;\n            const center = await resolveNearMeCenterFromUser();\n            if (!center) {\n                if (radiusHint) radiusHint.innerText = 'Set your location on account to use Near Me.';\n                return;\n            }\n\n            state.mapFocus = 'nearme';\n            state.radiusMiles = 15;\n            if (radiusInput) radiusInput.value = '15';\n            updateRadiusLabel();\n            if (radiusHint) radiusHint.innerText = 'Near Me active (15 mile radius).';\n            renderFocusToggle();\n            renderMap();\n            closeSidebarOnMobile();\n        });\n    }\n\n    if (sidebarToggleBtn) {\n        sidebarToggleBtn.addEventListener('click', () => {\n            const shelfOpenNow = sidebarEl && (sidebarEl.classList.contains('isOpen') || sidebarEl.classList.contains('activeMobileMenu'));\n            state.sidebarCollapsed = !!shelfOpenNow;\n            syncSidebarUi();\n        });\n    }\n\n    if (sidebarEl && typeof BUDDYUP.initShelfSwipeGestures === 'function') {\n        BUDDYUP.initShelfSwipeGestures({\n            shelf: sidebarEl,\n            tab: sidebarToggleBtn,\n            onOpen: () => { state.sidebarCollapsed = false; syncSidebarUi(); },\n            onClose: closeSidebarOnMobile,\n            isOpen: () => sidebarEl.classList.contains('isOpen') || sidebarEl.classList.contains('activeMobileMenu'),\n            key: 'explore.sidebar',\n        });\n    }\n\n    if (window && typeof window.addEventListener === 'function') {\n        window.addEventListener('resize', syncSidebarUi);\n    }\n\n    if (map && typeof map.on === 'function') {\n        map.on('click', closeSidebarOnMobile);\n    }\n\n    if (applyRadiusBtn) {\n        applyRadiusBtn.addEventListener('click', async () => {\n            const zip = String(zipInput && zipInput.value ? zipInput.value : '').trim();\n            if (!zip) {\n                state.searchNearCenter = null;\n                radiusHint.innerText = 'Radius cleared.';\n                renderMap();\n                return;\n            }\n\n            const center = await geocodeText(zip);\n            if (!center) {\n                radiusHint.innerText = 'Could not locate that zip code.';\n                return;\n            }\n\n            state.searchNearCenter = { latitude: Number(center.latitude), longitude: Number(center.longitude), label: zip };\n            state.mapFocus = 'nearme';\n            state.radiusMiles = Number(radiusInput && radiusInput.value ? radiusInput.value : 25);\n            updateRadiusLabel();\n            renderFocusToggle();\n            radiusHint.innerText = `Showing ${state.radiusMiles} mile radius around ${zip}.`;\n            renderMap();\n        });\n    }\n\n    if (radiusInput) {\n        radiusInput.addEventListener('input', () => {\n            state.radiusMiles = Number(radiusInput.value || 25);\n            updateRadiusLabel();\n        });\n    }\n})();\n<\/script><\/div>","protected":false},"excerpt":{"rendered":"","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"templates\/full-width-no-header.php","meta":{"footnotes":""},"class_list":["post-505","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/buddyupapi-staging.us35.cdn-alpha.com\/api\/wp\/v2\/pages\/505","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/buddyupapi-staging.us35.cdn-alpha.com\/api\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/buddyupapi-staging.us35.cdn-alpha.com\/api\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/buddyupapi-staging.us35.cdn-alpha.com\/api\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/buddyupapi-staging.us35.cdn-alpha.com\/api\/wp\/v2\/comments?post=505"}],"version-history":[{"count":1,"href":"https:\/\/buddyupapi-staging.us35.cdn-alpha.com\/api\/wp\/v2\/pages\/505\/revisions"}],"predecessor-version":[{"id":506,"href":"https:\/\/buddyupapi-staging.us35.cdn-alpha.com\/api\/wp\/v2\/pages\/505\/revisions\/506"}],"wp:attachment":[{"href":"https:\/\/buddyupapi-staging.us35.cdn-alpha.com\/api\/wp\/v2\/media?parent=505"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}