{"version":3,"file":"CLVic-6O.js","sources":["../../../../graphql/LoginRegisterUser.js","../../../../composables/stores/bcnAuth.js","../../../../graphql/fragments.js","../../../../graphql/GetBlogPosts.js","../../../../composables/stores/blogPosts.js","../../../../composables/stores/breadcrumbs.js","../../../../composables/stores/events.js","../../../../node_modules/nuxt/dist/app/compat/interval.js","../../../../graphql/Favorites.js","../../../../composables/stores/favorites.js","../../../../composables/stores/modalForm.js","../../../../composables/stores/modalImageSlider.js","../../../../composables/stores/modalLogin.js","../../../../composables/stores/modalVideo.js","../../../../composables/stores/neighborhoodDetails.js","../../../../composables/stores/newHomeSearch.js","../../../../graphql/GetOverviewMap.js","../../../../composables/stores/overview.js","../../../../graphql/GetTestimonials.js","../../../../composables/stores/testimonials.js","../../../../node_modules/@googlemaps/js-api-loader/dist/index.mjs","../../../../composables/maps/getInfoWindowContent.js","../../../../node_modules/fast-deep-equal/index.js","../../../../node_modules/kdbush/index.js","../../../../node_modules/supercluster/index.js","../../../../node_modules/@googlemaps/markerclusterer/dist/index.esm.js","../../../../composables/maps/mapStyles.js","../../../../composables/maps/mapOptions.js","../../../../composables/maps/mapHelpers.js","../../../../composables/maps/index.js"],"sourcesContent":["import gql from \"graphql-tag\";\n\nexport const LOGIN_USER = gql`\nmutation LoginUser($uniqueId: String, $username: String!, $password: String!) {\n login(input: {clientMutationId: $uniqueId, username: $username, password: $password}) {\n authToken\n clientMutationId\n refreshToken\n user {\n databaseId\n favorites\n firstName\n id\n jwtAuthExpiration\n }\n }\n}\n`;\n\nexport const REGISTER_USER = gql`\n mutation RegisterUser($uniqueId: String, $username: String!, $password: String!, $email: String!, $firstName: String!, $lastName: String!) {\n registerUser(\n input: {\n clientMutationId: $uniqueId,\n username: $username,\n password: $password,\n email: $email,\n firstName: $firstName,\n lastName: $lastName\n }) {\n clientMutationId\n user {\n databaseId\n favorites\n firstName\n id\n jwtAuthExpiration\n jwtAuthToken\n jwtRefreshToken\n }\n }\n }\n`;\n\nexport const REFRESH_TOKEN = gql`\nmutation RefreshToken($jwtRefreshToken: String!, $uniqueId: String) {\n refreshJwtAuthToken(\n input: {jwtRefreshToken: $jwtRefreshToken, clientMutationId: $uniqueId}\n ) {\n authToken\n clientMutationId\n }\n}\n`;\n\nexport const GET_USER_DATA = gql`\nquery GetUserData($id: ID!) {\n user(id: $id, idType: DATABASE_ID) {\n databaseId\n favorites\n firstName\n id\n jwtAuthExpiration\n jwtAuthToken\n jwtRefreshToken\n }\n}\n`;\n","import { defineStore } from \"pinia\";\nimport { useStorage } from \"@vueuse/core\";\nimport { GET_USER_DATA, REFRESH_TOKEN } from \"~/graphql/LoginRegisterUser\";\nimport { useMutation } from \"@vue/apollo-composable\";\nconst { onLogout } = useApollo();\n\nexport const useBcnAuth = defineStore(\"bcnAuth\", () => {\n const isLoggedIn = ref(false);\n const authLoading = ref(false);\n let isRefreshingLoginStatus = false;\n\n // let userCookie = ref();\n // let tokenCookie = ref();\n // let refreshTokenCookie = ref();\n // if (process.client) {\n const userCookie = useCookie(\"bcn.user\", {\n maxAge: 60 * 60 * 24 * 365,\n });\n const tokenCookie = useCookie(\"apollo:bcn.token\", {\n maxAge: 3600,\n });\n const refreshTokenCookie = useCookie(\"apollo:bcn.refreshToken\", {\n maxAge: 60 * 60 * 24 * 365,\n });\n // }\n\n const {\n mutate: refreshMutate,\n loading: refreshLoading,\n error: refreshError,\n called: refreshCalled,\n onDone: refreshOnDone,\n onError: refreshOnError,\n } = useMutation(REFRESH_TOKEN);\n\n const refreshAuthToken = (refreshToken) => {\n refreshMutate({\n jwtRefreshToken: refreshToken,\n });\n\n refreshOnDone((result) => {\n tokenCookie.value = result?.data?.refreshJwtAuthToken?.authToken ?? null;\n\n if (tokenCookie.value) {\n isLoggedIn.value = true;\n }\n });\n\n refreshOnError((error) => {\n console.error(\"Error refreshing token:\", error);\n\n refreshTokenCookie.value = null;\n });\n };\n\n const logout = () => {\n onLogout();\n\n refreshTokenCookie.value = null;\n\n userCookie.value = null;\n\n isLoggedIn.value = false;\n };\n\n const refreshLoginStatus = async () => {\n if (isRefreshingLoginStatus === true) {\n return;\n }\n isRefreshingLoginStatus = true;\n authLoading.value = true;\n\n if (tokenCookie.value) {\n isLoggedIn.value = true;\n } else if (refreshTokenCookie.value) {\n refreshAuthToken(refreshTokenCookie.value);\n }\n isRefreshingLoginStatus = false;\n authLoading.value = false;\n return;\n };\n\n return {\n authLoading,\n isLoggedIn,\n logout,\n refreshLoginStatus,\n refreshTokenCookie,\n tokenCookie,\n userCookie,\n };\n});\n","import gql from \"graphql-tag\";\n\nexport const FRAGMENT_MEDIA_ITEM = gql`\n fragment MediaItemFragment on MediaItem {\n altText\n databaseId\n id\n sourceUrl\n mediaDetails {\n sizes {\n file\n fileSize\n height\n mimeType\n name\n sourceUrl\n width\n }\n }\n }\n`;\n\nexport const FRAGMENT_NEIGHBORHOOD_DETAILS = gql`\n ${FRAGMENT_MEDIA_ITEM}\n fragment NeighborhoodDetailsFragment on Neighborhood {\n basePrice\n databaseId\n id\n slug\n status\n title\n types\n uri\n collection {\n collection\n }\n neighborhood {\n address1\n address2\n city\n hours\n legal\n phone\n state\n status\n zip\n popularPlans {\n ... on Plan {\n databaseId\n id\n slug\n title\n floorplanDetails {\n bathroomsMax\n bathroomsMin\n bedroomsMax\n bedroomsMin\n collection\n displayTitle\n finishedSqrFt\n mainSqrFt\n features {\n feature\n }\n }\n }\n }\n saleTeamMembers {\n name\n image {\n ...MediaItemFragment\n }\n }\n thumbnail {\n ...MediaItemFragment\n }\n }\n }\n`;\n\nexport const FRAGMENT_EVENT_DETAILS = gql`\n ${FRAGMENT_MEDIA_ITEM}\n ${FRAGMENT_NEIGHBORHOOD_DETAILS}\n fragment EventDetailsFragment on Event {\n content\n databaseId\n id\n slug\n title\n uri\n eventDetails {\n collection\n directionsUrl\n endDateTime\n eventSummary\n fieldGroupName\n location\n startDateTime\n image {\n ...MediaItemFragment\n }\n thumbnail {\n ...MediaItemFragment\n }\n neighborhood {\n ...NeighborhoodDetailsFragment\n }\n }\n }\n`;\n\nexport const FRAGMENT_ORGANISMS = gql`\n ${FRAGMENT_MEDIA_ITEM}\n fragment OrganismsFragment on Page {\n databaseId\n id\n title\n hlOrganisms {\n hlOrganism {\n address1\n address2\n arrow\n attribution\n autoplayDelay\n autoplaySlider\n backgroundColor\n removeMargin\n backgroundImageOpacity\n backgroundOverlayColor\n border\n borderColor\n borderInset\n borderWidth\n brandWindowLayout\n button1\n button1Color\n button1Target\n button1Text\n button2\n button2Color\n button2Target\n button2Text\n button3\n button3Color\n button3Target\n button3Text\n city\n collection\n containerWidth\n contentTheme\n cssClasses\n customBackgroundOverlayColor\n description\n equalizeSlideHeights\n fieldGroupName\n formHeader\n fullBleed\n hideInfo\n hours\n hubspotFormId\n id\n latitude\n legal\n link1\n link2\n link3\n longitude\n mapArbitraryLayout\n mapWithInfoMapType\n markerTitle\n neighborhoodsMapLayout\n phone\n primaryHeadingLevel\n productPicker {\n ... on Home {\n databaseId\n id\n slug\n title\n uri\n featuredImage {\n node {\n sourceUrl\n }\n }\n qmiHomeDetails {\n bathrooms\n bedrooms\n finishedSqrFt\n price\n }\n productStatus {\n enableSnipeLink\n fieldGroupName\n sectionId\n statusCustom\n statusMessage\n }\n }\n ... on Model {\n databaseId\n id\n slug\n status\n title\n uri\n featuredImage {\n node { \n sourceUrl\n }\n }\n modelDetails {\n floorplan {\n ... on Plan {\n floorplanDetails {\n basePrice\n bathroomsMax\n bathroomsMin\n bedroomsMax\n bedroomsMin\n finishedSqrFt\n }\n }\n }\n }\n productStatus {\n enableSnipeLink\n fieldGroupName\n sectionId\n statusCustom\n statusMessage\n } \n }\n ... on Plan {\n databaseId\n id\n slug\n status\n title\n uri\n floorplanDetails {\n basePrice\n bathroomsMax\n bathroomsMin\n bedroomsMax\n bedroomsMin\n collection\n displayTitle\n elevations {\n sourceUrl\n }\n finishedSqrFt\n mainSqrFt\n }\n productStatus {\n enableSnipeLink\n fieldGroupName\n sectionId\n statusCustom\n statusMessage\n } \n }\n }\n productType\n rounded\n siteMapCtaLayout\n splitContentLayout\n state\n text1\n thumbnailCount\n title1\n title2\n title3\n type\n videoEmbedCode\n virtualTourCustomEmbedCode\n virtualTourEmbedType\n virtualTourLayout\n virtualTourUrl\n zip\n backgroundImage {\n ...MediaItemFragment\n }\n backgroundVideoFile\n gallery {\n sourceUrl\n title\n mediaDetails {\n sizes {\n file\n fileSize\n height\n mimeType\n name\n sourceUrl\n width\n }\n }\n }\n hiddenFormFields {\n inputSelector\n inputValue\n }\n image {\n ...MediaItemFragment\n }\n item {\n attribution\n backgroundColor\n backgroundVideoFile\n brandWindowLayout\n button1\n button1Color\n button1Target\n button1Text\n button2\n button2Color\n button2Target\n button2Text\n button3\n button3Color\n button3Target\n button3Text\n contentTheme\n cssClasses\n description\n fieldGroupName\n fullBleed\n id\n imageLink\n link1\n link2\n link3\n splitContentLayout\n text1\n title1\n title2\n title3\n type\n virtualTourCustomEmbedCode\n virtualTourEmbedType\n virtualTourLayout\n virtualTourUrl\n item {\n backgroundColor\n button1\n button1Color\n button1Target\n button1Text\n button2\n button2Color\n button2Target\n button2Text\n containerWidth\n cssClasses\n description\n fieldGroupName\n id\n link1\n link2\n selectHomes {\n ... on Home {\n databaseId\n }\n }\n selectPlans {\n ... on Plan {\n databaseId\n }\n }\n title1\n type\n item {\n description\n fieldGroupName\n title1\n title2\n }\n }\n backgroundImage {\n ...MediaItemFragment\n }\n gallery {\n sourceUrl\n title\n mediaDetails {\n sizes {\n file\n fileSize\n height\n mimeType\n name\n sourceUrl\n width\n }\n }\n }\n image {\n ...MediaItemFragment\n }\n }\n salesTeamMembers {\n name\n image {\n ...MediaItemFragment\n }\n }\n }\n }\n }\n`;\n\nexport const FRAGMENT_CAMPAIGN_ORGANISMS = gql`\n ${FRAGMENT_MEDIA_ITEM}\n fragment CampaignOrganismsFragment on Campaign {\n databaseId\n id\n title\n hlOrganisms {\n hlOrganism {\n address1\n address2\n arrow\n attribution\n autoplayDelay\n autoplaySlider\n backgroundColor\n backgroundImageOpacity\n backgroundOverlayColor\n border\n borderColor\n borderInset\n borderWidth\n brandWindowLayout\n button1\n button1Color\n button1Target\n button1Text\n button2\n button2Color\n button2Target\n button2Text\n button3\n button3Color\n button3Target\n button3Text\n city\n collection\n containerWidth\n contentTheme\n cssClasses\n customBackgroundOverlayColor\n description\n equalizeSlideHeights\n fieldGroupName\n formHeader\n fullBleed\n hideInfo\n hours\n hubspotFormId\n id\n latitude\n legal\n link1\n link2\n link3\n longitude\n mapArbitraryLayout\n mapWithInfoMapType\n markerTitle\n neighborhoodsMapLayout\n phone\n primaryHeadingLevel\n productPicker {\n ... on Home {\n databaseId\n id\n slug\n title\n uri\n featuredImage {\n node {\n sourceUrl\n }\n }\n qmiHomeDetails {\n bathrooms\n bedrooms\n finishedSqrFt\n price\n }\n productStatus {\n enableSnipeLink\n fieldGroupName\n sectionId\n statusCustom\n statusMessage\n } \n }\n ... on Model {\n databaseId\n id\n slug\n status\n title\n uri\n featuredImage {\n node { \n sourceUrl\n }\n }\n modelDetails {\n floorplan {\n ... on Plan {\n floorplanDetails {\n basePrice\n bathroomsMax\n bathroomsMin\n bedroomsMax\n bedroomsMin\n finishedSqrFt\n }\n }\n }\n }\n productStatus {\n enableSnipeLink\n fieldGroupName\n sectionId\n statusCustom\n statusMessage\n } \n }\n ... on Plan {\n databaseId\n id\n slug\n status\n title\n uri\n floorplanDetails {\n basePrice\n bathroomsMax\n bathroomsMin\n bedroomsMax\n bedroomsMin\n collection\n displayTitle\n elevations {\n sourceUrl\n }\n finishedSqrFt\n mainSqrFt\n }\n productStatus {\n enableSnipeLink\n fieldGroupName\n sectionId\n statusCustom\n statusMessage\n } \n }\n }\n productType\n rounded\n siteMapCtaLayout\n splitContentLayout\n state\n text1\n thumbnailCount\n title1\n title2\n title3\n type\n videoEmbedCode\n virtualTourCustomEmbedCode\n virtualTourEmbedType\n virtualTourLayout\n virtualTourUrl\n zip\n backgroundImage {\n ...MediaItemFragment\n }\n backgroundVideoFile\n gallery {\n sourceUrl\n title\n mediaDetails {\n sizes {\n file\n fileSize\n height\n mimeType\n name\n sourceUrl\n width\n }\n }\n }\n hiddenFormFields {\n inputSelector\n inputValue\n }\n image {\n ...MediaItemFragment\n }\n item {\n attribution\n backgroundColor\n backgroundVideoFile\n brandWindowLayout\n button1\n button1Color\n button1Target\n button1Text\n button2\n button2Color\n button2Target\n button2Text\n button3\n button3Color\n button3Target\n button3Text\n contentTheme\n cssClasses\n description\n fieldGroupName\n fullBleed\n id\n imageLink\n link1\n link2\n link3\n splitContentLayout\n text1\n title1\n title2\n title3\n type\n virtualTourCustomEmbedCode\n virtualTourEmbedType\n virtualTourLayout\n virtualTourUrl\n item {\n backgroundColor\n button1\n button1Color\n button1Target\n button1Text\n button2\n button2Color\n button2Target\n button2Text\n containerWidth\n cssClasses\n description\n fieldGroupName\n id\n link1\n link2\n selectHomes {\n ... on Home {\n databaseId\n }\n }\n title1\n type\n item {\n description\n fieldGroupName\n title1\n title2\n }\n }\n backgroundImage {\n ...MediaItemFragment\n }\n gallery {\n sourceUrl\n title\n mediaDetails {\n sizes {\n file\n fileSize\n height\n mimeType\n name\n sourceUrl\n width\n }\n }\n }\n image {\n ...MediaItemFragment\n }\n }\n salesTeamMembers {\n name\n image {\n ...MediaItemFragment\n }\n }\n }\n }\n campaignDetails {\n modalImage {\n ...MediaItemFragment\n }\n } \n }\n`;\n\nexport const FRAGMENT_NEIGHBORHOOD_ORGANISMS = gql`\n ${FRAGMENT_MEDIA_ITEM}\n fragment OrganismsFragment on Neighborhood {\n databaseId\n id\n title\n hlOrganisms {\n hlOrganism {\n address1\n address2\n arrow\n attribution\n autoplayDelay\n autoplaySlider\n backgroundColor\n backgroundImageOpacity\n backgroundOverlayColor\n border\n borderColor\n borderInset\n borderWidth\n brandWindowLayout\n button1\n button1Color\n button1Target\n button1Text\n button2\n button2Color\n button2Target\n button2Text\n button3\n button3Color\n button3Target\n button3Text\n city\n collection\n containerWidth\n contentTheme\n cssClasses\n customBackgroundOverlayColor\n description\n equalizeSlideHeights\n fieldGroupName\n formHeader\n fullBleed\n hideInfo\n hours\n hubspotFormId\n id\n latitude\n legal\n link1\n link2\n link3\n longitude\n mapArbitraryLayout\n mapWithInfoMapType\n markerTitle\n neighborhoodsMapLayout\n phone\n primaryHeadingLevel\n productPicker {\n ... on Home {\n databaseId\n id\n slug\n title\n uri\n featuredImage {\n node {\n sourceUrl\n }\n }\n qmiHomeDetails {\n bathrooms\n bedrooms\n finishedSqrFt\n price\n }\n }\n ... on Model {\n databaseId\n id\n slug\n status\n title\n uri\n featuredImage {\n node { \n sourceUrl\n }\n }\n modelDetails {\n floorplan {\n ... on Plan {\n floorplanDetails {\n basePrice\n bathroomsMax\n bathroomsMin\n bedroomsMax\n bedroomsMin\n finishedSqrFt\n }\n }\n }\n }\n }\n ... on Plan {\n databaseId\n id\n slug\n status\n title\n uri\n floorplanDetails {\n basePrice\n bathroomsMax\n bathroomsMin\n bedroomsMax\n bedroomsMin\n collection\n displayTitle\n elevations {\n sourceUrl\n }\n finishedSqrFt\n mainSqrFt\n }\n }\n }\n productType\n rounded\n siteMapCtaLayout\n splitContentLayout\n state\n text1\n thumbnailCount\n title1\n title2\n title3\n type\n videoEmbedCode\n virtualTourCustomEmbedCode\n virtualTourEmbedType\n virtualTourLayout\n virtualTourUrl\n zip\n backgroundImage {\n ...MediaItemFragment\n }\n backgroundVideoFile\n gallery {\n sourceUrl\n title\n mediaDetails {\n sizes {\n file\n fileSize\n height\n mimeType\n name\n sourceUrl\n width\n }\n }\n }\n hiddenFormFields {\n inputSelector\n inputValue\n }\n image {\n ...MediaItemFragment\n }\n item {\n attribution\n backgroundColor\n backgroundVideoFile\n brandWindowLayout\n button1\n button1Color\n button1Target\n button1Text\n button2\n button2Color\n button2Target\n button2Text\n button3\n button3Color\n button3Target\n button3Text\n contentTheme\n cssClasses\n description\n fieldGroupName\n fullBleed\n id\n imageLink\n link1\n link2\n link3\n splitContentLayout\n text1\n title1\n title2\n title3\n type\n virtualTourCustomEmbedCode\n virtualTourEmbedType\n virtualTourLayout\n virtualTourUrl\n item {\n backgroundColor\n button1\n button1Color\n button1Target\n button1Text\n button2\n button2Color\n button2Target\n button2Text\n containerWidth\n cssClasses\n description\n fieldGroupName\n id\n link1\n link2\n selectHomes {\n ... on Home {\n databaseId\n }\n }\n selectPlans {\n ... on Plan {\n databaseId\n }\n }\n title1\n type\n item {\n description\n fieldGroupName\n title1\n title2\n }\n }\n backgroundImage {\n ...MediaItemFragment\n }\n gallery {\n sourceUrl\n title\n mediaDetails {\n sizes {\n file\n fileSize\n height\n mimeType\n name\n sourceUrl\n width\n }\n }\n }\n image {\n ...MediaItemFragment\n }\n }\n salesTeamMembers {\n name\n image {\n ...MediaItemFragment\n }\n }\n }\n }\n }\n`;\n\n\nexport const BLOG_POST_FRAGMENT = gql`\n ${FRAGMENT_MEDIA_ITEM}\n fragment BlogPostFragment on BlogPost {\n content\n date\n slug\n title\n uri\n blogCategories {\n nodes {\n count\n name\n slug\n }\n }\n customPostDetails {\n excerpt\n subtitle\n thumbnail {\n ...MediaItemFragment\n }\n image {\n ...MediaItemFragment\n }\n }\n }\n`;\n\nexport const TESTIMONIAL_FRAGMENT = gql`\n ${FRAGMENT_MEDIA_ITEM}\n fragment TestimonialFragment on Testimonial {\n content\n date\n slug\n title\n uri\n testimonialCategories {\n nodes {\n count\n name\n slug\n }\n }\n customPostDetails {\n excerpt\n subtitle\n thumbnail {\n ...MediaItemFragment\n }\n image {\n ...MediaItemFragment\n }\n }\n }\n`;\n","import gql from \"graphql-tag\";\nimport { BLOG_POST_FRAGMENT } from \"./fragments.js\";\n\nexport const GET_BLOG_POSTS = gql`\n ${BLOG_POST_FRAGMENT}\n query GetBlogPosts($first: Int, $last: Int, $after: String, $before: String ) {\n blogPosts(\n first: $first\n last: $last\n after: $after\n before: $before\n where: {orderby: {field: DATE, order: DESC}}\n ) {\n edges {\n node {\n ...BlogPostFragment\n }\n }\n pageInfo {\n endCursor\n hasNextPage\n hasPreviousPage\n startCursor\n }\n }\n }\n`;\n\nexport const GET_BLOG_CATEGORIES = gql`\n query GetBlogCategories {\n blogCategories(where: {orderby: COUNT, order: DESC}) {\n nodes {\n count\n name\n slug\n uri\n }\n }\n }\n`;\n\nexport const GET_POPULAR_BLOG_POSTS = gql`\n query GetPopularBlogPosts {\n popularBlogPosts\n }\n`;\n\nexport const GET_BLOG_POSTS_BY_IDS = gql`\n ${BLOG_POST_FRAGMENT}\n query GetBlogPostsByIds($in: [ID]) {\n blogPosts(where: {in: $in}) {\n edges {\n node {\n ...BlogPostFragment\n }\n }\n }\n }\n`;\n\nexport const GET_BLOG_POSTS_BY_CATEGORY = gql`\n ${BLOG_POST_FRAGMENT}\n query GetBlogPostsByCategory($categorySlug: [String], $first: Int, $last: Int, $before: String, $after: String) {\n blogCategories(where: {slug: $categorySlug}) {\n edges {\n node {\n blogPosts(where: {orderby: {field: DATE, order: DESC}}, first: $first, last: $last, before: $before, after: $after) {\n edges {\n node {\n ...BlogPostFragment\n }\n }\n pageInfo {\n endCursor\n hasNextPage\n hasPreviousPage\n startCursor\n }\n }\n }\n }\n }\n }\n`;\n\nexport const GET_SINGLE_BLOG_POST_BY_URI = gql`\n ${BLOG_POST_FRAGMENT}\n query GetSingleBlogPostByUri($id: ID!) {\n blogPost(id: $id, idType: URI) {\n ...BlogPostFragment\n }\n }\n`;\n\n","import { defineStore } from \"pinia\";\nimport { useQuery } from \"@vue/apollo-composable\";\nimport {\n GET_BLOG_CATEGORIES,\n GET_BLOG_POSTS,\n GET_BLOG_POSTS_BY_CATEGORY,\n GET_BLOG_POSTS_BY_IDS,\n GET_SINGLE_BLOG_POST_BY_URI,\n GET_POPULAR_BLOG_POSTS,\n} from \"~/graphql/GetBlogPosts\";\n\nexport const useBlogPosts = defineStore(\"blogPosts\", () => {\n const route = useRoute();\n const PAGE_SIZE = 6;\n const singleBlogPostUri = ref(\"\");\n const currentPage = ref(1);\n const currentCategoryPage = ref(1);\n const popularBlogPosts = ref([]);\n const categorySlug = computed(() => route.params.category);\n\n // Blog Posts\n const { result, loading, fetchMore, refetch } = useQuery(GET_BLOG_POSTS, {\n first: PAGE_SIZE,\n last: null,\n after: null,\n before: null,\n });\n\n const refreshBlogPosts = () => {\n refetch();\n };\n\n const posts = computed(\n () => result?.value?.blogPosts.edges.map((edge) => edge.node) ?? []\n );\n\n const hasNextPage = computed(\n () => result?.value?.blogPosts.pageInfo.hasNextPage ?? false\n );\n\n const hasPreviousPage = computed(\n () => result?.value?.blogPosts.pageInfo.hasPreviousPage ?? false\n );\n\n const loadMore = (direction = \"next\") => {\n let first, last, after, before;\n\n switch (direction) {\n case \"previous\":\n if (!hasPreviousPage) return;\n last = PAGE_SIZE;\n before = result.value?.blogPosts.pageInfo.startCursor;\n currentPage.value = Math.max(currentPage.value - 1, 1);\n break;\n case \"next\":\n default:\n if (!hasNextPage) return;\n first = PAGE_SIZE;\n after = result.value?.blogPosts.pageInfo.endCursor;\n currentPage.value = currentPage.value + 1;\n break;\n }\n\n fetchMore({\n variables: {\n first: first,\n last: last,\n after: after,\n before: before,\n },\n updateQuery: (previousResult, { fetchMoreResult }) => {\n return fetchMoreResult ?? previousResult;\n },\n });\n };\n\n // Blog Post Categories\n\n const {\n result: postsByCategoryResult,\n loading: postsByCategoryLoading,\n fetchMore: postsByCategoryFetchMore,\n refetch: postsByCategoryRefetch,\n } = useQuery(GET_BLOG_POSTS_BY_CATEGORY, {\n categorySlug: categorySlug,\n first: PAGE_SIZE,\n last: null,\n after: null,\n before: null,\n });\n\n watch(categorySlug, () => {\n postsByCategoryRefetch();\n });\n\n const postsByCategory = computed(() => {\n return (\n postsByCategoryResult?.value?.blogCategories?.edges?.[0]?.node?.blogPosts?.edges?.map(\n (edge) => edge.node\n ) ?? []\n );\n });\n\n const hasNextCategoryPage = computed(\n () =>\n postsByCategoryResult?.value?.blogCategories?.edges?.[0]?.node?.blogPosts\n ?.pageInfo.hasNextPage ?? false\n );\n\n const hasPreviousCategoryPage = computed(\n () =>\n postsByCategoryResult?.value?.blogCategories?.edges?.[0]?.node?.blogPosts\n ?.pageInfo.hasPreviousPage ?? false\n );\n\n const loadMoreCategoryPages = (direction = \"next\") => {\n let first, last, after, before;\n\n switch (direction) {\n case \"previous\":\n if (!hasPreviousCategoryPage) return;\n last = PAGE_SIZE;\n before =\n postsByCategoryResult?.value?.blogCategories?.edges?.[0]?.node\n ?.blogPosts?.pageInfo.startCursor;\n currentCategoryPage.value = Math.max(currentCategoryPage.value - 1, 1);\n break;\n case \"next\":\n default:\n if (!hasNextCategoryPage) return;\n first = PAGE_SIZE;\n after =\n postsByCategoryResult?.value?.blogCategories?.edges?.[0]?.node\n ?.blogPosts?.pageInfo.endCursor;\n currentCategoryPage.value = currentCategoryPage.value + 1;\n break;\n }\n\n postsByCategoryFetchMore({\n variables: {\n first: first,\n last: last,\n after: after,\n before: before,\n },\n updateQuery: (previousResult, { fetchMoreResult }) => {\n return fetchMoreResult ?? previousResult;\n },\n });\n };\n\n // Single Blog Post\n\n const { result: singleBlogPostResult, loading: singleBlogPostLoading } =\n useQuery(GET_SINGLE_BLOG_POST_BY_URI, {\n id: singleBlogPostUri,\n });\n const singleBlogPost = computed(() => singleBlogPostResult.value ?? []);\n\n // Other: Sidebar\n\n const { result: blogCategoriesResult } = useQuery(GET_BLOG_CATEGORIES);\n const blogCategories = computed(\n () => blogCategoriesResult.value?.blogCategories.nodes ?? []\n );\n\n const { result: popularBlogPostsResult, loading: popularBlogPostsLoading } =\n useQuery(GET_POPULAR_BLOG_POSTS);\n\n // ToDo: This could use a refactor\n // First we query to get the database IDs of the selected popular blog posts on the options page. Unfortunately when you return the posts as objects, it does not include all the information needed. (Could probably change this on the theme side by fetching and including the data where we add the hook in ./hooks/graphql.php)\n // Instead, we need to use those IDs fetch their information in a follow-up query.\n // These need to happen asynchronously as one query depends on the other, hence setting up the watcher.\n // The problem is this is slow. Probably need to revisit the php hook.\n watch(popularBlogPostsLoading, (newPopularBlogPostsLoading) => {\n if (!newPopularBlogPostsLoading) {\n const popularBlogPostIds = computed(() => {\n let parsedJSON = {};\n try {\n parsedJSON = JSON.parse(\n popularBlogPostsResult?.value?.popularBlogPosts\n );\n } catch (e) {\n return {};\n }\n return parsedJSON;\n });\n\n const {\n result: getBlogPostsByIdsResult,\n loading: getBlogPostsByIdsLoading,\n } = useQuery(GET_BLOG_POSTS_BY_IDS, {\n in: popularBlogPostIds.value.blogPosts,\n });\n\n popularBlogPosts.value = computed(\n () =>\n getBlogPostsByIdsResult.value?.blogPosts.edges.map(\n (edge) => edge.node\n ) ?? []\n );\n }\n });\n\n return {\n // Blog Posts\n currentPage,\n hasNextPage,\n hasPreviousPage,\n loadMore,\n loading,\n posts,\n refreshBlogPosts,\n\n // Blog Post Categories\n categorySlug,\n currentCategoryPage,\n hasNextCategoryPage,\n hasPreviousCategoryPage,\n loadMoreCategoryPages,\n postsByCategory,\n postsByCategoryLoading,\n\n // Single Blog Post\n singleBlogPost,\n singleBlogPostLoading,\n singleBlogPostUri,\n\n // Other: Sidebar\n blogCategories,\n popularBlogPosts,\n };\n});\n","import { defineStore } from \"pinia\";\n\nexport const useBreadcrumbs = defineStore(\"breadcrumbs\", () => {\n // State\n const breadcrumbsList = ref([]);\n\n return {\n breadcrumbsList,\n };\n});\n","import { defineStore } from \"pinia\";\n\nexport const useEvents = defineStore(\"events\", () => {\n // State\n const eventsList = ref([]);\n\n return {\n eventsList,\n };\n});\n","import { createError } from \"../composables/error.js\";\nconst intervalError = \"[nuxt] `setInterval` should not be used on the server. Consider wrapping it with an `onNuxtReady`, `onBeforeMount` or `onMounted` lifecycle hook, or ensure you only call it in the browser by checking `import.meta.client`.\";\nexport const setInterval = import.meta.client ? window.setInterval : () => {\n if (import.meta.dev) {\n throw createError({\n statusCode: 500,\n message: intervalError\n });\n }\n console.error(intervalError);\n};\n","import gql from \"graphql-tag\";\n\nexport const UPDATE_FAVORITES = gql`\nmutation UpdateFavorites($uniqueId: String, $userId: ID!, $favorites: String!) {\n updateUserFavorites(input: {clientMutationId: $uniqueId, favorites: $favorites, userId: $userId}) {\n clientMutationId\n user {\n databaseId\n favorites\n firstName\n id\n jwtAuthExpiration\n jwtAuthToken\n jwtRefreshToken\n }\n }\n}\n`;\n","import { defineStore } from \"pinia\";\nimport { useQuery } from \"@vue/apollo-composable\";\nimport { UPDATE_FAVORITES } from \"~/graphql/Favorites\";\nimport { useBcnAuth } from \"./bcnAuth\";\n\nexport const useFavorites = defineStore(\"favorites\", () => {\n const bcnAuth = useBcnAuth();\n const { isLoggedIn, userCookie } = storeToRefs(bcnAuth);\n\n const notificationIsOpen = ref(false);\n const notificationProductName = ref(\"\");\n const notificationImageUrl = ref(\"\");\n const notificationCountdownProgress = ref(100);\n const notificationCurrentInterval = ref(null);\n const refreshing = ref(false);\n\n const queue = ref([]);\n const processingQueue = ref(false);\n const debounceDelay = 2000;\n let debounceTimer = null;\n\n /**\n * Enqueues a request with a specific action and ID into the queue.\n * The request is processed if the queue is not already being processed.\n *\n * @param {Object} request - The request object to be enqueued.\n * @param {'add'|'remove'} request.action - The action type of the request. Must be either 'add' or 'remove'.\n * @param {number} request.id - The ID associated with the request. Must be an integer.\n */\n const enqueueRequest = (request) => {\n queue.value.push(request);\n\n if (!processingQueue.value) {\n processQueue();\n }\n };\n\n const processQueue = async () => {\n if (processingQueue.value) return;\n\n if (queue.value.length === 0) {\n // If the queue is empty, reset the processing state and do nothing.\n processingQueue.value = false;\n return;\n }\n\n processingQueue.value = true;\n\n // Process the first request immediately if it's the only item in the queue\n // to increase perceived resposiveness\n if (queue.value.length === 1) {\n await processRequests();\n } else {\n // Debounce subsequent requests\n debounceSubsequentRequests();\n }\n };\n\n const processRequests = async () => {\n try {\n // Batch processing: Process all requests in the queue at once\n const requestsToProcess = [...queue.value];\n queue.value = []; // Clear the queue\n\n const userId = userCookie?.value?.userId ?? -1;\n\n let cookieFavorites = [];\n if (isValidJSON(userCookie.value.favorites)) {\n const parsedFavorites = JSON.parse(userCookie.value.favorites);\n if (Array.isArray(parsedFavorites)) {\n cookieFavorites = parsedFavorites.filter(\n (item) => typeof item === \"number\",\n );\n }\n }\n let localFavorites = new Set(cookieFavorites);\n\n requestsToProcess.forEach((request) => {\n if (request.action === \"add\") {\n localFavorites.add(request.id);\n }\n if (request.action === \"remove\") {\n localFavorites.delete(request.id);\n }\n });\n\n const newFavorites = JSON.stringify([...localFavorites]);\n\n userCookie.value.favorites = newFavorites;\n await updateFavorites(userId, newFavorites);\n } catch (error) {\n console.error(error);\n bcnAuth.refreshLoginStatus();\n } finally {\n processingQueue.value = false;\n if (queue.value.length > 0) {\n processQueue(); // Process new items added during processing\n }\n }\n };\n\n const debounceSubsequentRequests = () => {\n clearTimeout(debounceTimer);\n debounceTimer = setTimeout(() => {\n processRequests();\n }, debounceDelay);\n };\n\n const refreshAll = async () => {\n refreshing.value = true;\n try {\n await refreshNuxtData();\n } finally {\n refreshing.value = false;\n }\n };\n\n const notificationStartCountdown = () => {\n if (notificationCurrentInterval.value) {\n clearInterval(notificationCurrentInterval.value);\n }\n\n const intervalTime = 50;\n const decrement = (intervalTime / 8000) * 100;\n notificationCurrentInterval.value = setInterval(() => {\n notificationCountdownProgress.value -= decrement;\n if (notificationCountdownProgress.value <= 0) {\n notificationCountdownProgress.value = 0;\n notificationIsOpen.value = false;\n clearInterval(notificationCurrentInterval.value);\n }\n }, intervalTime);\n };\n\n const openNotification = () => {\n notificationIsOpen.value = true;\n };\n const closeNotification = () => {\n notificationIsOpen.value = false;\n };\n\n const toggleFavoriteProduct = (product) => {\n\n const userId = userCookie?.value?.userId ?? -1;\n let newFavorites = \"\";\n\n const cookieFavorites = isValidJSON(userCookie.value.favorites)\n ? JSON.parse(userCookie.value.favorites)\n : [];\n\n const productIsFavorite = isFavorite(product.id, cookieFavorites);\n\n if (productIsFavorite) {\n enqueueRequest({ action: \"remove\", id: product.id });\n return;\n } else {\n enqueueRequest({ action: \"add\", id: product.id });\n\n notificationCountdownProgress.value = 100;\n notificationProductName.value = product.title;\n notificationImageUrl.value = product.thumbnail;\n openNotification();\n\n return;\n }\n };\n\n const isFavorite = (id, cookieFavorites) => {\n\n return cookieFavorites && Array.isArray(cookieFavorites)\n ? cookieFavorites?.some((itemId) => {\n return itemId === id;\n })\n : false;\n };\n\n const {\n mutate: favoritesMutate,\n loading: favoritesSubmitting,\n error: favoritesError,\n called: favoritesCalled,\n onDone: favoritesOnDone,\n onError: favoritesOnError,\n } = useMutation(UPDATE_FAVORITES);\n\n const updateFavorites = (userId, newFavorites) => {\n\n return new Promise((resolve, reject) => {\n if (!userId || !newFavorites || isLoggedIn.value !== true) {\n console.error(\n \"updateFavorites error: Invalid input or user not logged in.\",\n );\n reject(\"Invalid input or user not logged in.\");\n return;\n }\n\n favoritesMutate({\n uniqueId: generateRandomString(8),\n userId: userId,\n favorites: newFavorites,\n });\n\n favoritesOnDone((result) => {\n const resultFavorites = isValidJSON(\n result?.data?.updateUserFavorites?.user?.favorites,\n )\n ? result?.data?.updateUserFavorites?.user?.favorites\n : JSON.stringify([]);\n\n userCookie.value.favorites = resultFavorites;\n resolve(resultFavorites);\n });\n\n favoritesOnError((error) => {\n console.error(\"favoritesOnError error\", error);\n refreshAll();\n reject(error);\n });\n });\n };\n\n return {\n closeNotification,\n enqueueRequest,\n favoritesSubmitting,\n isFavorite,\n notificationCountdownProgress,\n notificationCurrentInterval,\n notificationImageUrl,\n notificationIsOpen,\n notificationProductName,\n notificationStartCountdown,\n openNotification,\n processingQueue,\n toggleFavoriteProduct,\n };\n});\n","import { defineStore } from \"pinia\";\n\nexport const useModalForm = defineStore(\"modalForm\", () => {\n const modalIsOpen = ref(false);\n // const formId = ref(0);\n const currentStep = ref(1);\n const hideForm = ref(false);\n const formSubmitting = ref(false);\n const formResponseMessage = ref(\"\");\n const formResponseMessageType = ref(\"\");\n\n const $reset = () => {\n modalIsOpen.value = false;\n // formId.value = 0;\n currentStep.value = 1;\n hideForm.value = false;\n formSubmitting.value = false;\n formResponseMessage.value = \"\";\n formResponseMessageType.value = \"\";\n };\n\n const closeModal = () => {\n modalIsOpen.value = false;\n $reset();\n };\n\n const openModal = () => {\n modalIsOpen.value = true;\n };\n\n const nextStep = () => {\n currentStep.value++;\n };\n\n const prevStep = () => {\n currentStep.value--;\n };\n\n const focusTarget = (targetId) => {\n const target = document.getElementById(targetId);\n target.focus();\n };\n\n // Trivial Example\n // const submitForm = () => {\n // // Your form submission logic here\n // console.log(\"Form submitted\");\n // };\n\n // const submitForm = async (formId, formData) => {\n // hideForm.value = true;\n // formSubmitting.value = true;\n // formResponseMessage.value = \"\";\n // formResponseMessageType.value = \"\";\n\n // try {\n // const response = await fetch(\n // \"https://staging-livebouldercreek.kinsta.cloud/wp-json/gf/v2/forms/\" +\n // formId +\n // \"/submissions\",\n // {\n // method: \"POST\",\n // headers: {\n // \"Content-Type\": \"application/json\",\n // },\n // body: JSON.stringify(formData),\n // }\n // );\n\n // if (!response.ok) {\n // throw new Error(\"An error occurred during form submission\");\n // }\n\n // const data = await response.json();\n\n // // Handle successful form submission\n // console.log(data);\n // formResponseMessageType.value = \"success\";\n // formResponseMessage.value = data.confirmation_message;\n // } catch (error) {\n // // Handle error during form submission\n // console.error(error);\n // formResponseMessageType.value = \"error\";\n // formResponseMessage.value = \"Sorry, an error occurred during form submission. Please contact us at 303-309-0362 if this issue persists.\";\n // } finally {\n // formSubmitting.value = false;\n // }\n // };\n\n // Track active modals\n const activeModalIds = ref(new Set());\n\n const isModalActive = (modalId) => {\n return activeModalIds.value.has(modalId);\n };\n\n const registerModal = (modalId) => {\n activeModalIds.value.add(modalId);\n };\n\n const unregisterModal = (modalId) => {\n activeModalIds.value.delete(modalId);\n };\n\n const openModalWithCheck = (modalId) => {\n if (!isModalActive(modalId)) {\n openModal();\n registerModal(modalId);\n }\n };\n\n const closeModalWithUnregister = (modalId) => {\n closeModal();\n if (modalId) unregisterModal(modalId);\n };\n\n return {\n $reset,\n closeModal,\n currentStep,\n focusTarget,\n // formId,\n formResponseMessage,\n formResponseMessageType,\n formSubmitting,\n hideForm,\n modalIsOpen,\n nextStep,\n openModal,\n prevStep,\n // submitForm,\n isModalActive,\n openModalWithCheck,\n closeModalWithUnregister,\n };\n});\n","import { defineStore } from \"pinia\";\n\nexport const useModalImageSlider = defineStore(\"modalImageSlider\", () => {\n const modalIsOpen = ref(false);\n const initialSlide = ref(0);\n const sliderImages = ref([]);\n // Set sliderImages to array of objects:\n // [\n // {\n // imageFullSrc: \"/img/example.png\",\n // alt: \"alt text\",\n // },\n // ...\n // ]\n\n const closeModal = () => {\n modalIsOpen.value = false;\n };\n\n const openModal = (index) => {\n initialSlide.value = index;\n modalIsOpen.value = true;\n };\n\n return {\n modalIsOpen,\n initialSlide,\n sliderImages,\n closeModal,\n openModal,\n };\n});\n","import { defineStore } from \"pinia\";\n\nexport const useModalLogin = defineStore(\"modalLogin\", () => {\n\n const modalIsOpen = ref(false);\n const modalTargetTab = ref(\"login\");\n\n const closeModal = () => {\n modalIsOpen.value = false;\n modalTargetTab.value = \"login\";\n };\n\n const openModal = (targetTab = \"login\") => {\n modalTargetTab.value = typeof targetTab === \"string\" ? targetTab : \"login\";\n modalIsOpen.value = true;\n };\n\n return {\n closeModal,\n modalIsOpen,\n modalTargetTab,\n openModal,\n };\n});\n","import { defineStore } from \"pinia\";\n\nexport const useModalVideo = defineStore(\"modalVideo\", () => {\n const modalIsOpen = ref(false);\n const videoUrl = ref(\"\");\n\n const closeModal = () => {\n modalIsOpen.value = false;\n };\n\n const openModal = (url) => {\n videoUrl.value = url;\n modalIsOpen.value = true;\n };\n\n return {\n modalIsOpen,\n videoUrl,\n closeModal,\n openModal,\n };\n});\n","import { defineStore } from \"pinia\";\n\nexport const useNeighborhoodDetails = defineStore(\"neighborhoodDetails\", () => {\n // State\n let currentTab = ref(\"\");\n\n return {\n currentTab,\n };\n});\n","import { defineStore } from \"pinia\";\n\nexport const useNewHomeSearch = defineStore(\"newHomeSearch\", () => {\n const filterReset = ref(false);\n\n return {\n filterReset,\n };\n});\n","import gql from \"graphql-tag\";\n\nexport const GET_OVERVIEW_MAP = gql`\n query GetOverviewMap($uri: ID = \"/our-neighborhoods/\") {\n tabsDescription: page(idType: URI, id: $uri) {\n id\n ourNeighborhoods {\n fieldGroupName\n modelHomesOverview\n ourNeighborhoodsOverview\n quickMoveInsOverview\n }\n }\n neighborhoods(last: 500) {\n nodes {\n basePrice\n databaseId\n id\n slug\n status\n title\n types\n uri\n collection {\n collection\n }\n neighborhood {\n status\n neighborhoodArea\n address1\n address2\n city\n featuredNeighborhood\n state\n longitude\n latitude\n thumbnail {\n altText\n sourceUrl\n mediaDetails {\n sizes {\n file\n fileSize\n height\n mimeType\n name\n sourceUrl\n width\n }\n }\n }\n }\n }\n }\n plans(last: 500) {\n nodes {\n id\n title\n uri\n floorplanDetails {\n collection\n displayTitle\n neighborhood {\n ... on Neighborhood {\n databaseId\n id\n slug\n title\n }\n }\n }\n productStatus {\n enableSnipeLink\n fieldGroupName\n sectionId\n statusCustom\n statusMessage\n }\n }\n }\n models(last: 500) {\n nodes {\n databaseId\n slug\n status\n title\n uri\n collection {\n collection\n fieldGroupName\n }\n featuredImage {\n node {\n altText\n slug\n sourceUrl\n title\n uri\n mediaDetails {\n sizes {\n file\n fileSize\n height\n mimeType\n name\n sourceUrl\n width\n }\n }\n }\n }\n modelDetails {\n latitude\n longitude\n floorplan {\n ... on Plan {\n floorplanDetails {\n bathroomsMax\n bathroomsMin\n bedroomsMax\n bedroomsMin\n collection\n displayTitle\n finishedSqrFt\n }\n }\n }\n neighborhood {\n ... on Neighborhood {\n basePrice\n databaseId\n id\n slug\n title\n types\n neighborhood {\n neighborhoodArea\n status\n thumbnail {\n altText\n sourceUrl\n mediaDetails {\n sizes {\n file\n fileSize\n height\n mimeType\n name\n sourceUrl\n width\n }\n }\n }\n }\n }\n }\n }\n productStatus {\n enableSnipeLink\n fieldGroupName\n sectionId\n statusCustom\n statusMessage\n }\n }\n }\n homes(last: 500) {\n nodes {\n databaseId\n uri\n title\n slug\n collection {\n collection\n fieldGroupName\n }\n featuredImage {\n node {\n altText\n slug\n sourceUrl\n title\n uri\n mediaDetails {\n sizes {\n file\n fileSize\n height\n mimeType\n name\n sourceUrl\n width\n }\n }\n }\n }\n qmiHomeDetails {\n bathrooms\n bedrooms\n finishedSqrFt\n latitude\n longitude\n price\n type\n floorplan {\n ... on Plan {\n title\n floorplanDetails {\n collection\n displayTitle\n }\n }\n }\n neighborhood {\n ... on Neighborhood {\n title\n neighborhood {\n neighborhoodArea\n thumbnail {\n altText\n sourceUrl\n mediaDetails {\n sizes {\n file\n fileSize\n height\n mimeType\n name\n sourceUrl\n width\n }\n }\n }\n }\n }\n }\n }\n productStatus {\n enableSnipeLink\n fieldGroupName\n sectionId\n statusCustom\n statusMessage\n }\n }\n }\n }\n`;\n","import { defineStore } from \"pinia\";\nimport { useQuery } from \"@vue/apollo-composable\";\nimport { GET_OVERVIEW_MAP } from \"~/graphql/GetOverviewMap\";\n\nexport const useOverview = defineStore(\"overview\", () => {\n // State\n const title = ref(\"\");\n const description = ref(\"\");\n const breadcrumb = ref(\"\");\n const filterReset = ref(false);\n const filterResultsEmpty = ref(false);\n const mapView = ref(\"neighborhoods\");\n const collectionFilter = ref(\"\");\n\n // Get Overview Map Data\n const { result: overviewMapResult } = useQuery(GET_OVERVIEW_MAP, {\n uri: \"/our-neighborhoods/\",\n });\n\n // Getters\n const tabsDescription = computed(\n () => overviewMapResult?.value?.tabsDescription ?? []\n );\n const neighborhoods = computed(\n () => overviewMapResult?.value?.neighborhoods ?? []\n );\n const models = computed(() => overviewMapResult?.value?.models ?? []);\n const homes = computed(() => overviewMapResult?.value?.homes ?? []);\n const plans = computed(() => overviewMapResult?.value?.plans ?? []);\n\n const mapInfo = computed(() => {\n switch (mapView.value) {\n case \"model-homes\":\n return {\n mapView: mapView.value,\n nodes: models?.value?.nodes?.length\n ? models.value.nodes\n .map((node) => {\n return {\n collection:\n node?.modelDetails?.floorplan?.floorplanDetails?.collection,\n listItemId: node.slug,\n title: node.title + \" Model\",\n beds: {\n min: node?.modelDetails?.floorplan?.floorplanDetails\n ?.bedroomsMin,\n max: node?.modelDetails?.floorplan?.floorplanDetails\n ?.bedroomsMax,\n },\n baths: {\n min: node?.modelDetails?.floorplan?.floorplanDetails\n ?.bathroomsMin,\n max: node?.modelDetails?.floorplan?.floorplanDetails\n ?.bathroomsMax,\n },\n sqft: node?.modelDetails?.floorplan?.floorplanDetails\n ?.finishedSqrFt,\n latitude: node.modelDetails.latitude,\n longitude: node.modelDetails.longitude,\n directionsLink:\n \"https://www.google.com/maps/dir/?api=1&destination=\" +\n node.modelDetails.latitude +\n \",\" +\n node.modelDetails.longitude,\n linkText: \"Explore \" + node.title,\n link: node.uri,\n thumbnailSrc: getImageSrc(\n node.featuredImage?.node ??\n node.modelDetails.neighborhood.neighborhood.thumbnail,\n \"medium\"\n ),\n thumbnailAlt:\n node.featuredImage?.node.altText ??\n node.modelDetails.neighborhood.neighborhood.thumbnail\n .altText,\n };\n })\n .filter((node) => {\n if (!collectionFilter.value) return true;\n return node.collection === collectionFilter.value;\n })\n : [],\n };\n\n case \"neighborhoods\":\n return {\n mapView: mapView.value,\n nodes: neighborhoods?.value?.nodes?.length\n ? neighborhoods.value.nodes\n .map((node) => {\n const collections = getCollectionsByNeighborhood(\n node.slug,\n plans?.value?.nodes,\n null,\n null,\n [node.collection?.collection]\n );\n return {\n collections: collections,\n listItemId: node.slug,\n title: node.title,\n subtitle: getNeighborhoodNavSubtitle(\n node.types,\n getRoundedPrice(node.basePrice),\n node.neighborhood.status,\n true\n ),\n latitude: node.neighborhood.latitude,\n longitude: node.neighborhood.longitude,\n directionsLink:\n \"https://www.google.com/maps/dir/?api=1&destination=\" +\n node.neighborhood.latitude +\n \",\" +\n node.neighborhood.longitude,\n linkText: \"Explore this neighborhood\",\n link: node.uri,\n thumbnailSrc: getImageSrc(\n node.neighborhood.thumbnail,\n \"medium\"\n ),\n thumbnailAlt: node.neighborhood.thumbnail.altText,\n };\n })\n .filter((node) => {\n if (!collectionFilter.value) return true;\n return node.collections.includes(collectionFilter.value);\n })\n : [],\n };\n\n case \"quick-move-in\":\n return {\n mapView: mapView.value,\n nodes: homes?.value?.nodes?.length\n ? homes.value.nodes\n .map((node) => {\n return {\n collection:\n node.qmiHomeDetails?.floorplan?.floorplanDetails\n ?.collection,\n listItemId: node.slug,\n title: node.title,\n plan: node.qmiHomeDetails?.floorplan?.title,\n beds: {\n min: node.qmiHomeDetails?.bedrooms,\n },\n baths: {\n min: node.qmiHomeDetails?.bathrooms,\n },\n sqft: node.qmiHomeDetails?.finishedSqrFt,\n latitude: node.qmiHomeDetails?.latitude,\n longitude: node.qmiHomeDetails?.longitude,\n directionsLink:\n \"https://www.google.com/maps/dir/?api=1&destination=\" +\n node.qmiHomeDetails?.latitude +\n \",\" +\n node.qmiHomeDetails?.longitude,\n linkText: \"Explore this home\",\n link: node.uri,\n productStatus: {\n statusCustom: node.productStatus?.statusCustom,\n statusMessage: node.productStatus?.statusMessage,\n },\n thumbnailSrc: getImageSrc(\n node.featuredImage?.node ??\n node.qmiHomeDetails?.neighborhood?.neighborhood?.thumbnail,\n \"medium\"\n ),\n thumbnailAlt:\n node.featuredImage?.node?.altText ??\n node.qmiHomeDetails?.neighborhood?.neighborhood?.thumbnail\n .altText,\n };\n })\n .filter((node) => {\n if (!collectionFilter.value) return true;\n return node.collection === collectionFilter.value;\n })\n : [],\n };\n\n default:\n return {};\n }\n });\n\n return {\n breadcrumb,\n collectionFilter,\n description,\n filterReset,\n filterResultsEmpty,\n homes,\n mapInfo,\n mapView,\n models,\n neighborhoods,\n plans,\n tabsDescription,\n title,\n };\n});\n","import gql from \"graphql-tag\";\nimport { TESTIMONIAL_FRAGMENT } from \"./fragments.js\";\nimport { FRAGMENT_MEDIA_ITEM } from \"./fragments.js\";\n\nexport const GET_TESTIMONIALS = gql`\n ${TESTIMONIAL_FRAGMENT}\n query GetTestimonials(\n $first: Int\n $last: Int\n $after: String\n $before: String\n ) {\n testimonials(\n first: $first\n after: $after\n before: $before\n last: $last\n where: { orderby: { field: DATE, order: DESC } }\n ) {\n pageInfo {\n endCursor\n hasNextPage\n hasPreviousPage\n startCursor\n }\n edges {\n node {\n ...TestimonialFragment\n }\n }\n }\n }\n`;\n\nexport const GET_TESTIMONIAL_CATEGORIES = gql`\n query GetTestimonialCategories {\n testimonialCategories(where: { orderby: COUNT, order: DESC }) {\n nodes {\n count\n name\n slug\n uri\n }\n }\n }\n`;\n\nexport const GET_POPULAR_TESTIMONIALS = gql`\n query GetPopularTestimonials {\n popularTestimonials\n }\n`;\n\nexport const GET_TESTIMONIALS_BY_IDS = gql`\n ${TESTIMONIAL_FRAGMENT}\n query GetTestimonialsByIds($in: [ID]) {\n testimonials(where: { in: $in }) {\n edges {\n node {\n ...TestimonialFragment\n }\n }\n }\n }\n`;\n\nexport const GET_TESTIMONIALS_BY_CATEGORY = gql`\n ${TESTIMONIAL_FRAGMENT}\n query GetTestimonialsByCategory(\n $categorySlug: [String]\n $first: Int\n $last: Int\n $before: String\n $after: String\n ) {\n testimonialCategories(where: { slug: $categorySlug }) {\n edges {\n node {\n testimonials(\n where: { orderby: { field: DATE, order: DESC } }\n first: $first\n last: $last\n before: $before\n after: $after\n ) {\n edges {\n node {\n ...TestimonialFragment\n }\n }\n pageInfo {\n endCursor\n hasNextPage\n hasPreviousPage\n startCursor\n }\n }\n }\n }\n }\n }\n`;\n\nexport const GET_SINGLE_TESTIMONIAL_BY_SLUG = gql`\n ${TESTIMONIAL_FRAGMENT}\n query GetSingleTestimonialBySlug($id: ID!) {\n testimonial(id: $id, idType: SLUG) {\n ...TestimonialFragment\n testimonials {\n videoUrl\n }\n }\n }\n`;\n\nexport const GET_TESTIMONIALS_HIGHLIGHTS = gql`\n ${FRAGMENT_MEDIA_ITEM}\n query GetTestimonialsHighlights {\n testimonialsHighlights {\n attribution\n tagline\n text\n image {\n ...MediaItemFragment\n }\n }\n }\n`;\n","import { defineStore } from \"pinia\";\nimport { useQuery } from \"@vue/apollo-composable\";\nimport {\n GET_TESTIMONIALS,\n GET_POPULAR_TESTIMONIALS,\n GET_TESTIMONIALS_BY_IDS,\n GET_TESTIMONIALS_BY_CATEGORY,\n GET_TESTIMONIAL_CATEGORIES,\n GET_SINGLE_TESTIMONIAL_BY_SLUG,\n} from \"~/graphql/GetTestimonials\";\n\nexport const useTestimonials = defineStore(\"testimonials\", () => {\n const PAGE_SIZE = 6;\n const singleTestimonialSlug = ref(\"\");\n let currentPage = ref(1);\n\n const { result: singleTestimonialResult, loading: singleTestimonialLoading } =\n useQuery(GET_SINGLE_TESTIMONIAL_BY_SLUG, {\n id: singleTestimonialSlug,\n });\n const singleTestimonial = computed(() => singleTestimonialResult.value ?? []);\n\n const { result: testimonialCategoriesResult } = useQuery(\n GET_TESTIMONIAL_CATEGORIES\n );\n const testimonialCategories = computed(\n () => testimonialCategoriesResult.value?.testimonialCategories.nodes ?? []\n );\n\n const {\n onResult: onPopularTestimonialsResult,\n loading: popularTestimonialsLoading,\n } = useQuery(GET_POPULAR_TESTIMONIALS);\n\n const { result: testimonialsByIdsResult, refetch: refetchTestimonialsByIds } = useQuery(GET_TESTIMONIALS_BY_IDS, { in: [] });\n\n const popularTestimonials = ref([]);\n const categorySlug = ref(\"\");\n\n onPopularTestimonialsResult((result) => {\n if (result?.data?.popularTestimonials) {\n const ids = JSON.parse(result?.data?.popularTestimonials);\n\n if (ids) {\n refetchTestimonialsByIds({ in: ids.testimonials }).then(fullTestimonials => {\n popularTestimonials.value = fullTestimonials?.data?.testimonials?.edges.map((fullTestimonial) => fullTestimonial.node);\n });\n }\n }\n });\n\n const { result, loading, fetchMore } = useQuery(GET_TESTIMONIALS, {\n first: PAGE_SIZE,\n last: null,\n after: null,\n before: null,\n });\n const testimonials = computed(\n () => result.value?.testimonials.edges.map((edge) => edge.node) ?? []\n );\n\n // Avoiding getting post total as it's an expensive operation and I have deactivatied the plugin\n // const testimonialCount = computed(() => result.value?.testimonials.pageInfo.total ?? 0);\n\n const hasNextPage = computed(\n () => result.value?.testimonials.pageInfo.hasNextPage ?? false\n );\n const hasPreviousPage = computed(\n () => result.value?.testimonials.pageInfo.hasPreviousPage ?? false\n );\n const startCursor = computed(\n () => result.value?.testimonials.pageInfo.startCursor ?? \"\"\n );\n const endCursor = computed(\n () => result.value?.testimonials.pageInfo.endCursor ?? \"\"\n );\n\n const loadMore = (direction = \"next\") => {\n let first, last, after, before;\n\n switch (direction) {\n case \"previous\":\n if (!hasPreviousPage) return;\n last = PAGE_SIZE;\n before = result.value?.testimonials.pageInfo.startCursor;\n currentPage.value = currentPage.value <= 1 ? 1 : currentPage.value - 1;\n break;\n case \"next\":\n default:\n if (!hasNextPage) return;\n first = PAGE_SIZE;\n after = result.value?.testimonials.pageInfo.endCursor;\n currentPage.value = currentPage.value + 1;\n break;\n }\n\n fetchMore({\n variables: {\n first: first,\n last: last,\n after: after,\n before: before,\n },\n updateQuery: (previousResult, { fetchMoreResult }) => {\n return fetchMoreResult ?? previousResult;\n },\n });\n };\n\n let testimonialsByCategoryResult,\n testimonialsByCategoryLoading,\n testimonialsByCategoryFetchMore;\n const testimonialsByCategory = ref([]);\n const testimonialsByCategoryPageInfo = ref({});\n watch(categorySlug, (newCategorySlug) => {\n const {\n result: testimonialsByCategoryResult,\n loading: testimonialsByCategoryLoading,\n fetchMore: testimonialsByCategoryFetchMore,\n } = useQuery(GET_TESTIMONIALS_BY_CATEGORY, {\n categorySlug: newCategorySlug,\n first: PAGE_SIZE,\n last: null,\n after: null,\n before: null,\n });\n\n testimonialsByCategory.value = computed(() => {\n return (\n testimonialsByCategoryResult?.value?.testimonialCategories?.edges?.[0]?.node?.testimonials?.edges?.map(\n (edge) => edge.node\n ) ?? []\n );\n });\n\n testimonialsByCategoryPageInfo.value = computed(() => {\n return (\n testimonialsByCategoryResult?.value?.testimonialCategories?.edges?.[0]\n ?.node?.testimonials?.pageInfo ?? {}\n );\n });\n });\n\n const hasNextPageCategoryPages = computed(\n () => testimonialsByCategoryPageInfo.hasNextPage ?? false\n );\n const hasPreviousPageCategoryPages = computed(\n () => testimonialsByCategoryPageInfo.hasPreviousPage ?? false\n );\n const startCursorCategoryPages = computed(\n () => testimonialsByCategoryPageInfo.startCursor ?? \"\"\n );\n const endCursorCategoryPages = computed(\n () => testimonialsByCategoryPageInfo.endCursor ?? \"\"\n );\n\n const loadMoreCategoryPages = (direction = \"next\") => {\n let first, last, after, before;\n\n switch (direction) {\n case \"previous\":\n if (!hasPreviousPageCategoryPages) return;\n last = PAGE_SIZE;\n before = testimonialsByCategoryPageInfo.startCursor;\n currentPage.value = currentPage.value <= 1 ? 1 : currentPage.value - 1;\n break;\n case \"next\":\n default:\n if (!hasNextPageCategoryPages) return;\n first = PAGE_SIZE;\n after = testimonialsByCategoryPageInfo.endCursor;\n currentPage.value = currentPage.value + 1;\n break;\n }\n\n testimonialsByCategoryFetchMore({\n variables: {\n categorySlug: categorySlug,\n first: first,\n last: last,\n after: after,\n before: before,\n },\n updateQuery: (previousResult, { fetchMoreResult }) => {\n return fetchMoreResult ?? previousResult;\n },\n });\n };\n\n return {\n loading,\n testimonialCategories,\n categorySlug,\n currentPage,\n hasNextPage,\n hasNextPageCategoryPages,\n hasPreviousPage,\n hasPreviousPageCategoryPages,\n popularTestimonials,\n testimonials,\n testimonialsByCategory,\n testimonialsByCategoryLoading,\n loadMore,\n loadMoreCategoryPages,\n singleTestimonial,\n singleTestimonialLoading,\n singleTestimonialSlug,\n };\n});\n","/******************************************************************************\r\nCopyright (c) Microsoft Corporation.\r\n\r\nPermission to use, copy, modify, and/or distribute this software for any\r\npurpose with or without fee is hereby granted.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\r\nREGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\r\nAND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\r\nINDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\r\nLOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\r\nOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\r\nPERFORMANCE OF THIS SOFTWARE.\r\n***************************************************************************** */\r\n/* global Reflect, Promise, SuppressedError, Symbol */\r\n\r\n\r\nfunction __awaiter(thisArg, _arguments, P, generator) {\r\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\r\n return new (P || (P = Promise))(function (resolve, reject) {\r\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\r\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\r\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\r\n step((generator = generator.apply(thisArg, _arguments || [])).next());\r\n });\r\n}\r\n\r\ntypeof SuppressedError === \"function\" ? SuppressedError : function (error, suppressed, message) {\r\n var e = new Error(message);\r\n return e.name = \"SuppressedError\", e.error = error, e.suppressed = suppressed, e;\r\n};\n\nfunction getDefaultExportFromCjs (x) {\n\treturn x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;\n}\n\n// do not edit .js files directly - edit src/index.jst\n\n\n\nvar fastDeepEqual = function equal(a, b) {\n if (a === b) return true;\n\n if (a && b && typeof a == 'object' && typeof b == 'object') {\n if (a.constructor !== b.constructor) return false;\n\n var length, i, keys;\n if (Array.isArray(a)) {\n length = a.length;\n if (length != b.length) return false;\n for (i = length; i-- !== 0;)\n if (!equal(a[i], b[i])) return false;\n return true;\n }\n\n\n\n if (a.constructor === RegExp) return a.source === b.source && a.flags === b.flags;\n if (a.valueOf !== Object.prototype.valueOf) return a.valueOf() === b.valueOf();\n if (a.toString !== Object.prototype.toString) return a.toString() === b.toString();\n\n keys = Object.keys(a);\n length = keys.length;\n if (length !== Object.keys(b).length) return false;\n\n for (i = length; i-- !== 0;)\n if (!Object.prototype.hasOwnProperty.call(b, keys[i])) return false;\n\n for (i = length; i-- !== 0;) {\n var key = keys[i];\n\n if (!equal(a[key], b[key])) return false;\n }\n\n return true;\n }\n\n // true if both NaN, false otherwise\n return a!==a && b!==b;\n};\n\nvar isEqual = /*@__PURE__*/getDefaultExportFromCjs(fastDeepEqual);\n\n/**\n * Copyright 2019 Google LLC. All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at.\n *\n * Http://www.apache.org/licenses/LICENSE-2.0.\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nconst DEFAULT_ID = \"__googleMapsScriptId\";\n/**\n * The status of the [[Loader]].\n */\nvar LoaderStatus;\n(function (LoaderStatus) {\n LoaderStatus[LoaderStatus[\"INITIALIZED\"] = 0] = \"INITIALIZED\";\n LoaderStatus[LoaderStatus[\"LOADING\"] = 1] = \"LOADING\";\n LoaderStatus[LoaderStatus[\"SUCCESS\"] = 2] = \"SUCCESS\";\n LoaderStatus[LoaderStatus[\"FAILURE\"] = 3] = \"FAILURE\";\n})(LoaderStatus || (LoaderStatus = {}));\n/**\n * [[Loader]] makes it easier to add Google Maps JavaScript API to your application\n * dynamically using\n * [Promises](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).\n * It works by dynamically creating and appending a script node to the the\n * document head and wrapping the callback function so as to return a promise.\n *\n * ```\n * const loader = new Loader({\n * apiKey: \"\",\n * version: \"weekly\",\n * libraries: [\"places\"]\n * });\n *\n * loader.load().then((google) => {\n * const map = new google.maps.Map(...)\n * })\n * ```\n */\nclass Loader {\n /**\n * Creates an instance of Loader using [[LoaderOptions]]. No defaults are set\n * using this library, instead the defaults are set by the Google Maps\n * JavaScript API server.\n *\n * ```\n * const loader = Loader({apiKey, version: 'weekly', libraries: ['places']});\n * ```\n */\n constructor({ apiKey, authReferrerPolicy, channel, client, id = DEFAULT_ID, language, libraries = [], mapIds, nonce, region, retries = 3, url = \"https://maps.googleapis.com/maps/api/js\", version, }) {\n this.callbacks = [];\n this.done = false;\n this.loading = false;\n this.errors = [];\n this.apiKey = apiKey;\n this.authReferrerPolicy = authReferrerPolicy;\n this.channel = channel;\n this.client = client;\n this.id = id || DEFAULT_ID; // Do not allow empty string\n this.language = language;\n this.libraries = libraries;\n this.mapIds = mapIds;\n this.nonce = nonce;\n this.region = region;\n this.retries = retries;\n this.url = url;\n this.version = version;\n if (Loader.instance) {\n if (!isEqual(this.options, Loader.instance.options)) {\n throw new Error(`Loader must not be called again with different options. ${JSON.stringify(this.options)} !== ${JSON.stringify(Loader.instance.options)}`);\n }\n return Loader.instance;\n }\n Loader.instance = this;\n }\n get options() {\n return {\n version: this.version,\n apiKey: this.apiKey,\n channel: this.channel,\n client: this.client,\n id: this.id,\n libraries: this.libraries,\n language: this.language,\n region: this.region,\n mapIds: this.mapIds,\n nonce: this.nonce,\n url: this.url,\n authReferrerPolicy: this.authReferrerPolicy,\n };\n }\n get status() {\n if (this.errors.length) {\n return LoaderStatus.FAILURE;\n }\n if (this.done) {\n return LoaderStatus.SUCCESS;\n }\n if (this.loading) {\n return LoaderStatus.LOADING;\n }\n return LoaderStatus.INITIALIZED;\n }\n get failed() {\n return this.done && !this.loading && this.errors.length >= this.retries + 1;\n }\n /**\n * CreateUrl returns the Google Maps JavaScript API script url given the [[LoaderOptions]].\n *\n * @ignore\n * @deprecated\n */\n createUrl() {\n let url = this.url;\n url += `?callback=__googleMapsCallback&loading=async`;\n if (this.apiKey) {\n url += `&key=${this.apiKey}`;\n }\n if (this.channel) {\n url += `&channel=${this.channel}`;\n }\n if (this.client) {\n url += `&client=${this.client}`;\n }\n if (this.libraries.length > 0) {\n url += `&libraries=${this.libraries.join(\",\")}`;\n }\n if (this.language) {\n url += `&language=${this.language}`;\n }\n if (this.region) {\n url += `®ion=${this.region}`;\n }\n if (this.version) {\n url += `&v=${this.version}`;\n }\n if (this.mapIds) {\n url += `&map_ids=${this.mapIds.join(\",\")}`;\n }\n if (this.authReferrerPolicy) {\n url += `&auth_referrer_policy=${this.authReferrerPolicy}`;\n }\n return url;\n }\n deleteScript() {\n const script = document.getElementById(this.id);\n if (script) {\n script.remove();\n }\n }\n /**\n * Load the Google Maps JavaScript API script and return a Promise.\n * @deprecated, use importLibrary() instead.\n */\n load() {\n return this.loadPromise();\n }\n /**\n * Load the Google Maps JavaScript API script and return a Promise.\n *\n * @ignore\n * @deprecated, use importLibrary() instead.\n */\n loadPromise() {\n return new Promise((resolve, reject) => {\n this.loadCallback((err) => {\n if (!err) {\n resolve(window.google);\n }\n else {\n reject(err.error);\n }\n });\n });\n }\n importLibrary(name) {\n this.execute();\n return google.maps.importLibrary(name);\n }\n /**\n * Load the Google Maps JavaScript API script with a callback.\n * @deprecated, use importLibrary() instead.\n */\n loadCallback(fn) {\n this.callbacks.push(fn);\n this.execute();\n }\n /**\n * Set the script on document.\n */\n setScript() {\n var _a, _b;\n if (document.getElementById(this.id)) {\n // TODO wrap onerror callback for cases where the script was loaded elsewhere\n this.callback();\n return;\n }\n const params = {\n key: this.apiKey,\n channel: this.channel,\n client: this.client,\n libraries: this.libraries.length && this.libraries,\n v: this.version,\n mapIds: this.mapIds,\n language: this.language,\n region: this.region,\n authReferrerPolicy: this.authReferrerPolicy,\n };\n // keep the URL minimal:\n Object.keys(params).forEach(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (key) => !params[key] && delete params[key]);\n if (!((_b = (_a = window === null || window === void 0 ? void 0 : window.google) === null || _a === void 0 ? void 0 : _a.maps) === null || _b === void 0 ? void 0 : _b.importLibrary)) {\n // tweaked copy of https://developers.google.com/maps/documentation/javascript/load-maps-js-api#dynamic-library-import\n // which also sets the base url, the id, and the nonce\n /* eslint-disable */\n ((g) => {\n // @ts-ignore\n let h, a, k, p = \"The Google Maps JavaScript API\", c = \"google\", l = \"importLibrary\", q = \"__ib__\", m = document, b = window;\n // @ts-ignore\n b = b[c] || (b[c] = {});\n // @ts-ignore\n const d = b.maps || (b.maps = {}), r = new Set(), e = new URLSearchParams(), u = () => \n // @ts-ignore\n h || (h = new Promise((f, n) => __awaiter(this, void 0, void 0, function* () {\n var _a;\n yield (a = m.createElement(\"script\"));\n a.id = this.id;\n e.set(\"libraries\", [...r] + \"\");\n // @ts-ignore\n for (k in g)\n e.set(k.replace(/[A-Z]/g, (t) => \"_\" + t[0].toLowerCase()), g[k]);\n e.set(\"callback\", c + \".maps.\" + q);\n a.src = this.url + `?` + e;\n d[q] = f;\n a.onerror = () => (h = n(Error(p + \" could not load.\")));\n // @ts-ignore\n a.nonce = this.nonce || ((_a = m.querySelector(\"script[nonce]\")) === null || _a === void 0 ? void 0 : _a.nonce) || \"\";\n m.head.append(a);\n })));\n // @ts-ignore\n d[l] ? console.warn(p + \" only loads once. Ignoring:\", g) : (d[l] = (f, ...n) => r.add(f) && u().then(() => d[l](f, ...n)));\n })(params);\n /* eslint-enable */\n }\n // While most libraries populate the global namespace when loaded via bootstrap params,\n // this is not the case for \"marker\" when used with the inline bootstrap loader\n // (and maybe others in the future). So ensure there is an importLibrary for each:\n const libraryPromises = this.libraries.map((library) => this.importLibrary(library));\n // ensure at least one library, to kick off loading...\n if (!libraryPromises.length) {\n libraryPromises.push(this.importLibrary(\"core\"));\n }\n Promise.all(libraryPromises).then(() => this.callback(), (error) => {\n const event = new ErrorEvent(\"error\", { error }); // for backwards compat\n this.loadErrorCallback(event);\n });\n }\n /**\n * Reset the loader state.\n */\n reset() {\n this.deleteScript();\n this.done = false;\n this.loading = false;\n this.errors = [];\n this.onerrorEvent = null;\n }\n resetIfRetryingFailed() {\n if (this.failed) {\n this.reset();\n }\n }\n loadErrorCallback(e) {\n this.errors.push(e);\n if (this.errors.length <= this.retries) {\n const delay = this.errors.length * Math.pow(2, this.errors.length);\n console.error(`Failed to load Google Maps script, retrying in ${delay} ms.`);\n setTimeout(() => {\n this.deleteScript();\n this.setScript();\n }, delay);\n }\n else {\n this.onerrorEvent = e;\n this.callback();\n }\n }\n callback() {\n this.done = true;\n this.loading = false;\n this.callbacks.forEach((cb) => {\n cb(this.onerrorEvent);\n });\n this.callbacks = [];\n }\n execute() {\n this.resetIfRetryingFailed();\n if (this.done) {\n this.callback();\n }\n else {\n // short circuit and warn if google.maps is already loaded\n if (window.google && window.google.maps && window.google.maps.version) {\n console.warn(\"Google Maps already loaded outside @googlemaps/js-api-loader.\" +\n \"This may result in undesirable behavior as options and script parameters may not match.\");\n this.callback();\n return;\n }\n if (this.loading) ;\n else {\n this.loading = true;\n this.setScript();\n }\n }\n }\n}\n\nexport { DEFAULT_ID, Loader, LoaderStatus };\n//# sourceMappingURL=index.mjs.map\n","export const getInfowindowContent = (mapInfo) => {\n const styles = `\n \n `;\n\n\n switch (mapInfo.value.mapView) {\n case \"model-homes\":\n return (\n mapInfo.value.nodes.map((node) => {\n const beds = (node.beds.min && node.beds.max) ? node.beds.min+' - '+node.beds.max : node.beds.min;\n const sqft = node?.sqft?.toLocaleString('en-US');\n return styles + `\n