{"version":3,"file":"modules/subLandingMain-ba8ebb6ca5f98d141dc1.js","mappings":"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","sources":["webpack:///./scripts/components/carousel/dynamicCarousel.js","webpack:///./scripts/apis/getTypeaheadSuggestions.js","webpack:///./scripts/components/typeahead/typeahead.js","webpack:///./scripts/components/typeahead/typeaheadKeyboardHandler.js","webpack:///./scripts/constants/googleAnalyticsCustomDimension.js","webpack:///./scripts/constants/housingProductType.js","webpack:///./scripts/constants/routes.js","webpack:///./scripts/constants/svg-assets.js","webpack:///./scripts/dataTransferObjects/googleAnalyticsEvent.js","webpack:///./scripts/enums/googleAnalytics4EventType.js","webpack:///./scripts/enums/loadingStatus.js","webpack:///./scripts/enums/marketingStatus.js","webpack:///./scripts/enums/pageType.js","webpack:///./scripts/enums/typeaheadLocationType.js","webpack:///./scripts/features/googleAnalytics4/index.js","webpack:///./scripts/features/googleAnalytics4/redux/actions.js","webpack:///./scripts/features/googleAnalytics4/redux/beaconMiddleware.js","webpack:///./scripts/features/searchResultsFacets/enums/thankScreenVariation.js","webpack:///./scripts/features/leadGenerators/components/detailsAnchor.js","webpack:///./scripts/features/leadGenerators/components/schedulerAnchor.js","webpack:///./scripts/features/leadGenerators/components/phoneAnchor.js","webpack:///./scripts/features/leadGenerators/components/phoneAnchorCallTracking.js","webpack:///./scripts/features/leadGenerators/components/createAccountAnchor.js","webpack:///./scripts/features/leadGenerators/components/returnToSearchAnchor.js","webpack:///./scripts/features/leadGenerators/services/anchorConstructor.js","webpack:///./scripts/features/leadGenerators/constants/sharedHtml.js","webpack:///./scripts/features/leadGenerators/models/communityInformationLead.js","webpack:///./scripts/features/leadGenerators/models/planInformationLead.js","webpack:///./scripts/features/leadGenerators/models/recommendedBrochureLead.js","webpack:///./scripts/features/leadGenerators/models/specInformationLead.js","webpack:///./scripts/features/leadGenerators/services/leadConstructor.js","webpack:///./scripts/features/leadGenerators/models/buildablePlanBrochureLead.js","webpack:///./scripts/features/leadGenerators/models/communityBrochureLead.js","webpack:///./scripts/features/leadGenerators/models/planBrochureLead.js","webpack:///./scripts/features/leadGenerators/models/specBrochureLead.js","webpack:///./scripts/features/leadGenerators/models/buildablePlanInformationLead.js","webpack:///./scripts/features/leadGenerators/models/communityTourLead.js","webpack:///./scripts/features/leadGenerators/models/planTourLead.js","webpack:///./scripts/features/leadGenerators/models/specTourLead.js","webpack:///./scripts/features/leadGenerators/models/planInformationLeadBasic.js","webpack:///./scripts/features/leadGenerators/models/specInformationLeadBasic.js","webpack:///./scripts/features/leadGenerators/models/communityInformationLeadBasic.js","webpack:///./scripts/features/leadGenerators/models/basicListingInformationLeadBasic.js","webpack:///./scripts/enums/googleAnalyticsEventAction.js","webpack:///./scripts/enums/googleAnalyticsEventCategory.js","webpack:///./scripts/features/leadGenerators/analytics/eventTrackingTdvEventsMixin.js","webpack:///./scripts/features/leadGenerators/analytics/basicLeadTrackingEvent.js","webpack:///./scripts/features/leadGenerators/analytics/eventTrackingNonDirectLeadsMixin.js","webpack:///./scripts/features/leadGenerators/analytics/eventTrackingRealTimeEventsMixin.js","webpack:///./scripts/features/leadGenerators/analytics/eventTrackingTdvMetricsMixin.js","webpack:///./scripts/features/leadGenerators/analytics/brochureTrackingEvent.js","webpack:///./scripts/features/leadGenerators/analytics/informationTracking.js","webpack:///./scripts/features/leadGenerators/analytics/tourTrackingEvent.js","webpack:///./scripts/features/leadGenerators/analytics/askQuestionTrackingEvent.js","webpack:///./scripts/features/leadGenerators/services/taskFlow.js","webpack:///./scripts/features/leadGenerators/components/brochureButton.js","webpack:///./scripts/features/leadGenerators/components/commentsTextArea.js","webpack:///./scripts/features/leadGenerators/components/emailInput.js","webpack:///./scripts/features/leadGenerators/components/nameInput.js","webpack:///./scripts/features/leadGenerators/components/phoneInput.js","webpack:///./scripts/features/leadGenerators/components/recommendedCheckbox.js","webpack:///./scripts/features/leadGenerators/components/zipInput.js","webpack:///./scripts/features/leadGenerators/components/realtorDropdown.js","webpack:///./scripts/features/leadGenerators/components/brochureFormPaid.js","webpack:///./scripts/features/leadGenerators/enums/basicContactVendor.js","webpack:///./scripts/features/leadGenerators/services/basicPrivacyPolicyParagraph.js","webpack:///./scripts/features/leadGenerators/components/informationButtonBasic.js","webpack:///./scripts/features/leadGenerators/components/informationFormBasic.js","webpack:///./scripts/features/leadGenerators/components/informationButton.js","webpack:///./scripts/features/leadGenerators/components/informationFormPaid.js","webpack:///./scripts/features/leadGenerators/components/contactRadioGroup.js","webpack:///./scripts/features/leadGenerators/components/dateInput.js","webpack:///./scripts/features/leadGenerators/components/requestButton.js","webpack:///./scripts/features/leadGenerators/components/tourRadioOptions.js","webpack:///./scripts/features/leadGenerators/components/requestTourForm.js","webpack:///./scripts/features/leadGenerators/components/brochureFormLimitedAvailability.js","webpack:///./scripts/features/leadGenerators/components/askQuestionButton.js","webpack:///./scripts/features/leadGenerators/components/askQuestionFormPaid.js","webpack:///./scripts/features/leadGenerators/components/manufacturedBrochureFormPaid.js","webpack:///./scripts/features/leadGenerators/services/leadGeneratorConstructor.js","webpack:///./scripts/features/leadGenerators/components/recommendedButton.js","webpack:///./scripts/features/leadGenerators/components/skipButton.js","webpack:///./scripts/features/leadGenerators/constants/svgIcons.js","webpack:///./scripts/features/leadGenerators/components/recommendedScreen.js","webpack:///./scripts/features/leadGenerators/components/recommendedButtonBasic.js","webpack:///./scripts/features/leadGenerators/components/recommendedScreenBasic.js","webpack:///./scripts/features/leadGenerators/components/thankScreenAskQuestion.js","webpack:///./scripts/features/leadGenerators/components/thankScreenBasic.js","webpack:///./scripts/features/leadGenerators/components/thankScreenBrochure.js","webpack:///./scripts/features/leadGenerators/components/thankScreenComingSoon.js","webpack:///./scripts/features/leadGenerators/components/thankScreenLimitedAvailability.js","webpack:///./scripts/features/leadGenerators/components/thankScreenTour.js","webpack:///./scripts/features/leadGenerators/components/wrapper.js","webpack:///./scripts/features/leadGenerators/enums/leadFormType.js","webpack:///./scripts/features/leadGenerators/apis/recommendedCommunities.js","webpack:///./scripts/features/leadGenerators/apis/postBrochure.js","webpack:///./scripts/features/leadGenerators/redux/epics.js","webpack:///./scripts/features/leadGenerators/index.js","webpack:///./scripts/features/leadGenerators/apis/postBrochureBasic.js","webpack:///./scripts/features/routing/components/pageLinkHandler.js","webpack:///./scripts/features/routing/redux/epics.js","webpack:///./scripts/features/routing/index.js","webpack:///./scripts/features/routing/redux/listeners.js","webpack:///./scripts/features/routing/redux/selectors.js","webpack:///./scripts/features/routing/redux/initialState.js","webpack:///./scripts/features/routing/redux/slices.js","webpack:///./scripts/features/routing/services/urlBuilder.js","webpack:///./scripts/features/searchResultsFacets/enums/locationType.js","webpack:///./scripts/features/searchResultsFacets/enums/moveInDate.js","webpack:///./scripts/features/searchResultsFacets/enums/planStatus.js","webpack:///./scripts/features/searchResultsFacets/enums/productType.js","webpack:///./scripts/features/searchResultsFacets/enums/resultType.js","webpack:///./scripts/features/searchResultsFacets/enums/specStatus.js","webpack:///./scripts/features/searchResultsFacets/redux/selectors.js","webpack:///./scripts/features/searchResultsFacets/services/homeStatusValidator.js","webpack:///./scripts/features/searchResultsFacets/services/moveInDateService.js","webpack:///./scripts/features/searchResultsMap/enums/markerType.js","webpack:///./scripts/features/searchResultsMap/redux/selectors.js","webpack:///./scripts/libraries/segmentAnalyticsLibrary.js","webpack:///./scripts/features/segment/index.js","webpack:///./scripts/features/segment/redux/actions.js","webpack:///./scripts/enums/segmentEventType.js","webpack:///./scripts/middlewares/segment/services/segment.js","webpack:///./scripts/middlewares/segment/services/eventDefinition.js","webpack:///./scripts/dataTransferObjects/segmentEvent.js","webpack:///./scripts/dataTransferObjects/segmentIdentifyEvent.js","webpack:///./scripts/utils/dateExtensions.js","webpack:///./scripts/dataTransferObjects/segmentPageEvent.js","webpack:///./scripts/services/segmentEventBuilder.js","webpack:///./scripts/features/segment/redux/beaconMiddleware.js","webpack:///./scripts/constants/partner.js","webpack:///./scripts/modules/deviceCapabilities.js","webpack:///./scripts/features/trackingProperties/redux/selectors.js","webpack:///./scripts/features/trackingProperties/index.js","webpack:///./scripts/features/userProfile/services/getListingInformationForPendingSave.js","webpack:///./scripts/features/userProfile/components/favorites.js","webpack:///./scripts/libraries/googleOneTapLibrary.js","webpack:///./scripts/features/userProfile/apis/loginWithGoogleOneTap.js","webpack:///./scripts/features/userProfile/services/parseJsonWebToken.js","webpack:///./scripts/features/userProfile/components/googleOneTapAuthentication.js","webpack:///./scripts/features/userProfile/components/signUpValidator.js","webpack:///./scripts/features/userProfile/components/auth0BaseConfiguration.js","webpack:///./scripts/features/userProfile/components/mainAuthentication.js","webpack:///./scripts/features/userProfile/components/modal.js","webpack:///./scripts/features/userProfile/components/neustarListener.js","webpack:///./scripts/features/userProfile/components/sessionAliveInteraction.js","webpack:///./scripts/features/userProfile/components/userMenu.js","webpack:///./scripts/features/userProfile/constants/auth0Constants.js","webpack:///./scripts/features/userProfile/constants/sessionStorageConstants.js","webpack:///./scripts/features/userProfile/enums/favoriteType.js","webpack:///./scripts/features/userProfile/index.js","webpack:///./scripts/features/userProfile/redux/listeners.js","webpack:///./scripts/features/userProfile/redux/selectors.js","webpack:///./scripts/features/userProfile/redux/initialState.js","webpack:///./scripts/features/userProfile/redux/slices.js","webpack:///./scripts/features/utm/redux/selectors.js","webpack:///./scripts/layout/constants/pageLayoutNames.js","webpack:///./scripts/layout/constants/resultPresentationType.js","webpack:///./scripts/layout/redux/selectors.js","webpack:///./scripts/layout/services/resultsPresentationService.js","webpack:///./scripts/layout/redux/uiStateSlice.js","webpack:///./scripts/layout/services/messageService.js","webpack:///./scripts/layout/services/modalService.js","webpack:///./scripts/libraries/authLibrary.js","webpack:///./scripts/middlewares/googleTagManager/services/googleTagManager.js","webpack:///./scripts/middlewares/googleTagManager/index.js","webpack:///./scripts/modules/cookieManager.js","webpack:///./scripts/pages/blog/components/articleSearchBox.js","webpack:///./scripts/pages/blog/components/categoryArticlesSection.js","webpack:///./scripts/pages/blog/components/listingsForYouSection.js","webpack:///./scripts/apis/getListingsForYouContent.js","webpack:///./scripts/apis/getMetroSpecificArticles.js","webpack:///./scripts/pages/blog/components/metroSpecificSection.js","webpack:///./scripts/pages/blog/components/mostPopularArticleSection.js","webpack:///./scripts/pages/blog/components/popularPillsCarousel.js","webpack:///./scripts/pages/blog/components/redirectHandler.js","webpack:///./scripts/pages/blog/components/handlerErrorImages.js","webpack:///./scripts/pages/blog/components/standardCard.js","webpack:///./scripts/pages/blog/subLandingPage/components/eventTracking/googleAnalytics4EventsHandler.js","webpack:///./scripts/pages/blog/subLandingPage/components/eventTracking/segmentEventsHandler.js","webpack:///./scripts/pages/blog/subLandingPage/subLandingPage.js","webpack:///./scripts/pages/searchResults/enums/urlSubdirectoryTypes.js","webpack:///./scripts/pages/searchResults/redux/actions.js","webpack:///./scripts/features/userProfile/apis/getUserProfile.js","webpack:///./scripts/features/userProfile/apis/getUserFavorites.js","webpack:///./scripts/features/userProfile/apis/saveFavorite.js","webpack:///./scripts/features/userProfile/apis/deleteFavorite.js","webpack:///./scripts/features/userProfile/services/getHousingProductType.js","webpack:///./scripts/features/userProfile/models/specProductType.js","webpack:///./scripts/features/userProfile/models/planProductType.js","webpack:///./scripts/features/userProfile/models/communityProductType.js","webpack:///./scripts/features/userProfile/redux/epics.js","webpack:///./scripts/redux/rootEpics.js","webpack:///./scripts/features/userProfile/services/getFavoriteFromState.js","webpack:///./scripts/redux/store.js","webpack:///./scripts/services/googleAnalytics.js","webpack:///./scripts/dataTransferObjects/googleAnalytics4Event.js","webpack:///./scripts/modules/getCentralStandardTime.js","webpack:///./scripts/services/googleAnalytics4EventBuilder.js","webpack:///./scripts/services/marketingStatusValidator.js","webpack:///./scripts/utils/camelCase.js","webpack:///./scripts/utils/cleanObject/cleanObject.js","webpack:///./scripts/utils/randomNumber.js","webpack:///./scripts/utils/stringExtensions.js","webpack:///./scripts/utils/urlExtension.js","webpack:///./images/icons/dynamic/callForPriceCommunityIcon.svg","webpack:///./images/icons/dynamic/callForPriceHomeIcon.svg"],"sourcesContent":["import fastdom from 'fastdom';\r\nimport { fromEvent, of, Subject, switchMap } from 'rxjs';\r\n\r\n/**\r\n * Carousel file is incharge of create a slider on elements without default size\r\n * To use thois coursel you need to add the next css properties to your container element\r\n * overflow-x: auto; to allow scroll event in the container element\r\n * overflow-y: hidden; to avoid scroll in the y-axis\r\n * scrollbar-width: none; to avoid show scroll or scroll manually functionality\r\n */\r\n\r\nclass Carousel {\r\n\r\n /**\r\n * Toggle the visibility of the previous and next element based on its visibility.\r\n */\r\n toggleArrowControllElements() {\r\n if(this.itemListElement && this.visibleElementIndexes){\r\n fastdom.measure(() => {\r\n const firstElement = this.itemListElement.firstElementChild;\r\n const lastElement = this.itemListElement.lastElementChild;\r\n const lastElementIndex = this.itemListElement.children.length-1;\r\n\r\n const shouldDisplayPreviousArrow = firstElement ? !this.visibleElementIndexes.has(0) : false;\r\n const shouldDisplayNextArrow = lastElement ? !this.visibleElementIndexes.has(lastElementIndex) : false;\r\n \r\n fastdom.mutate(() => {\r\n this.previousElement.style.visibility = shouldDisplayPreviousArrow ? 'visible' : 'hidden';\r\n this.nextElement.style.visibility = shouldDisplayNextArrow ? 'visible' : 'hidden';\r\n });\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * Set up a subcription event to update controlls based on new visibles elements.\r\n */\r\n setUpdateControllsEvent() {\r\n if (this.visibleElementsSubject$) {\r\n const updateControllsSubscription = this.visibleElementsSubject$.subscribe(\r\n this.toggleArrowControllElements.bind(this));\r\n this.observerSubscriptions.push(updateControllsSubscription);\r\n }\r\n }\r\n\r\n /**\r\n * Smoothly scroll to a specified horizontal position.\r\n * @param {number} scrollX - The horizontal position to scroll to.\r\n */\r\n scrollTo(scrollX) {\r\n if(this.itemListElement){\r\n fastdom.mutate(() => {\r\n this.itemListElement.scroll({\r\n left: scrollX,\r\n behavior: 'smooth'\r\n });\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * Smoothly scroll by an specific number of pixel.\r\n * Use this function when no elements are visible in the intersection observer.\r\n * @param {number} scrollX - The horizontal count of pixels to scroll.\r\n */\r\n scrollBy(scrollX){\r\n if(this.itemListElement){\r\n fastdom.mutate(() => {\r\n this.itemListElement.scrollBy({\r\n left: scrollX,\r\n behavior: 'smooth'\r\n });\r\n });\r\n } \r\n }\r\n\r\n /**\r\n * Set up the observer for previous button clicks.\r\n */\r\n setPreviousArrowObserver() {\r\n if(this.previousElement){\r\n const previousButtonClick$ = fromEvent(this.previousElement, 'click').pipe(\r\n switchMap(() => {\r\n const position = this.getVisibleElementIndexes().previous;\r\n const elementToScroll = this.itemListElement.children[position];\r\n return of(elementToScroll);\r\n })\r\n );\r\n \r\n const previousButtonSubscription = previousButtonClick$.subscribe((elementToScroll) => {\r\n fastdom.measure(() => {\r\n if(elementToScroll){\r\n const elementRightPosition = elementToScroll.getBoundingClientRect().right;\r\n const itemListElementRightPosition = this.itemListElement.getBoundingClientRect().right;\r\n const itemListElementScrollLeft = this.itemListElement.scrollLeft;\r\n const scrollX = elementRightPosition - itemListElementRightPosition + itemListElementScrollLeft;\r\n this.scrollTo(scrollX);\r\n }else{\r\n this.scrollBy(-100);\r\n }\r\n });\r\n });\r\n\r\n this.observerSubscriptions.push(previousButtonSubscription);\r\n }\r\n }\r\n\r\n /**\r\n * Set up the observer for next button clicks.\r\n */\r\n setNextArrowObserver() {\r\n if(this.nextElement){\r\n const nextButtonClick$ = fromEvent(this.nextElement, 'click').pipe(\r\n switchMap(() => {\r\n const position = this.getVisibleElementIndexes().next;\r\n const elementToScroll = this.itemListElement.children[position];\r\n return of(elementToScroll);\r\n })\r\n );\r\n \r\n const nextButtonSubscription = nextButtonClick$.subscribe((elementToScroll) => {\r\n fastdom.measure(() => {\r\n if(elementToScroll){\r\n const elementLeftPosition = elementToScroll.getBoundingClientRect().left;\r\n const itemListElementLeftPosition = this.itemListElement.getBoundingClientRect().left;\r\n const itemListElementScrollLeft = this.itemListElement.scrollLeft;\r\n const scrollX = elementLeftPosition - itemListElementLeftPosition + itemListElementScrollLeft;\r\n this.scrollTo(scrollX);\r\n }else{\r\n this.scrollBy(100);\r\n }\r\n });\r\n });\r\n\r\n this.observerSubscriptions.push(nextButtonSubscription);\r\n }\r\n }\r\n\r\n /**\r\n * Set the indexes of visible elements based on their positions.\r\n */\r\n setIntersectionObserver() {\r\n if(this.itemListElement && this.visibleElementIndexes){\r\n const elementsToObserve = Array.from(this.itemListElement.children);\r\n this.intersectionObserver = new IntersectionObserver(\r\n (entries) => {\r\n entries.forEach((entry) => {\r\n if (entry.isIntersecting) {\r\n this.visibleElementIndexes.add(entry.target.index);\r\n } else {\r\n this.visibleElementIndexes.delete(entry.target.index);\r\n }\r\n });\r\n\r\n this.visibleElementsSubject$.next();\r\n },\r\n {\r\n root: this.itemListElement,\r\n threshold: 0.95,\r\n }\r\n );\r\n \r\n elementsToObserve.forEach((element, index) => {\r\n element.index = index;\r\n this.intersectionObserver.observe(element);\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * Get the index of the possible elements to scroll on next and previous controlls.\r\n */\r\n getVisibleElementIndexes(){\r\n const indexes = { previous: -1, next: -1 };\r\n const visibleElementsCount = this.visibleElementIndexes.size;\r\n const itemListElementCount = this.itemListElement.children.length;\r\n\r\n if(visibleElementsCount > 0 && itemListElementCount > 0) {\r\n const visibleIndexesArray = [...this.visibleElementIndexes];\r\n const lastPossibleElementIndex = itemListElementCount - 1;\r\n\r\n // get left and right visible element index in the contairner\r\n const visibleLeftmostIndex = Math.min(...visibleIndexesArray);\r\n const visibleRightmostIndex = Math.max(...visibleIndexesArray);\r\n\r\n // get possible index to show in the container\r\n const possiblePreviousIndex = visibleLeftmostIndex - 1;\r\n const possibleNextIndex = visibleRightmostIndex + 1;\r\n\r\n indexes.previous = possiblePreviousIndex >= 0 ? possiblePreviousIndex : 0;\r\n indexes.next = possibleNextIndex <= lastPossibleElementIndex ? possibleNextIndex : lastPossibleElementIndex;\r\n }\r\n\r\n return indexes;\r\n }\r\n\r\n /**\r\n * Method in charge of disconnect the current observer to create a new one\r\n * Use this method only when you refresh the item list element.\r\n */\r\n updateIntersectionObserver(){\r\n this.intersectionObserver.disconnect();\r\n this.visibleElementIndexes = new Set();\r\n this.setIntersectionObserver();\r\n }\r\n\r\n /**\r\n * Set the carousel settings from the provided configuration object.\r\n * @param {Object} settings - The configuration settings for the carousel.\r\n * @param {string} settings.itemListQuerySelector - The selector for the item list element.\r\n * @param {string} settings.previousQuerySelector - The selector for the previous button element.\r\n * @param {string} settings.nextQuerySelector - The selector for the next button element.\r\n */\r\n setSettings(settings) {\r\n this.itemListElement = settings.itemListQuerySelector\r\n ? document.querySelector(settings.itemListQuerySelector) : undefined;\r\n this.previousElement = settings.previousQuerySelector\r\n ? document.querySelector(settings.previousQuerySelector) : undefined;\r\n this.nextElement = settings.nextQuerySelector\r\n ? document.querySelector(settings.nextQuerySelector) : undefined;\r\n this.visibleElementIndexes = new Set();\r\n this.observerSubscriptions = [];\r\n this.visibleElementsSubject$ = new Subject();\r\n }\r\n\r\n /**\r\n * delete all reference of observers and events from memory\r\n */\r\n destroy(){\r\n this.intersectionObserver.disconnect();\r\n this.observerSubscriptions.forEach(sub => sub.unsubscribe());\r\n }\r\n\r\n /**\r\n * Initialize the carousel and set up observers.\r\n */\r\n create() {\r\n this.setUpdateControllsEvent();\r\n this.setIntersectionObserver();\r\n this.setPreviousArrowObserver();\r\n this.setNextArrowObserver();\r\n }\r\n\r\n /**\r\n * Refresh the carousel, updating the positions and visibility of elements.\r\n */\r\n refresh() {\r\n this.scrollTo(0);\r\n this.updateIntersectionObserver();\r\n }\r\n}\r\n\r\nexport default Carousel;","import { switchMap, of, catchError } from 'rxjs';\r\nimport { fromFetch } from 'rxjs/fetch';\r\n\r\n/**\r\n * getTypeaheadSuggestions: function to fetch suggestion from any source.\r\n * @param {string} url: url source to fetch suggestions.\r\n */\r\nconst getTypeaheadSuggestions = function (url) {\r\n return fromFetch(url, {\r\n headers: {\r\n 'Accept': 'application/json',\r\n }\r\n }).pipe(\r\n switchMap((response) => response.json()),\r\n catchError(() => of([]))\r\n );\r\n}\r\n\r\nexport default getTypeaheadSuggestions;\r\n\r\n","import { fromEvent, partition, merge, filter, map, EMPTY, of } from 'rxjs';\r\nimport fastdom from 'fastdom';\r\nimport { debounceTime, switchMap } from 'rxjs/operators';\r\nimport getTypeaheadSuggestions from 'api/getTypeaheadSuggestions';\r\nimport typeaheadKeyboardHandler from './typeaheadKeyboardHandler';\r\n\r\nclass Typeahead {\r\n\r\n getSourceUrl(searchTerm) {\r\n const separator = this.sourceUrl.includes('?') ? '&' : '?';\r\n return `${this.sourceUrl}${separator}searchTerm=${encodeURIComponent(searchTerm)}`;\r\n }\r\n\r\n displayErrorMessage() {\r\n this.errorContainer.removeAttribute('hidden');\r\n }\r\n \r\n setInitialSearchInputValue() {\r\n // setting the value on initial load if available\r\n // we need to set the value using javascript because if the value is set on the HTML\r\n // it will be set as the input's default value, preventing the user from clearing the input\r\n // since the X icon is a button[type='reset'] which will reset the input to its default value.\r\n // for more: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/reset\r\n if (this.searchInput?.dataset?.value) {\r\n this.searchInput.value = this.searchInput.dataset.value;\r\n }\r\n }\r\n\r\n closeErrorMessage() {\r\n this.errorContainer.setAttribute('hidden', '');\r\n }\r\n\r\n clearSuggestions() {\r\n this.suggestionsList.innerHTML = '';\r\n this.suggestionsList.setAttribute('hidden', ''); \r\n }\r\n\r\n clearSearchInput() {\r\n this.searchInput.value = '';\r\n }\r\n\r\n autoSelectSuggestion() {\r\n const searchInputValue = this.searchInput?.value.trim() ?? '';\r\n \r\n // redirect when the value is in the suggestion list\r\n const suggestedOption = this.suggestionsList.querySelector(`[value=\"${searchInputValue}\"]`);\r\n suggestedOption.click();\r\n }\r\n\r\n displaySuggestions(suggestions) {\r\n const fragment = document.createDocumentFragment();\r\n\r\n suggestions.forEach(suggestion => {\r\n const content = suggestion[this.suggestionValueKey];\r\n const li = document.createElement('li');\r\n\r\n // value for typeahead keyboard handler\r\n li.setAttribute('value', content);\r\n\r\n // value to display on suggestion item\r\n li.textContent = content;\r\n\r\n const keysArray = Object.keys(suggestion);\r\n keysArray.forEach((key) => {\r\n li.setAttribute(`data-${key}`, suggestion[key]);\r\n });\r\n\r\n fragment.appendChild(li);\r\n });\r\n\r\n fastdom.mutate(() => {\r\n this.suggestionsList.appendChild(fragment);\r\n this.suggestionsList.removeAttribute('hidden');\r\n this.suggestionsList.scrollTop = 0;\r\n });\r\n }\r\n\r\n setSearchResultEvent(){\r\n if(this.searchInput && this.suggestionsList && this.errorContainer){\r\n const searchInput$ = fromEvent(this.searchInput, 'input');\r\n const searchFocus$ = fromEvent(this.searchInput, 'focus');\r\n const searchEvent$ = merge(searchInput$, searchFocus$);\r\n this.searchResult$ = searchEvent$.pipe(\r\n debounceTime(100),\r\n switchMap((event) => {\r\n this.clearSuggestions();\r\n this.closeErrorMessage();\r\n const userInput = event.target.value;\r\n const trimmedUserInput = userInput?.trim();\r\n if (!trimmedUserInput) {\r\n return [];\r\n }\r\n\r\n return getTypeaheadSuggestions(this.getSourceUrl(trimmedUserInput));\r\n })\r\n );\r\n\r\n const [displaySuggestions$, displayErrorMessage$] = partition(\r\n this.searchResult$, (list) => list.length > 0\r\n );\r\n\r\n displaySuggestions$.subscribe(this.displaySuggestions.bind(this));\r\n displayErrorMessage$.subscribe(this.displayErrorMessage.bind(this));\r\n }\r\n }\r\n\r\n setSuggestionListClickedEvent(){\r\n if(this.suggestionsList && this.searchInput){\r\n this.suggestionListClicked$ = fromEvent(this.suggestionsList, 'click').pipe(\r\n filter((event) => event.target.closest('li')),\r\n map((event) => event.target.closest('li'))\r\n );\r\n\r\n this.suggestionListClicked$.subscribe((suggestion) => {\r\n this.searchInput.value = suggestion.innerText.trim();\r\n });\r\n }\r\n }\r\n\r\n setSubmitButtonClickedEvent(){\r\n if(this.submitButton){\r\n\r\n const submitButtonClicked$ = fromEvent(this.submitButton, 'click');\r\n const enterKeydown$ = fromEvent(this.searchInput, 'keydown').pipe(\r\n filter((event) => event.key === 'Enter')\r\n );\r\n\r\n const autoSelectSuggestion$ = merge(enterKeydown$, submitButtonClicked$).pipe(\r\n switchMap((event) => {\r\n event.preventDefault();\r\n const searchTerm = this.searchInput?.value.trim() ?? '';\r\n return of(searchTerm);\r\n }),\r\n filter((searchTerm) => searchTerm !== '') \r\n );\r\n\r\n const [selectSuggestion$, submitSuggestion$] = partition(\r\n autoSelectSuggestion$, (searchTerm) => !!this.suggestionsList.querySelector(`[value=\"${searchTerm}\"]`)\r\n );\r\n\r\n selectSuggestion$.subscribe(this.autoSelectSuggestion.bind(this));\r\n\r\n this.submitEventObserver$ = submitSuggestion$;\r\n }\r\n }\r\n\r\n setClearButtonClickedEvent(){\r\n if(this.clearButton && this.suggestionsList && this.searchInput){\r\n const clearButtonClicked$ = fromEvent(this.clearButton, 'click');\r\n clearButtonClicked$.subscribe(() => {\r\n this.closeErrorMessage();\r\n this.clearSuggestions();\r\n this.clearSearchInput();\r\n });\r\n }\r\n }\r\n\r\n setInputOutClickedEvent(){\r\n if(this.searchInput && this.suggestionsList){\r\n\r\n // add debounce of 500 to avoid delete the suggestion list before to perform another operation\r\n const inputBlur$ = fromEvent(this.searchInput, 'blur').pipe(debounceTime(500));\r\n inputBlur$.subscribe(this.clearSuggestions.bind(this));\r\n }\r\n }\r\n\r\n setkeyDownHandler(){\r\n if(this.searchInput && this.suggestionsList){\r\n const keyDownHandler = typeaheadKeyboardHandler({\r\n searchInput: this.searchInput,\r\n suggestList: this.suggestionsList,\r\n selectedOptionIndex: -1,\r\n searchObserver: this.searchResult$\r\n });\r\n\r\n const keydown$ = fromEvent(this.searchInput, 'keydown').pipe(\r\n filter((event) => event.key !== 'Enter')\r\n );\r\n\r\n keydown$.subscribe(keyDownHandler);\r\n }\r\n }\r\n\r\n setTypeaheadSetting(setting){\r\n this.searchInput = setting.searchInputQuerySelector\r\n ? document.querySelector(setting.searchInputQuerySelector) : undefined;\r\n this.suggestionsList = setting.suggestionsListQuerySelector\r\n ? document.querySelector(setting.suggestionsListQuerySelector) : undefined;\r\n this.errorContainer = setting.errorContainerQuerySelector\r\n ? document.querySelector(setting.errorContainerQuerySelector) : undefined;\r\n this.submitButton = setting.submitButtonQuerySelector\r\n ? document.querySelector(setting.submitButtonQuerySelector) : undefined;\r\n this.clearButton = setting.clearButtonQuerySelector\r\n ? document.querySelector(setting.clearButtonQuerySelector) : undefined;\r\n\r\n this.sourceUrl = setting.sourceUrl;\r\n this.suggestionValueKey = setting.suggestionValueKey;\r\n\r\n this.setSearchResultEvent();\r\n this.setSuggestionListClickedEvent();\r\n this.setClearButtonClickedEvent();\r\n this.setSubmitButtonClickedEvent();\r\n this.setInputOutClickedEvent();\r\n this.setkeyDownHandler();\r\n this.setInitialSearchInputValue();\r\n }\r\n\r\n getSuggestionListClickedObserver(){\r\n // To avoid null references\r\n return this.suggestionListClicked$ ?? EMPTY;\r\n }\r\n\r\n getSubmitEventObserver(){\r\n // To avoid null references\r\n return this.submitEventObserver$ ?? EMPTY;\r\n }\r\n}\r\n\r\nexport default Typeahead;","/**\r\n * The idea behind this module is to separate the concerns of the typeahead\r\n * initially this was inside the typeahead.js file, but since it only handles what\r\n * we call keyboard accesibilty, we felt it was better that this code was separated from the\r\n * typeahead itself, and that modularize itself for easier reading of the typeahead code.\r\n */\r\n\r\nfunction typeaheadKeyboardHandler(config) {\r\n const suggestList = config.suggestList;\r\n const searchInput = config.searchInput;\r\n let selectedOptionIndex = config.selectedOptionIndex;\r\n const search$ = config.searchObserver;\r\n\r\n // reset index when a new search was performed\r\n search$.subscribe(() => { selectedOptionIndex = config.selectedOptionIndex });\r\n\r\n /**\r\n * updateOptionsStatus: Adds the active class to options if they're being actively focused via keyboard.\r\n * remove the active class from previously selected options to avoid displaying multiple selected options.\r\n * @param {Number} activeOptionIndex the currently active option's index.\r\n */\r\n function updateOptionsStatus(activeOptionIndex) {\r\n const options = suggestList.children;\r\n for (let index = 0; index < options.length; index += 1) {\r\n if (activeOptionIndex === index) {\r\n options[index].classList.add('active');\r\n options[index].ariaSelected = true;\r\n } else {\r\n options[index].classList.remove('active');\r\n options[index].ariaSelected = false;\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * setSelectedOptionInTypeahead: Update the search input with the selected option.\r\n * @param {Number} optionIndex Option index that is active.\r\n */\r\n function setSelectedOptionInTypeahead(optionIndex) {\r\n const optionSelected = suggestList.children[optionIndex];\r\n searchInput.value = optionSelected.getAttribute('value');\r\n const end = searchInput.value.length;\r\n\r\n // move the cursor to the end of the input.\r\n searchInput.setSelectionRange(end, end);\r\n }\r\n\r\n /**\r\n * scrollToOption: Scrolls to the option to make it visible on screen.\r\n * @param {Number} optionIndex Option index that will be shown.\r\n */\r\n function scrollToOption(optionIndex) {\r\n const optionToShow = suggestList.children[optionIndex];\r\n optionToShow.scrollIntoViewIfNeeded();\r\n }\r\n\r\n /**\r\n * upArrowHandler: Handles the up arrow key when it is pressed.\r\n */\r\n function upArrowHandler() {\r\n if (selectedOptionIndex < 1) {\r\n return;\r\n }\r\n\r\n selectedOptionIndex -= 1;\r\n setSelectedOptionInTypeahead(selectedOptionIndex);\r\n updateOptionsStatus(selectedOptionIndex);\r\n scrollToOption(selectedOptionIndex);\r\n }\r\n\r\n /**\r\n * downArrowHandler: Handles the down arrow key when it is pressed.\r\n */\r\n function downArrowHandler() {\r\n const optionSize = suggestList.childElementCount;\r\n if (optionSize < 1 || selectedOptionIndex === optionSize - 1) {\r\n return;\r\n }\r\n\r\n selectedOptionIndex += 1;\r\n setSelectedOptionInTypeahead(selectedOptionIndex);\r\n updateOptionsStatus(selectedOptionIndex);\r\n scrollToOption(selectedOptionIndex);\r\n }\r\n\r\n /**\r\n * closeOptions: Closes the suggestion list.\r\n */\r\n function closeOptions() {\r\n suggestList.innerHTML = '';\r\n suggestList.setAttribute('hidden', '');\r\n selectedOptionIndex = -1;\r\n }\r\n\r\n /**\r\n * enterHandler: Handles the enter key when it is pressed.\r\n */\r\n function enterHandler() {\r\n const currentSearch = searchInput.value;\r\n const suggestedOption = suggestList.querySelector(\r\n `[value=\"${currentSearch}\"]`\r\n );\r\n if (suggestedOption) {\r\n suggestedOption.click();\r\n closeOptions();\r\n }\r\n }\r\n\r\n const keyHandlers = {\r\n ArrowDown: downArrowHandler,\r\n ArrowUp: upArrowHandler,\r\n Enter: enterHandler,\r\n };\r\n\r\n /**\r\n * keyDownHandler: Handles the all the key down events on the search input.\r\n * @param {Event} event Any key down event.\r\n */\r\n function keyDownHandler(event) {\r\n const arrowHandler = keyHandlers[event.key];\r\n if (arrowHandler) {\r\n event.preventDefault();\r\n arrowHandler();\r\n }\r\n }\r\n\r\n return keyDownHandler;\r\n}\r\n\r\nexport default typeaheadKeyboardHandler;\r\n","export default class GoogleAnalyticsCustomDimensions {\r\n static MarketId() {\r\n return new GoogleAnalyticsCustomDimensions('marketId');\r\n }\r\n\r\n static PartnerName() {\r\n return new GoogleAnalyticsCustomDimensions('partnerName');\r\n }\r\n\r\n static BuilderCorporation() {\r\n return new GoogleAnalyticsCustomDimensions('builderCorp');\r\n }\r\n\r\n static CommunityName() {\r\n return new GoogleAnalyticsCustomDimensions('communityName');\r\n }\r\n\r\n static City() {\r\n return new GoogleAnalyticsCustomDimensions('city');\r\n }\r\n\r\n static PageType() {\r\n return new GoogleAnalyticsCustomDimensions('pageType');\r\n }\r\n\r\n static PartnerId() {\r\n return new GoogleAnalyticsCustomDimensions('partnerId');\r\n }\r\n\r\n static MarketName() {\r\n return new GoogleAnalyticsCustomDimensions('marketName');\r\n }\r\n\r\n static CommunityId() {\r\n return new GoogleAnalyticsCustomDimensions('communityId');\r\n }\r\n\r\n static UserId() {\r\n return new GoogleAnalyticsCustomDimensions('i_uid');\r\n }\r\n\r\n static CurrentPageNumber() {\r\n return new GoogleAnalyticsCustomDimensions('currentPageNumber');\r\n }\r\n\r\n static NeustarResponse() {\r\n return new GoogleAnalyticsCustomDimensions('n_response');\r\n }\r\n\r\n static OffMarket() {\r\n return new GoogleAnalyticsCustomDimensions('OffMarket');\r\n }\r\n\r\n static BuilderId() {\r\n return new GoogleAnalyticsCustomDimensions('builderId');\r\n }\r\n\r\n static BrandName() {\r\n return new GoogleAnalyticsCustomDimensions('brandName');\r\n }\r\n\r\n static PlanId() {\r\n return new GoogleAnalyticsCustomDimensions('planId');\r\n }\r\n\r\n static SpecId() {\r\n return new GoogleAnalyticsCustomDimensions('specId');\r\n }\r\n\r\n static IsPaid() {\r\n return new GoogleAnalyticsCustomDimensions('IsPaid');\r\n }\r\n\r\n static MatchingResults() {\r\n return new GoogleAnalyticsCustomDimensions('matchingResults');\r\n }\r\n\r\n static Counties() {\r\n return new GoogleAnalyticsCustomDimensions('counties');\r\n }\r\n\r\n static Location() {\r\n return new GoogleAnalyticsCustomDimensions('location');\r\n }\r\n\r\n static PriceReduction() {\r\n return new GoogleAnalyticsCustomDimensions('priceReduction');\r\n }\r\n\r\n static SearchWithinMapActivated() {\r\n return new GoogleAnalyticsCustomDimensions('searchWithinMapActivated');\r\n }\r\n\r\n constructor(dimension) {\r\n this.dimension = dimension;\r\n }\r\n\r\n getName() {\r\n return this.dimension;\r\n }\r\n}\r\n","export default class HousingProductType {\r\n\r\n static Spec() {\r\n return new HousingProductType('spec');\r\n }\r\n\r\n static Plan() {\r\n return new HousingProductType('plan');\r\n }\r\n\r\n static Community() {\r\n return new HousingProductType('community');\r\n }\r\n\r\n static BasicListing() {\r\n return new HousingProductType('basicListing');\r\n }\r\n\r\n constructor(type) {\r\n this.type = type;\r\n }\r\n\r\n getName() {\r\n return this.type;\r\n }\r\n}\r\n","/**\r\n * The idea for this filter is to have a centralized list of all routes used in the front-end,\r\n * Using destructuring assignment and tree-shaking, we can only load those routes that we need\r\n * making sure that if the routes change in the future, we can easily update them in the front-end\r\n * without requiring changes in multiple places\r\n *\r\n * an example of how to load routes can be seen below:\r\n *\r\n * import { getTypeaheadOptions } from 'constants/routes'\r\n */\r\n\r\n/*\r\n * Gets the value of the `href` attribute of the `base` element in the HTML document.\r\n * If the `base` element does not exist or does not have an `href` attribute, `baseElementUrl` will be `undefined`.\r\n *\r\n * Using document.querySelector('base').href could induce error in the code if the base element does not exist\r\n * or the href attribute is undefined, as it fallbacks to the document's fallback base URL, which is the current\r\n * Document's URL.\r\n */\r\nconst baseElementUrl = document.querySelector('base')?.attributes?.href?.value;\r\n\r\n/*\r\n * Object that contains properties that can be useful for configuring the API requests\r\n * or other network requests in the application.\r\n */\r\nconst configuration = {\r\n baseUrl: baseElementUrl || window.location.origin,\r\n};\r\n\r\nexport const getAdConfiguration = `${configuration.baseUrl}/ajax/getadconfiguration`;\r\nexport const getBreadcrumbContent = `${configuration.baseUrl}/ajax/getonpagebreadcrumb`;\r\nexport const getCommunitiesResults = `${configuration.baseUrl}/ajax/getResults`;\r\nexport const getHousingProductSnippetContent = `${configuration.baseUrl}/ajax/gethousingproductsnippetscontent`;\r\nexport const getListingCounts = `${configuration.baseUrl}/ajax/getResultCounts`;\r\nexport const getOnPageContent = `${configuration.baseUrl}/ajax/gethousingproductlocationcontentajax`;\r\nexport const getResultFacets = `${configuration.baseUrl}/ajax/getResultFacets`;\r\nexport const getTypeaheadOptions = `${configuration.baseUrl}/gettypeaheadoptions`;\r\nexport const leadsBasicCommunitySubmission = `${configuration.baseUrl}/ajax/leads/basiccommunitysubmission/`;\r\nexport const leadsBasicPlanSubmission = `${configuration.baseUrl}/ajax/leads/basicplansubmission/`;\r\nexport const leadsBasicSpecSubmission = `${configuration.baseUrl}/ajax/leads/basicspecsubmission/`;\r\nexport const leadsBasicListingSubmission = `${configuration.baseUrl}/ajax/leads/basiclistingsubmission/`;\r\nexport const leadsGetRecommendedCommunities = `${configuration.baseUrl}/ajax/leads/getrecommendedcommunities/`;\r\nexport const leadsPaidCommunitySubmission = `${configuration.baseUrl}/ajax/leads/paidcommunitysubmission/`;\r\nexport const leadsPaidPlanSubmission = `${configuration.baseUrl}/ajax/leads/paidplansubmission/`;\r\nexport const leadsPaidSpecSubmission = `${configuration.baseUrl}/ajax/leads/paidspecsubmission/`;\r\nexport const leadsRecommendedCommunitySubmission = `${configuration.baseUrl}/ajax/leads/recommendedcommunitysubmission/`;\r\nexport const mapGetCommunitiesPoints = `${configuration.baseUrl}/ajax/communities/getcommunitypoints`;\r\nexport const mapGetHomesPoints = `${configuration.baseUrl}/ajax/homes/gethomepoints`;\r\nexport const totalDeliveryValueCommunityLogger = `${configuration.baseUrl}/communitylogger`;\r\nexport const totalDeliveryValuePlanLogger = `${configuration.baseUrl}/planlogger`;\r\nexport const totalDeliveryValueSpecLogger = `${configuration.baseUrl}/speclogger`;\r\nexport const userDeleteFavorite = `${configuration.baseUrl}/user/deleteFavorite`;\r\nexport const userGetProfile = `${configuration.baseUrl}/getUserProfile`;\r\nexport const userProfileGetFavorites = `${configuration.baseUrl}/getUserFavorites`;\r\nexport const userSaveFavorite = `${configuration.baseUrl}/user/saveFavorite`;\r\nexport const marketingcampaignUnsubscribe = `${configuration.baseUrl}/marketingcampaign/unsubscribemarketingcampaign`;\r\nexport const marketingcampaignUnsubscribeFeedback = `${configuration.baseUrl}/marketingcampaign/unsubscribefeedback`;\r\nexport const googleOneTapLogin = `${configuration.baseUrl}/ajax/googleOneTapLogin`;\r\nexport const getCommunityNearbyListingsInfo = `${configuration.baseUrl}/ajax/getcommunitynearbylistings`;\r\nexport const getBuildablePlanNearbylistingsInfo = `${configuration.baseUrl}/ajax/getbuildableplannearbylistings`;\r\nexport const getPlanNearbyListingsInfo = `${configuration.baseUrl}/ajax/getplannearbylistings`;\r\nexport const getSpecNearbyListingsInfo = `${configuration.baseUrl}/ajax/getspecnearbylistings`;\r\nexport const listingCounts = `${configuration.baseUrl}/learn/dynamic/getlistingcounts`;\r\nexport const getArticleSuggestions = `${configuration.baseUrl}/learn/dynamic/getarticlesuggestions`;\r\nexport const getCommunitiesForYou = `${configuration.baseUrl}/learn/dynamic/getcommunitiesforyou`;\r\nexport const getHomesForYou = `${configuration.baseUrl}/learn/dynamic/gethomesforyou`;\r\nexport const getMetroSpecificArticles = `${configuration.baseUrl}/learn/dynamic/getmetroarearelatedarticles`;\r\nexport const getMostRecentArticles = `${configuration.baseUrl}/learn/dynamic/getmostrecentarticles`\r\nexport const blogRequestAccessToCacheManager = `${configuration.baseUrl}/util/blogcachemanager/requestaccess`;\r\nexport const deleteItemInAllServers = `${configuration.baseUrl}/util/cachemanager/deleteiteminallservers`;\r\nexport const purgeCdnCache = `${configuration.baseUrl}/util/purge-cdn-cache`;\r\nexport const learningCenter = `${configuration.baseUrl}/learn/`;\r\nexport const getArticleSearchResults = `${configuration.baseUrl}/learn/dynamic/getresults/`;\r\nexport const getArticleCountResults = `${configuration.baseUrl}/learn/dynamic/getcountsresults/`;\r\nexport const searchCommunitySitePlans = `${configuration.baseUrl}/ajax/searchcommunitysiteplans`;\r\nexport const getCommunityInteractiveSitePlanMarkers = `${configuration.baseUrl}/ajax/getcommunityinteractivesiteplanmarkers`;\r\nexport const getCommunitySummaryCard = `${configuration.baseUrl}/ajax/getcommunitysummarycard`;\r\nexport const getHousingUnitSummaryCard = `${configuration.baseUrl}/ajax/gethousingunitsummarycard`;","import backArrowIcon from '@icons/backArrow.svg';\r\nimport closeIcon from '@icons/closeIcon.svg';\r\nimport closeModalIcon from '@icons/closeModal.svg';\r\nimport priceReducedIcon from '@icons/priceReducedIcon.svg';\r\nimport callForPriceCommunityIcon from '@icons/dynamic/callForPriceCommunityIcon.svg';\r\nimport callForPriceHomeIcon from '@icons/dynamic/callForPriceHomeIcon.svg';\r\nimport thanksContentIcon from '@icons/thanksContent.svg';\r\nimport locationIcon from '@icons/location.svg';\r\nimport interactiveSitePlanIcon from '@icons/interactiveSitePlan.svg';\r\n\r\n// modal icons\r\nimport thankYouHeart from '@icons/modal/thankYouHeart.svg';\r\nimport thankYouEmail from '@icons/modal/thankYouEmail.svg';\r\nimport thankYouPhone from '@icons/modal/thankYouPhone.svg';\r\nimport thankYouSuccess from '@icons/modal/thankYouSuccess.svg';\r\n\r\n// toast icons\r\nimport circleCheck from '@icons/circleCheck.svg';\r\nimport circleWarning from '@icons/circleWarning.svg';\r\n\r\n// these are static icons, webpack will return the path to the file instead of the icon itself\r\nexport const backArrowSvg = ``;\r\nexport const closeIconSvg = ``;\r\nexport const closeModalIconSvg = ``;\r\nexport const priceReducedIconSvg = `\"Price`;\r\nexport const thanksContentIconSvg = ``;\r\nexport const locationIconSvg = ``;\r\nexport const interactiveSitePlanSvg = ``;\r\n\r\nexport const thankYouHeartSvg = ``;\r\nexport const thankYouEmailSvg = ``;\r\nexport const thankYouPhoneSvg = ``;\r\nexport const thankYouSuccessSvg = ``;\r\n\r\n// These are dynamic icons, these are served as svg-in-js and are included in the .js bundle\r\n// you should only consider using dynamic icons if you need to change the color or any other\r\n// attribute of the icon itself.\r\nexport const callForPriceCommunityIconSvg = callForPriceCommunityIcon;\r\nexport const callForPriceHomeIconSvg = callForPriceHomeIcon;\r\n\r\nexport const circleCheckSvg = ``;\r\nexport const circleWarningSvg = ``;\r\n","class GoogleAnalyticsEvent {\r\n constructor(category, action, label, customDimensions = {}) {\r\n this.eventCategory = category;\r\n this.eventAction = action;\r\n this.eventLabel = label;\r\n this.event = 'GAEvent';\r\n\r\n // Use this property to add custom dimensions that are part of the\r\n // event you are tracking. These properties will be pushed to the data layer.\r\n Object.assign(this, customDimensions);\r\n }\r\n}\r\n\r\nexport default GoogleAnalyticsEvent;","export default class GoogleAnalytics4EventType {\r\n /**\r\n * This is a static method that returns an instance of the \"Event\" class.\r\n * @returns The `Event` instance is being returned. It is obtained by calling the `getInstance`\r\n * method of the current class (`this`) and passing in the string `'Event'` as an argument.\r\n */\r\n static get Event() {\r\n return this.getInstance('Event');\r\n }\r\n\r\n /**\r\n * The function returns a value from a map based on the input name.\r\n *\r\n * @param name - The name of the key in the `statusMap` object that we want to retrieve the value for.\r\n *\r\n * @returns the value of the `statusMap` object that corresponds to the `name` parameter passed to the function.\r\n * If `name` matches one of the keys in `statusMap`, the corresponding value is returned.\r\n */\r\n static fromKey(key) {\r\n const statusMap = {\r\n Event: GoogleAnalytics4EventType.Event,\r\n };\r\n return statusMap[key];\r\n }\r\n\r\n /**\r\n * Gets an instance of a GoogleAnalytics4EventType object based on a given name.\r\n * If the instance does not already exist, it creates a new instance using the configuration provided.\r\n *\r\n * @param name a unique identifier used to retrieve or create an instance of the GoogleAnalytics4EventType class.\r\n * @param configuration an object that contains various properties and values that are used to configure\r\n * the instance of the GoogleAnalytics4EventType class that is being created.\r\n *\r\n * @returns an instance of `GoogleAnalytics4EventType` that corresponds to the given `name`.\r\n */\r\n static getInstance(key) {\r\n if (!this.instances[key]) {\r\n this.instances[key] = new GoogleAnalytics4EventType(key);\r\n }\r\n return this.instances[key];\r\n }\r\n\r\n /**\r\n * This is a constructor function that takes a name as a parameter and sets the name\r\n * @param name -The `name` property is a string that represents the name of the\r\n * configuration\r\n */\r\n constructor(name) {\r\n this.name = name;\r\n }\r\n\r\n /**\r\n * Method that returns the name property of an object as a string.\r\n * @returns returns the `name` property of that object as a string.\r\n */\r\n toString() {\r\n return `${this.name}`;\r\n }\r\n}\r\n\r\nObject.defineProperty(GoogleAnalytics4EventType, 'instances', { value: {} });\r\n","/* \r\n Defines a LoadingStatus object with four static properties: failed, idle, loading, and succeeded.\r\n The statuses indicates the state of an asynchronous operation.\r\n\r\n It provides the methods for creating and retrieving instances of the object.\r\n*/\r\nexport default class LoadingStatus {\r\n /**\r\n * This is a static getter function that returns an instance of the \"Failed\" loading status.\r\n * This status indicates the asynchronous operation has finished but returned an error.\r\n *\r\n * @returns it returns the instance of the class with the name `'failed'`.\r\n */\r\n static get Failed() {\r\n return this.getInstance('failed');\r\n }\r\n\r\n /**\r\n * This is a static getter function that returns an instance of the \"Idle\" loading status.\r\n * This status indicates the asynchronous operation is not started.\r\n *\r\n * @returns it returns the instance of the class with the name `'idle'`.\r\n */\r\n static get Idle() {\r\n return this.getInstance('idle');\r\n }\r\n\r\n /**\r\n * This is a static getter function that returns an instance of the \"Loading\" loading status.\r\n * This status indicates the asynchronous operation has started but it hasn't finished.\r\n *\r\n * @returns it returns the instance of the class with the name `'loading'`.\r\n */\r\n static get Loading() {\r\n return this.getInstance('loading');\r\n }\r\n\r\n /**\r\n * This is a static getter function that returns an instance of the \"Succeeded\" loading status.\r\n * This status indicates the asynchronous operation has finished without errors.\r\n *\r\n * @returns it returns the instance of the class with the name `'succeeded'`.\r\n */\r\n static get Succeeded() {\r\n return this.getInstance('succeeded');\r\n }\r\n\r\n static fromKey(key) {\r\n const statusMap = {\r\n failed: LoadingStatus.Failed,\r\n idle: LoadingStatus.Idle,\r\n loading: LoadingStatus.Loading,\r\n succeeded: LoadingStatus.Succeeded,\r\n };\r\n return statusMap[key];\r\n }\r\n\r\n /**\r\n * This function returns an instance of the LoadingStatus class based on a given key, creating a new\r\n * instance if one does not already exist.\r\n *\r\n * @param key - a unique identifier used to create and retrieve instances of the LoadingStatus class.\r\n * It is used to ensure that only one instance of the LoadingStatus class is created for each unique key value.\r\n *\r\n * @returns returns an instance of the `LoadingStatus` class with the specified `key`.\r\n * If an instance with the specified `key` already exists, it returns that instance instead of creating a new one.\r\n */\r\n static getInstance(key) {\r\n if (!this.instances[key]) {\r\n this.instances[key] = new LoadingStatus(key);\r\n }\r\n return this.instances[key];\r\n }\r\n\r\n constructor(name) {\r\n this.name = name;\r\n }\r\n\r\n toString() {\r\n return `${this.name}`;\r\n }\r\n}\r\n\r\nObject.defineProperty(LoadingStatus, 'instances', { value: {} });\r\n","/**\r\n * @classdesc The `MarketingStatus` class serves as the source of truth for current marketing statuses and their codes.\r\n */\r\nexport default class MarketingStatus {\r\n /**\r\n * Gets the instance for the ComingSoon marketing status.\r\n * @returns {MarketingStatus} The instance for the ComingSoon status.\r\n */\r\n static get ComingSoon() {\r\n return this.getInstance('C');\r\n }\r\n\r\n /**\r\n * Gets the instance for the Active marketing status.\r\n * @returns {MarketingStatus} The instance for the Active status.\r\n */\r\n static get Active() {\r\n return this.getInstance('N');\r\n }\r\n\r\n /**\r\n * Gets the instance for the GrandOpening marketing status.\r\n * @returns {MarketingStatus} The instance for the GrandOpening status.\r\n */\r\n static get GrandOpening() {\r\n return this.getInstance('G');\r\n }\r\n\r\n /**\r\n * Gets the instance for the CloseOut marketing status.\r\n * @returns {MarketingStatus} The instance for the CloseOut status.\r\n */\r\n static get CloseOut() {\r\n return this.getInstance('X');\r\n }\r\n\r\n /**\r\n * Gets the instance for the ComingSoonGrandOpening marketing status.\r\n * @returns {MarketingStatus} The instance for the ComingSoonGrandOpening status.\r\n */\r\n static get ComingSoonGrandOpening() {\r\n return this.getInstance('CG');\r\n }\r\n\r\n /**\r\n * Converts a key to the corresponding marketing status instance.\r\n * @param {string} key The key representing a marketing status.\r\n * @returns {MarketingStatus|null} The marketing status instance or null if not found.\r\n */\r\n static fromKey(key) {\r\n const statusMap = {\r\n C: MarketingStatus.ComingSoon,\r\n N: MarketingStatus.Active,\r\n G: MarketingStatus.GrandOpening,\r\n X: MarketingStatus.CloseOut,\r\n CG: MarketingStatus.ComingSoonGrandOpening,\r\n };\r\n return statusMap[key] || null;\r\n }\r\n\r\n /**\r\n * Gets or creates an instance of the `MarketingStatus` class based on the provided key.\r\n * @param {string} key The key representing a marketing status.\r\n * @returns {MarketingStatus} The marketing status instance.\r\n */\r\n static getInstance(key) {\r\n if (!this.instances[key]) {\r\n this.instances[key] = new MarketingStatus(key);\r\n }\r\n return this.instances[key];\r\n }\r\n\r\n /**\r\n * Creates a new instance of the `MarketingStatus` class.\r\n * @param {string} name The name of the marketing status.\r\n */\r\n constructor(name) {\r\n this.name = name;\r\n }\r\n\r\n /**\r\n * Returns the name of the marketing status as a string.\r\n * @returns {string} The name of the marketing status.\r\n */\r\n toString() {\r\n return `${this.name}`;\r\n }\r\n}\r\n\r\nObject.defineProperty(MarketingStatus, 'instances', { value: {} });\r\n","import { UrlSubdirectoryTypes } from \"features/searchResultsFacets\";\r\n\r\nexport default class PageType {\r\n /**\r\n * The static get Homes function returns an instance of the 'Home_Results' class.\r\n * @returns The method is returning an instance of the 'Home_Results' class.\r\n */\r\n static get Homes() {\r\n return this.getInstance('Home_Results');\r\n }\r\n\r\n /**\r\n * The function returns an instance of the 'Community_Results' class.\r\n * @returns The method `get Communities()` is returning the result of calling the `getInstance`\r\n * method with the argument `'Community_Results'`.\r\n */\r\n static get Communities() {\r\n return this.getInstance('Community_Results');\r\n }\r\n\r\n /**\r\n * The function returns an instance of the 'Builder_Results' class.\r\n * @returns The method `get Builders()` is returning the result of calling the `getInstance`\r\n * method with the argument `'Builder_Results'`.\r\n */\r\n static get Builders() {\r\n return this.getInstance('Builder_Results');\r\n }\r\n\r\n /**\r\n * The function returns an instance of the 'boylresults' class.\r\n * @returns The method `get BuildOnYorLotLocations()` is returning the result of calling the `getInstance`\r\n * method with the argument `'boylresults'`.\r\n */\r\n static get BuildOnYorLotLocations() {\r\n return this.getInstance('boylresults');\r\n }\r\n \r\n /**\r\n * The function returns an instance of the 'Custom_Homes' class.\r\n * @returns The method `get CustomHomes()` is returning the result of calling the `getInstance`\r\n * method with the argument `'Custom_Homes'`.\r\n */\r\n static get CustomHomes() {\r\n return this.getInstance('Custom_Homes');\r\n }\r\n \r\n /**\r\n * The function returns an instance of the 'Manufactured_Homes' class.\r\n * @returns The method `get ManufacturedHomes()` is returning the result of calling the `getInstance`\r\n * method with the argument `'Manufactured_Homes'`.\r\n */\r\n static get ManufacturedHomes() {\r\n return this.getInstance('Manufactured_Homes');\r\n }\r\n \r\n /**\r\n * The function returns an instance of the 'Manufactured_Results' class.\r\n * @returns The method `get Manufactured()` is returning the result of calling the `getInstance`\r\n * method with the argument `'Manufactured_Results'`.\r\n */\r\n static get Manufactured() {\r\n return this.getInstance('Manufactured_Results');\r\n }\r\n\r\n static get LearningCenter() {\r\n return this.getInstance('Learning Center');\r\n }\r\n \r\n /**\r\n * The function \"fromKey\" takes a key as input and returns the corresponding value from a\r\n * predefined map.\r\n * @param key - The `key` parameter is a string that represents a key in the `statusMap` object.\r\n * It should be formatted like {product type}-{result type}.\r\n * @returns The value associated with the given key in the statusMap object is being returned.\r\n */\r\n static fromKey(key) {\r\n const statusMap = {\r\n [UrlSubdirectoryTypes.Communities.toString()]: PageType.Communities,\r\n [UrlSubdirectoryTypes.Homes.toString()]: PageType.Homes,\r\n [UrlSubdirectoryTypes.Builders.toString()]: PageType.Builders,\r\n [UrlSubdirectoryTypes.CondoDevelopment.toString()]: PageType.Communities,\r\n [UrlSubdirectoryTypes.CondosAndTownHomes.toString()]: PageType.Homes,\r\n [UrlSubdirectoryTypes.SingleFamilyHomes.toString()]: PageType.Homes,\r\n [UrlSubdirectoryTypes.SingleFamilyCommunities.toString()]: PageType.Communities,\r\n [UrlSubdirectoryTypes.CustomHomes.toString()]: PageType.CustomHomes,\r\n [UrlSubdirectoryTypes.OnYourLot.toString()]: PageType.BuildOnYorLotLocations,\r\n [UrlSubdirectoryTypes.ManufacturedHomes.toString()]: PageType.ManufacturedHomes,\r\n [UrlSubdirectoryTypes.ManufacturedLocations.toString()]: PageType.Manufactured,\r\n [UrlSubdirectoryTypes.FloorPlans.toString()]: PageType.Homes,\r\n [UrlSubdirectoryTypes.ModelHomes.toString()]: PageType.Homes,\r\n [UrlSubdirectoryTypes.LearningCenter.toString()]: PageType.LearningCenter,\r\n };\r\n return statusMap[key];\r\n }\r\n\r\n /**\r\n * Gets an instance of a PageType object based on a given name.\r\n * If the instance does not already exist, it creates a new instance using the configuration provided.\r\n *\r\n * @param name a unique identifier used to retrieve or create an instance of the PageType class.\r\n * @param configuration an object that contains various properties and values that are used to configure\r\n * the instance of the PageType class that is being created.\r\n *\r\n * @returns an instance of `PageType` that corresponds to the given `name`.\r\n */\r\n static getInstance(key) {\r\n if (!this.instances[key]) {\r\n this.instances[key] = new PageType(key);\r\n }\r\n return this.instances[key];\r\n }\r\n\r\n /**\r\n * This is a constructor function that takes a name as a parameter and sets the name\r\n * @param name -The `name` property is a string that represents the name of the\r\n * configuration\r\n */\r\n constructor(name) {\r\n this.name = name;\r\n }\r\n\r\n /**\r\n * Method that returns the name property of an object as a string.\r\n * @returns returns the `name` property of that object as a string.\r\n */\r\n toString() {\r\n return `${this.name}`;\r\n }\r\n}\r\n\r\nObject.defineProperty(PageType, 'instances', { value: {} });\r\n","export default class TypeaheadLocationType {\r\n\r\n // TODO: review the rest of the search types in the typehead.\r\n /**\r\n * This is a static method that returns a new instance of the LocationType class with the type\r\n * 'city'.\r\n * @returns A new instance of the `LocationType` class with the value of `'city'` as its parameter.\r\n */\r\n static get City() {\r\n return new TypeaheadLocationType('city');\r\n }\r\n\r\n /**\r\n * The above code defines a static getter function that returns a new instance of a LocationType object\r\n * with the type 'market'.\r\n * @returns A new instance of the `LocationType` class with the type `market` is being returned.\r\n */\r\n static get Market() {\r\n return new TypeaheadLocationType('market');\r\n }\r\n\r\n /**\r\n * This is a static method that returns a new instance of the LocationType class with the type\r\n * 'community'.\r\n * @returns A new instance of the `LocationType` class with the value of `'community'` as its parameter.\r\n */\r\n static get Community() {\r\n return new TypeaheadLocationType('community');\r\n }\r\n\r\n /**\r\n * This is a static method that returns a new instance of the LocationType class with the type\r\n * 'masterPlannedCommunity'.\r\n * @returns A new instance of the `LocationType` class with the value of `'masterPlannedCommunity'` as its parameter.\r\n */\r\n static get MasterPlannedCommunity() {\r\n return new TypeaheadLocationType('masterPlannedCommunity');\r\n }\r\n\r\n /**\r\n * The function returns a new LocationType object with the type 'zip'.\r\n * @returns A new instance of the `LocationType` class with the argument `'zip'`.\r\n */\r\n static get Zip() {\r\n return new TypeaheadLocationType('zip');\r\n }\r\n\r\n /**\r\n * The function returns a new instance of a LocationType object with the type 'synthetic'.\r\n * @returns A new instance of the LocationType class with the type 'synthetic'.\r\n */\r\n static get Synthetic() {\r\n return new TypeaheadLocationType('syntheticGeo');\r\n }\r\n\r\n /**\r\n * The function returns a new instance of a LocationType object with the type 'county'.\r\n * @returns A new instance of the LocationType class with the type 'county'.\r\n */\r\n static get County() {\r\n return new TypeaheadLocationType('county');\r\n }\r\n\r\n constructor(name) {\r\n this.name = name;\r\n }\r\n\r\n /**\r\n * This is a toString() method in JavaScript that returns the name property of an object as a string.\r\n * @returns The `toString()` method is returning the value of the `name` property of the object.\r\n */\r\n toString() {\r\n return `${this.name}`;\r\n }\r\n}","import googleAnalytics4Event from './redux/actions';\r\n\r\nrequire('./redux/beaconMiddleware');\r\n\r\nexport default googleAnalytics4Event;\r\n","import { createAction } from '@reduxjs/toolkit';\r\n\r\n// Event Action of type Track\r\n/* `const googleAnalytics4Event = createAction('googleAnalytics4/event');` is creating an action creator function using\r\nthe `createAction` function from the `@reduxjs/toolkit` library. This action creator function will\r\nreturn an action object with a `type` property set to `'googleAnalytics4/event'` when it is called. This\r\naction can then be dispatched to the Redux store to trigger a state update or other side effects. */\r\nconst googleAnalytics4Event = createAction('googleAnalytics4/event');\r\n\r\nexport default googleAnalytics4Event;\r\n","import { createMiddleware } from 'redux-beacon';\r\nimport debounceEvent from '@redux-beacon/debounce-event';\r\nimport { addMiddleware } from 'redux-dynamic-middlewares';\r\nimport GoogleTagManager from 'middlewares/googleTagManager';\r\nimport GoogleAnalytics4EventType from 'enums/googleAnalytics4EventType';\r\nimport { getGoogleAnalytics4Event } from 'services/googleAnalytics4EventBuilder';\r\nimport googleAnalytics4Event from './actions';\r\n\r\n/**\r\n * The eventsMap function is a mapping of Redux actions to GoogleAnalytics4 events.\r\n * It returns an array of GoogleAnalytics4 events, which are objects with the following shape:\r\n * {\r\n * eventType: string, // The name of the event (e.g., 'track')\r\n * fieldsObj: object, // An object containing all properties for this event type (e.g., {eventName})\r\n * }\r\n *\r\n * @param action Determine which event to return\r\n *\r\n * @return An array of events\r\n */\r\nconst eventsMap = (action) => {\r\n if (action.type === googleAnalytics4Event.type) {\r\n const payload = action.payload;\r\n const event = debounceEvent(\r\n 100,\r\n getGoogleAnalytics4Event(GoogleAnalytics4EventType.Event, payload.eventName, payload.customProperties)\r\n );\r\n return event;\r\n }\r\n\r\n return [];\r\n};\r\n\r\nconst googleTagManager = new GoogleTagManager();\r\nconst searchResultsGoogleTagManagerMiddleware = createMiddleware(eventsMap, googleTagManager.getTarget());\r\naddMiddleware(searchResultsGoogleTagManagerMiddleware);\r\n","export default class ThankScreenVariation {\r\n static get ComingSoon() {\r\n return this.getInstance('comingSoon');\r\n }\r\n\r\n static get AskQuestion() {\r\n return this.getInstance('askQuestion');\r\n }\r\n\r\n static get Brochure() {\r\n return this.getInstance('brochure');\r\n }\r\n\r\n static get Tour() {\r\n return this.getInstance('tour');\r\n }\r\n\r\n static get LimitedAvailability() {\r\n return this.getInstance('limitedAvailability');\r\n }\r\n\r\n static get Basic() {\r\n return this.getInstance('basic');\r\n }\r\n\r\n\r\n static fromKey(key) {\r\n const statusMap = {\r\n comingSoon: ThankScreenVariation.ComingSoon,\r\n askQuestion: ThankScreenVariation.AskQuestion,\r\n brochure: ThankScreenVariation.Brochure,\r\n tour: ThankScreenVariation.Tour,\r\n limitedAvailability: ThankScreenVariation.LimitedAvailability,\r\n basic: ThankScreenVariation.Basic\r\n };\r\n\r\n return statusMap[key];\r\n }\r\n\r\n static getInstance(key) {\r\n if (!this.instances[key]) {\r\n this.instances[key] = new ThankScreenVariation(key);\r\n }\r\n return this.instances[key];\r\n }\r\n\r\n constructor(name) {\r\n this.name = name;\r\n }\r\n\r\n toString() {\r\n return `${this.name}`;\r\n }\r\n}\r\n\r\nObject.defineProperty(ThankScreenVariation, 'instances', { value: {} });\r\n","/**\r\n * Represents a DetailsAnchor component that generates an HTML anchor element with a URL and an ID.\r\n * @class\r\n */\r\nexport default class DetailsAnchor {\r\n /**\r\n * Creates a new instance of DetailsAnchor.\r\n * @constructor\r\n * @param {string} url - The URL to be used in the anchor element.\r\n */\r\n constructor() {\r\n this.anchorId = 'detailPageAnchor';\r\n }\r\n\r\n /**\r\n * Sets the binding required for the anchor details.\r\n */\r\n bindEvents() {\r\n this.getAnchor().addEventListener('click', this.onClickEvent.bind(this));\r\n }\r\n\r\n /**\r\n * Dispatches a custom event named 'detailAnchorClicked' with details of the lisitng clicked\r\n */\r\n onClickEvent() {\r\n document.body.dispatchEvent(\r\n new CustomEvent('detailAnchorClicked', {\r\n detail: {\r\n listingId: this.listingId,\r\n listingType: this.listingType,\r\n },\r\n })\r\n );\r\n }\r\n\r\n /**\r\n * Sets the URL for the details anchor.\r\n * @param {string} url - The URL to set.\r\n */\r\n setUrl(url) {\r\n this.url = url;\r\n }\r\n\r\n /**\r\n * Sets the listing id for the details anchor.\r\n * @param {number} id - The id of the listing.\r\n */\r\n setListingId(id) {\r\n this.listingId = id;\r\n }\r\n\r\n /**\r\n * Sets the listing type for the details anchor.\r\n * @param {number} id - The type of the listing.\r\n */\r\n setListingType(type) {\r\n this.listingType = type;\r\n }\r\n\r\n /**\r\n * Gets the HTML anchor element with the specified ID.\r\n * @returns {HTMLElement} The HTML anchor element.\r\n */\r\n getAnchor() {\r\n return document.getElementById(this.anchorId);\r\n }\r\n\r\n /**\r\n * Gets the HTML code for the anchor element.\r\n * @returns {string} The HTML code for the anchor element.\r\n */\r\n getHtml() {\r\n return this.url\r\n ? `\r\n \r\n More Details\r\n `\r\n : ``;\r\n }\r\n}\r\n","/**\r\n * Represents a Scheduler Anchor component.\r\n * @class\r\n */\r\nexport default class SchedulerAnchor {\r\n /**\r\n * Creates a new instance of SchedulerAnchor.\r\n * @constructor\r\n * @param {string} url - The URL to schedule a tour.\r\n */\r\n constructor() {\r\n this.anchorId = 'schedulerAnchor';\r\n }\r\n\r\n /**\r\n * Sets the URL for the scheduler anchor.\r\n * @param {string} url - The URL to set.\r\n */\r\n setUrl(url) {\r\n this.url = url;\r\n }\r\n\r\n /**\r\n * Binds events to the SchedulerAnchor component.\r\n * @function bindEvents\r\n * @memberof SchedulerAnchor\r\n * @instance\r\n */\r\n bindEvents() {\r\n const anchor = this.getAnchor();\r\n anchor?.addEventListener('click', ()=> document.body.dispatchEvent(new CustomEvent('schedulerAnchorClick')));\r\n }\r\n\r\n /**\r\n * Gets the anchor element by ID.\r\n * @returns {HTMLElement} The anchor element.\r\n */\r\n getAnchor() {\r\n return document.getElementById(this.anchorId);\r\n }\r\n\r\n /**\r\n * Gets the HTML for the scheduler anchor.\r\n * @returns {string} The HTML for the scheduler anchor.\r\n */\r\n getHtml() {\r\n return this.url\r\n ? `\r\n \r\n Don’t Miss Out!
Schedule a Tour Now\r\n
`\r\n : ``;\r\n}\r\n}\r\n ","/**\r\n * Represents a phone anchor component that displays a phone number and allows the user to call it.\r\n */\r\nexport default class PhoneAnchor {\r\n /**\r\n * Creates a new instance of the PhoneAnchor class.\r\n * @param {string} phoneNumber - The phone number to display.\r\n */\r\n constructor() {\r\n this.anchorId = 'nhs_phoneAnchor';\r\n this.buttonId = 'nhs_phoneButton';\r\n }\r\n\r\n /**\r\n * Sets the phone number and removes any dashes.\r\n * @param {string} phoneNumber - The phone number to set.\r\n */\r\n setPhoneNumber(phoneNumber) {\r\n this.phoneNumber = phoneNumber?.replaceAll('-', '');\r\n this.userFriendlyPhone = phoneNumber;\r\n }\r\n\r\n /**\r\n * Reveals the phone number by hiding the button and showing the anchor.\r\n */\r\n revealPhone() {\r\n const anchor = this.getPhoneAnchor();\r\n const button = this.getPhoneButton();\r\n\r\n button.setAttribute('hidden', 'true');\r\n anchor.removeAttribute('hidden');\r\n }\r\n\r\n /**\r\n * Binds the click event to the phone button.\r\n */\r\n bindEvents() {\r\n const button = this.getPhoneButton();\r\n button?.addEventListener('click', this.revealPhone.bind(this));\r\n\r\n const anchor = this.getAnchor();\r\n anchor?.addEventListener('click', ()=> document.body.dispatchEvent(new CustomEvent('phoneAnchorClick')));\r\n }\r\n\r\n /**\r\n * Gets the phone button element.\r\n * @returns {HTMLElement} The phone button element.\r\n */\r\n getPhoneButton() {\r\n return document.getElementById(this.buttonId);\r\n }\r\n\r\n /**\r\n * Gets the phone anchor element.\r\n * @returns {HTMLElement} The phone anchor element.\r\n */\r\n getPhoneAnchor() {\r\n return document.getElementById(this.anchorId);\r\n }\r\n\r\n /**\r\n * Returns the phone anchor.\r\n * @returns {string} The phone anchor.\r\n */\r\n getAnchor() {\r\n return this.getPhoneAnchor();\r\n }\r\n\r\n /**\r\n * Gets the HTML for the phone anchor component.\r\n * @returns {string} The HTML for the phone anchor component.\r\n */\r\n getHtml() {\r\n if (!this.phoneNumber) {\r\n return '';\r\n }\r\n\r\n return `\r\n \r\n \r\n `;\r\n }\r\n}\r\n","/**\r\n * Represents a phone anchor for call tracking.\r\n */\r\nexport default class PhoneAnchorCallTracking {\r\n /**\r\n * Creates a new instance of PhoneAnchorCallTracking.\r\n */\r\n constructor() {\r\n this.anchorId = 'nhs_phoneCallTrackingAnchor';\r\n }\r\n\r\n /**\r\n * Sets the phone number for the anchor.\r\n * @param {string} phoneNumber - The phone number to set.\r\n */\r\n setPhoneNumber(phoneNumber) {\r\n this.phoneNumber = phoneNumber.replaceAll('-', '');\r\n this.userFriendlyPhone = phoneNumber;\r\n }\r\n\r\n /**\r\n * Binds events to the PhoneAnchorCallTracking component.\r\n * @function bindEvents\r\n * @memberof PhoneAnchorCallTracking\r\n * @instance\r\n */\r\n bindEvents() {\r\n const anchor = this.getAnchor();\r\n anchor?.addEventListener('click', ()=> document.body.dispatchEvent(new CustomEvent('phoneAnchorTrackingClick')));\r\n }\r\n \r\n /**\r\n * Gets the phone anchor element.\r\n * @returns {HTMLElement} - The phone anchor element.\r\n */\r\n getPhoneAnchor() {\r\n return document.getElementById(this.anchorId);\r\n }\r\n\r\n /**\r\n * Returns the phone anchor.\r\n * @returns {string} The phone anchor.\r\n */\r\n getAnchor() {\r\n return this.getPhoneAnchor();\r\n }\r\n\r\n /**\r\n * Gets the HTML for the phone anchor.\r\n * @returns {string} - The HTML for the phone anchor.\r\n */\r\n getHtml() {\r\n if (!this.phoneNumber) {\r\n return '';\r\n }\r\n\r\n return `\r\n \r\n Don’t Miss Out!
${this.userFriendlyPhone}\r\n
`;\r\n }\r\n}\r\n","/**\r\n * Represents a create account component.\r\n */\r\nexport default class CreateAccountAnchor {\r\n /**\r\n * Creates a new instance of CreateAccountAnchor.\r\n * @constructor\r\n */\r\n constructor() {\r\n this.buttonId = 'createAccountBtn';\r\n }\r\n\r\n /**\r\n * Binds events to the CreateAccountAnchor component.\r\n * @function bindEvents\r\n * @memberof CreateAccountAnchor\r\n * @instance\r\n */\r\n bindEvents() {\r\n const anchor = this.getAnchor();\r\n anchor?.addEventListener('click', ()=> document.body.dispatchEvent(new CustomEvent('createAccountAnchorClick')));\r\n }\r\n\r\n /**\r\n * Gets the anchor element by ID.\r\n * @returns {HTMLElement} The anchor element.\r\n */\r\n getAnchor() {\r\n return document.getElementById(this.buttonId);\r\n }\r\n\r\n /**\r\n * Gets the HTML for the create account anchor component.\r\n * @returns {string} The HTML for the create account anchor component.\r\n */\r\n getHtml() {\r\n return `\r\n `;\r\n }\r\n}","/**\r\n * Represents a return to search component.\r\n */\r\nexport default class ReturnToSearchAnchor {\r\n /**\r\n * Creates a new instance of ReturnToSearchAnchor.\r\n * @constructor\r\n */\r\n constructor() {\r\n this.buttonId = 'returnToSearchBtn';\r\n }\r\n\r\n /**\r\n * Gets the anchor element by ID.\r\n * @returns {HTMLElement} The anchor element.\r\n */\r\n getAnchor() {\r\n return document.getElementById(this.buttonId);\r\n }\r\n\r\n /**\r\n * Gets the HTML for the return to search anchor component.\r\n * @returns {string} The HTML for the return to search anchor component.\r\n */\r\n getHtml() {\r\n return `\r\n `;\r\n }\r\n}","import DetailsAnchor from '../components/detailsAnchor';\r\nimport SchedulerAnchor from '../components/schedulerAnchor';\r\nimport PhoneAnchor from '../components/phoneAnchor';\r\nimport PhoneAnchorCallTracking from '../components/phoneAnchorCallTracking';\r\nimport CreateAccountAnchor from '../components/createAccountAnchor';\r\nimport ReturnToSearchAnchor from '../components/returnToSearchAnchor';\r\n\r\n/**\r\n * Returns a contact builder anchor element based on the modal information and listing information provided.\r\n * @param {Object} modalInformation - The modal information object.\r\n * @param {string} modalInformation.url - The URL for the listing's detail page.\r\n * @param {Object} modalInformation.listingInformation - The listing information object.\r\n * @param {string} modalInformation.listingInformation.schedulerUrl -The scheduler URL.\r\n * @param {string} modalInformation.listingInformation.phoneNumber The phone number.\r\n * @param {boolean} modalInformation.listingInformation.hasCallTracking if the phone number has call tracking.\r\n * @returns {Object} - The anchor element.\r\n */\r\nfunction getContactBuilderAnchor(modalInformation) {\r\n const { url, listingInformation } = modalInformation;\r\n const { schedulerUrl, phoneNumber, hasCallTracking } = listingInformation;\r\n const anchors = [];\r\n\r\n // instantiate all the possible anchor elements and add them to the anchors list\r\n if (schedulerUrl) {\r\n const schedulerAnchor = new SchedulerAnchor();\r\n schedulerAnchor.setUrl(schedulerUrl);\r\n anchors.push({ anchor: schedulerAnchor, condition: true });\r\n }\r\n\r\n if (phoneNumber && hasCallTracking === 'True') {\r\n const phoneCallTrackingAnchor = new PhoneAnchorCallTracking();\r\n phoneCallTrackingAnchor.setPhoneNumber(phoneNumber);\r\n anchors.push({ anchor: phoneCallTrackingAnchor, condition: true });\r\n }\r\n\r\n if (phoneNumber) {\r\n const phoneAnchor = new PhoneAnchor();\r\n phoneAnchor.setPhoneNumber(phoneNumber);\r\n anchors.push({ anchor: phoneAnchor, condition: true });\r\n }\r\n\r\n // always instantiate the details anchor.\r\n const detailAnchor = new DetailsAnchor();\r\n detailAnchor.setUrl(url);\r\n detailAnchor.setListingId(listingInformation.id);\r\n detailAnchor.setListingType(listingInformation.type);\r\n anchors.push({ anchor: detailAnchor, condition: true });\r\n\r\n // Find the first anchor that has a true condition.\r\n return anchors.find(({ condition }) => condition)?.anchor;\r\n}\r\n\r\n/**\r\n * Returns an anchor element based on the user logged status.\r\n * @param {boolean} isLoggedIn if the user is logged in.\r\n * @returns {Object} - The anchor element.\r\n */\r\nfunction getInternalBrowsingAnchor(isLoggedIn) {\r\n if (isLoggedIn) {\r\n return new ReturnToSearchAnchor();\r\n }\r\n return new CreateAccountAnchor();\r\n}\r\n\r\nexport { getContactBuilderAnchor, getInternalBrowsingAnchor };\r\n","import { backArrowSvg, closeIconSvg } from 'constants/svg-assets.js';\r\n\r\nexport const backButton = ``;\r\n\r\nexport const privacyPolicyParagraph = `
By providing your name and contact information and clicking the {0} button, you consent and agree to receive marketing communications from NewHomeSource and {1} selected above, including emails, calls or text messages using an automatic telephone dialing system or an artificial or prerecorded voice. Your agreement is not a condition to purchasing any property, goods or services, and you may call us instead of submitting the information online. You also acknowledge and agree that you can revoke your authorization at any time. Your consent herein also applies to any future registration on national or state Do-No-Call lists. For mobile phones, standard message and data charges apply. Consult our Privacy Policy for additional information, including unsubscribe options. You also agree \r\nto our Privacy Policy, including TCPA Policy and Terms of Use.
`;\r\n\r\nexport const closeButton = ``;\r\n\r\nexport const recommendedPolicyParagraph = `
By providing your name and contact information and clicking the\r\n{0} button, you consent and agree to receive marketing communications from NewHomeSource and the builder(s) selected above,\r\nincluding emails, calls or text messages using an automatic telephone dialing system or an artificial or prerecorded voice. Your agreement is not a\r\ncondition to purchasing any property, goods or services, and you may call us instead of submitting the information online. You also acknowledge and\r\nagree that you can revoke your authorization at any time. Your consent herein also applies to any future registration on national or state Do-No-Call\r\nlists. For mobile phones, standard message and data charges apply. Consult our Privacy Policy for additional information, including unsubscribe options.\r\nYou also agree to our Privacy Policy, including TCPA Policy and Terms of Use.
`;","/* This class represents a lead of type More Information for a community. */\r\nexport default class CommunityInformationLead {\r\n constructor(formData) {\r\n this.communityId = formData.id;\r\n this.comments = formData.comments;\r\n this.includeRecommendations = formData.includeRecommended;\r\n this.mailAddress = formData.email;\r\n this.name = formData.name;\r\n this.type = 'postCommunityBrochure';\r\n this.userPhoneNumber = formData.phone;\r\n this.leadAction = formData.leadAction;\r\n this.fromPage = formData.fromPage;\r\n this.excludeRecommendations = formData.excludeRecommendations;\r\n this.realtorQuestionAnswerId = formData.realtorQuestion;\r\n \r\n if (formData.postalCode) {\r\n this.userPostalCode = formData.postalCode;\r\n } else {\r\n this.livesOutside = true;\r\n }\r\n }\r\n\r\n setHousingInformation(properties) {\r\n this.marketId = properties.marketId;\r\n this.marketName = properties.marketName;\r\n this.builderName = properties.brandName;\r\n this.communityName = properties.communityName;\r\n }\r\n }\r\n ","/* This class represents a lead of type Information for a plan. */\r\nexport default class PlanInformationLead {\r\n constructor(formData) {\r\n this.planId = formData.id;\r\n this.comments = formData.comments;\r\n this.includeRecommendations = formData.includeRecommended;\r\n this.mailAddress = formData.email;\r\n this.name = formData.name;\r\n this.type = 'postPlanBrochure';\r\n this.userPhoneNumber = formData.phone;\r\n this.leadAction = formData.leadAction;\r\n this.fromPage = formData.fromPage;\r\n this.excludeRecommendations = formData.excludeRecommendations;\r\n this.realtorQuestionAnswerId = formData.realtorQuestion;\r\n \r\n if (formData.postalCode) {\r\n this.userPostalCode = formData.postalCode;\r\n } else {\r\n this.livesOutside = true;\r\n }\r\n }\r\n\r\n setHousingInformation(properties) {\r\n this.marketId = properties.marketId;\r\n this.marketName = properties.marketName;\r\n this.builderName = properties.brandName;\r\n this.communityName = properties.communityName;\r\n this.communityId = properties.communityId;\r\n }\r\n }\r\n ","/* This class represents a lead of type Free Brochure for recommended communities. */\r\n\r\nexport default class RecommendedBrochureLead {\r\n constructor(formData) {\r\n this.communityId = formData.id;\r\n this.type = 'postRecommendedBrochure';\r\n this.recoComms = RecommendedBrochureLead.getRecommendedCommunities(formData);\r\n this.email = formData.email;\r\n this.zip = formData.postalCode;\r\n this.international = formData.livesOutside;\r\n this.phone = formData.phone;\r\n this.firstName = formData.firstName;\r\n this.lastName = formData.lastName;\r\n this.marketId = formData.marketId;\r\n this.builderId = formData.builderId;\r\n this.fromPage = formData.fromPage;\r\n }\r\n\r\n /**\r\n * Gets an array with the recommended communities information selected by the user.\r\n * @param {Object} formData with the form inputs to be submited. \r\n */\r\n static getRecommendedCommunities(formData) {\r\n const recommendations = [];\r\n const recommendationsKeys = Object.keys(formData).filter((key) => key.includes('RecoComms'));\r\n recommendationsKeys.forEach((key) => recommendations.push(JSON.parse(formData[key])));\r\n\r\n return recommendations;\r\n };\r\n}\r\n","/* This class represents a lead of type More Information for a spec. */\r\nexport default class SpecInformationLead {\r\n constructor(formData) {\r\n this.specId = formData.id;\r\n this.comments = formData.comments;\r\n this.includeRecommendations = formData.includeRecommended;\r\n this.mailAddress = formData.email;\r\n this.name = formData.name;\r\n this.type = 'postSpecBrochure';\r\n this.userPhoneNumber = formData.phone;\r\n this.leadAction = formData.leadAction;\r\n this.fromPage = formData.fromPage;\r\n this.excludeRecommendations = formData.excludeRecommendations;\r\n this.realtorQuestionAnswerId = formData.realtorQuestion;\r\n \r\n if (formData.postalCode) {\r\n this.userPostalCode = formData.postalCode;\r\n } else {\r\n this.livesOutside = true;\r\n }\r\n }\r\n\r\n setHousingInformation(properties) {\r\n this.marketId = properties.marketId;\r\n this.marketName = properties.marketName;\r\n this.builderName = properties.brandName;\r\n this.communityName = properties.communityName;\r\n this.communityId = properties.communityId;\r\n }\r\n }\r\n ","import BuildablePlanBrochureLead from '../models/buildablePlanBrochureLead';\r\nimport BuildablePlanInformationLead from '../models/buildablePlanInformationLead';\r\nimport CommunityInformationLeadBasic from '../models/communityInformationLeadBasic';\r\nimport CommunityBrochureLead from '../models/communityBrochureLead';\r\nimport CommunityInformationLead from '../models/communityInformationLead';\r\nimport CommunityTourLead from '../models/communityTourLead';\r\nimport PlanBrochureLead from '../models/planBrochureLead';\r\nimport PlanInformationLead from '../models/planInformationLead';\r\nimport PlanInformationLeadBasic from '../models/planInformationLeadBasic';\r\nimport PlanTourLead from '../models/planTourLead';\r\nimport RecommendedBrochureLead from '../models/recommendedBrochureLead';\r\nimport SpecBrochureLead from '../models/specBrochureLead';\r\nimport SpecInformationLead from '../models/specInformationLead';\r\nimport SpecInformationLeadBasic from '../models/specInformationLeadBasic';\r\nimport SpecTourLead from '../models/specTourLead';\r\nimport BasicListingInformationLeadBasic from '../models/basicListingInformationLeadBasic';\r\n\r\nconst leadConstructor = new Map();\r\n\r\nleadConstructor.set('buildeablePlan-brochure', BuildablePlanBrochureLead);\r\nleadConstructor.set('community-brochure', CommunityBrochureLead);\r\nleadConstructor.set('plan-brochure', PlanBrochureLead);\r\nleadConstructor.set('spec-brochure', SpecBrochureLead);\r\nleadConstructor.set('recommended', RecommendedBrochureLead);\r\nleadConstructor.set('buildeablePlan-information', BuildablePlanInformationLead);\r\nleadConstructor.set('community-information', CommunityInformationLead);\r\nleadConstructor.set('plan-information', PlanInformationLead);\r\nleadConstructor.set('spec-information', SpecInformationLead);\r\nleadConstructor.set('community-tour', CommunityTourLead);\r\nleadConstructor.set('plan-tour', PlanTourLead);\r\nleadConstructor.set('spec-tour', SpecTourLead);\r\nleadConstructor.set('plan-information-basic', PlanInformationLeadBasic);\r\nleadConstructor.set('spec-information-basic', SpecInformationLeadBasic);\r\nleadConstructor.set('community-information-basic', CommunityInformationLeadBasic);\r\nleadConstructor.set('basicListing-information-basic', BasicListingInformationLeadBasic);\r\n\r\n\r\n/**\r\n * Returns the class constructor to create a lead generator.\r\n *\r\n * @param data - The information to build the lead for the housing product or service.\r\n */\r\nexport default (data) => {\r\n const generator = leadConstructor.get(data.type);\r\n\r\n if (!generator) {\r\n return null;\r\n }\r\n\r\n return new generator.prototype.constructor(data);\r\n};\r\n","/* This class represents a lead of type Free Brochure for a Buildable Plan. */\r\nexport default class BuildablePlanBrochureLead {\r\n constructor(formData) {\r\n this.communityId = formData.id;\r\n this.comments = formData.comments;\r\n this.includeRecommendations = formData.includeRecommended;\r\n this.mailAddress = formData.email;\r\n this.name = formData.name;\r\n this.type = 'postBuildeablePlanBrochure';\r\n this.userPhoneNumber = formData.phone;\r\n\r\n // Represents Free Brochure.\r\n this.leadAction = 'fb';\r\n this.excludeRecommendations = formData.excludeRecommendations;\r\n\r\n if (formData.postalCode) {\r\n this.userPostalCode = formData.postalCode;\r\n } else {\r\n this.livesOutside = true;\r\n }\r\n }\r\n \r\n setHousingInformation(properties) {\r\n this.marketId = properties.marketId;\r\n this.marketName = properties.marketName;\r\n this.builderName = properties.brandName;\r\n this.communityName = properties.communityName;\r\n }\r\n}\r\n","/* This class represents a lead of type Free Brochure for a community. */\r\nexport default class CommunityBrochureLead {\r\n constructor(formData) {\r\n this.communityId = formData.id;\r\n this.comments = formData.comments;\r\n this.includeRecommendations = formData.includeRecommended;\r\n this.mailAddress = formData.email;\r\n this.name = formData.name;\r\n this.type = 'postCommunityBrochure';\r\n this.userPhoneNumber = formData.phone;\r\n this.leadAction = formData.leadAction;\r\n this.fromPage = formData.fromPage;\r\n this.excludeRecommendations = formData.excludeRecommendations;\r\n this.preferredContactMethod = formData.preferredContactMethod;\r\n this.realtorQuestionAnswerId = formData.realtorQuestion;\r\n\r\n if (formData.postalCode) {\r\n this.userPostalCode = formData.postalCode;\r\n } else {\r\n this.livesOutside = true;\r\n }\r\n }\r\n\r\n setHousingInformation(properties) {\r\n this.marketId = properties.marketId;\r\n this.marketName = properties.marketName;\r\n this.builderName = properties.brandName;\r\n this.communityName = properties.communityName;\r\n }\r\n}\r\n","/* This class represents a lead of type Free Brochure for a plan. */\r\nexport default class PlanBrochureLead {\r\n constructor(formData) {\r\n this.planId = formData.id;\r\n this.comments = formData.comments;\r\n this.includeRecommendations = formData.includeRecommended;\r\n this.mailAddress = formData.email;\r\n this.name = formData.name;\r\n this.type = 'postPlanBrochure';\r\n this.userPhoneNumber = formData.phone;\r\n this.realtorQuestionAnswerId = formData.realtorQuestion;\r\n\r\n // Represents Free Brochure.\r\n this.leadAction = formData.leadAction;\r\n this.fromPage = formData.fromPage;\r\n this.excludeRecommendations = formData.excludeRecommendations;\r\n this.preferredContactMethod = formData.preferredContactMethod;\r\n\r\n if (formData.postalCode) {\r\n this.userPostalCode = formData.postalCode;\r\n } else {\r\n this.livesOutside = true;\r\n }\r\n }\r\n\r\n setHousingInformation(properties) {\r\n this.marketId = properties.marketId;\r\n this.marketName = properties.marketName;\r\n this.builderName = properties.brandName;\r\n this.communityName = properties.communityName;\r\n this.communityId = properties.communityId;\r\n }\r\n}\r\n","/* This class represents a lead of type Free Brochure for a spec. */\r\nexport default class SpecBrochureLead {\r\n constructor(formData) {\r\n this.specId = formData.id;\r\n this.comments = formData.comments;\r\n this.includeRecommendations = formData.includeRecommended;\r\n this.mailAddress = formData.email;\r\n this.name = formData.name;\r\n this.type = 'postSpecBrochure';\r\n this.userPhoneNumber = formData.phone;\r\n this.realtorQuestionAnswerId = formData.realtorQuestion;\r\n\r\n // Represents Free Brochure.\r\n this.leadAction = formData.leadAction;\r\n this.fromPage = formData.fromPage;\r\n this.excludeRecommendations = formData.excludeRecommendations;\r\n this.preferredContactMethod = formData.preferredContactMethod;\r\n\r\n if (formData.postalCode) {\r\n this.userPostalCode = formData.postalCode;\r\n } else {\r\n this.livesOutside = true;\r\n }\r\n }\r\n\r\n setHousingInformation(properties) {\r\n this.marketId = properties.marketId;\r\n this.marketName = properties.marketName;\r\n this.builderName = properties.brandName;\r\n this.communityName = properties.communityName;\r\n this.communityId = properties.communityId;\r\n }\r\n}\r\n","/* This class represents a lead of type More Information for a Buildable Plan. */\r\nexport default class BuildablePlanInformationLead {\r\n constructor(formData) {\r\n this.communityId = formData.id;\r\n this.comments = formData.comments;\r\n this.includeRecommendations = formData.includeRecommended;\r\n this.mailAddress = formData.email;\r\n this.name = formData.name;\r\n this.type = 'postBuildeablePlanBrochure';\r\n this.userPhoneNumber = formData.phone;\r\n this.leadAction = 'ri';\r\n this.excludeRecommendations = formData.excludeRecommendations;\r\n \r\n if (formData.postalCode) {\r\n this.userPostalCode = formData.postalCode;\r\n } else {\r\n this.livesOutside = true;\r\n }\r\n }\r\n\r\n setHousingInformation(properties) {\r\n this.marketId = properties.marketId;\r\n this.marketName = properties.marketName;\r\n this.builderName = properties.brandName;\r\n this.communityName = properties.communityName;\r\n }\r\n }\r\n ","/* This class represents a lead of type Tour Lead for a community. */\r\nexport default class CommunityTourLead {\r\n constructor(formData) {\r\n this.communityId = formData.id;\r\n this.mailAddress = formData.email;\r\n this.name = formData.name;\r\n this.type = 'postCommunityBrochure';\r\n this.userPhoneNumber = formData.phone;\r\n this.leadAction = formData.leadAction;\r\n this.preferredContactMethod = formData.preferredContactMethod;\r\n this.date = formData.date;\r\n this.excludeRecommendations = formData.excludeRecommendations;\r\n \r\n if (formData.postalCode) {\r\n this.userPostalCode = formData.postalCode;\r\n } else {\r\n this.livesOutside = true;\r\n }\r\n }\r\n \r\n setHousingInformation(properties) {\r\n this.marketId = properties.marketId;\r\n this.marketName = properties.marketName;\r\n this.builderName = properties.brandName;\r\n this.communityName = properties.communityName;\r\n }\r\n }\r\n ","/* This class represents a lead of type Tour Lead for a plan. */\r\nexport default class PlanTourLead {\r\n constructor(formData) {\r\n this.planId = formData.id;\r\n this.mailAddress = formData.email;\r\n this.name = formData.name;\r\n this.type = 'postPlanBrochure';\r\n this.userPhoneNumber = formData.phone;\r\n this.leadAction = formData.leadAction;\r\n this.preferredContactMethod = formData.preferredContactMethod;\r\n this.date = formData.date;\r\n this.excludeRecommendations = formData.excludeRecommendations;\r\n \r\n if (formData.postalCode) {\r\n this.userPostalCode = formData.postalCode;\r\n } else {\r\n this.livesOutside = true;\r\n }\r\n }\r\n \r\n setHousingInformation(properties) {\r\n this.marketId = properties.marketId;\r\n this.marketName = properties.marketName;\r\n this.builderName = properties.brandName;\r\n this.communityName = properties.communityName;\r\n this.communityId = properties.communityId;\r\n }\r\n }\r\n ","/* This class represents a lead of type Tour Lead for a spec. */\r\nexport default class SpecTourLead {\r\n constructor(formData) {\r\n this.specId = formData.id;\r\n this.mailAddress = formData.email;\r\n this.name = formData.name;\r\n this.type = 'postSpecBrochure';\r\n this.userPhoneNumber = formData.phone;\r\n this.leadAction = formData.leadAction;\r\n this.preferredContactMethod = formData.preferredContactMethod;\r\n this.date = formData.date;\r\n this.excludeRecommendations = formData.excludeRecommendations;\r\n \r\n if (formData.postalCode) {\r\n this.userPostalCode = formData.postalCode;\r\n } else {\r\n this.livesOutside = true;\r\n }\r\n }\r\n\r\n setHousingInformation(properties) {\r\n this.marketId = properties.marketId;\r\n this.marketName = properties.marketName;\r\n this.builderName = properties.brandName;\r\n this.communityName = properties.communityName;\r\n this.communityId = properties.communityId;\r\n }\r\n }\r\n ","import GoogleAnalyticsEvent from \"dataTransferObjects/googleAnalyticsEvent\";\r\nimport PlanInformationLead from \"./planInformationLead\";\r\n\r\n/* This class represents a lead of type More Information for a basic plan. */\r\nexport default class PlanInformationLeadBasic extends PlanInformationLead {\r\n constructor(formData) {\r\n super(formData);\r\n this.type = 'postPlanBrochureBasic';\r\n this.xxTrustedFormCertUrl = formData.xxTrustedFormCertUrl;\r\n }\r\n\r\n static getLeadSubmitedAnalyticsData() {\r\n return new GoogleAnalyticsEvent(\"TDV Events\", \"Direct Leads\", \"Search-CTA-Learn-More\")\r\n }\r\n }\r\n ","import GoogleAnalyticsEvent from \"dataTransferObjects/googleAnalyticsEvent\";\r\nimport SpecInformationLead from \"./specInformationLead\";\r\n\r\n/* This class represents a lead of type More Information for a basic spec. */\r\nexport default class SpecInformationLeadBasic extends SpecInformationLead {\r\n constructor(formData) {\r\n super(formData);\r\n this.type = 'postSpecBrochureBasic';\r\n this.xxTrustedFormCertUrl = formData.xxTrustedFormCertUrl;\r\n }\r\n\r\n static getLeadSubmitedAnalyticsData() {\r\n return new GoogleAnalyticsEvent(\"TDV Events\", \"Direct Leads\", \"Search-CTA-Learn-More\")\r\n }\r\n }","import GoogleAnalyticsEvent from \"dataTransferObjects/googleAnalyticsEvent\";\r\nimport CommunityInformationLead from \"./communityInformationLead\";\r\n\r\n/* This class represents a lead of type More Information for a basic community. */\r\nexport default class CommunityInformationLeadBasic extends CommunityInformationLead {\r\n constructor(formData) {\r\n super(formData);\r\n this.type = 'postCommunityBrochureBasic';\r\n this.xxTrustedFormCertUrl = formData.xxTrustedFormCertUrl;\r\n }\r\n\r\n static getLeadSubmitedAnalyticsData() {\r\n return new GoogleAnalyticsEvent(\"TDV Events\", \"Direct Leads\", \"Search-CTA-Learn-More\")\r\n }\r\n }\r\n ","import GoogleAnalyticsEvent from \"dataTransferObjects/googleAnalyticsEvent\";\r\n\r\n/* This class represents a lead of type More Information for a basic listing. */\r\nexport default class BasicListingInformationLeadBasic {\r\n constructor(formData) {\r\n this.type = 'postBasicListingBrochureBasic';\r\n this.xxTrustedFormCertUrl = formData.xxTrustedFormCertUrl;\r\n this.listingId = formData.id;\r\n this.comments = formData.comments;\r\n this.includeRecommendations = formData.includeRecommended;\r\n this.mailAddress = formData.email;\r\n this.name = formData.name;\r\n this.userPhoneNumber = formData.phone;\r\n this.leadAction = formData.leadAction;\r\n this.fromPage = formData.fromPage;\r\n this.excludeRecommendations = formData.excludeRecommendations;\r\n \r\n if (formData.postalCode) {\r\n this.userPostalCode = formData.postalCode;\r\n } else {\r\n this.livesOutside = true;\r\n }\r\n }\r\n\r\n setHousingInformation(properties) {\r\n this.marketId = properties.marketId;\r\n this.marketName = properties.marketName;\r\n }\r\n\r\n static getLeadSubmitedAnalyticsData() {\r\n return new GoogleAnalyticsEvent(\"TDV Events\", \"Direct Leads\", \"Search-CTA-Learn-More\")\r\n }\r\n }","export default class GoogleAnalyticsEventAction {\r\n static get DirectLeads() {\r\n return this.getInstance('Direct Leads');\r\n }\r\n\r\n static get NonDirectLeads() {\r\n return this.getInstance('RCL NonDirect leads');\r\n }\r\n\r\n static get Leads() {\r\n return this.getInstance('Leads');\r\n }\r\n\r\n static fromKey(key) {\r\n const statusMap = {\r\n R: GoogleAnalyticsEventAction.DirectLeads,\r\n A: GoogleAnalyticsEventAction.Leads,\r\n 'RCL NonDirect leads': GoogleAnalyticsEventAction.NonDirectLeads,\r\n };\r\n return statusMap[key];\r\n }\r\n\r\n static getInstance(key) {\r\n if (!this.instances[key]) {\r\n this.instances[key] = new GoogleAnalyticsEventAction(key);\r\n }\r\n return this.instances[key];\r\n }\r\n\r\n constructor(name) {\r\n this.name = name;\r\n }\r\n\r\n toString() {\r\n return `${this.name}`;\r\n }\r\n}\r\n\r\nObject.defineProperty(GoogleAnalyticsEventAction, 'instances', { value: {} });\r\n","export default class GoogleAnalyticsEventCategory {\r\n static get TdvMetrics() {\r\n return this.getInstance('TDV Metrics');\r\n }\r\n\r\n static get TdvEvents() {\r\n return this.getInstance('TDV Events');\r\n }\r\n\r\n static get RealtimeEvents() {\r\n return this.getInstance('Realtime Events');\r\n }\r\n\r\n static fromKey(key) {\r\n const statusMap = {\r\n 'TDV Metrics': GoogleAnalyticsEventCategory.TdvMetrics,\r\n 'TDV Events': GoogleAnalyticsEventCategory.TdvEvents,\r\n 'Realtime Events': GoogleAnalyticsEventCategory.RealtimeEvents,\r\n };\r\n return statusMap[key];\r\n }\r\n\r\n static getInstance(key) {\r\n if (!this.instances[key]) {\r\n this.instances[key] = new GoogleAnalyticsEventCategory(key);\r\n }\r\n return this.instances[key];\r\n }\r\n\r\n constructor(name) {\r\n this.name = name;\r\n }\r\n\r\n toString() {\r\n return `${this.name}`;\r\n }\r\n}\r\n\r\nObject.defineProperty(GoogleAnalyticsEventCategory, 'instances', { value: {} });\r\n","import GoogleAnalyticsEvent from \"dataTransferObjects/googleAnalyticsEvent\";\r\nimport GoogleAnalyticsEventAction from \"enums/googleAnalyticsEventAction\";\r\nimport GoogleAnalyticsEventCategory from \"enums/googleAnalyticsEventCategory\";\r\n\r\n/* Creates a new instance of a Google Analytics Tdv Event Mixin to track users events when the user subimits a lead. */\r\nexport default class EventTrackingTdvEventsMixin {\r\n constructor(model) {\r\n Object.assign(this, model);\r\n }\r\n \r\n getGoogleAnalyticsData() {\r\n return new GoogleAnalyticsEvent(\r\n GoogleAnalyticsEventCategory.TdvEvents.toString(), \r\n GoogleAnalyticsEventAction.DirectLeads.toString(), \r\n this.eventLabel);\r\n }\r\n }","import EventTrackingTdvEventsMixin from \"./eventTrackingTdvEventsMixin\";\r\n\r\n\r\n/* Creates a new instance of a basic lead Tracking Event to track users events when the user subimits a lead.\r\n this class contains all the events that needs be to be done.\r\n*/\r\nexport default class BasicLeadTrackingEvents {\r\n constructor(model) { \r\n const data = {...model, eventLabel: 'Search-CTA-Learn-More'}\r\n this.events = {};\r\n this.events.googleAnalytics = [\r\n new EventTrackingTdvEventsMixin(data)];\r\n }\r\n }","import GoogleAnalyticsEvent from 'dataTransferObjects/googleAnalyticsEvent';\r\nimport GoogleAnalyticsEventAction from 'enums/googleAnalyticsEventAction';\r\nimport GoogleAnalyticsEventCategory from 'enums/googleAnalyticsEventCategory';\r\n\r\n/* Creates a new instance of a Google Analytics Tdv Events Mixin to track user's events when the user submits a lead. */\r\nexport default class EventTrackingNonDirectLeadsMixin {\r\n constructor(model) {\r\n Object.assign(this, model);\r\n }\r\n\r\n getGoogleAnalyticsData() {\r\n return new GoogleAnalyticsEvent(\r\n GoogleAnalyticsEventCategory.TdvEvents.toString(),\r\n GoogleAnalyticsEventAction.NonDirectLeads.toString(),\r\n this.eventLabel\r\n );\r\n }\r\n}\r\n","import GoogleAnalyticsEvent from \"dataTransferObjects/googleAnalyticsEvent\";\r\nimport GoogleAnalyticsEventAction from \"enums/googleAnalyticsEventAction\";\r\nimport GoogleAnalyticsEventCategory from \"enums/googleAnalyticsEventCategory\";\r\n\r\n/* Creates a new instance of a Google Analytics Tdv metric Mixin to track users events when the user subimits a lead. */\r\nexport default class EventTrackingRealTimeEventsMixin {\r\n constructor(model) {\r\n Object.assign(this, model);\r\n }\r\n \r\n getGoogleAnalyticsData() {\r\n return new GoogleAnalyticsEvent(\r\n GoogleAnalyticsEventCategory.RealtimeEvents.toString(),\r\n GoogleAnalyticsEventAction.DirectLeads.toString(),\r\n this.marketId);\r\n }\r\n }","import GoogleAnalyticsEvent from \"dataTransferObjects/googleAnalyticsEvent\";\r\nimport GoogleAnalyticsEventAction from \"enums/googleAnalyticsEventAction\";\r\nimport GoogleAnalyticsEventCategory from \"enums/googleAnalyticsEventCategory\";\r\n\r\n/* Creates a new instance of a Google Analytics Tdv metric Mixin to track users events when the user subimits a lead. */\r\nexport default class EventTrackingTdvMetricsMixin {\r\n constructor(model) {\r\n Object.assign(this, model);\r\n }\r\n \r\n getGoogleAnalyticsData() { \r\n const eventLabel = `MN: ${this.marketName} | BN: ${this.builderName} | CN: ${this.communityName} | CI: ${this.communityId}`;\r\n return new GoogleAnalyticsEvent(\r\n GoogleAnalyticsEventCategory.TdvMetrics.toString(),\r\n GoogleAnalyticsEventAction.Leads.toString(),\r\n eventLabel);\r\n }\r\n }","import EventTrackingNonDirectLeadsMixin from './eventTrackingNonDirectLeadsMixin';\r\nimport EventTrackingRealTimeEventsMixin from './eventTrackingRealTimeEventsMixin';\r\nimport EventTrackingTdvEventsMixin from './eventTrackingTdvEventsMixin';\r\nimport EventTrackingTdvMetricsMixin from './eventTrackingTdvMetricsMixin';\r\n\r\n/* Creates a new instance of a Brochure Tracking Event to track users events when the user submits a lead.\r\n this class contains all the events that needs be to be done.\r\n*/\r\nexport default class BrochureTrackingEvents {\r\n constructor(model) {\r\n const data = { ...model, eventLabel: 'Search-CTA-Free-Brochure' };\r\n this.events = {};\r\n this.events.googleAnalytics = [\r\n new EventTrackingTdvEventsMixin(data),\r\n new EventTrackingTdvMetricsMixin(data),\r\n new EventTrackingRealTimeEventsMixin(data),\r\n ];\r\n\r\n /* This \"condition\" is where we take control of the new Event, without it, this is always fired.\r\n So, if the \"include communities\" checkbox is checked, push the instance into the googleAnalytics \r\n array and the event is fired. Otherwise, the event is omitted */\r\n if (data.includeRecommendations === 'True') {\r\n this.events.googleAnalytics.push(\r\n new EventTrackingNonDirectLeadsMixin(data)\r\n );\r\n }\r\n }\r\n}\r\n","import EventTrackingRealTimeEventsMixin from \"./eventTrackingRealTimeEventsMixin\";\r\nimport EventTrackingTdvEventsMixin from \"./eventTrackingTdvEventsMixin\";\r\nimport EventTrackingTdvMetricsMixin from \"./eventTrackingTdvMetricsMixin\";\r\n\r\n\r\n/* Creates a new instance of a Brochure Tracking Event to track users events when the user subimits a lead.\r\n this class contains all the events that needs be to be done.\r\n*/\r\nexport default class InformationTrackingEvents {\r\n constructor(model) { \r\n const data = {...model, eventLabel: 'Search-CTA-Free-Brochure'}\r\n this.events = {};\r\n this.events.googleAnalytics = [\r\n new EventTrackingTdvEventsMixin(data),\r\n new EventTrackingTdvMetricsMixin(data),\r\n new EventTrackingRealTimeEventsMixin(data)];\r\n }\r\n }","import EventTrackingTdvEventsMixin from \"./eventTrackingTdvEventsMixin\";\r\n\r\n\r\n/* Creates a new instance of a Brochure Tracking Event to track users events when the user subimits a lead.\r\n this class contains all the events that needs be to be done.\r\n*/\r\nexport default class TourTrackingEvents {\r\n constructor(model) { \r\n const data = {...model, eventLabel: 'Search-Results-Request-Tour'}\r\n this.events = {};\r\n this.events.googleAnalytics = [\r\n new EventTrackingTdvEventsMixin(data)];\r\n }\r\n }","import EventTrackingNonDirectLeadsMixin from './eventTrackingNonDirectLeadsMixin';\r\nimport EventTrackingRealTimeEventsMixin from './eventTrackingRealTimeEventsMixin';\r\nimport EventTrackingTdvEventsMixin from './eventTrackingTdvEventsMixin';\r\nimport EventTrackingTdvMetricsMixin from './eventTrackingTdvMetricsMixin';\r\n\r\n/* Creates a new instance of a Ask Question Tracking Event to track users events when the user submits a lead.\r\n this class contains all the events that needs be to be done.\r\n*/\r\nexport default class AskQuestionTrackingEvent {\r\n constructor(model) {\r\n const data = { ...model, eventLabel: 'Search-CTA-Ask-Question' };\r\n this.events = {};\r\n this.events.googleAnalytics = [\r\n new EventTrackingTdvEventsMixin(data),\r\n new EventTrackingTdvMetricsMixin(data),\r\n new EventTrackingRealTimeEventsMixin(data),\r\n ];\r\n\r\n /* This \"condition\" is where we take control of the new Event, without it, this is always fired.\r\n So, if the \"include communities\" checkbox is checked, push the instance into the googleAnalytics \r\n array and the event is fired. Otherwise, the event is omitted */\r\n if (data.includeRecommendations === 'True') {\r\n this.events.googleAnalytics.push(new EventTrackingNonDirectLeadsMixin(data));\r\n }\r\n }\r\n}\r\n","import { store } from '@redux/store';\r\nimport uiStateSlice from 'layout/redux/uiStateSlice';\r\nimport BasicLeadTrackingEvents from '../analytics/basicLeadTrackingEvent';\r\nimport BrochureTrackingEvents from '../analytics/brochureTrackingEvent';\r\nimport InformationTrackingEvents from '../analytics/informationTracking';\r\nimport TourTrackingEvents from '../analytics/tourTrackingEvent';\r\nimport AskQuestionTrackingEvents from '../analytics/askQuestionTrackingEvent';\r\n\r\n/**\r\n * Gets the current state of the modalInformation object, and dispatch an action to update the modalInformation\r\n * object to reflect the lead generator flow.\r\n *\r\n * @returns The initial value from modalInformation object.\r\n */\r\nexport const initialState = (properties, getGoogleAnalyticsDTOCallback) => {\r\n const modalInformation = store.getState().uiState.modalInformation;\r\n const { listingInformation } = properties;\r\n const googleAnalyticsDTO = getGoogleAnalyticsDTOCallback ? getGoogleAnalyticsDTOCallback(listingInformation) : '';\r\n const newState = {\r\n id: modalInformation.id,\r\n type: modalInformation.type,\r\n name: 'leadGenerator',\r\n ...properties,\r\n googleAnalyticsDTO,\r\n };\r\n\r\n store.dispatch(uiStateSlice.actions.modalInformation(newState));\r\n\r\n return modalInformation;\r\n};\r\n\r\nexport const postRecommendedLeadForm = (leadInformation) => {\r\n store.dispatch(\r\n uiStateSlice.actions.fetchModal({\r\n isFetchingModal: true,\r\n parameters: leadInformation,\r\n })\r\n );\r\n};\r\n\r\nexport const postLeadBrochureForm = (leadInformation) => {\r\n const eventTracking = new BrochureTrackingEvents(Object.assign({}, leadInformation));\r\n const googleAnalyticsDTO = eventTracking.events.googleAnalytics.map((event) => event.getGoogleAnalyticsData());\r\n store.dispatch(\r\n uiStateSlice.actions.fetchModal({\r\n isFetchingModal: true,\r\n parameters: leadInformation,\r\n googleAnalyticsDTO,\r\n })\r\n );\r\n};\r\n\r\nexport const postLeadInformationForm = (leadInformation) => {\r\n const eventTracking = new InformationTrackingEvents(Object.assign({}, leadInformation));\r\n const googleAnalyticsDTO = eventTracking.events.googleAnalytics.map((event) => event.getGoogleAnalyticsData());\r\n store.dispatch(\r\n uiStateSlice.actions.fetchModal({\r\n isFetchingModal: true,\r\n parameters: leadInformation,\r\n googleAnalyticsDTO,\r\n })\r\n );\r\n};\r\n\r\nexport const postLeadTourForm = (leadInformation) => {\r\n const eventTracking = new TourTrackingEvents(Object.assign({}, leadInformation));\r\n const googleAnalyticsDTO = eventTracking.events.googleAnalytics.map((event) => event.getGoogleAnalyticsData());\r\n store.dispatch(\r\n uiStateSlice.actions.fetchModal({\r\n isFetchingModal: true,\r\n parameters: leadInformation,\r\n googleAnalyticsDTO,\r\n })\r\n );\r\n};\r\n\r\nexport const postLeadInformationFormBasic = (leadInformation) => {\r\n const eventTracking = new BasicLeadTrackingEvents(Object.assign({}, leadInformation));\r\n const googleAnalyticsDTO = eventTracking.events.googleAnalytics.map((event) => event.getGoogleAnalyticsData());\r\n store.dispatch(\r\n uiStateSlice.actions.fetchModal({\r\n isFetchingModal: true,\r\n parameters: leadInformation,\r\n googleAnalyticsDTO,\r\n })\r\n );\r\n};\r\n\r\n\r\nexport const postLeadAskQuestionForm = (leadInformation) => {\r\n const eventTracking = new AskQuestionTrackingEvents(Object.assign({}, leadInformation));\r\n const googleAnalyticsDTO = eventTracking.events.googleAnalytics.map((event) => event.getGoogleAnalyticsData());\r\n store.dispatch(\r\n uiStateSlice.actions.fetchModal({\r\n isFetchingModal: true,\r\n parameters: leadInformation,\r\n googleAnalyticsDTO,\r\n })\r\n );\r\n};\r\n\r\n/**\r\n * This function takes in a modalInformation object and dispatches it to the reducer.\r\n * @param modalInformation - object with the id, type, and name to identify the modal.\r\n */\r\nexport const updateModalProgress = (modalInformation) => {\r\n store.dispatch(uiStateSlice.actions.modalInformation(modalInformation));\r\n};\r\n","export default class BrochureButton {\r\n constructor() {\r\n this.id = 'getBrochureButton';\r\n }\r\n\r\n getHtml() {\r\n const styles = 'class=\"btn btn--yellow btn--width-100 btn--48-lg loading\"';\r\n return ``;\r\n }\r\n\r\n getNode() {\r\n return document.getElementById(this.id);\r\n }\r\n}\r\n","export default class CommentsTextArea {\r\n constructor() {\r\n this.input = ``;\r\n this.label = ``;\r\n }\r\n\r\n getHtml() {\r\n return `${this.label}${this.input}`;\r\n }\r\n}\r\n","import { fromEvent, map } from \"rxjs\";\r\n\r\nexport default class EmailInput {\r\n constructor() {\r\n this.valueInput = '';\r\n this.errorMessageId = 'nhs_ErrorForEmail';\r\n this.id = 'MailAddress';\r\n this.errorCssClass = 'error';\r\n this.errorMessage = ``;\r\n this.label = ``;\r\n this.matchingPattern =\r\n /^(([^<>()\\\\[\\]\\\\.,;:\\s@\"]+(\\.[^<>()\\\\[\\]\\\\.,;:\\s@\"]+)*)|(\".+\"))@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}])|(([a-zA-Z\\-0-9]+\\.)+[a-zA-Z]{2,}))$/;\r\n }\r\n\r\n set value(newValue){\r\n this.valueInput = newValue || '';\r\n }\r\n\r\n get value(){\r\n return this.valueInput;\r\n }\r\n\r\n getHtml() {\r\n return `${this.label}${this.errorMessage}`;\r\n }\r\n\r\n getNode() {\r\n return document.getElementById(this.id);\r\n }\r\n\r\n /**\r\n * getOnChangeEvent: On input change map its value to the storage property.\r\n */\r\n getOnChangeEvent() {\r\n return fromEvent(this.getNode(), 'change').pipe(\r\n map((event) => ({email: event.target.value}))\r\n );\r\n }\r\n\r\n setInvalidState(node) {\r\n const errorMessage = document.getElementById(this.errorMessageId);\r\n\r\n node.setAttribute('aria-invalid', true);\r\n node.classList.add(this.errorCssClass);\r\n errorMessage.removeAttribute('hidden');\r\n }\r\n\r\n setValidState(node) {\r\n const errorMessage = document.getElementById(this.errorMessageId);\r\n\r\n node.removeAttribute('aria-invalid');\r\n node.classList.remove(this.errorCssClass);\r\n errorMessage.setAttribute('hidden', true);\r\n }\r\n\r\n validate() {\r\n const node = this.getNode();\r\n\r\n /* NHS20-1684: we verify that the value taken from the input it's clean,\r\n in case of spaces before and after the text, also is updated in the UI. */\r\n const cleanedValue = node.value.trim().replace(/\\s+/g, ' ');\r\n node.value = cleanedValue;\r\n const isValid = this.matchingPattern.test(node.value);\r\n\r\n if (isValid) {\r\n this.setValidState(node);\r\n } else {\r\n this.setInvalidState(node);\r\n }\r\n\r\n return isValid;\r\n }\r\n}\r\n","import { fromEvent, map } from \"rxjs\";\r\n\r\nexport default class NameInput {\r\n constructor() {\r\n this.valueInput = '';\r\n this.errorMessageId = 'nhs_ErrorForName';\r\n this.id = 'Name';\r\n this.errorCssClass = 'error';\r\n this.errorMessage = ``;\r\n this.label = ``;\r\n this.pattern = `^([A-Za-zà-ü]+(-?'?[A-Za-z+'?-?à-ü]+))(\\\\s([A-Za-zà-ü]+(-?'?[A-Za-z+'?-?à-ü]+)?))+?$`;\r\n this.matchingPattern = new RegExp(this.pattern);\r\n }\r\n\r\n set value(newValue){\r\n this.valueInput = newValue || '';\r\n }\r\n\r\n get value(){\r\n return this.valueInput;\r\n }\r\n\r\n getHtml() {\r\n return `${this.label}${this.errorMessage}`;\r\n }\r\n\r\n getNode() {\r\n return document.getElementById(this.id);\r\n }\r\n\r\n /**\r\n * getOnChangeEvent: On input change map its value to the storage property.\r\n */\r\n getOnChangeEvent() {\r\n return fromEvent(this.getNode(), 'change').pipe(\r\n map((event) => ({name: event.target.value}))\r\n );\r\n }\r\n\r\n setInvalidState(node) {\r\n const errorMessage = document.getElementById(this.errorMessageId);\r\n\r\n node.setAttribute('aria-invalid', true);\r\n node.classList.add(this.errorCssClass);\r\n errorMessage.removeAttribute('hidden');\r\n }\r\n\r\n setValidState(node) {\r\n const errorMessage = document.getElementById(this.errorMessageId);\r\n\r\n node.removeAttribute('aria-invalid');\r\n node.classList.remove(this.errorCssClass);\r\n errorMessage.setAttribute('hidden', true);\r\n }\r\n\r\n focus() {\r\n const nameInput = this.getNode();\r\n nameInput.focus();\r\n }\r\n\r\n validate() {\r\n const node = this.getNode();\r\n\r\n /* NHS20-1684: we verify that the value taken from the input it's clean,\r\n in case of spaces before and after the text, also is updated in the UI. */\r\n const cleanedValue = node.value.trim().replace(/\\s+/g, ' ');\r\n node.value = cleanedValue;\r\n const isValid = this.matchingPattern.test(cleanedValue);\r\n\r\n if (isValid) {\r\n this.setValidState(node);\r\n } else {\r\n this.setInvalidState(node);\r\n }\r\n\r\n return isValid;\r\n }\r\n}\r\n","import { fromEvent, map } from 'rxjs';\r\nimport VMasker from 'vanilla-masker';\r\n\r\nexport default class PhoneInput {\r\n constructor() {\r\n this.valueInput = '';\r\n this.required = false;\r\n this.errorMessageId = 'nhs_ErrorForPhone';\r\n this.id = 'UserPhoneNumber';\r\n this.errorCssClass = 'error';\r\n this.errorMessage = ``;\r\n this.label = ``;\r\n this.pattern = '^\\\\([2-9][0-9]{2}\\\\)\\\\s[0-9]{3}-[0-9]{4}$';\r\n this.matchingPattern = new RegExp(this.pattern);\r\n this.screenReaderMessage = ``;\r\n }\r\n\r\n set value(newValue){\r\n this.valueInput = newValue || '';\r\n }\r\n\r\n get value(){\r\n return this.valueInput;\r\n }\r\n\r\n bindEvents() {\r\n const phoneInput = this.getNode();\r\n VMasker(phoneInput).maskPattern('(999) 999-9999');\r\n }\r\n\r\n getHtml() {\r\n return `${this.label}\r\n ${this.errorMessage}${this.screenReaderMessage}`;\r\n }\r\n\r\n getNode() {\r\n return document.getElementById(this.id);\r\n }\r\n\r\n /**\r\n * getOnChangeEvent: On input change map its value to the storage property.\r\n */\r\n getOnChangeEvent() {\r\n return fromEvent(this.getNode(), 'blur').pipe(\r\n map((event) => ({phone: event.target.value}))\r\n );\r\n }\r\n\r\n removeRequired() {\r\n const node = this.getNode();\r\n node.placeholder = \"Phone\";\r\n node.removeAttribute('required');\r\n }\r\n\r\n setInvalidState(node) {\r\n const errorMessage = document.getElementById(this.errorMessageId);\r\n\r\n node.setAttribute('aria-invalid', true);\r\n node.classList.add(this.errorCssClass);\r\n errorMessage.removeAttribute('hidden');\r\n }\r\n\r\n setRequired() {\r\n const node = this.getNode();\r\n node.placeholder = \"*Phone\";\r\n node.setAttribute('required', 'true');\r\n }\r\n\r\n setValidState(node) {\r\n const errorMessage = document.getElementById(this.errorMessageId);\r\n\r\n node.removeAttribute('aria-invalid');\r\n node.classList.remove(this.errorCssClass);\r\n errorMessage.setAttribute('hidden', true);\r\n }\r\n\r\n isValid() {\r\n const node = this.getNode();\r\n const isEmpy = node.value === '';\r\n const isRequired = node.required;\r\n \r\n // If it is empty and is required, the input is not valid\r\n if(isEmpy && isRequired) {\r\n return false;\r\n }\r\n\r\n // If it is empty a is not required, the input is valid\r\n if (isEmpy && !isRequired) {\r\n return true;\r\n }\r\n\r\n // Otherwise the input is not empty and need to match with the regex.\r\n return this.matchingPattern.test(node.value);\r\n }\r\n\r\n validate() {\r\n const node = this.getNode();\r\n const isValid = this.isValid()\r\n\r\n if (isValid) {\r\n this.setValidState(node);\r\n } else {\r\n this.setInvalidState(node);\r\n }\r\n\r\n return isValid;\r\n }\r\n}\r\n","import { fromEvent, map } from \"rxjs\";\r\n\r\nexport default class RecommendedCheckbox {\r\n constructor() {\r\n this.id = 'includeRecommended';\r\n this.label = ``;\r\n }\r\n\r\n set value(newValue){\r\n this.valueInput = newValue;\r\n }\r\n\r\n get value(){\r\n return this.valueInput;\r\n }\r\n\r\n getHtml() {\r\n return `${this.label}`;\r\n }\r\n \r\n getNode() {\r\n return document.getElementById(this.id);\r\n }\r\n\r\n /**\r\n * getOnChangeEvent: On input change map its value to the storage property.\r\n */\r\n getOnChangeEvent() {\r\n return fromEvent(this.getNode(), 'change').pipe(\r\n map((event) => ({hasUserOptedIntoRecommendationEmail: event.target.checked}))\r\n );\r\n }\r\n}\r\n","import { combineLatest, fromEvent, map, skip, startWith } from \"rxjs\";\r\n\r\nexport default class ZipInput {\r\n constructor() {\r\n this.valueInput = '';\r\n this.isInternationalInput = false;\r\n this.errorMessageId = 'nhs_ErrorForipCodeReg';\r\n this.idForOutside = 'livesOutside';\r\n this.idForZip = 'postalCode';\r\n this.errorCssClass = 'error';\r\n this.errorMessage = ``;\r\n this.labelForOutside = ``;\r\n this.labelForZipCode = ``;\r\n this.pattern = '^\\\\d{5}(-\\\\d{4})?$';\r\n this.matchingPattern = new RegExp(this.pattern);\r\n }\r\n\r\n set isInternational(newValue){\r\n this.isInternationalInput = !!newValue;\r\n }\r\n\r\n get isInternational(){\r\n return this.isInternationalInput;\r\n }\r\n\r\n set value(newValue){\r\n this.valueInput = newValue;\r\n }\r\n\r\n get value(){\r\n return this.valueInput;\r\n }\r\n\r\n bindEvents() {\r\n this.getOutsideUsNode().addEventListener('change', this.onOutsideUsChanged.bind(this));\r\n }\r\n\r\n getHtml() {\r\n return `
\r\n ${this.labelForZipCode}\r\n \r\n ${this.errorMessage}\r\n
\r\n
\r\n \r\n ${this.labelForOutside}\r\n
`;\r\n }\r\n\r\n getOutsideUsNode() {\r\n return document.getElementById(this.idForOutside);\r\n }\r\n\r\n getZipNode() {\r\n return document.getElementById(this.idForZip);\r\n }\r\n\r\n /**\r\n * getOnChangeEvent: On inputs change map their values to the storage properties.\r\n */\r\n getOnChangeEvent() {\r\n const outSideNode = this.getOutsideUsNode();\r\n const zipNode = this.getZipNode();\r\n const onOutSideChange$ = fromEvent(outSideNode, 'change').pipe(\r\n map((event) => event.target),\r\n startWith(outSideNode)\r\n );\r\n const onZipChange$ = fromEvent(zipNode, 'change').pipe(\r\n map((event) => event.target),\r\n startWith(zipNode)\r\n );\r\n return combineLatest([onZipChange$, onOutSideChange$]).pipe(\r\n map(([zipInput, livesOutsideInput]) => ({\r\n zip: zipInput.value,\r\n livesOutside: livesOutsideInput.checked,\r\n })),\r\n skip(1)\r\n );\r\n }\r\n\r\n isOutsideUs() {\r\n return this.getOutsideUsNode().checked;\r\n }\r\n\r\n isValidZipCode() {\r\n const node = this.getZipNode();\r\n return this.matchingPattern.test(node.value?.trim());\r\n }\r\n\r\n onOutsideUsChanged(event) {\r\n const node = this.getZipNode();\r\n\r\n if (event.currentTarget.checked) {\r\n node.setAttribute('disabled', true);\r\n node.value = '';\r\n this.setValidState(node);\r\n } else {\r\n node.removeAttribute('disabled', true);\r\n }\r\n }\r\n\r\n setInvalidState() {\r\n const errorMessage = document.getElementById(this.errorMessageId);\r\n const node = this.getZipNode();\r\n\r\n node.setAttribute('aria-invalid', true);\r\n node.classList.add(this.errorCssClass);\r\n errorMessage.removeAttribute('hidden');\r\n }\r\n\r\n setValidState() {\r\n const errorMessage = document.getElementById(this.errorMessageId);\r\n const node = this.getZipNode();\r\n\r\n node.removeAttribute('aria-invalid');\r\n node.classList.remove(this.errorCssClass);\r\n errorMessage.setAttribute('hidden', true);\r\n }\r\n\r\n validate() {\r\n const isOutsideUs = this.isOutsideUs();\r\n const isValidZipCode = this.isValidZipCode();\r\n const isValid = isOutsideUs || isValidZipCode;\r\n\r\n if (isValid) {\r\n this.setValidState();\r\n } else {\r\n this.setInvalidState();\r\n }\r\n\r\n return isValid;\r\n }\r\n}\r\n","import { fromEvent, map } from \"rxjs\";\r\n\r\nexport default class RealtorDropdown {\r\n constructor() {\r\n this.selectedValue = '';\r\n this.required = false;\r\n this.errorMessageId = 'nhs_ErrorForRealtorQuestion';\r\n this.errorCssClass = 'error'\r\n this.id = 'nhs-real-agent';\r\n this.errorMessage = ``;\r\n this.label = ``;\r\n }\r\n\r\n set value(newValue) {\r\n this.selectedValue = newValue || ''; \r\n const realtorDropdown = this.getNode();\r\n if (realtorDropdown) {\r\n realtorDropdown.value = this.selectedValue;\r\n }\r\n }\r\n\r\n get value() {\r\n return this.selectedValue;\r\n }\r\n\r\n getHtml() {\r\n return `${this.label} \r\n
\r\n \r\n ${this.errorMessage}\r\n
`;\r\n }\r\n\r\n getNode() {\r\n return document.getElementById(this.id);\r\n }\r\n \r\n /**\r\n * setSelectedValue: Finds the correct index based on the selectedValue\r\n * and updates the select element.\r\n */\r\n setSelectedValue() {\r\n const realtorDropdownNode = this.getNode();\r\n if (realtorDropdownNode) {\r\n const optionsArray = Array.from(realtorDropdownNode.options);\r\n realtorDropdownNode.selectedIndex = optionsArray.findIndex(\r\n (option) => option.value === this.selectedValue\r\n );\r\n }\r\n }\r\n\r\n /**\r\n * getOnChangeEvent: On select change map its value to the storage property.\r\n */\r\n getOnChangeEvent() {\r\n return fromEvent(this.getNode(), 'change').pipe(\r\n map((event) => {\r\n this.value = event.target.value;\r\n return { realtorQuestion: this.selectedValue };\r\n })\r\n );\r\n }\r\n\r\n /**\r\n * Method to remove the required attribute.\r\n */\r\n\r\n removeRequired() {\r\n const node = this.getNode();\r\n node.removeAttribute('required');\r\n }\r\n\r\n setInvalidState(node) {\r\n const errorMessage = document.getElementById(this.errorMessageId);\r\n\r\n node.setAttribute('aria-invalid', true);\r\n node.classList.add(this.errorCssClass);\r\n errorMessage.removeAttribute('hidden');\r\n }\r\n\r\n /**\r\n * Method to set the required attribute.\r\n */\r\n\r\n setRequired() {\r\n const node = this.getNode();\r\n node.setAttribute('required', 'true');\r\n }\r\n\r\n setValidState(node) {\r\n const errorMessage = document.getElementById(this.errorMessageId);\r\n\r\n node.removeAttribute('aria-invalid');\r\n node.classList.remove(this.errorCssClass);\r\n errorMessage.setAttribute('hidden', true);\r\n }\r\n\r\n isValid() {\r\n const node = this.getNode();\r\n const isEmpty = node.value === '';\r\n const isRequired = node.required;\r\n \r\n // If it is empty and is required, the input is not valid\r\n if(isEmpty && isRequired) {\r\n return false;\r\n }\r\n\r\n return true;\r\n }\r\n\r\n validate() {\r\n const node = this.getNode();\r\n const isValid = this.isValid();\r\n\r\n if (isValid) {\r\n this.setValidState(node);\r\n } else {\r\n this.setInvalidState(node);\r\n }\r\n\r\n return isValid;\r\n }\r\n}\r\n","import { store } from '@redux/store';\r\nimport GoogleAnalyticsCustomDimensions from 'constants/googleAnalyticsCustomDimension';\r\nimport GoogleAnalyticsEvent from 'dataTransferObjects/googleAnalyticsEvent';\r\nimport { userProfileActions } from 'features/userProfile';\r\nimport { closeButton, privacyPolicyParagraph } from '../constants/sharedHtml';\r\nimport leadConstructor from '../services/leadConstructor';\r\nimport { postLeadBrochureForm } from '../services/taskFlow';\r\nimport BrochureButton from './brochureButton';\r\nimport CommentsTextArea from './commentsTextArea';\r\nimport EmailInput from './emailInput';\r\nimport NameInput from './nameInput';\r\nimport PhoneInput from './phoneInput';\r\nimport RecommendedCheckbox from './recommendedCheckbox';\r\nimport ZipInput from './zipInput';\r\nimport RealtorDropdown from './realtorDropdown';\r\n\r\n/* Creates a new instance of a Request Tour Form to allow users making an appointment to tour the selected housing. */\r\nexport default class BrochureFormPaid {\r\n constructor() {\r\n const state = store.getState();\r\n const userProfile = state?.userProfile || {};\r\n this.id = state?.uiState.modalInformation.id;\r\n this.type = state?.uiState.modalInformation.type;\r\n this.fromPage = state?.uiState.modalInformation.fromPage;\r\n this.excludeRecommendations = false;\r\n this.getBrochureButton = new BrochureButton();\r\n this.commentsTextArea = new CommentsTextArea();\r\n this.emailAddressInput = new EmailInput();\r\n this.emailAddressInput.value = userProfile.email;\r\n this.formId = 'brochureFormPaid';\r\n this.fullNameInput = new NameInput();\r\n this.fullNameInput.value = userProfile.name;\r\n this.phoneNumberInput = new PhoneInput();\r\n this.phoneNumberInput.value = userProfile.phone;\r\n this.postalCodeInput = new ZipInput();\r\n this.postalCodeInput.value = userProfile.zip;\r\n this.postalCodeInput.isInternational = userProfile.livesOutside;\r\n this.realtorDropdown = new RealtorDropdown();\r\n this.realtorDropdown.value = userProfile.realtorQuestion;\r\n this.recommendedCheckbox = new RecommendedCheckbox();\r\n this.recommendedCheckbox.value = userProfile.hasUserOptedIntoRecommendationEmail;\r\n this.onClickEvent = null;\r\n }\r\n\r\n /**\r\n * validateNode: Check if the field has a value as expected.\r\n * @param {Object} node Input to validate\r\n * @returns A boolean value indicating whether the input is valid or not.\r\n */\r\n static validateNode(node) {\r\n return node.validate();\r\n }\r\n\r\n /**\r\n * getFormOpenedAnalyticsData: Gets the object required for the Google Analytics events on form opened.\r\n * @param {Object} properties Information regarding to the listing.\r\n * @returns The Google Analtic event information.\r\n */\r\n static getFormOpenedAnalyticsData(properties) {\r\n const customDimensions = {};\r\n\r\n if (properties.marketId) {\r\n customDimensions[[GoogleAnalyticsCustomDimensions.MarketId().getName()]] = properties.marketId;\r\n }\r\n\r\n if (properties.marketName && properties.stateAbbreviation) {\r\n customDimensions[[GoogleAnalyticsCustomDimensions.MarketName().getName()]] = `${properties.marketName}, ${properties.stateAbbreviation}`;\r\n }\r\n\r\n if (properties.city) {\r\n customDimensions[[GoogleAnalyticsCustomDimensions.City().getName()]] = properties.city;\r\n }\r\n\r\n return new GoogleAnalyticsEvent(\r\n \"Lead Events\",\r\n \"Search Results CTA Free Brochure\",\r\n \"Open Form - Free Brochure\",\r\n customDimensions);\r\n }\r\n\r\n /**\r\n * setHousingData: Sets the housing information for the form.\r\n * @param {Object} properties Information regarding to the listing.\r\n */\r\n setHousingData(properties = {}) {\r\n this.housingData = properties;\r\n }\r\n\r\n /**\r\n * submitBrochureForm: Process to validate and submit the form.\r\n * @param {event} event Click event.\r\n */\r\n submitBrochureForm(event) {\r\n event.preventDefault();\r\n\r\n const validationFunctions = [\r\n this.emailAddressInput,\r\n this.fullNameInput,\r\n this.postalCodeInput,\r\n this.phoneNumberInput,\r\n this.realtorDropdown,\r\n ];\r\n\r\n const result = validationFunctions.map(BrochureFormPaid.validateNode);\r\n\r\n if (result.some((isValid) => !isValid)) {\r\n return;\r\n }\r\n\r\n this.getBrochureButton.getNode().disabled = 'disabled';\r\n const formData = new FormData(this.getForm());\r\n const brochureInformation = Object.fromEntries(formData.entries());\r\n\r\n brochureInformation.id = this.id;\r\n brochureInformation.type = `${this.type}-brochure`;\r\n brochureInformation.excludeRecommendations = this.excludeRecommendations;\r\n brochureInformation.fromPage = this.housingData.fromPage;\r\n brochureInformation.includeRecommended = !!brochureInformation.includeRecommended;\r\n\r\n const brochureLeadObject = leadConstructor(brochureInformation);\r\n brochureLeadObject.setHousingInformation?.(this.housingData.listingInformation);\r\n\r\n postLeadBrochureForm(brochureLeadObject);\r\n }\r\n\r\n /**\r\n * Sets the binding required for the form.\r\n */\r\n bindEvents() {\r\n this.onClickEvent = this.submitBrochureForm.bind(this);\r\n this.phoneNumberInput.bindEvents();\r\n this.postalCodeInput.bindEvents();\r\n if (this.fullNameInput.value === '') {\r\n this.fullNameInput.focus();\r\n }\r\n this.realtorDropdown.setSelectedValue();\r\n this.getBrochureButton.getNode().addEventListener('click', this.onClickEvent);\r\n this.bindChangeEvents();\r\n }\r\n\r\n /**\r\n * bindChangeEvents: Get the form inputs then subscribe each OnChangeEvent to store and persist their values\r\n */\r\n bindChangeEvents() {\r\n const changeInputs = [\r\n this.emailAddressInput,\r\n this.fullNameInput,\r\n this.postalCodeInput,\r\n this.phoneNumberInput,\r\n this.recommendedCheckbox,\r\n this.realtorDropdown,\r\n ];\r\n changeInputs.forEach(input => input.getOnChangeEvent().subscribe(data =>\r\n store.dispatch(userProfileActions.update(data))));\r\n }\r\n\r\n /**\r\n * Removes the bindings that should not be still using.\r\n */\r\n unbindEvents() {\r\n this.getBrochureButton.getNode().removeEventListener('click', this.onClickEvent);\r\n }\r\n\r\n /**\r\n * getForm: Gets the form container \r\n * @returns A HTML element related to the form container.\r\n */\r\n getForm() {\r\n return document.getElementById(this.formId);\r\n }\r\n\r\n /**\r\n * Gets the HTML structure for the brochure form paid.\r\n * @returns The string with the HTML structure.\r\n */\r\n getHtml() {\r\n return `\r\n
\r\n ${closeButton}\r\n

Check your email & download the brochure

\r\n
\r\n
\r\n
\r\n ${this.fullNameInput.getHtml()}\r\n
\r\n
\r\n ${this.emailAddressInput.getHtml()}\r\n
\r\n
\r\n ${this.phoneNumberInput.getHtml()}\r\n
\r\n
\r\n ${this.postalCodeInput.getHtml()}\r\n
\r\n
\r\n ${this.realtorDropdown.getHtml()}\r\n
\r\n
\r\n ${this.recommendedCheckbox.getHtml()}\r\n
\r\n
\r\n ${this.commentsTextArea.getHtml()}\r\n
\r\n
\r\n ${this.getBrochureButton.getHtml()}\r\n
\r\n \r\n
\r\n
\r\n ${privacyPolicyParagraph.replace(\"{0}\", \"Get Brochure\")\r\n .replace(\"{1}\", this.housingData.listingInformation?.brandName ?? \"the builder\")}\r\n
`;\r\n }\r\n}\r\n","export default class BasicContactVendor {\r\n static get OpCity() {\r\n return this.getInstance('OpCity');\r\n }\r\n\r\n static get PrimeStreet() {\r\n return this.getInstance('PrimeStreet');\r\n }\r\n\r\n static get CoffmanProperties() {\r\n return this.getInstance('Coffman Properties');\r\n }\r\n\r\n static get Dezka() {\r\n return this.getInstance('Dezka');\r\n }\r\n\r\n static get MarketplaceHomes() {\r\n return this.getInstance('Marketplace Homes');\r\n }\r\n\r\n static get NewHomeExpertsDetroit() {\r\n return this.getInstance('New Home Experts - Detroit');\r\n }\r\n\r\n static get NewHomeExpertsLasVegas() {\r\n return this.getInstance('New Home Experts - Las Vegas');\r\n }\r\n\r\n static get NewHomeExpertsSarasota() {\r\n return this.getInstance('New Home Experts - Sarasota');\r\n }\r\n\r\n static get NHSAustin() {\r\n return this.getInstance('NHS Austin');\r\n }\r\n\r\n static fromKey(key) {\r\n const formTypeMap = {\r\n\r\n 'OpCity': BasicContactVendor.OpCity,\r\n 'PrimeStreet': BasicContactVendor.PrimeStreet,\r\n 'Coffman Properties': BasicContactVendor.CoffmanProperties,\r\n 'Dezka': BasicContactVendor.Dezka,\r\n 'Marketplace Homes': BasicContactVendor.MarketplaceHomes,\r\n 'New Home Experts - Detroit': BasicContactVendor.NewHomeExpertsDetroit,\r\n 'New Home Experts - Las Vegas': BasicContactVendor.NewHomeExpertsLasVegas,\r\n 'New Home Experts - Sarasota': BasicContactVendor.NewHomeExpertsSarasota,\r\n 'NHS Austin': BasicContactVendor.NHSAustin,\r\n };\r\n return formTypeMap[key];\r\n }\r\n\r\n static getInstance(key) {\r\n if (!this.instances[key]) {\r\n this.instances[key] = new BasicContactVendor(key);\r\n }\r\n return this.instances[key];\r\n }\r\n\r\n constructor(name) {\r\n this.name = name;\r\n }\r\n\r\n toString() {\r\n return `${this.name}`;\r\n }\r\n}\r\n\r\nObject.defineProperty(BasicContactVendor, 'instances', { value: {} });\r\n","import BasicContactVendor from '../enums/basicContactVendor';\r\n\r\nconst opCityPrivacyPolicyParagraph = `
By proceeding, you consent to receive calls and texts at the number you \r\nprovided, including marketing by autodialer and prerecorded and artificial voice, and email, from Realtor.com (Move Sales, Inc.) \r\nabout your inquiry and other home-related matters, but not as a condition of any purchase. You also agree to Realtor.com ’s Terms of Use \r\nand to Realtor.com ’s Privacy Policy regarding information relating to you. Msg/data rates may apply. \r\nThis consent applies even if you are on a corporate, state, or national Do Not Call list.
\r\nBy providing your name and contact information, you consent and agree to receive email marketing communications from NewHomeSource. Your Agreement \r\nis not a condition of purchasing any property, goods, or services, and you may call us instead of submitting your information online. Consult our \r\nPrivacy Policy for additional information, including unsubscribe options. \r\nYou also agree to our Privacy Policy and \r\nTerms of Use.
`;\r\n\r\nconst defaultPrivacyPolicyParagraph = `
By providing your name and contact information and clicking the Learn More button, \r\nyou consent and agree to receive marketing communications from NewHomeSource and {0}, including emails, calls or text messages using an automatic \r\ntelephone dialing system or an artificial or prerecorded voice. You also agree to our Privacy Policy, including TCPA Policy and Terms of Use. Your agreement is not a condition to purchasing any property, \r\ngoods or services, and you may call us instead of submitting the information online. You also acknowledge \r\nand agree that you can revoke your authorization at any time. Your consent herein also applies to any future registration on national or state \r\nDo-No-Call lists. For mobile phones, standard message and data charges apply. Consult our Privacy Policy for additional information, \r\nincluding unsubscribe options.
`;\r\n\r\n/**\r\n * Returns the privacy policy paragraph for basic listings according to the contact vendor name.\r\n * @param {string} contactVendorName the contact vendor name.\r\n * @returns {string} - The privacy policy paragraph.\r\n */\r\nfunction getBasicPrivacyPolicyParagraph(contactVendorName) {\r\n\r\n switch (contactVendorName) {\r\n case BasicContactVendor.OpCity.name:\r\n return opCityPrivacyPolicyParagraph;\r\n default:\r\n return defaultPrivacyPolicyParagraph.replace('{0}', contactVendorName);\r\n }\r\n}\r\n\r\nexport default getBasicPrivacyPolicyParagraph;","export default class InformationButtonBasic {\r\n constructor() {\r\n this.id = 'moreInformationButtonBasic';\r\n }\r\n \r\n getHtml() {\r\n const styles = 'class=\"btn btn--yellow btn--width-100 btn--48-lg loading\"';\r\n return ``;\r\n }\r\n \r\n getNode() {\r\n return document.getElementById(this.id);\r\n }\r\n }\r\n ","import { store } from '@redux/store';\r\nimport GoogleAnalyticsCustomDimensions from 'constants/googleAnalyticsCustomDimension';\r\nimport GoogleAnalyticsEvent from 'dataTransferObjects/googleAnalyticsEvent';\r\nimport { userProfileActions } from 'features/userProfile';\r\nimport { closeButton } from '../constants/sharedHtml';\r\nimport leadConstructor from '../services/leadConstructor';\r\nimport { postLeadInformationFormBasic } from '../services/taskFlow';\r\nimport getBasicPrivacyPolicyParagraph from '../services/basicPrivacyPolicyParagraph';\r\nimport CommentsTextArea from './commentsTextArea';\r\nimport EmailInput from './emailInput';\r\nimport InformationButtonBasic from './informationButtonBasic';\r\nimport NameInput from './nameInput';\r\nimport PhoneInput from './phoneInput';\r\nimport ZipInput from './zipInput';\r\n\r\n/* Creates a new instance of a Get More Information Basic Form to allow users getting in touch with an agent\r\nthat will lead them into the home buying process. */\r\nexport default class InformationFormBasic {\r\n constructor() {\r\n const state = store.getState();\r\n const userProfile = state?.userProfile || {};\r\n this.id = state?.uiState?.modalInformation.id;\r\n this.type = state?.uiState?.modalInformation.type;\r\n this.fromPage = state?.uiState.modalInformation.fromPage;\r\n this.excludeRecommendations = true;\r\n this.moreInformationButton = new InformationButtonBasic();\r\n this.commentsTextArea = new CommentsTextArea();\r\n this.emailAddressInput = new EmailInput();\r\n this.emailAddressInput.value = userProfile.email;\r\n this.formId = 'informationFormBasic';\r\n this.fullNameInput = new NameInput();\r\n this.fullNameInput.value = userProfile.name;\r\n this.phoneNumberInput = new PhoneInput();\r\n this.phoneNumberInput.value = userProfile.phone;\r\n this.postalCodeInput = new ZipInput();\r\n this.postalCodeInput.value = userProfile.zip;\r\n this.postalCodeInput.isInternational = userProfile.livesOutside;\r\n this.onClickEvent = null;\r\n }\r\n\r\n /**\r\n * validateNode: Check if the field has a value as expected.\r\n * @param {Object} node Input to validate\r\n * @returns A boolean value indicating whether the input is valid or not.\r\n */\r\n static validateNode(node) {\r\n return node.validate();\r\n }\r\n\r\n /**\r\n * getFormOpenedAnalyticsData: Gets the object required for the Google Analytics events on form opened.\r\n * @param {Object} properties Information regarding to the listing.\r\n * @returns The Google Analtic event information.\r\n */\r\n static getFormOpenedAnalyticsData(properties) {\r\n const customDimensions = {};\r\n\r\n if (properties.marketId) {\r\n customDimensions[[GoogleAnalyticsCustomDimensions.MarketId().getName()]] = properties.marketId;\r\n }\r\n\r\n if (properties.marketName && properties.stateAbbreviation) {\r\n customDimensions[[GoogleAnalyticsCustomDimensions.MarketName().getName()]] = `${properties.marketName}, ${properties.stateAbbreviation}`;\r\n }\r\n\r\n if (properties.city) {\r\n customDimensions[[GoogleAnalyticsCustomDimensions.City().getName()]] = properties.city;\r\n }\r\n return new GoogleAnalyticsEvent(\r\n 'Lead Events',\r\n 'Search Results CTA Learn More',\r\n 'Open Form - Learn More',\r\n customDimensions);\r\n }\r\n\r\n /**\r\n * setPrivacyPolicyText: Sets the structure related to the privacy policy text for the form.\r\n * @param {string} phoneNumber Builder phone number value.\r\n * @param {string} contactVendorName Contact vendor name value.\r\n */\r\n setPrivacyPolicyText(phoneNumber, contactVendorName) {\r\n const container = document.createElement('div');\r\n const privacyPolicyParagraph = getBasicPrivacyPolicyParagraph(contactVendorName);\r\n container.innerHTML = privacyPolicyParagraph;\r\n\r\n this.basicPrivacyPolicyParagraph = privacyPolicyParagraph;\r\n\r\n if (phoneNumber) {\r\n container.firstChild.innerHTML = `${container.firstChild.innerHTML}`;\r\n this.basicPrivacyPolicyParagraph = container.firstChild.outerHTML;\r\n }\r\n }\r\n\r\n /**\r\n * submitInformationForm: Process to validate and submit the form.\r\n * @param {event} event Click event.\r\n */\r\n submitInformationForm(event) {\r\n event.preventDefault();\r\n\r\n const validationFunctions = [\r\n this.emailAddressInput,\r\n this.fullNameInput,\r\n this.postalCodeInput,\r\n this.phoneNumberInput,\r\n ];\r\n\r\n const result = validationFunctions.map(InformationFormBasic.validateNode);\r\n\r\n if (result.some((isValid) => !isValid)) {\r\n return;\r\n }\r\n\r\n this.moreInformationButton.getNode().disabled = 'disabled';\r\n const formData = new FormData(this.getForm());\r\n const leadInformation = Object.fromEntries(formData.entries());\r\n\r\n leadInformation.id = this.id;\r\n leadInformation.type = `${this.type}-information-basic`;\r\n leadInformation.excludeRecommendations = this.excludeRecommendations;\r\n leadInformation.fromPage = this.housingData.fromPage;\r\n const leadObject = leadConstructor(leadInformation);\r\n leadObject.setHousingInformation?.(this.housingData);\r\n \r\n postLeadInformationFormBasic(leadObject);\r\n }\r\n\r\n /**\r\n * Sets the binding required for the form.\r\n */\r\n setHousingData(properties={}) {\r\n this.housingData = properties;\r\n }\r\n\r\n /**\r\n * Sets the binding required for the form.\r\n */\r\n bindEvents() {\r\n this.onClickEvent = this.submitInformationForm.bind(this);\r\n this.phoneNumberInput.bindEvents();\r\n this.postalCodeInput.bindEvents();\r\n if (this.fullNameInput.value === '') {\r\n this.fullNameInput.focus();\r\n }\r\n this.moreInformationButton.getNode().addEventListener('click', this.onClickEvent);\r\n this.phoneNumberInput.setRequired();\r\n this.bindChangeEvents();\r\n }\r\n\r\n /**\r\n * bindChangeEvents: Get the form inputs then subscribe each OnChangeEvent to store and persist their values\r\n */\r\n bindChangeEvents() {\r\n const changeInputs = [\r\n this.emailAddressInput,\r\n this.fullNameInput,\r\n this.postalCodeInput,\r\n this.phoneNumberInput,\r\n ];\r\n changeInputs.forEach(input => input.getOnChangeEvent().subscribe(data => \r\n store.dispatch(userProfileActions.update(data))));\r\n }\r\n\r\n /**\r\n * Removes the bindings that should not be still using.\r\n */\r\n unbindEvents() {\r\n this.moreInformationButton.getNode().removeEventListener('click', this.onClickEvent);\r\n }\r\n\r\n /**\r\n * getForm: Gets the form container \r\n * @returns A HTML element related to the form container.\r\n */\r\n getForm() {\r\n return document.getElementById(this.formId);\r\n }\r\n\r\n /**\r\n * Gets the HTML structure for the information brochure form basic.\r\n * @returns The string with the HTML structure.\r\n */\r\n getHtml() {\r\n return `\r\n
\r\n ${closeButton}\r\n

Connect with a local agent

\r\n

\r\n
\r\n
\r\n
\r\n ${this.fullNameInput.getHtml()}\r\n
\r\n
\r\n ${this.emailAddressInput.getHtml()}\r\n
\r\n
\r\n ${this.phoneNumberInput.getHtml()}\r\n
\r\n
\r\n ${this.postalCodeInput.getHtml()}\r\n
\r\n
\r\n ${this.commentsTextArea.getHtml()}\r\n
\r\n
\r\n ${this.moreInformationButton.getHtml()}\r\n
\r\n
\r\n
\r\n ${this.basicPrivacyPolicyParagraph}\r\n
`;\r\n }\r\n}","export default class InformationButton {\r\n constructor() {\r\n this.id = 'moreInformationButton';\r\n }\r\n \r\n getHtml() {\r\n const styles = 'class=\"btn btn--yellow btn--width-100 btn--48-lg loading\"';\r\n return ``;\r\n }\r\n \r\n getNode() {\r\n return document.getElementById(this.id);\r\n }\r\n }\r\n ","import { store } from '@redux/store';\r\nimport GoogleAnalyticsCustomDimensions from 'constants/googleAnalyticsCustomDimension';\r\nimport GoogleAnalyticsEvent from 'dataTransferObjects/googleAnalyticsEvent';\r\nimport { userProfileActions } from 'features/userProfile';\r\nimport { closeButton, privacyPolicyParagraph } from '../constants/sharedHtml';\r\nimport leadConstructor from '../services/leadConstructor';\r\nimport { postLeadInformationForm } from '../services/taskFlow';\r\nimport CommentsTextArea from './commentsTextArea';\r\nimport EmailInput from './emailInput';\r\nimport InformationButton from './informationButton';\r\nimport NameInput from './nameInput';\r\nimport PhoneInput from './phoneInput';\r\nimport ZipInput from './zipInput';\r\nimport RealtorDropdown from './realtorDropdown';\r\n\r\n/* Creates a new instance of a Get More Information Form to allow users making an \r\nappointment to tour the selected housing. */\r\nexport default class InformationFormPaid {\r\n constructor() {\r\n const state = store.getState();\r\n const userProfile = state?.userProfile || {};\r\n this.id = state?.uiState?.modalInformation.id;\r\n this.type = state?.uiState?.modalInformation.type;\r\n this.excludeRecommendations = true;\r\n this.isPersistent = true;\r\n this.moreInformationButton = new InformationButton();\r\n this.commentsTextArea = new CommentsTextArea();\r\n this.emailAddressInput = new EmailInput();\r\n this.emailAddressInput.value = userProfile.email;\r\n this.formId = 'informationFormPaid';\r\n this.fullNameInput = new NameInput();\r\n this.fullNameInput.value = userProfile.name;\r\n this.phoneNumberInput = new PhoneInput();\r\n this.phoneNumberInput.value = userProfile.phone;\r\n this.postalCodeInput = new ZipInput();\r\n this.postalCodeInput.value = userProfile.zip;\r\n this.postalCodeInput.isInternational = userProfile.livesOutside;\r\n this.realtorDropdown = new RealtorDropdown();\r\n this.realtorDropdown.value = userProfile.realtorQuestion;\r\n this.onClickEvent = null;\r\n this.buttonText = state?.uiState?.modalInformation.buttonText;\r\n }\r\n\r\n /**\r\n * validateNode: Check if the field has a value as expected.\r\n * @param {Object} node Input to validate\r\n * @returns A boolean value indicating whether the input is valid or not.\r\n */\r\n static validateNode(node) {\r\n return node.validate();\r\n }\r\n\r\n /**\r\n * getFormOpenedAnalyticsData: Gets the object required for the Google Analytics events on form opened.\r\n * @param {Object} properties Information regarding to the listing.\r\n * @returns The Google Analtic event information.\r\n */\r\n static getFormOpenedAnalyticsData(properties) {\r\n const customDimensions = {};\r\n\r\n if (properties.marketId) {\r\n customDimensions[[GoogleAnalyticsCustomDimensions.MarketId().getName()]] = properties.marketId;\r\n }\r\n\r\n if (properties.marketName && properties.stateAbbreviation) {\r\n customDimensions[[GoogleAnalyticsCustomDimensions.MarketName().getName()]] = `${properties.marketName}, ${properties.stateAbbreviation}`;\r\n }\r\n\r\n if (properties.city) {\r\n customDimensions[[GoogleAnalyticsCustomDimensions.City().getName()]] = properties.city;\r\n }\r\n\r\n return new GoogleAnalyticsEvent(\r\n 'Lead Events',\r\n 'Search Results CTA Get More Info',\r\n 'Open Form - Get More Info',\r\n customDimensions);\r\n }\r\n\r\n /**\r\n * setHousingData: Sets the housing information for the form.\r\n * @param {Object} properties Information regarding to the listing.\r\n */\r\n setHousingData(properties = {}) {\r\n this.housingData = properties;\r\n }\r\n\r\n /**\r\n * submitBrochureForm: Process to validate and submit the form.\r\n * @param {event} event Click event.\r\n */\r\n submitInformationForm(event) {\r\n event.preventDefault();\r\n\r\n const validationFunctions = [\r\n this.emailAddressInput,\r\n this.fullNameInput,\r\n this.postalCodeInput,\r\n this.phoneNumberInput,\r\n ];\r\n const result = validationFunctions.map(InformationFormPaid.validateNode);\r\n\r\n if (result.some((isValid) => !isValid)) {\r\n return;\r\n }\r\n\r\n this.moreInformationButton.getNode().disabled = 'disabled';\r\n const formData = new FormData(this.getForm());\r\n const leadInformation = Object.fromEntries(formData.entries());\r\n\r\n leadInformation.id = this.id;\r\n leadInformation.type = `${this.type}-information`;\r\n leadInformation.excludeRecommendations = this.excludeRecommendations;\r\n leadInformation.fromPage = this.housingData.fromPage;\r\n const leadObject = leadConstructor(leadInformation);\r\n leadObject.setHousingInformation?.(this.housingData);\r\n\r\n postLeadInformationForm(leadObject);\r\n }\r\n\r\n /**\r\n * Sets the binding required for the form.\r\n */\r\n bindEvents() {\r\n this.onClickEvent = this.submitInformationForm.bind(this);\r\n this.phoneNumberInput.bindEvents();\r\n this.postalCodeInput.bindEvents();\r\n if (this.fullNameInput.value === '') {\r\n this.fullNameInput.focus();\r\n }\r\n this.realtorDropdown.setSelectedValue();\r\n this.moreInformationButton.getNode().addEventListener('click', this.onClickEvent);\r\n this.bindChangeEvents();\r\n }\r\n\r\n /**\r\n * bindChangeEvents: Get the form inputs then subscribe each OnChangeEvent to store and persist their values\r\n */\r\n bindChangeEvents() {\r\n const changeInputs = [\r\n this.emailAddressInput,\r\n this.fullNameInput,\r\n this.postalCodeInput,\r\n this.phoneNumberInput,\r\n this.realtorDropdown,\r\n ];\r\n changeInputs.forEach(input => input.getOnChangeEvent().subscribe(data =>\r\n store.dispatch(userProfileActions.update(data))));\r\n }\r\n\r\n /**\r\n * Removes the bindings that should not be still using.\r\n */\r\n unbindEvents() {\r\n this.moreInformationButton.getNode().removeEventListener('click', this.onClickEvent);\r\n }\r\n\r\n /**\r\n * getForm: Gets the form container \r\n * @returns A HTML element related to the form container.\r\n */\r\n getForm() {\r\n return document.getElementById(this.formId);\r\n }\r\n\r\n /**\r\n * Gets the HTML structure for the information form paid.\r\n * @returns The string with the HTML structure.\r\n */\r\n getHtml() {\r\n return `\r\n
\r\n ${closeButton}\r\n

Get More Information

\r\n

\r\n We will keep you updated in your area of interest, our progress, and much more…\r\n

\r\n

\r\n
\r\n
\r\n
\r\n ${this.fullNameInput.getHtml()}\r\n
\r\n
\r\n ${this.emailAddressInput.getHtml()}\r\n
\r\n
\r\n ${this.phoneNumberInput.getHtml()}\r\n
\r\n
\r\n ${this.postalCodeInput.getHtml()}\r\n
\r\n
\r\n ${this.realtorDropdown.getHtml()}\r\n
\r\n
\r\n ${this.commentsTextArea.getHtml()}\r\n
\r\n
\r\n ${this.moreInformationButton.getHtml()}\r\n
\r\n
\r\n
\r\n ${privacyPolicyParagraph.replace(\"{0}\", \"Get More Information\")\r\n .replace(\"{1}\", this.housingData?.listingInformation?.brandName ?? \"the builder\")}\r\n
`;\r\n }\r\n}\r\n","export default class ContactRadioGroup {\r\n constructor() {\r\n this.valueInput = '';\r\n this.idEmail = 'contact-email';\r\n this.idPhone = 'contact-phone';\r\n this.idText = 'contact-text';\r\n this.radioInputSelector = '[name=\"preferredContactMethod\"]';\r\n this.labelEmail = ``;\r\n this.labelPhone = ``;\r\n this.labelText = ``;\r\n }\r\n\r\n set value(newValue){\r\n this.valueInput = newValue || '';\r\n }\r\n \r\n get value(){\r\n return this.valueInput;\r\n }\r\n \r\n getHtml() {\r\n return `
\r\n \r\n ${this.labelEmail}\r\n
\r\n
\r\n \r\n ${this.labelPhone}\r\n
\r\n
\r\n \r\n ${this.labelText}\r\n
`;\r\n }\r\n \r\n onChange(callback) {\r\n document.querySelectorAll(this.radioInputSelector).forEach((node) => node.addEventListener('change', callback));\r\n }\r\n }\r\n ","export default class DateInput {\r\n constructor() {\r\n this.tomorrow = (Date.parse(new Date().toDateString()) + 86400000);\r\n const tomorrowIsoString = new Date(this.tomorrow).toISOString().split(\"T\")[0];\r\n this.id = 'nhs_date';\r\n this.errorMessageId = 'nhs_ErrorForTourDateTime';\r\n this.errorCssClass = 'error';\r\n\r\n this.input = ``;\r\n this.label = ``;\r\n \r\n\r\n this.error = ``;\r\n }\r\n \r\n getHtml() {\r\n return `
\r\n ${this.label}${this.input}\r\n
\r\n ${this.error}`;\r\n }\r\n \r\n getNode() {\r\n return document.getElementById(this.id);\r\n }\r\n\r\n setInvalidState() {\r\n const errorMessage = document.getElementById(this.errorMessageId);\r\n const node = this.getNode();\r\n \r\n node.setAttribute('aria-invalid', true);\r\n node.classList.add(this.errorCssClass);\r\n errorMessage.removeAttribute('hidden');\r\n }\r\n \r\n setValidState() {\r\n const errorMessage = document.getElementById(this.errorMessageId);\r\n const node = this.getNode();\r\n \r\n node.removeAttribute('aria-invalid');\r\n node.classList.remove(this.errorCssClass);\r\n errorMessage.setAttribute('hidden', true);\r\n }\r\n\r\n isValid(node) {\r\n return (+new Date(`${node.value}T00:00`)) >= (+this.tomorrow);\r\n }\r\n\r\n validate() {\r\n const node = this.getNode();\r\n const isValid = this.isValid(node);\r\n \r\n if (isValid) {\r\n this.setValidState(node);\r\n } else {\r\n this.setInvalidState(node);\r\n }\r\n \r\n return isValid;\r\n }\r\n }\r\n ","export default class SubmitRequestButton {\r\n constructor() {\r\n this.id = 'submitRequestButton';\r\n }\r\n \r\n getHtml() {\r\n const styles = 'class=\"btn btn--blue btn--width-100 btn--64-xl loading\"';\r\n return ``;\r\n }\r\n \r\n getNode() {\r\n return document.getElementById(this.id);\r\n }\r\n }\r\n ","export default class TourRadioOptions {\r\n constructor() {\r\n this.errorMessageId = 'nhs_ErrorForTourOption';\r\n this.idContactOneOnOne = 'contact-1-1';\r\n this.errorCssClass = 'error';\r\n this.idVideoChat = 'contact-vid-chat';\r\n this.radioChecked = '[name=\"leadAction\"]:checked';\r\n\r\n this.inputContactOneOne = ``;\r\n this.labelContactOneOne = ``;\r\n \r\n this.inputVideoChat = ``;\r\n this.labelVideoChat = ``;\r\n\r\n this.error = ``;\r\n }\r\n\r\n getHtml() {\r\n return `
\r\n
${this.inputContactOneOne}${this.labelContactOneOne}
\r\n
${this.inputVideoChat}${this.labelVideoChat}
\r\n
${this.error}`;\r\n }\r\n\r\n getCheckedNode() {\r\n return document.querySelector(this.radioChecked);\r\n }\r\n\r\n getVideoChatLabelNode() {\r\n return document.querySelector(`[for=\"${this.idVideoChat}\"]`);\r\n }\r\n\r\n getOneOnOnetLabelNode() {\r\n return document.querySelector(`[for=\"${this.idContactOneOnOne}\"]`);\r\n }\r\n\r\n setInvalidState(node) {\r\n const errorMessage = document.getElementById(this.errorMessageId);\r\n\r\n node.setAttribute('aria-invalid', true);\r\n node.classList.add(this.errorCssClass);\r\n errorMessage.removeAttribute('hidden');\r\n }\r\n\r\n setValidState(node) {\r\n const errorMessage = document.getElementById(this.errorMessageId);\r\n\r\n node.removeAttribute('aria-invalid');\r\n node.classList.remove(this.errorCssClass);\r\n errorMessage.setAttribute('hidden', true);\r\n }\r\n\r\n validate() {\r\n const node = this.getCheckedNode();\r\n const isValid = !!node;\r\n const nodeVideoChat = this.getVideoChatLabelNode();\r\n const nodeOneOnOne = this.getOneOnOnetLabelNode();\r\n\r\n if (isValid) {\r\n this.setValidState(nodeVideoChat);\r\n this.setValidState(nodeOneOnOne);\r\n } else {\r\n this.setInvalidState(nodeVideoChat);\r\n this.setInvalidState(nodeOneOnOne);\r\n }\r\n\r\n return isValid;\r\n }\r\n}\r\n","import { store } from '@redux/store';\r\nimport GoogleAnalyticsCustomDimensions from 'constants/googleAnalyticsCustomDimension';\r\nimport GoogleAnalyticsEvent from 'dataTransferObjects/googleAnalyticsEvent';\r\nimport { userProfileActions } from 'features/userProfile';\r\nimport { backButton, privacyPolicyParagraph } from '../constants/sharedHtml';\r\nimport leadConstructor from '../services/leadConstructor';\r\nimport { postLeadTourForm } from '../services/taskFlow';\r\nimport ContactRadioGroup from './contactRadioGroup';\r\nimport DateInput from './dateInput';\r\nimport EmailInput from './emailInput';\r\nimport NameInput from './nameInput';\r\nimport PhoneInput from './phoneInput';\r\nimport RequestButton from './requestButton';\r\nimport TourRadioOptions from './tourRadioOptions';\r\nimport ZipInput from './zipInput';\r\n\r\n/* Creates a new instance of a Request Tour Form to allow users making an appointment to tour the selected housing. */\r\nexport default class RequestTourForm {\r\n constructor() {\r\n const userProfile = store.getState()?.userProfile || {};\r\n const state = store.getState();\r\n this.id = state?.uiState?.modalInformation?.id;\r\n this.type = state?.uiState?.modalInformation?.type;\r\n this.excludeRecommendations = true;\r\n this.isPersistent = true;\r\n this.requestButton = new RequestButton();\r\n this.emailAddressInput = new EmailInput();\r\n this.emailAddressInput.value = userProfile.email;\r\n this.formId = 'requestATourPaid';\r\n this.fullNameInput = new NameInput();\r\n this.fullNameInput.value = userProfile.name;\r\n this.phoneNumberInput = new PhoneInput();\r\n this.phoneNumberInput.value = userProfile.phone;\r\n this.postalCodeInput = new ZipInput();\r\n this.postalCodeInput.value = userProfile.zip;\r\n this.postalCodeInput.isInternational = userProfile.livesOutside;\r\n this.contactRadioGroup = new ContactRadioGroup();\r\n this.contactRadioGroup.value = userProfile.preferredContactMethod;\r\n this.tourRadioOptions = new TourRadioOptions();\r\n this.dateInput = new DateInput();\r\n this.onClickEvent = null;\r\n }\r\n\r\n static validateNode(node) {\r\n return node.validate();\r\n }\r\n\r\n static getFormOpenedAnalyticsData(properties) {\r\n const customDimensions = {};\r\n\r\n if (properties.marketId) {\r\n customDimensions[[GoogleAnalyticsCustomDimensions.MarketId().getName()]] = properties.marketId;\r\n }\r\n\r\n if (properties.marketName && properties.stateAbbreviation) {\r\n customDimensions[[GoogleAnalyticsCustomDimensions.MarketName().getName()]] = `${properties.marketName}, ${properties.stateAbbreviation}`;\r\n }\r\n\r\n if (properties.city) {\r\n customDimensions[[GoogleAnalyticsCustomDimensions.City().getName()]] = properties.city;\r\n }\r\n\r\n return new GoogleAnalyticsEvent(\r\n 'Lead_Events',\r\n 'Search_Results_CTA_Request_Tour',\r\n 'Open_Form_Request_Tour',\r\n customDimensions);\r\n }\r\n\r\n setHousingData(properties = {}) {\r\n this.housingData = properties;\r\n }\r\n\r\n submitBrochureForm(event) {\r\n event.preventDefault();\r\n\r\n const validationFunctions = [\r\n this.emailAddressInput,\r\n this.fullNameInput,\r\n this.postalCodeInput,\r\n this.dateInput,\r\n this.tourRadioOptions,\r\n this.phoneNumberInput\r\n ];\r\n const result = validationFunctions.map(RequestTourForm.validateNode);\r\n\r\n if (result.some((isValid) => !isValid)) {\r\n return;\r\n }\r\n\r\n this.requestButton.getNode().disabled = 'disabled';\r\n const formData = new FormData(this.getForm());\r\n const brochureInformation = Object.fromEntries(formData.entries());\r\n\r\n brochureInformation.id = this.id;\r\n brochureInformation.type = `${this.type}-tour`;\r\n brochureInformation.excludeRecommendations = this.excludeRecommendations;\r\n\r\n const brochureLeadObject = leadConstructor(brochureInformation);\r\n brochureLeadObject.setHousingInformation?.(this.housingData.listingInformation);\r\n\r\n postLeadTourForm(brochureLeadObject);\r\n }\r\n\r\n bindEvents() {\r\n this.onClickEvent = this.submitBrochureForm.bind(this);\r\n this.phoneNumberInput.bindEvents();\r\n this.postalCodeInput.bindEvents();\r\n this.requestButton.getNode().addEventListener('click', this.onClickEvent);\r\n this.contactRadioGroup.onChange(this.onPreferredContactMethodChange.bind(this));\r\n\r\n const userProfile = store.getState()?.userProfile || {};\r\n this.setRequiredAttributeInPhone(userProfile.preferredContactMethod);\r\n this.bindChangeEvents();\r\n }\r\n\r\n /**\r\n * bindChangeEvents: Get the form inputs then subscribe each OnChangeEvent to store and persist their values\r\n */\r\n bindChangeEvents() {\r\n const changeInputs = [\r\n this.emailAddressInput,\r\n this.fullNameInput,\r\n this.postalCodeInput,\r\n this.phoneNumberInput,\r\n ];\r\n changeInputs.forEach(input => input.getOnChangeEvent().subscribe(data =>\r\n store.dispatch(userProfileActions.update(data))));\r\n }\r\n\r\n onPreferredContactMethodChange(event) {\r\n const value = event.target.value;\r\n this.setRequiredAttributeInPhone(value);\r\n }\r\n\r\n setRequiredAttributeInPhone(value) {\r\n if (value === 'Phone' || value === 'Text Message') {\r\n this.phoneNumberInput.setRequired();\r\n return;\r\n }\r\n\r\n this.phoneNumberInput.removeRequired();\r\n }\r\n\r\n unbindEvents() {\r\n this.requestButton.getNode().removeEventListener('click', this.onClickEvent);\r\n }\r\n\r\n getForm() {\r\n return document.getElementById(this.formId);\r\n }\r\n\r\n getHtml() {\r\n return `\r\n
\r\n ${this.isPersistent ? backButton : ``}\r\n

Request A Tour

\r\n
\r\n
\r\n
\r\n Appointment Type\r\n
\r\n ${this.tourRadioOptions.getHtml()}\r\n
\r\n
\r\n ${this.dateInput.getHtml()}\r\n
\r\n
\r\n
\r\n ${this.fullNameInput.getHtml()}\r\n
\r\n
\r\n ${this.emailAddressInput.getHtml()}\r\n
\r\n
\r\n ${this.phoneNumberInput.getHtml()}\r\n
\r\n
\r\n ${this.postalCodeInput.getHtml()}\r\n
\r\n
\r\n Preferred Contact Method\r\n
\r\n ${this.contactRadioGroup.getHtml()}\r\n
\r\n
\r\n
\r\n ${this.requestButton.getHtml()}\r\n
\r\n
\r\n
\r\n ${privacyPolicyParagraph.replace(\"{0}\", \"Submit Request\")\r\n .replace(\"{1}\", this.housingData?.listingInformation?.brandName ?? \"the builder\")}\r\n
`;\r\n }\r\n}\r\n","import { store } from '@redux/store';\r\nimport GoogleAnalyticsCustomDimensions from 'constants/googleAnalyticsCustomDimension';\r\nimport GoogleAnalyticsEvent from 'dataTransferObjects/googleAnalyticsEvent';\r\nimport { userProfileActions } from 'features/userProfile';\r\nimport { backButton, privacyPolicyParagraph } from '../constants/sharedHtml';\r\nimport leadConstructor from '../services/leadConstructor';\r\nimport { postLeadBrochureForm } from '../services/taskFlow';\r\nimport CommentsTextArea from './commentsTextArea';\r\nimport ContactRadioGroup from './contactRadioGroup';\r\nimport EmailInput from './emailInput';\r\nimport InformationButton from './informationButton';\r\nimport NameInput from './nameInput';\r\nimport PhoneInput from './phoneInput';\r\nimport ZipInput from './zipInput';\r\n\r\n/* Creates a new instance of a Limited Availability Form to allow users to get more information on a lisiting. */\r\nexport default class BrochureFormLimitedAvailability {\r\n constructor() {\r\n const state = store.getState();\r\n const userProfile = state?.userProfile || {};\r\n this.id = state?.uiState.modalInformation.id;\r\n this.type = state?.uiState.modalInformation.type;\r\n this.excludeRecommendations = false;\r\n this.isPersistent = true;\r\n this.moreInformationButton = new InformationButton();\r\n this.commentsTextArea = new CommentsTextArea();\r\n this.emailAddressInput = new EmailInput();\r\n this.emailAddressInput.value = userProfile.email;\r\n this.formId = 'limitedAvailabilityForm';\r\n this.fullNameInput = new NameInput();\r\n this.fullNameInput.value = userProfile.name;\r\n this.contactRadioGroup = new ContactRadioGroup();\r\n this.contactRadioGroup.value = userProfile.preferredContactMethod;\r\n this.postalCodeInput = new ZipInput();\r\n this.postalCodeInput.value = userProfile.zip;\r\n this.postalCodeInput.isInternational = userProfile.livesOutside;\r\n this.phoneNumberInput = new PhoneInput();\r\n this.phoneNumberInput.value = userProfile.phone;\r\n this.onClickEvent = null;\r\n }\r\n\r\n /**\r\n * validateNode: Check if the field has a value as expected.\r\n * @param {Object} node Input to validate\r\n * @returns A boolean value indicating whether the input is valid or not.\r\n */\r\n static validateNode(node) {\r\n return node.validate();\r\n }\r\n\r\n /**\r\n * getFormOpenedAnalyticsData: Gets the object required for the Google Analytics events on form opened.\r\n * @param {Object} properties Information regarding to the listing.\r\n * @returns The Google Analtic event information.\r\n */\r\n static getFormOpenedAnalyticsData(properties) {\r\n const customDimensions = {};\r\n\r\n if (properties.marketId) {\r\n customDimensions[[GoogleAnalyticsCustomDimensions.MarketId().getName()]] = properties.marketId;\r\n }\r\n\r\n if (properties.marketName && properties.stateAbbreviation) {\r\n customDimensions[[GoogleAnalyticsCustomDimensions.MarketName().getName()]] = `${properties.marketName}, ${properties.stateAbbreviation}`;\r\n }\r\n\r\n if (properties.city) {\r\n customDimensions[[GoogleAnalyticsCustomDimensions.City().getName()]] = properties.city;\r\n }\r\n return new GoogleAnalyticsEvent(\r\n \"Lead_Events\",\r\n \"Search_Results_CTA_Free_Brochure\",\r\n \"Open_Form_Free_Brochure\",\r\n customDimensions);\r\n }\r\n\r\n /**\r\n * setHousingData: Sets the housing information for the form.\r\n * @param {Object} properties Information regarding to the listing.\r\n */\r\n setHousingData(properties = {}) {\r\n this.housingData = properties;\r\n }\r\n\r\n /**\r\n * submitBrochureForm: Process to validate and submit the form.\r\n * @param {event} event Click event.\r\n */\r\n submitBrochureForm(event) {\r\n event.preventDefault();\r\n\r\n const validationFunctions = [\r\n this.emailAddressInput,\r\n this.fullNameInput,\r\n this.postalCodeInput,\r\n this.phoneNumberInput,\r\n ];\r\n const result = validationFunctions.map(BrochureFormLimitedAvailability.validateNode);\r\n\r\n if (result.some((isValid) => !isValid)) {\r\n return;\r\n }\r\n\r\n this.moreInformationButton.getNode().disabled = 'disabled';\r\n const formData = new FormData(this.getForm());\r\n const brochureInformation = Object.fromEntries(formData.entries());\r\n\r\n brochureInformation.id = this.id;\r\n brochureInformation.type = `${this.type}-brochure`;\r\n\r\n const brochureLeadObject = leadConstructor(brochureInformation);\r\n brochureLeadObject.setHousingInformation?.(this.housingData.listingInformation);\r\n\r\n postLeadBrochureForm(brochureLeadObject);\r\n }\r\n\r\n /**\r\n * Sets the binding required for the form.\r\n */\r\n bindEvents() {\r\n this.onClickEvent = this.submitBrochureForm.bind(this);\r\n this.phoneNumberInput.bindEvents();\r\n this.postalCodeInput.bindEvents();\r\n this.moreInformationButton.getNode().addEventListener('click', this.onClickEvent);\r\n this.contactRadioGroup.onChange(this.onPreferredContactMethodChange.bind(this));\r\n\r\n const userProfile = store.getState()?.userProfile || {};\r\n this.setRequiredAttributeInPhone(userProfile.preferredContactMethod);\r\n this.bindChangeEvents();\r\n }\r\n\r\n /**\r\n * bindChangeEvents: Get the form inputs then subscribe each OnChangeEvent to store and persist their values\r\n */\r\n bindChangeEvents() {\r\n const changeInputs = [\r\n this.emailAddressInput,\r\n this.fullNameInput,\r\n this.postalCodeInput,\r\n this.phoneNumberInput,\r\n ];\r\n changeInputs.forEach(input => input.getOnChangeEvent().subscribe(data =>\r\n store.dispatch(userProfileActions.update(data))));\r\n }\r\n\r\n /**\r\n * Handles the change contact radio group event.\r\n * @param {event} event Change event.\r\n */\r\n onPreferredContactMethodChange(event) {\r\n const value = event.target.value;\r\n this.setRequiredAttributeInPhone(value);\r\n }\r\n\r\n /**\r\n * Sets the phone number input as required when it applies.\r\n * @param {string} value Contact option selected.\r\n */\r\n setRequiredAttributeInPhone(value) {\r\n if (value === 'Phone' || value === 'Text Message') {\r\n this.phoneNumberInput.setRequired();\r\n return;\r\n }\r\n\r\n this.phoneNumberInput.removeRequired();\r\n }\r\n\r\n /**\r\n * Removes the bindings that should not be still using.\r\n */\r\n unbindEvents() {\r\n this.moreInformationButton.getNode().removeEventListener('click', this.onClickEvent);\r\n }\r\n\r\n /**\r\n * getForm: Gets the form container \r\n * @returns A HTML element related to the form container.\r\n */\r\n getForm() {\r\n return document.getElementById(this.formId);\r\n }\r\n\r\n /**\r\n * Gets the HTML structure for the limited availability brochure form paid.\r\n * @returns The string with the HTML structure.\r\n */\r\n getHtml() {\r\n return `\r\n
\r\n ${this.isPersistent ? backButton : ``}\r\n

Limited Availability at this Community!

\r\n

\r\n Don't miss out! Get info and updates.\r\n You'll be put on the list for updates, and you can ask other questions about availability.

\r\n
\r\n
\r\n
\r\n ${this.fullNameInput.getHtml()}\r\n
\r\n
\r\n ${this.emailAddressInput.getHtml()}\r\n
\r\n
\r\n ${this.phoneNumberInput.getHtml()}\r\n
\r\n
\r\n ${this.postalCodeInput.getHtml()}\r\n
\r\n
\r\n Preferred Contact Method\r\n
\r\n ${this.contactRadioGroup.getHtml()}\r\n
\r\n
\r\n
\r\n ${this.commentsTextArea.getHtml()}\r\n
\r\n
\r\n ${this.moreInformationButton.getHtml()}\r\n
\r\n \r\n
\r\n
\r\n ${privacyPolicyParagraph.replace(\"{0}\", \"Get More Information\")\r\n .replace(\"{1}\", this.housingData?.listingInformation?.brandName ?? \"the builder\")}\r\n
`;\r\n }\r\n}\r\n","export default class AskQuestionButton {\r\n constructor() {\r\n this.id = 'askQuestionButton';\r\n }\r\n\r\n getHtml() {\r\n const styles = 'class=\"btn btn--yellow btn--width-100 btn--48-lg loading\"';\r\n return ``;\r\n }\r\n\r\n getNode() {\r\n return document.getElementById(this.id);\r\n }\r\n}\r\n","import { store } from '@redux/store';\r\nimport GoogleAnalyticsCustomDimensions from 'constants/googleAnalyticsCustomDimension';\r\nimport GoogleAnalyticsEvent from 'dataTransferObjects/googleAnalyticsEvent';\r\nimport { userProfileActions } from 'features/userProfile';\r\nimport { closeButton, privacyPolicyParagraph } from '../constants/sharedHtml';\r\nimport leadConstructor from '../services/leadConstructor';\r\nimport { postLeadAskQuestionForm } from '../services/taskFlow';\r\nimport AskQuestionButton from './askQuestionButton';\r\nimport CommentsTextArea from './commentsTextArea';\r\nimport EmailInput from './emailInput';\r\nimport NameInput from './nameInput';\r\nimport PhoneInput from './phoneInput';\r\nimport ZipInput from './zipInput';\r\nimport RealtorDropdown from './realtorDropdown';\r\n\r\n/* Creates a new instance of a Ask Question Form to allow users asking question about the selected housing unit. */\r\nexport default class AskQuestionFormPaid {\r\n\tconstructor() {\r\n\t\tconst state = store.getState();\r\n\t\tconst userProfile = state?.userProfile || {};\r\n\t\tthis.id = state?.uiState.modalInformation.id;\r\n\t\tthis.type = state?.uiState.modalInformation.type;\r\n\t\tthis.fromPage = state?.uiState.modalInformation.fromPage;\r\n\t\tthis.excludeRecommendations = false;\r\n\t\tthis.getAskQuestionButton = new AskQuestionButton();\r\n\t\tthis.commentsTextArea = new CommentsTextArea();\r\n\t\tthis.emailAddressInput = new EmailInput();\r\n\t\tthis.emailAddressInput.value = userProfile.email;\r\n\t\tthis.formId = 'askQuestionFormPaid';\r\n\t\tthis.fullNameInput = new NameInput();\r\n\t\tthis.fullNameInput.value = userProfile.name;\r\n\t\tthis.phoneNumberInput = new PhoneInput();\r\n\t\tthis.phoneNumberInput.value = userProfile.phone;\r\n\t\tthis.postalCodeInput = new ZipInput();\r\n\t\tthis.postalCodeInput.value = userProfile.zip;\r\n\t\tthis.postalCodeInput.isInternational = userProfile.livesOutside;\r\n this.realtorDropdown = new RealtorDropdown();\r\n this.realtorDropdown.value = userProfile.realtorQuestion;\r\n\t\tthis.onClickEvent = null;\r\n\t}\r\n\r\n\t/**\r\n\t\t* validateNode: Check if the field has a value as expected.\r\n\t\t* @param {Object} node Input to validate\r\n\t\t* @returns A boolean value indicating whether the input is valid or not.\r\n\t\t*/\r\n\tstatic validateNode(node) {\r\n\t\treturn node.validate();\r\n\t}\r\n\r\n\t/**\r\n\t\t* getFormOpenedAnalyticsData: Gets the object required for the Google Analytics events on form opened.\r\n\t\t* @param {Object} properties Information regarding to the listing.\r\n\t\t* @returns The Google Analtic event information.\r\n\t\t*/\r\n\tstatic getFormOpenedAnalyticsData(properties) {\r\n\t\tconst customDimensions = {};\r\n\r\n\t\tif (properties.marketId) {\r\n\t\t\tcustomDimensions[[GoogleAnalyticsCustomDimensions.MarketId().getName()]] = properties.marketId;\r\n\t\t}\r\n\r\n\t\tif (properties.marketName && properties.stateAbbreviation) {\r\n\t\t\tcustomDimensions[\r\n\t\t\t\t[GoogleAnalyticsCustomDimensions.MarketName().getName()]\r\n\t\t\t] = `${properties.marketName}, ${properties.stateAbbreviation}`;\r\n\t\t}\r\n\r\n\t\tif (properties.city) {\r\n\t\t\tcustomDimensions[[GoogleAnalyticsCustomDimensions.City().getName()]] = properties.city;\r\n\t\t}\r\n\r\n\t\treturn new GoogleAnalyticsEvent(\r\n\t\t\t'Lead Events',\r\n\t\t\t'Search Results CTA Ask Question',\r\n\t\t\t'Open Form - Ask Question',\r\n\t\t\tcustomDimensions\r\n\t\t);\r\n\t}\r\n\r\n\t/**\r\n\t\t* setHousingData: Sets the housing information for the form.\r\n\t\t* @param {Object} properties Information regarding to the listing.\r\n\t\t*/\r\n\tsetHousingData(properties = {}) {\r\n\t\tthis.housingData = properties;\r\n\t}\r\n\r\n\t/**\r\n\t\t* submitAskQuestionForm: Process to validate and submit the form.\r\n\t\t* @param {event} event Click event.\r\n\t\t*/\r\n\tsubmitAskQuestionForm(event) {\r\n\t\tevent.preventDefault();\r\n\r\n\t\tconst validationFunctions = [\r\n\t\t\tthis.emailAddressInput,\r\n\t\t\tthis.fullNameInput,\r\n\t\t\tthis.postalCodeInput,\r\n\t\t\tthis.phoneNumberInput,\r\n\t\t];\r\n\t\tconst result = validationFunctions.map(AskQuestionFormPaid.validateNode);\r\n\r\n\t\tif (result.some((isValid) => !isValid)) {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tthis.getAskQuestionButton.getNode().disabled = 'disabled';\r\n\t\tconst formData = new FormData(this.getForm());\r\n\t\tconst formInformation = Object.fromEntries(formData.entries());\r\n\r\n\t\tformInformation.id = this.id;\r\n\t\tformInformation.type = `${this.type}-brochure`;\r\n\t\tformInformation.excludeRecommendations = this.excludeRecommendations;\r\n\t\tformInformation.fromPage = this.housingData.fromPage;\r\n\r\n\t\tconst leadObject = leadConstructor(formInformation);\r\n\t\tleadObject.setHousingInformation?.(this.housingData.listingInformation);\r\n\r\n\t\tpostLeadAskQuestionForm(leadObject);\r\n\t}\r\n\r\n\t/**\r\n\t\t* Sets the binding required for the form.\r\n\t\t*/\r\n\tbindEvents() {\r\n\t\tthis.onClickEvent = this.submitAskQuestionForm.bind(this);\r\n\t\tthis.phoneNumberInput.bindEvents();\r\n\t\tthis.postalCodeInput.bindEvents();\r\n\t\tif (this.fullNameInput.value === '') {\r\n\t\t\tthis.fullNameInput.focus();\r\n\t\t}\r\n this.realtorDropdown.setSelectedValue();\r\n\t\tthis.getAskQuestionButton.getNode().addEventListener('click', this.onClickEvent);\r\n\t\tthis.bindChangeEvents();\r\n\t}\r\n\r\n\t/**\r\n\t\t* bindChangeEvents: Get the form inputs then subscribe each OnChangeEvent to store and persist their values\r\n\t\t*/\r\n\tbindChangeEvents() {\r\n\t\tconst changeInputs = [\r\n\t\t\tthis.emailAddressInput,\r\n\t\t\tthis.fullNameInput,\r\n\t\t\tthis.postalCodeInput,\r\n\t\t\tthis.phoneNumberInput,\r\n this.realtorDropdown,\r\n\t\t];\r\n\t\tchangeInputs.forEach(input => input.getOnChangeEvent().subscribe(data =>\r\n\t\t\tstore.dispatch(userProfileActions.update(data))));\r\n\t}\r\n\r\n\t/**\r\n\t\t* Removes the bindings that should not be still using.\r\n\t\t*/\r\n\tunbindEvents() {\r\n\t\tthis.getAskQuestionButton.getNode().removeEventListener('click', this.onClickEvent);\r\n\t}\r\n\r\n\t/**\r\n\t\t* getForm: Gets the form container \r\n\t\t* @returns A HTML element related to the form container.\r\n\t\t*/\r\n\tgetForm() {\r\n\t\treturn document.getElementById(this.formId);\r\n\t}\r\n\r\n\t/**\r\n\t\t* Gets the HTML structure for the ask question form paid.\r\n\t\t* @returns The string with the HTML structure.\r\n\t\t*/\r\n\tgetHtml() {\r\n return `\r\n
\r\n ${closeButton}\r\n

Ask a question

\r\n
\r\n
\r\n
\r\n ${this.fullNameInput.getHtml()}\r\n
\r\n
\r\n ${this.emailAddressInput.getHtml()}\r\n
\r\n
\r\n ${this.phoneNumberInput.getHtml()}\r\n
\r\n
\r\n ${this.postalCodeInput.getHtml()}\r\n
\r\n
\r\n ${this.realtorDropdown.getHtml()}\r\n
\r\n
\r\n ${this.commentsTextArea.getHtml()}\r\n
\r\n
\r\n ${this.getAskQuestionButton.getHtml()}\r\n
\r\n \r\n
\r\n
\r\n ${privacyPolicyParagraph.replace(\"{0}\", \"Ask Question\")\r\n .replace(\"{1}\", this.housingData?.listingInformation?.brandName ?? \"the builder\")}\r\n
`;\r\n }\r\n}\r\n","import { store } from '@redux/store';\r\nimport GoogleAnalyticsCustomDimensions from 'constants/googleAnalyticsCustomDimension';\r\nimport GoogleAnalyticsEvent from 'dataTransferObjects/googleAnalyticsEvent';\r\nimport { userProfileActions } from 'features/userProfile';\r\nimport { closeButton, privacyPolicyParagraph } from '../constants/sharedHtml';\r\nimport leadConstructor from '../services/leadConstructor';\r\nimport { postLeadBrochureForm } from '../services/taskFlow';\r\nimport BrochureButton from './brochureButton';\r\nimport CommentsTextArea from './commentsTextArea';\r\nimport EmailInput from './emailInput';\r\nimport NameInput from './nameInput';\r\nimport PhoneInput from './phoneInput';\r\nimport ZipInput from './zipInput';\r\nimport RealtorDropdown from './realtorDropdown';\r\n\r\n/* Creates a new instance of a Brochure form paid version to manage the Manufactured product type listings. */\r\nexport default class ManufacturedBrochureFormPaid {\r\n\tconstructor() {\r\n\t\tconst state = store.getState();\r\n\t\tconst userProfile = state?.userProfile || {};\r\n\t\tthis.id = state?.uiState.modalInformation.id;\r\n\t\tthis.type = state?.uiState.modalInformation.type;\r\n\t\tthis.fromPage = state?.uiState.modalInformation.fromPage;\r\n\t\tthis.excludeRecommendations = true;\r\n\t\tthis.getBrochureButton = new BrochureButton();\r\n\t\tthis.commentsTextArea = new CommentsTextArea();\r\n\t\tthis.emailAddressInput = new EmailInput();\r\n\t\tthis.emailAddressInput.value = userProfile.email;\r\n\t\tthis.formId = 'manufacturedBrochureFormPaid';\r\n\t\tthis.fullNameInput = new NameInput();\r\n\t\tthis.fullNameInput.value = userProfile.name;\r\n\t\tthis.phoneNumberInput = new PhoneInput();\r\n\t\tthis.phoneNumberInput.value = userProfile.phone;\r\n\t\tthis.postalCodeInput = new ZipInput();\r\n\t\tthis.postalCodeInput.value = userProfile.zip;\r\n\t\tthis.postalCodeInput.isInternational = userProfile.livesOutside;\r\n this.realtorDropdown = new RealtorDropdown();\r\n this.realtorDropdown.value = userProfile.realtorQuestion;\r\n\t\tthis.onClickEvent = null;\r\n\t}\r\n\r\n\t/**\r\n\t * validateNode: Check if the field has a value as expected.\r\n\t * @param {Object} node Input to validate\r\n\t * @returns A boolean value indicating whether the input is valid or not.\r\n\t */\r\n\tstatic validateNode(node) {\r\n\t\treturn node.validate();\r\n\t}\r\n\r\n\t/**\r\n\t * getFormOpenedAnalyticsData: Gets the object required for the Google Analytics events on form opened.\r\n\t * @param {Object} properties Information regarding to the listing.\r\n\t * @returns The Google Analtic event information.\r\n\t */\r\n\tstatic getFormOpenedAnalyticsData(properties) {\r\n\t\tconst customDimensions = {};\r\n\r\n\t\tif (properties.marketId) {\r\n\t\t\tcustomDimensions[[GoogleAnalyticsCustomDimensions.MarketId().getName()]] = properties.marketId;\r\n\t\t}\r\n\r\n\t\tif (properties.marketName && properties.stateAbbreviation) {\r\n\t\t\tcustomDimensions[[GoogleAnalyticsCustomDimensions.MarketName().getName()]] = `${properties.marketName}, ${properties.stateAbbreviation}`;\r\n\t\t}\r\n\r\n\t\tif (properties.city) {\r\n\t\t\tcustomDimensions[[GoogleAnalyticsCustomDimensions.City().getName()]] = properties.city;\r\n\t\t}\r\n\r\n\t\treturn new GoogleAnalyticsEvent(\r\n\t\t\t\"Lead Events\",\r\n\t\t\t\"Search Results CTA Free Brochure\",\r\n\t\t\t\"Open Form - Free Brochure\",\r\n\t\t\tcustomDimensions);\r\n\t}\r\n\r\n\t/**\r\n\t * setHousingData: Sets the housing information for the form.\r\n\t * @param {Object} properties Information regarding to the listing.\r\n\t */\r\n\tsetHousingData(properties = {}) {\r\n\t\tthis.housingData = properties;\r\n\t}\r\n\r\n\t/**\r\n\t * submitBrochureForm: Process to validate and submit the form.\r\n\t * @param {event} event Click event.\r\n\t */\r\n\tsubmitBrochureForm(event) {\r\n\t\tevent.preventDefault();\r\n\r\n\t\tconst validationFunctions = [\r\n\t\t\tthis.emailAddressInput,\r\n\t\t\tthis.fullNameInput,\r\n\t\t\tthis.postalCodeInput,\r\n\t\t\tthis.phoneNumberInput,\r\n\t\t];\r\n\t\tconst result = validationFunctions.map(ManufacturedBrochureFormPaid.validateNode);\r\n\t\tconst isSomeInvalidField = result.some((isValid) => !isValid);\r\n\t\tif (isSomeInvalidField) {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tthis.getBrochureButton.getNode().disabled = 'disabled';\r\n\t\tconst formData = new FormData(this.getForm());\r\n\t\tconst brochureInformation = Object.fromEntries(formData.entries());\r\n\r\n\t\tbrochureInformation.id = this.id;\r\n\t\tbrochureInformation.type = `${this.type}-brochure`;\r\n\t\tbrochureInformation.excludeRecommendations = this.excludeRecommendations;\r\n\t\tbrochureInformation.fromPage = this.housingData.fromPage;\r\n\r\n\t\tconst brochureLeadObject = leadConstructor(brochureInformation);\r\n\t\tbrochureLeadObject.setHousingInformation?.(this.housingData.listingInformation);\r\n\r\n\t\tpostLeadBrochureForm(brochureLeadObject);\r\n\t}\r\n\r\n\t/**\r\n\t * Sets the binding required for the form.\r\n\t */\r\n\tbindEvents() {\r\n\t\tthis.onClickEvent = this.submitBrochureForm.bind(this);\r\n\t\tthis.phoneNumberInput.bindEvents();\r\n\t\tthis.postalCodeInput.bindEvents();\r\n\t\tif (this.fullNameInput.value === '') {\r\n\t\t\tthis.fullNameInput.focus();\r\n\t\t}\r\n this.realtorDropdown.setSelectedValue();\r\n\t\tthis.getBrochureButton.getNode().addEventListener('click', this.onClickEvent);\r\n\t\tthis.bindChangeEvents();\r\n\t}\r\n\r\n\t/**\r\n\t * bindChangeEvents: Get the form inputs then subscribe each OnChangeEvent to store and persist their values\r\n\t */\r\n\tbindChangeEvents() {\r\n\t\tconst changeInputs = [\r\n\t\t\tthis.emailAddressInput,\r\n\t\t\tthis.fullNameInput,\r\n\t\t\tthis.postalCodeInput,\r\n\t\t\tthis.phoneNumberInput,\r\n this.realtorDropdown,\r\n\t\t];\r\n\t\tchangeInputs.forEach(input => input.getOnChangeEvent().subscribe(data =>\r\n\t\t\tstore.dispatch(userProfileActions.update(data))));\r\n\t}\r\n\r\n\t/**\r\n\t * Removes the bindings that should not be still using.\r\n\t */\r\n\tunbindEvents() {\r\n\t\tthis.getBrochureButton.getNode().removeEventListener('click', this.onClickEvent);\r\n\t}\r\n\r\n\t/**\r\n\t * getForm: Gets the form container \r\n\t * @returns A HTML element related to the form container.\r\n\t */\r\n\tgetForm() {\r\n\t\treturn document.getElementById(this.formId);\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the HTML structure for the manufactured brochure form paid.\r\n\t * @returns The string with the HTML structure.\r\n\t */\r\n\tgetHtml() {\r\n\t\treturn `\r\n
\r\n ${closeButton}\r\n

Check your email & download the brochure

\r\n
\r\n
\r\n
\r\n ${this.fullNameInput.getHtml()}\r\n
\r\n
\r\n ${this.emailAddressInput.getHtml()}\r\n
\r\n
\r\n ${this.phoneNumberInput.getHtml()}\r\n
\r\n
\r\n ${this.postalCodeInput.getHtml()}\r\n
\r\n
\r\n ${this.realtorDropdown.getHtml()}\r\n
\r\n
\r\n ${this.commentsTextArea.getHtml()}\r\n
\r\n
\r\n ${this.getBrochureButton.getHtml()}\r\n
\r\n \r\n
\r\n
\r\n ${privacyPolicyParagraph.replace(\"{0}\", \"Get Brochure\")\r\n .replace(\"{1}\", this.housingData?.listingInformation?.brandName ?? \"the builder\")}\r\n
`;\r\n\t}\r\n}\r\n","import BrochureFormPaid from '../components/brochureFormPaid';\r\nimport InformationFormBasic from '../components/informationFormBasic';\r\nimport InformationFormPaid from '../components/informationFormPaid';\r\nimport RequestTourForm from '../components/requestTourForm';\r\nimport BrochureFormLimitedAvailability from '../components/brochureFormLimitedAvailability';\r\nimport LeadFormType from '../enums/leadFormType';\r\nimport AskQuestionFormPaid from '../components/askQuestionFormPaid';\r\nimport ManufacturedBrochureFormPaid from '../components/manufacturedBrochureFormPaid';\r\n\r\nconst leadGeneratorConstructors = new Map();\r\n\r\nleadGeneratorConstructors.set(LeadFormType.BrochureFormPaid.toString(), BrochureFormPaid);\r\nleadGeneratorConstructors.set(LeadFormType.InformationFormPaid.toString(), InformationFormPaid);\r\nleadGeneratorConstructors.set(LeadFormType.RequestTourForm.toString(), RequestTourForm);\r\nleadGeneratorConstructors.set(LeadFormType.BrochureFormLimitedAvailability.toString(), BrochureFormLimitedAvailability);\r\nleadGeneratorConstructors.set(LeadFormType.InformationFormBasic.toString(), InformationFormBasic);\r\nleadGeneratorConstructors.set(LeadFormType.AskQuestionFormPaid.toString(), AskQuestionFormPaid);\r\nleadGeneratorConstructors.set(LeadFormType.ManufacturedBrochureFormPaid.toString(), ManufacturedBrochureFormPaid);\r\n\r\n/**\r\n * Returns the class constructor to create a lead generator.\r\n *\r\n * @param leadGeneratorName - The name of the lead generator requested.\r\n */\r\nexport default (leadGeneratorName, properties) => {\r\n const generator = leadGeneratorConstructors.get(leadGeneratorName);\r\n\r\n if (!generator) {\r\n return null;\r\n }\r\n\r\n return new generator.prototype.constructor(properties);\r\n};\r\n","export default class RecommendedButton {\r\n constructor() {\r\n this.id = 'getRecommendedBrochureButton';\r\n }\r\n\r\n getHtml() {\r\n return ``;\r\n }\r\n\r\n getNode() {\r\n return document.getElementById(this.id);\r\n }\r\n}\r\n","export default class SkipButton {\r\n constructor() {\r\n this.id = 'skipRecommendation';\r\n }\r\n\r\n getHtml() {\r\n return ``;\r\n }\r\n\r\n getNode() {\r\n return document.getElementById(this.id);\r\n }\r\n}\r\n","import {\r\n closeModalIconSvg,\r\n thanksContentIconSvg,\r\n thankYouEmailSvg, \r\n thankYouHeartSvg, \r\n thankYouPhoneSvg, \r\n thankYouSuccessSvg\r\n} from 'constants/svg-assets.js';\r\n\r\nexport const closeModalSvg = closeModalIconSvg;\r\nexport const thanksContentSvg = thanksContentIconSvg;\r\nexport const thankYouEmail = thankYouEmailSvg;\r\nexport const thankYouHeart = thankYouHeartSvg;\r\nexport const thankYouPhone = thankYouPhoneSvg;\r\nexport const thankYouSuccess = thankYouSuccessSvg;\r\n","import { store } from '@redux/store';\r\nimport GoogleAnalyticsEvent from 'dataTransferObjects/googleAnalyticsEvent';\r\nimport uiStateSlice from 'layout/redux/uiStateSlice';\r\nimport modalService from 'layout/services/modalService';\r\nimport brochureLeadConstructor from '../services/leadConstructor';\r\nimport { postRecommendedLeadForm, updateModalProgress } from '../services/taskFlow';\r\nimport RecommendedButton from './recommendedButton';\r\nimport SkipButton from './skipButton';\r\nimport { closeModalSvg } from '../constants/svgIcons';\r\nimport { recommendedPolicyParagraph } from '../constants/sharedHtml';\r\n\r\nexport default class RecommendedScreen {\r\n constructor(recommendationsHtml) {\r\n this.closeAttribute = '[data-close]';\r\n this.formId = 'get-recommended-communities';\r\n this.getBrochureButton = new RecommendedButton();\r\n this.id = store.getState().uiState.modalInformation.id;\r\n this.onClickEvent = null;\r\n this.onSkipEvent = null;\r\n this.recommendationsHtml = recommendationsHtml;\r\n this.recommendedCheckAttribute = '[data-recommendation-check]';\r\n this.skipButton = new SkipButton();\r\n this.type = 'recommended';\r\n }\r\n\r\n /**\r\n * Submits information for recommended communities selected by the user.\r\n * @param {*} event that triggered this action\r\n */\r\n submitRecommendationsForm(event) {\r\n event.preventDefault();\r\n\r\n const formData = new FormData(this.getForm());\r\n const brochureInformation = Object.fromEntries(formData.entries());\r\n const state = store.getState();\r\n const userProfile = state?.userProfile;\r\n brochureInformation.id = this.id;\r\n brochureInformation.type = this.type;\r\n\r\n // we fill the user information with \r\n // the data captured in the previous form.\r\n brochureInformation.email = userProfile.email;\r\n brochureInformation.postalCode = userProfile.zip;\r\n brochureInformation.international = userProfile.livesOutside;\r\n brochureInformation.phone = userProfile.phone;\r\n\r\n const userName = userProfile.name.split(' ');\r\n brochureInformation.firstName = userName[0];\r\n brochureInformation.lastName = userName.slice(1).join(\" \").trim();\r\n brochureInformation.fromPage = state?.uiState?.modalInformation?.fromPage;\r\n\r\n const brochureLeadObject = brochureLeadConstructor(brochureInformation);\r\n\r\n const modalInformation = this.getThankYouModalInformation(brochureLeadObject.recoComms);\r\n store.dispatch(uiStateSlice.actions.modalInformation(modalInformation));\r\n\r\n postRecommendedLeadForm(brochureLeadObject);\r\n }\r\n\r\n /**\r\n * Binds the events needed so recommended screen can respond to user interactions.\r\n */\r\n bindEvents() {\r\n this.onClickEvent = this.submitRecommendationsForm.bind(this);\r\n this.onSkipEvent = this.skipModal.bind(this);\r\n\r\n const getRecoBrochureElement = this.getBrochureButton.getNode();\r\n getRecoBrochureElement?.addEventListener('click', this.onClickEvent);\r\n\r\n const skipElement = this.skipButton.getNode();\r\n skipElement?.addEventListener('click', this.onSkipEvent);\r\n\r\n const closeElements = document.querySelectorAll(this.closeAttribute);\r\n closeElements.forEach((element) => element.addEventListener('click', RecommendedScreen.closeModal));\r\n\r\n const recommendedElements = document.querySelectorAll(this.recommendedCheckAttribute);\r\n recommendedElements.forEach((elem) =>\r\n elem?.addEventListener('click', this.onRecommendationChecked.bind(this)));\r\n }\r\n\r\n /**\r\n * Unbinds the events needed so recommended screen can respond to user interactions.\r\n */\r\n unbindEvents() {\r\n this.skipButton.getNode().removeEventListener('click', this.onSkipEvent);\r\n this.getBrochureButton.getNode().removeEventListener('click', this.onClickEvent);\r\n const recommendedElements = document.querySelectorAll(this.recommendedCheckAttribute);\r\n recommendedElements.forEach((elem) => {\r\n elem.click = null\r\n });\r\n }\r\n\r\n /**\r\n * Skips the recommended modal step since the user is not interested in any of the\r\n * recommendations provided.\r\n */\r\n skipModal(event) {\r\n event.preventDefault();\r\n const modalInformation = this.getThankYouModalInformation();\r\n modalInformation.googleAnalyticsDTO =\r\n new GoogleAnalyticsEvent(\"Lead Events\", \"Form Skip\", \"Search - FB - Dir Rec\");\r\n updateModalProgress(modalInformation);\r\n }\r\n\r\n /**\r\n * \r\n * Validates if there's at least 1 recommendation selected. If that's not the case,\r\n * disables the brochure button.\r\n */\r\n onRecommendationChecked() {\r\n const checkedRecos = this.getForm().querySelectorAll(`${this.recommendedCheckAttribute}:checked`);\r\n if (checkedRecos.length === 0) {\r\n this.getBrochureButton.getNode().disabled = true;\r\n return;\r\n }\r\n\r\n this.getBrochureButton.getNode().disabled = false;\r\n }\r\n\r\n static closeModal() {\r\n modalService.clearHtml();\r\n }\r\n\r\n /**\r\n * \r\n * @returns the DOM element representing the recommendations form.\r\n */\r\n getForm() {\r\n return document.getElementById(this.formId);\r\n }\r\n\r\n /**\r\n * \r\n * @returns an object with the information to move to thank you screen\r\n */\r\n getThankYouModalInformation(recommendedCommunities) {\r\n return {\r\n id: this.id,\r\n name: 'thankYouScreen',\r\n selectedRecommendedCommunities: recommendedCommunities,\r\n };\r\n }\r\n\r\n /**\r\n * Returns an array of unique recommended brands from the recommendationsHtml property.\r\n * @returns {string[]} An array of unique recommended brands.\r\n */\r\n getRecommendedBrands() {\r\n const parser = new DOMParser();\r\n const doc = parser.parseFromString(this.recommendationsHtml, 'text/html');\r\n const brandElements = doc.querySelectorAll('.result__brand');\r\n const brands = [];\r\n brandElements.forEach((el) => {\r\n const brand = el.textContent.trim();\r\n\r\n // Only count unique brands\r\n if (!brands.includes(brand)) {\r\n brands.push(brand);\r\n }\r\n });\r\n return brands;\r\n }\r\n\r\n /**\r\n * \r\n * @returns the HTML that represents the recommendations screen.\r\n */\r\n getHtml() {\r\n return `\r\n
\r\n \r\n

Discover More Great Communities

\r\n

Select additional listings for more information

\r\n
\r\n
\r\n
\r\n ${this.recommendationsHtml}\r\n
\r\n
\r\n ${this.skipButton.getHtml()}\r\n ${this.getBrochureButton.getHtml()}\r\n
\r\n
\r\n
\r\n ${recommendedPolicyParagraph.replace(\"{0}\", \"Get More Info\")}\r\n
`;\r\n }\r\n}","export default class RecommendedButtonBasic {\r\n constructor() {\r\n this.id = 'getRecommendedBrochureButton';\r\n }\r\n\r\n /**\r\n * \r\n * @returns the HTML that represents the basic recommendation modal button.\r\n */\r\n getHtml() {\r\n return ``;\r\n }\r\n\r\n /**\r\n * \r\n * @returns the HTML button in the element with the corresponding id.\r\n */\r\n getNode() {\r\n return document.getElementById(this.id);\r\n }\r\n}","import { store } from '@redux/store';\r\nimport GoogleAnalyticsEvent from 'dataTransferObjects/googleAnalyticsEvent';\r\nimport uiStateSlice from 'layout/redux/uiStateSlice';\r\nimport modalService from 'layout/services/modalService';\r\nimport brochureLeadConstructor from '../services/leadConstructor';\r\nimport { postRecommendedLeadForm, updateModalProgress } from '../services/taskFlow';\r\nimport RecommendedButtonBasic from './recommendedButtonBasic';\r\nimport SkipButton from './skipButton';\r\nimport { closeModalSvg } from '../constants/svgIcons';\r\nimport { recommendedPolicyParagraph } from '../constants/sharedHtml';\r\n\r\nexport default class RecommendedScreenBasic {\r\n constructor(recommendationsHtml) {\r\n this.closeAttribute = '[data-close]';\r\n this.formId = 'get-recommended-communities';\r\n this.getBrochureButtonBasic = new RecommendedButtonBasic();\r\n this.id = store.getState().uiState.modalInformation.id;\r\n this.onClickEvent = null;\r\n this.onSkipEvent = null;\r\n this.recommendationsHtml = recommendationsHtml;\r\n this.recommendedCheckAttribute = '[data-recommendation-check]';\r\n this.skipButton = new SkipButton();\r\n this.type = 'recommended';\r\n }\r\n\r\n /**\r\n * Submits information for recommended communities selected by the user.\r\n * @param {*} event that triggered this action\r\n */\r\n submitRecommendationsForm(event) {\r\n event.preventDefault();\r\n\r\n const formData = new FormData(this.getForm());\r\n const brochureInformation = Object.fromEntries(formData.entries());\r\n const state = store.getState();\r\n const userProfile = state?.userProfile;\r\n brochureInformation.id = this.id;\r\n brochureInformation.type = this.type;\r\n\r\n // we fill the user information with \r\n // the data captured in the previous form.\r\n brochureInformation.email = userProfile.email;\r\n brochureInformation.postalCode = userProfile.zip;\r\n brochureInformation.international = userProfile.livesOutside;\r\n brochureInformation.phone = userProfile.phone;\r\n\r\n const userName = userProfile.name.split(' ');\r\n brochureInformation.firstName = userName[0];\r\n brochureInformation.lastName = userName.slice(1).join(\" \").trim();\r\n brochureInformation.fromPage = state?.uiState?.modalInformation?.fromPage;\r\n\r\n const brochureLeadObject = brochureLeadConstructor(brochureInformation);\r\n\r\n const modalInformation = this.getThankYouModalInformation(brochureLeadObject.recoComms);\r\n store.dispatch(uiStateSlice.actions.modalInformation(modalInformation));\r\n\r\n postRecommendedLeadForm(brochureLeadObject);\r\n }\r\n\r\n /**\r\n * Binds the events needed so recommended screen can respond to user interactions.\r\n */\r\n bindEvents() {\r\n this.onClickEvent = this.submitRecommendationsForm.bind(this);\r\n this.onSkipEvent = this.skipModal.bind(this);\r\n\r\n const getRecoBrochureElement = this.getBrochureButtonBasic.getNode();\r\n getRecoBrochureElement?.addEventListener('click', this.onClickEvent);\r\n\r\n const skipElement = this.skipButton.getNode();\r\n skipElement?.addEventListener('click', this.onSkipEvent);\r\n\r\n const closeElements = document.querySelectorAll(this.closeAttribute);\r\n closeElements.forEach((element) => element.addEventListener('click', RecommendedScreenBasic.closeModal));\r\n\r\n const recommendedElements = document.querySelectorAll(this.recommendedCheckAttribute);\r\n recommendedElements.forEach((elem) =>\r\n elem?.addEventListener('click', this.onRecommendationChecked.bind(this)));\r\n }\r\n\r\n /**\r\n * Unbinds the events needed so recommended screen can respond to user interactions.\r\n */\r\n unbindEvents() {\r\n this.skipButton.getNode().removeEventListener('click', this.onSkipEvent);\r\n this.getBrochureButtonBasic.getNode().removeEventListener('click', this.onClickEvent);\r\n const recommendedElements = document.querySelectorAll(this.recommendedCheckAttribute);\r\n recommendedElements.forEach((elem) => {\r\n elem.click = null\r\n });\r\n }\r\n\r\n /**\r\n * Skips the recommended modal step since the user is not interested in any of the\r\n * recommendations provided.\r\n */\r\n skipModal(event) {\r\n event.preventDefault();\r\n const modalInformation = this.getThankYouModalInformation();\r\n modalInformation.googleAnalyticsDTO = new GoogleAnalyticsEvent(\"Lead Events\", \"Form Skip\", \r\n \"Search - LM - Dir Rec\");\r\n updateModalProgress(modalInformation);\r\n }\r\n\r\n /**\r\n * \r\n * Validates if there's at least 1 recommendation selected. If that's not the case,\r\n * disables the brochure button.\r\n */\r\n onRecommendationChecked() {\r\n const checkedRecos = this.getForm().querySelectorAll(`${this.recommendedCheckAttribute}:checked`);\r\n if (checkedRecos.length === 0) {\r\n this.getBrochureButtonBasic.getNode().disabled = true;\r\n return;\r\n }\r\n\r\n this.getBrochureButtonBasic.getNode().disabled = false;\r\n }\r\n\r\n static closeModal() {\r\n modalService.clearHtml();\r\n }\r\n\r\n /**\r\n * \r\n * @returns the DOM element representing the recommendations form.\r\n */\r\n getForm() {\r\n return document.getElementById(this.formId);\r\n }\r\n\r\n /**\r\n * \r\n * @returns an object with the information to move to thank you screen\r\n */\r\n getThankYouModalInformation(recommendedCommunities) {\r\n return {\r\n id: this.id,\r\n name: 'thankYouScreen',\r\n selectedRecommendedCommunities: recommendedCommunities,\r\n };\r\n }\r\n\r\n /**\r\n * Returns an array of unique recommended brands from the recommendationsHtml property.\r\n * @returns {string[]} An array of unique recommended brands.\r\n */\r\n getRecomendedBrands() {\r\n const parser = new DOMParser();\r\n const doc = parser.parseFromString(this.recommendationsHtml, 'text/html');\r\n const brandElements = doc.querySelectorAll('.result__brand');\r\n const brands = [];\r\n brandElements.forEach((el) => {\r\n const brand = el.textContent.trim();\r\n\r\n // Only count unique brands\r\n if (!brands.includes(brand)) {\r\n brands.push(brand);\r\n }\r\n });\r\n return brands;\r\n }\r\n\r\n /**\r\n * \r\n * @returns the HTML that represents the recommendations screen.\r\n */\r\n getHtml() {\r\n return `\r\n
\r\n \r\n

Discover More Great Communities

\r\n

Select additional listings for more information

\r\n
\r\n
\r\n
\r\n ${this.recommendationsHtml}\r\n
\r\n
\r\n ${this.skipButton.getHtml()}\r\n ${this.getBrochureButtonBasic.getHtml()}\r\n
\r\n
\r\n
\r\n ${recommendedPolicyParagraph.replace(\"{0}\", \"I'm Interested\")}\r\n
`;\r\n }\r\n}","import { store } from '@redux/store';\r\nimport GoogleAnalyticsEvent from 'dataTransferObjects/googleAnalyticsEvent';\r\nimport uiStateSlice from 'layout/redux/uiStateSlice';\r\nimport modalService from 'layout/services/modalService';\r\nimport { closeModalSvg, thanksContentSvg } from '../constants/svgIcons';\r\nimport DetailsAnchor from './detailsAnchor';\r\n\r\nexport default class ThankScreenAskQuestion {\r\n constructor() {\r\n const state = store.getState();\r\n const modalInformation = state?.uiState?.modalInformation;\r\n const listingInformation = modalInformation?.listingInformation;\r\n this.url = modalInformation?.url;\r\n this.builderName = listingInformation?.brandName ?? 'the builder';\r\n this.marketId = listingInformation?.marketId;\r\n this.closeAttribute = '[data-close]';\r\n this.moreDetailsAnchor = new DetailsAnchor();\r\n this.moreDetailsAnchor.setUrl(this.url);\r\n this.moreDetailsAnchor.setListingId(listingInformation.id);\r\n this.moreDetailsAnchor.setListingType(listingInformation.type);\r\n }\r\n\r\n emitMoreDetailsClickEvent() {\r\n const googleAnalyticsDTO = new GoogleAnalyticsEvent('Card-Clicks', 'SRP-Card-Clicks', this.url);\r\n store.dispatch(uiStateSlice.actions.trackUserEvent({ googleAnalyticsDTO }));\r\n }\r\n\r\n bindEvents() {\r\n const closeElements = document.querySelectorAll(this.closeAttribute);\r\n closeElements.forEach((element) => element.addEventListener('click', ThankScreenAskQuestion.closeModal));\r\n\r\n const detailsLink = this.moreDetailsAnchor.getAnchor();\r\n // if the anchor element contains any events, bind them here.\r\n this.moreDetailsAnchor.bindEvents();\r\n detailsLink.addEventListener('click', this.emitMoreDetailsClickEvent.bind(this));\r\n }\r\n\r\n unbindEvents() {\r\n const detailsLink = this.moreDetailsAnchor.getAnchor();\r\n detailsLink.removeEventListener('click', this.emitMoreDetailsClickEvent);\r\n }\r\n\r\n static closeModal() {\r\n modalService.clearHtml();\r\n }\r\n\r\n getHtml() {\r\n return `\r\n
\r\n \r\n
\r\n ${thanksContentSvg}\r\n

Thank You!

\r\n

${this.builderName} will reach out to you soon with an answer.

\r\n
\r\n
\r\n \r\n ${this.moreDetailsAnchor.getHtml()}\r\n
\r\n
`;\r\n }\r\n}\r\n","import { store } from '@redux/store';\r\nimport modalService from 'layout/services/modalService';\r\nimport { closeModalSvg, thankYouEmail, thankYouPhone, thankYouSuccess } from '../constants/svgIcons';\r\n\r\nexport default class ThankScreenBasic {\r\n constructor() {\r\n const state = store.getState();\r\n this.url = state?.uiState?.modalInformation?.url;\r\n this.builderName = state?.uiState?.modalInformation?.listingInformation?.brandName ?? 'the builder';\r\n this.closeAttribute = '[data-close]';\r\n this.thankYouSuccess = thankYouSuccess;\r\n this.closeModalSvg = closeModalSvg;\r\n }\r\n\r\n /**\r\n * Sets the internal browsing anchor for the ThankScreenBasic component.\r\n * @param {object} anchor - The anchor to be set (CreateAccountAnchor or ReturnToSearchAnchor).\r\n */\r\n setInternalBrowsingAnchor(anchor) {\r\n this.internalBrowsingAnchor = anchor;\r\n }\r\n\r\n /**\r\n * Binds events to the ThankScreenBasic component.\r\n * @function bindEvents\r\n * @memberof ThankScreenBasic\r\n * @instance\r\n */\r\n bindEvents() {\r\n const closeElements = document.querySelectorAll(this.closeAttribute);\r\n closeElements.forEach((element) => element.addEventListener('click', ThankScreenBasic.closeModal));\r\n\r\n this.internalBrowsingAnchor?.bindEvents?.();\r\n }\r\n\r\n static closeModal() {\r\n modalService.clearHtml();\r\n }\r\n\r\n getHtml() {\r\n return `\r\n
\r\n \r\n
\r\n ${thankYouSuccess}\r\n

Way to Go!

\r\n

\r\n An agent will be in contact soon!\r\n

\r\n
\r\n
\r\n \r\n \r\n
\r\n
\r\n
\r\n ${this.internalBrowsingAnchor.getHtml()}\r\n
\r\n
`;\r\n }\r\n}","import { store } from '@redux/store';\r\nimport GoogleAnalyticsEvent from \"dataTransferObjects/googleAnalyticsEvent\";\r\nimport uiStateSlice from 'layout/redux/uiStateSlice';\r\nimport modalService from 'layout/services/modalService';\r\nimport { closeModalSvg,\r\n thankYouEmail,\r\n thankYouHeart,\r\n thankYouPhone,\r\n thankYouSuccess \r\n} from '../constants/svgIcons';\r\n\r\nexport default class ThankScreenBrochure {\r\n constructor() {\r\n const state = store.getState();\r\n const modalInformation = state?.uiState?.modalInformation;\r\n const listingInformation = modalInformation?.listingInformation;\r\n\r\n this.url = modalInformation?.url;\r\n this.schedulerUrl = listingInformation?.schedulerUrl;\r\n this.hasCallTracking = listingInformation?.hasCallTracking === \"True\";\r\n this.phoneNumber = listingInformation?.phoneNumber;\r\n this.builderName = listingInformation?.brandName ?? 'the builder';\r\n this.marketId = listingInformation?.marketId;\r\n this.closeAttribute = '[data-close]';\r\n this.closeBtnId = 'closeBtn';\r\n }\r\n\r\n emitMoreDetailsClickEvent() {\r\n const googleAnalyticsDTO = new GoogleAnalyticsEvent('Card-Clicks', 'SRP-Card-Clicks', this.url);\r\n store.dispatch(uiStateSlice.actions.trackUserEvent({ googleAnalyticsDTO }));\r\n }\r\n\r\n /**\r\n * Sets the contact builder anchor for the ThankScreenBrochure component.\r\n * @param {object} anchor - The anchor to be set (SchedulerAnchor, PhoneAnchorCallTracking or PhoneAnchor).\r\n */\r\n setContactBuilderAnchor(anchor) {\r\n this.contactBuilderAnchor = anchor;\r\n }\r\n\r\n /**\r\n * Sets the internal browsing anchor for the ThankScreenBrochure component.\r\n * @param {object} anchor - The anchor to be set (CreateAccountAnchor or ReturnToSearchAnchor).\r\n */\r\n setInternalBrowsingAnchor(anchor) {\r\n this.internalBrowsingAnchor = anchor;\r\n }\r\n\r\n /**\r\n * Binds events to the ThankScreenBrochure component.\r\n * @function bindEvents\r\n * @memberof ThankScreenBrochure\r\n * @instance\r\n */\r\n bindEvents() {\r\n const closeElements = document.querySelectorAll(this.closeAttribute);\r\n closeElements.forEach((element) => element.addEventListener('click', ThankScreenBrochure.closeModal));\r\n\r\n // if the anchor element contains any events, bind them here.\r\n this.contactBuilderAnchor?.bindEvents?.()\r\n\r\n const detailsLink = this.contactBuilderAnchor?.getAnchor?.();\r\n detailsLink?.addEventListener('click', this.emitMoreDetailsClickEvent.bind(this));\r\n\r\n const closeBtn = this.getCloseBtn();\r\n closeBtn?.addEventListener('click', ()=> document.body.dispatchEvent(new CustomEvent('closeAnchorClick')));\r\n\r\n this.internalBrowsingAnchor?.bindEvents?.();\r\n }\r\n\r\n /**\r\n * Removes event listeners from the anchor element.\r\n * @function\r\n */\r\n unbindEvents() {\r\n const detailsLink = this.contactBuilderAnchor?.getAnchor?.();\r\n detailsLink?.removeEventListener('click', this.emitMoreDetailsClickEvent);\r\n }\r\n\r\n /**\r\n * Closes the modal by clearing its HTML content.\r\n */\r\n static closeModal() {\r\n modalService?.clearHtml();\r\n }\r\n\r\n /**\r\n * Gets the close button element by ID.\r\n * @returns {HTMLElement} The button element.\r\n */\r\n getCloseBtn() {\r\n return document.getElementById(this.closeBtnId);\r\n }\r\n\r\n getHtml() {\r\n return `\r\n
\r\n \r\n
\r\n ${thankYouSuccess}\r\n

Way to Go!

\r\n

\r\n You're connected with ${this.builderName}.
\r\n The best way to find out more is to visit the community yourself!\r\n

\r\n
\r\n
\r\n \r\n \r\n
\r\n
\r\n
\r\n ${this.internalBrowsingAnchor.getHtml()}\r\n ${this.contactBuilderAnchor.getHtml()}\r\n
\r\n
`;\r\n }\r\n}\r\n","import { store } from '@redux/store';\r\nimport GoogleAnalyticsEvent from 'dataTransferObjects/googleAnalyticsEvent';\r\nimport uiStateSlice from 'layout/redux/uiStateSlice';\r\nimport modalService from 'layout/services/modalService';\r\nimport { closeModalSvg, \r\n thankYouEmail,\r\n thankYouHeart,\r\n thankYouPhone,\r\n thankYouSuccess \r\n } from '../constants/svgIcons';\r\n\r\nexport default class ThankScreenComingSoon {\r\n constructor() {\r\n const state = store.getState();\r\n const modalInformation = state?.uiState?.modalInformation;\r\n const listingInformation = modalInformation?.listingInformation;\r\n\r\n this.url = modalInformation?.url;\r\n this.schedulerUrl = listingInformation?.schedulerUrl;\r\n this.hasCallTracking = listingInformation?.hasCallTracking === \"True\";\r\n this.phoneNumber = listingInformation?.phoneNumber;\r\n this.builderName = listingInformation?.brandName ?? 'the builder';\r\n this.marketId = listingInformation?.marketId;\r\n this.closeAttribute = '[data-close]';\r\n this.closeBtnId = 'closeBtn';\r\n }\r\n\r\n emitMoreDetailsClickEvent() {\r\n const googleAnalyticsDTO = new GoogleAnalyticsEvent('Card-Clicks', 'SRP-Card-Clicks', this.url);\r\n store.dispatch(uiStateSlice.actions.trackUserEvent({ googleAnalyticsDTO }));\r\n }\r\n\r\n /**\r\n * Sets the contact builder anchor for the ThankScreenBrochure component.\r\n * @param {object} anchor - The anchor to be set (SchedulerAnchor, PhoneAnchorCallTracking or PhoneAnchor).\r\n */\r\n setContactBuilderAnchor(anchor) {\r\n this.contactBuilderAnchor = anchor;\r\n }\r\n\r\n /**\r\n * Sets the internal browsing anchor for the ThankScreenBrochure component.\r\n * @param {object} anchor - The anchor to be set (CreateAccountAnchor or ReturnToSearchAnchor).\r\n */\r\n setInternalBrowsingAnchor(anchor) {\r\n this.internalBrowsingAnchor = anchor;\r\n }\r\n\r\n /**\r\n * Binds events to the ThankScreenBrochure component.\r\n * @function bindEvents\r\n * @memberof ThankScreenBrochure\r\n * @instance\r\n */\r\n bindEvents() {\r\n const closeElements = document.querySelectorAll(this.closeAttribute);\r\n closeElements.forEach((element) => element.addEventListener('click', ThankScreenComingSoon.closeModal));\r\n\r\n // if the anchor element contains any events, bind them here.\r\n this.contactBuilderAnchor?.bindEvents?.()\r\n\r\n const detailsLink = this.contactBuilderAnchor?.getAnchor?.();\r\n detailsLink?.addEventListener('click', this.emitMoreDetailsClickEvent.bind(this));\r\n\r\n const closeBtn = this.getCloseBtn();\r\n closeBtn?.addEventListener('click', ()=> document.body.dispatchEvent(new CustomEvent('closeAnchorClick')));\r\n\r\n this.internalBrowsingAnchor?.bindEvents?.();\r\n }\r\n\r\n /**\r\n * Removes event listeners from the anchor element.\r\n * @function\r\n */\r\n unbindEvents() {\r\n const detailsLink = this.contactBuilderAnchor.getAnchor();\r\n detailsLink?.removeEventListener('click', this.emitMoreDetailsClickEvent);\r\n }\r\n\r\n /**\r\n * Closes the modal by clearing its HTML content.\r\n */\r\n static closeModal() {\r\n modalService.clearHtml();\r\n }\r\n\r\n /**\r\n * Gets the close button element by ID.\r\n * @returns {HTMLElement} The button element.\r\n */\r\n getCloseBtn() {\r\n return document.getElementById(this.closeBtnId);\r\n }\r\n\r\n getHtml() {\r\n return `\r\n
\r\n \r\n
\r\n ${thankYouSuccess}\r\n

Way to Go!

\r\n

\r\n You're connected with ${this.builderName}.
\r\n The best way to find out more is to visit the community yourself!\r\n

\r\n
\r\n
\r\n \r\n \r\n
\r\n
\r\n
\r\n ${this.internalBrowsingAnchor.getHtml()}\r\n ${this.contactBuilderAnchor.getHtml()}\r\n
\r\n
`;\r\n }\r\n}\r\n","import { store } from '@redux/store';\r\nimport modalService from 'layout/services/modalService';\r\nimport DetailsAnchor from './detailsAnchor';\r\nimport { closeModalSvg, thanksContentSvg } from '../constants/svgIcons';\r\n\r\nexport default class ThankScreenLimitedAvailability {\r\n constructor() {\r\n const state = store.getState();\r\n const modalInformation = state?.uiState?.modalInformation;\r\n const listingInformation = modalInformation?.listingInformation;\r\n this.url = modalInformation?.url;\r\n this.builderName = listingInformation?.brandName ?? 'the builder';\r\n this.closeAttribute = '[data-close]';\r\n this.moreDetailsAnchor = new DetailsAnchor();\r\n this.moreDetailsAnchor.setUrl(this.url);\r\n this.moreDetailsAnchor.setListingId(listingInformation.id);\r\n this.moreDetailsAnchor.setListingType(listingInformation.type);\r\n }\r\n\r\n bindEvents() {\r\n const closeElements = document.querySelectorAll(this.closeAttribute);\r\n closeElements.forEach((element) => element.addEventListener('click', ThankScreenLimitedAvailability.closeModal));\r\n this.moreDetailsAnchor.bindEvents();\r\n }\r\n\r\n static closeModal() {\r\n modalService.clearHtml();\r\n }\r\n\r\n getHtml() {\r\n return `\r\n
\r\n \r\n
\r\n ${thanksContentSvg}\r\n

Thank You!

\r\n

${this.builderName} will reach out to you soon with more information!.

\r\n
\r\n
\r\n \r\n ${this.moreDetailsAnchor.getHtml()}\r\n
\r\n
`;\r\n }\r\n}\r\n","import { store } from '@redux/store';\r\nimport modalService from 'layout/services/modalService';\r\nimport DetailsAnchor from './detailsAnchor';\r\nimport { closeModalSvg, thanksContentSvg } from '../constants/svgIcons';\r\n\r\nexport default class ThankScreenTour {\r\n constructor() {\r\n const state = store.getState();\r\n const modalInformation = state?.uiState?.modalInformation;\r\n const listingInformation = modalInformation?.listingInformation;\r\n this.url = modalInformation?.url;\r\n this.builderName = listingInformation?.brandName ?? 'the builder';\r\n this.closeAttribute = '[data-close]';\r\n this.moreDetailsAnchor = new DetailsAnchor();\r\n this.moreDetailsAnchor.setUrl(this.url);\r\n this.moreDetailsAnchor.setListingId(listingInformation.id);\r\n this.moreDetailsAnchor.setListingType(listingInformation.type);\r\n }\r\n\r\n bindEvents() {\r\n const closeElements = document.querySelectorAll(this.closeAttribute);\r\n closeElements.forEach((element) => element.addEventListener('click', ThankScreenTour.closeModal));\r\n this.moreDetailsAnchor.bindEvents();\r\n }\r\n\r\n static closeModal() {\r\n modalService.clearHtml();\r\n }\r\n\r\n getHtml() {\r\n return `\r\n
\r\n \r\n
\r\n ${thanksContentSvg}\r\n

Thank You!

\r\n

Your request has been sent to ${this.builderName}.

\r\n

They will be in touch with you soon with more information!

\r\n
\r\n
\r\n \r\n ${this.moreDetailsAnchor.getHtml()}\r\n
\r\n
`;\r\n }\r\n}\r\n","import { store, store$ } from '@redux/store';\r\nimport { selectIsLoggedIn } from 'features/userProfile';\r\nimport messageService from 'layout/services/messageService';\r\nimport modalService from 'layout/services/modalService';\r\nimport { distinctUntilChanged, distinctUntilKeyChanged, filter, map } from 'rxjs';\r\nimport ThankScreenVariation from '../../searchResultsFacets/enums/thankScreenVariation';\r\nimport { getContactBuilderAnchor, getInternalBrowsingAnchor } from '../services/anchorConstructor';\r\nimport createLeadGenerator from '../services/leadGeneratorConstructor';\r\nimport { initialState, updateModalProgress } from '../services/taskFlow';\r\nimport RecommendedScreen from './recommendedScreen';\r\nimport RecommendedScreenBasic from './recommendedScreenBasic';\r\nimport ThankScreenAskQuestion from './thankScreenAskQuestion';\r\nimport ThankScreenBasic from './thankScreenBasic';\r\nimport ThankScreenBrochure from './thankScreenBrochure';\r\nimport ThankScreenComingSoon from './thankScreenComingSoon';\r\nimport ThankScreenLimitedAvailability from './thankScreenLimitedAvailability';\r\nimport ThankScreenTour from './thankScreenTour';\r\n\r\nconst message$ = messageService.getMessage();\r\nconst isThankYouScreen = (state) => state?.uiState?.modalInformation?.name === 'thankYouScreen';\r\nconst isRecommendationsScreen = (state) => state?.uiState?.modalInformation?.name === 'recommendedScreen';\r\nconst isRecommendationsScreenBasic = (state) => state?.uiState?.modalInformation?.name === 'recommendedScreenBasic';\r\nconst hasFinishedLoading = (state) => !state?.uiState?.isFetchingModal;\r\nconst leadGeneratorInstance = {\r\n generator: null,\r\n state: null,\r\n};\r\nconst recommendationsInstance = {\r\n generator: null,\r\n};\r\n\r\n/**\r\n * Returns a Free Brochure Thank You screen.\r\n *\r\n * @param {Object} modalInformation - Information about the modal.\r\n * @returns {ThankScreenBrochure} - The Thank You screen for a free brochure request.\r\n */\r\nfunction getFreeBrochureThankYouScreen(modalInformation, isLoggedIn) {\r\n const brochureThankYouScreen = new ThankScreenBrochure(modalInformation);\r\n const contactBuilderAnchor = getContactBuilderAnchor(modalInformation);\r\n const internalBrowsingAnchor = getInternalBrowsingAnchor(isLoggedIn);\r\n brochureThankYouScreen.setContactBuilderAnchor(contactBuilderAnchor);\r\n brochureThankYouScreen.setInternalBrowsingAnchor(internalBrowsingAnchor);\r\n\r\n return brochureThankYouScreen;\r\n}\r\n\r\n/**\r\n * Returns a Coming Soon Thank You screen.\r\n *\r\n * @param {Object} modalInformation - Information about the modal.\r\n * @returns {ThankScreenBrochure} - The Thank You screen for a coming soon brochure request.\r\n */\r\nfunction getComingSoonThankYouScreen(modalInformation, isLoggedIn) {\r\n const comingSoonThankYouScreen = new ThankScreenComingSoon(modalInformation);\r\n const contactBuilderAnchor = getContactBuilderAnchor(modalInformation);\r\n const internalBrowsingAnchor = getInternalBrowsingAnchor(isLoggedIn);\r\n comingSoonThankYouScreen.setContactBuilderAnchor(contactBuilderAnchor);\r\n comingSoonThankYouScreen.setInternalBrowsingAnchor(internalBrowsingAnchor);\r\n\r\n return comingSoonThankYouScreen;\r\n}\r\n\r\n/**\r\n * Returns a Thank You Basic screen.\r\n *\r\n * @param {Object} modalInformation - Information about the modal.\r\n * @returns {ThankScreenBasic} - The Thank You Basic screen.\r\n */\r\nfunction getThankScreenBasicScreen(modalInformation, isLoggedIn) {\r\n const thankYouScreenBasic = new ThankScreenBasic(modalInformation);\r\n const internalBrowsingAnchor = getInternalBrowsingAnchor(isLoggedIn);\r\n thankYouScreenBasic.setInternalBrowsingAnchor(internalBrowsingAnchor);\r\n\r\n return thankYouScreenBasic;\r\n}\r\n\r\n/**\r\n * Decides which variation of the thank you screen to show and returns an instance of it.\r\n */\r\nconst getThankYouScreen = () => {\r\n const state = store.getState();\r\n const screenVariation = state?.uiState?.modalInformation?.variation;\r\n const modalInformation = state?.uiState?.modalInformation;\r\n const isLoggedIn = selectIsLoggedIn(state);\r\n\r\n switch (screenVariation) {\r\n case ThankScreenVariation.ComingSoon.toString():\r\n return getComingSoonThankYouScreen(modalInformation, isLoggedIn);\r\n case ThankScreenVariation.AskQuestion.toString():\r\n return new ThankScreenAskQuestion();\r\n case ThankScreenVariation.Brochure.toString():\r\n return getFreeBrochureThankYouScreen(modalInformation, isLoggedIn);\r\n case ThankScreenVariation.Tour.toString():\r\n return new ThankScreenTour(modalInformation);\r\n case ThankScreenVariation.LimitedAvailability.toString():\r\n return new ThankScreenLimitedAvailability(modalInformation);\r\n case ThankScreenVariation.Basic.toString():\r\n return getThankScreenBasicScreen(modalInformation, isLoggedIn);\r\n default:\r\n // if no version is provided, we default to the free brochure one.\r\n return getFreeBrochureThankYouScreen(modalInformation, isLoggedIn);\r\n }\r\n};\r\n\r\n/**\r\n * This function takes the user to a \"thank you screen\". This screen is different\r\n * depending on which flow the user is following, so we receive an argument indicating\r\n * the name of the thank you screen to show.\r\n * @param {string} thankYouScreen is the name of the thank you screen to show.\r\n */\r\nconst showThankYouScreen = () => {\r\n const screen = getThankYouScreen();\r\n\r\n modalService.onHtmlRemoved({\r\n name: 'thankYouScreen',\r\n fn: screen.unbindEvents?.bind(screen),\r\n });\r\n\r\n modalService.onHtmlReady({\r\n name: 'thankYouScreen',\r\n fn: screen.bindEvents.bind(screen),\r\n });\r\n\r\n modalService.setHtml({ payload: screen.getHtml() });\r\n}\r\n\r\nconst showRecommendationsScreen = (data) => {\r\n recommendationsInstance.generator = new RecommendedScreen(data?.uiState?.modalInformation?.html);\r\n\r\n modalService.onHtmlReady({\r\n name: 'recommendedScreen',\r\n fn: recommendationsInstance.generator.bindEvents.bind(recommendationsInstance.generator),\r\n });\r\n\r\n modalService.onHtmlRemoved({\r\n name: 'recommendedScreen',\r\n fn: recommendationsInstance.generator.unbindEvents.bind(recommendationsInstance.generator),\r\n });\r\n\r\n modalService.setHtml({ payload: recommendationsInstance.generator.getHtml() });\r\n}\r\n\r\nconst showRecommendationsScreenBasic = (data) => {\r\n recommendationsInstance.generator = new RecommendedScreenBasic(data?.uiState?.modalInformation?.html);\r\n\r\n modalService.onHtmlReady({\r\n name: 'recommendedScreenBasic',\r\n fn: recommendationsInstance.generator.bindEvents.bind(recommendationsInstance.generator),\r\n });\r\n\r\n modalService.onHtmlRemoved({\r\n name: 'recommendedScreenBasic',\r\n fn: recommendationsInstance.generator.unbindEvents.bind(recommendationsInstance.generator),\r\n });\r\n\r\n modalService.setHtml({ payload: recommendationsInstance.generator.getHtml() });\r\n}\r\n\r\ndocument.body.addEventListener('click', (event) => {\r\n const leadGeneratorOpener = event.target.closest('[data-lead-generator-opener]');\r\n const properties = { ...leadGeneratorOpener?.dataset };\r\n const openerKey = properties?.leadGeneratorOpener;\r\n const leadGenerator = createLeadGenerator(openerKey, properties);\r\n\r\n if (!leadGenerator) {\r\n return false;\r\n }\r\n\r\n const cardContainer = event.target.closest('[data-card]');\r\n const listingInformation = cardContainer?.dataset;\r\n // Here we are checking all the values from the data set, and we are going to use the ones that are not empty. \r\n const validListingInformation =\r\n Object.fromEntries(Object.entries(listingInformation).filter(([, value]) => Boolean(value)))\r\n properties.listingInformation = validListingInformation;\r\n const getGoogleAnalyticsEventCallback = leadGenerator.constructor.getFormOpenedAnalyticsData;\r\n leadGenerator.excludeRecommendations = properties?.excludeRecommendations === \"true\";\r\n const contactVendorName = properties?.listingInformation?.contactVendorName ?? '';\r\n leadGenerator.setPrivacyPolicyText?.(properties?.phoneNumber, contactVendorName);\r\n leadGenerator.setHousingData?.(properties);\r\n leadGeneratorInstance.state = initialState(properties, getGoogleAnalyticsEventCallback);\r\n leadGeneratorInstance.generator = leadGenerator;\r\n\r\n modalService.onHtmlReady({\r\n name: 'leadGenerator',\r\n fn: leadGeneratorInstance.generator.bindEvents.bind(leadGeneratorInstance.generator),\r\n });\r\n\r\n modalService.onHtmlRemoved({\r\n name: 'leadGenerator',\r\n fn: leadGeneratorInstance.generator.unbindEvents.bind(leadGeneratorInstance.generator),\r\n });\r\n\r\n modalService.setHtml({ payload: leadGeneratorInstance.generator.getHtml() });\r\n return true;\r\n});\r\n\r\ndocument.body.addEventListener('click', (event) => {\r\n const backButton = event.target.closest('.modal__back');\r\n const closeButton = event.target.closest('#nhs_modalClose');\r\n const overlayElement = event.target.closest('#overlayElement');\r\n\r\n if (backButton && leadGeneratorInstance.state) {\r\n updateModalProgress(leadGeneratorInstance.state);\r\n modalService.setPreviousHtml();\r\n return;\r\n }\r\n\r\n if ((closeButton || overlayElement) && leadGeneratorInstance.state) {\r\n modalService.clearHtml();\r\n }\r\n});\r\n\r\nstore$.pipe(\r\n map(isThankYouScreen),\r\n distinctUntilChanged(),\r\n filter(Boolean))\r\n .subscribe(showThankYouScreen);\r\n\r\nstore$.pipe(\r\n filter(isRecommendationsScreen),\r\n filter(hasFinishedLoading),\r\n distinctUntilKeyChanged('uiState'))\r\n .subscribe(showRecommendationsScreen);\r\n\r\nstore$.pipe(\r\n filter(isRecommendationsScreenBasic),\r\n filter(hasFinishedLoading),\r\n distinctUntilKeyChanged('uiState'))\r\n .subscribe(showRecommendationsScreenBasic);\r\n\r\nmessage$.pipe(\r\n filter((msg) => msg.messageType === 'leadPosted'),\r\n filter((msg) => msg.payload.html !== ''),\r\n filter((message) => !message.isBasic),\r\n map((data) => data.payload))\r\n .subscribe((data) => {\r\n const modalInformation = {\r\n name: 'recommendedScreen',\r\n html: data.html\r\n };\r\n\r\n updateModalProgress(modalInformation);\r\n });\r\n\r\nmessage$.pipe(\r\n filter((msg) => msg.messageType === 'leadPosted'),\r\n filter((msg) => msg.payload.html !== ''),\r\n filter((message) => message.isBasic),\r\n map((data) => data.payload))\r\n .subscribe((data) => {\r\n const modalInformation = {\r\n name: 'recommendedScreenBasic',\r\n html: data.html\r\n };\r\n\r\n updateModalProgress(modalInformation);\r\n });\r\n\r\nmessage$.pipe(\r\n filter((msg) => msg.messageType === 'leadPosted'),\r\n filter((msg) => msg.payload.html === ''))\r\n .subscribe(() => {\r\n const modalInformation = {\r\n name: 'thankYouScreen',\r\n };\r\n\r\n updateModalProgress(modalInformation);\r\n });","export default class LeadFormType {\r\n static get BrochureFormPaid() {\r\n return this.getInstance('get-brochure-paid');\r\n }\r\n\r\n static get InformationFormPaid() {\r\n return this.getInstance('more-information-paid');\r\n }\r\n\r\n static get RequestTourForm() {\r\n return this.getInstance('request-a-tour');\r\n }\r\n\r\n static get BrochureFormLimitedAvailability() {\r\n return this.getInstance('get-information-limited-availability');\r\n }\r\n\r\n static get InformationFormBasic() {\r\n return this.getInstance('get-information-basic');\r\n }\r\n\r\n static get AskQuestionFormPaid() {\r\n return this.getInstance('ask-question-paid');\r\n }\r\n\r\n static get ManufacturedBrochureFormPaid() {\r\n return this.getInstance('get-manufactured-brochure-paid');\r\n }\r\n\r\n static fromKey(key) {\r\n const formTypeMap = {\r\n 'get-brochure-paid': LeadFormType.BrochureFormPaid,\r\n 'more-information-paid': LeadFormType.InformationFormPaid,\r\n 'request-a-tour': LeadFormType.RequestTourForm,\r\n 'get-information-limited-availability': LeadFormType.BrochureFormLimitedAvailability,\r\n 'get-information-basic': LeadFormType.InformationFormBasic,\r\n 'ask-question-paid': LeadFormType.AskQuestionFormPaid,\r\n 'get-manufactured-brochure-paid': LeadFormType.ManufacturedBrochureFormPaid,\r\n };\r\n return formTypeMap[key];\r\n }\r\n\r\n static getInstance(key) {\r\n if (!this.instances[key]) {\r\n this.instances[key] = new LeadFormType(key);\r\n }\r\n return this.instances[key];\r\n }\r\n\r\n constructor(name) {\r\n this.name = name;\r\n }\r\n\r\n toString() {\r\n return `${this.name}`;\r\n }\r\n}\r\n\r\nObject.defineProperty(LeadFormType, 'instances', { value: {} });\r\n","import { fromFetch } from 'rxjs/fetch';\r\nimport { leadsRecommendedCommunitySubmission, leadsGetRecommendedCommunities } from 'constants/routes';\r\n\r\nexport const postRecommendedCommunities = (payload) => {\r\n const requestObject = {\r\n 'credentials': 'include',\r\n method: 'POST',\r\n body: JSON.stringify({\r\n ...payload,\r\n }),\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n },\r\n selector: (response) => response.text(),\r\n };\r\n\r\n fetch(leadsRecommendedCommunitySubmission, requestObject);\r\n};\r\n\r\nexport const getRecommendedCommunities$ = (payload) => {\r\n const requestObject = {\r\n 'credentials': 'include',\r\n method: 'POST',\r\n body: JSON.stringify({\r\n leadCommand: {\r\n ...payload,\r\n },\r\n }),\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n },\r\n selector: (response) => response.text(),\r\n };\r\n\r\n return fromFetch(leadsGetRecommendedCommunities, requestObject);\r\n};\r\n","import { leadsPaidCommunitySubmission, leadsPaidPlanSubmission, leadsPaidSpecSubmission } from 'constants/routes';\r\n\r\nexport const postBuildablePlanBrochure$ = (payload) => {\r\n const requestObject = {\r\n 'credentials': 'include',\r\n method: 'POST',\r\n body: JSON.stringify({\r\n leadCommand: {\r\n ...payload,\r\n },\r\n }),\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n },\r\n selector: (response) => response.text(),\r\n };\r\n\r\n fetch(leadsPaidCommunitySubmission, requestObject);\r\n};\r\n\r\nexport const postCommunityBrochure = (payload) => {\r\n const requestObject = {\r\n 'credentials': 'include',\r\n method: 'POST',\r\n body: JSON.stringify({\r\n leadCommand: {\r\n ...payload,\r\n },\r\n }),\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n },\r\n selector: (response) => response.text(),\r\n };\r\n\r\n fetch(leadsPaidCommunitySubmission, requestObject);\r\n};\r\n\r\nexport const postPlanBrochure = (payload) => {\r\n const requestObject = {\r\n 'credentials': 'include',\r\n method: 'POST',\r\n body: JSON.stringify({\r\n leadCommand: {\r\n ...payload,\r\n },\r\n }),\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n },\r\n selector: (response) => response.text(),\r\n };\r\n\r\n fetch(leadsPaidPlanSubmission, requestObject);\r\n};\r\n\r\nexport const postSpecBrochure = (payload) => {\r\n const requestObject = {\r\n 'credentials': 'include',\r\n method: 'POST',\r\n body: JSON.stringify({\r\n leadCommand: {\r\n ...payload,\r\n },\r\n }),\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n },\r\n selector: (response) => response.text(),\r\n };\r\n\r\n fetch(leadsPaidSpecSubmission, requestObject);\r\n};\r\n","import { catchError, distinctUntilChanged, filter, of, switchMap, tap } from 'rxjs';\r\nimport { ofType } from 'redux-observable';\r\nimport uiStateSlice from 'layout/redux/uiStateSlice';\r\nimport messageService from 'layout/services/messageService';\r\nimport { postRecommendedCommunities, getRecommendedCommunities$ } from '../apis/recommendedCommunities';\r\nimport { postCommunityBrochure, postPlanBrochure, postSpecBrochure } from '../apis/postBrochure';\r\nimport {\r\n postPlanBrochureBasic,\r\n postSpecBrochureBasic,\r\n postCommunityBrochureBasic,\r\n postBasicListingBrochureBasic\r\n} from '../apis/postBrochureBasic';\r\n\r\nconst actions = uiStateSlice.actions;\r\n\r\nexport const postBuildablePlanBrochureEpic = (action$) =>\r\n action$.pipe(\r\n ofType(actions.fetchModal.type),\r\n filter((action) => action.payload.parameters.type === 'postBuildeablePlanBrochure'),\r\n tap((action) => postCommunityBrochure(action.payload.parameters)),\r\n switchMap(() => of(actions.fetchModalFulfilled()))\r\n );\r\n\r\nexport const postCommunityBrochureEpic = (action$) =>\r\n action$.pipe(\r\n ofType(actions.fetchModal.type),\r\n filter((action) => action.payload.parameters.type === 'postCommunityBrochure'),\r\n tap((action) => postCommunityBrochure(action.payload.parameters)),\r\n switchMap(() => of(actions.fetchModalFulfilled()))\r\n );\r\n\r\nexport const postPlanBrochureEpic = (action$) =>\r\n action$.pipe(\r\n ofType(actions.fetchModal.type),\r\n filter((action) => action.payload.parameters.type === 'postPlanBrochure'),\r\n tap((action) => postPlanBrochure(action.payload.parameters)),\r\n switchMap(() => of(actions.fetchModalFulfilled()))\r\n );\r\n\r\nexport const postSpecBrochureEpic = (action$) =>\r\n action$.pipe(\r\n ofType(actions.fetchModal.type),\r\n filter((action) => action.payload.parameters.type === 'postSpecBrochure'),\r\n tap((action) => postSpecBrochure(action.payload.parameters)),\r\n switchMap(() => of(actions.fetchModalFulfilled()))\r\n );\r\n\r\nexport const postRecommendedBrochureEpic = (action$) =>\r\n action$.pipe(\r\n ofType(actions.fetchModal.type),\r\n filter((action) => action.payload.parameters.type === 'postRecommendedBrochure'),\r\n distinctUntilChanged(),\r\n tap((action) => postRecommendedCommunities(action.payload.parameters)),\r\n switchMap(() => of(actions.fetchModalFulfilled()))\r\n );\r\n\r\nexport const getRecommendedBrochureEpicPaid = (action$) =>\r\n action$.pipe(\r\n ofType(actions.fetchModal.type),\r\n filter((action) => action.payload.parameters.type === 'postSpecBrochure' ||\r\n action.payload.parameters.type === 'postPlanBrochure' ||\r\n action.payload.parameters.type === 'postCommunityBrochure' ||\r\n action.payload.parameters.type === 'postBuildeablePlanBrochure'),\r\n switchMap((action) => {\r\n if (action.payload.parameters.excludeRecommendations) {\r\n messageService.sendMessage({\r\n messageType: 'leadPosted', payload: {\r\n html: '',\r\n }\r\n });\r\n\r\n return of(actions.fetchModalFulfilled());\r\n }\r\n\r\n return getRecommendedCommunities$(action.payload.parameters).pipe(\r\n switchMap((data) => {\r\n messageService.sendMessage({\r\n messageType: 'leadPosted', isBasic: false, payload: {\r\n html: data,\r\n }\r\n });\r\n\r\n return of(actions.fetchModalFulfilled());\r\n }),\r\n catchError((err) => of(actions.fetchModalError(err)))\r\n );\r\n }),\r\n );\r\n\r\n\r\nexport const getRecommendedBrochureEpicBasic = (action$) =>\r\n action$.pipe(\r\n ofType(actions.fetchModal.type),\r\n filter((action) => action.payload.parameters.type === 'postSpecBrochureBasic' ||\r\n action.payload.parameters.type === 'postPlanBrochureBasic' ||\r\n action.payload.parameters.type === 'postCommunityBrochureBasic' ||\r\n action.payload.parameters.type === 'postBasicListingBrochureBasic'),\r\n switchMap((action) => {\r\n if (action.payload.parameters.excludeRecommendations) {\r\n messageService.sendMessage({\r\n messageType: 'leadPosted', payload: {\r\n html: '',\r\n }\r\n });\r\n\r\n return of(actions.fetchModalFulfilled());\r\n }\r\n\r\n return getRecommendedCommunities$(action.payload.parameters).pipe(\r\n switchMap((data) => {\r\n messageService.sendMessage({\r\n messageType: 'leadPosted', isBasic: true, payload: {\r\n html: data,\r\n }\r\n });\r\n\r\n return of(actions.fetchModalFulfilled());\r\n }),\r\n catchError((err) => of(actions.fetchModalError(err)))\r\n );\r\n }),\r\n );\r\n\r\nexport const postSpecBrochureBasicEpic = (action$) =>\r\n action$.pipe(\r\n ofType(actions.fetchModal.type),\r\n filter((action) => action.payload.parameters.type === 'postSpecBrochureBasic'),\r\n tap((action) => postSpecBrochureBasic(action.payload.parameters)),\r\n switchMap((action) => of(actions.fetchModalFulfilled(action)))\r\n );\r\n\r\nexport const postPlanBrochureBasicEpic = (action$) =>\r\n action$.pipe(\r\n ofType(actions.fetchModal.type),\r\n filter((action) => action.payload.parameters.type === 'postPlanBrochureBasic'),\r\n tap((action) => postPlanBrochureBasic(action.payload.parameters)),\r\n switchMap((action) => of(actions.fetchModalFulfilled(action)))\r\n );\r\n\r\nexport const postCommunityBrochureBasicEpic = (action$) =>\r\n action$.pipe(\r\n ofType(actions.fetchModal.type),\r\n filter((action) => action.payload.parameters.type === 'postCommunityBrochureBasic'),\r\n tap((action) => postCommunityBrochureBasic(action.payload.parameters)),\r\n switchMap((action) => of(actions.fetchModalFulfilled(action)))\r\n );\r\n\r\nexport const postBasicLisitingBrochureBasicEpic = (action$) =>\r\n action$.pipe(\r\n ofType(actions.fetchModal.type),\r\n filter((action) => action.payload.parameters.type === 'postBasicListingBrochureBasic'),\r\n tap((action) => postBasicListingBrochureBasic(action.payload.parameters)),\r\n switchMap((action) => of(actions.fetchModalFulfilled(action)))\r\n );","import { epic$ } from '@redux/store';\r\nimport {\r\n postBuildablePlanBrochureEpic,\r\n postCommunityBrochureEpic,\r\n postPlanBrochureEpic,\r\n postSpecBrochureEpic,\r\n postRecommendedBrochureEpic,\r\n getRecommendedBrochureEpicPaid,\r\n getRecommendedBrochureEpicBasic,\r\n postSpecBrochureBasicEpic,\r\n postPlanBrochureBasicEpic,\r\n postCommunityBrochureBasicEpic,\r\n postBasicLisitingBrochureBasicEpic\r\n} from './redux/epics';\r\nimport LeadFormType from './enums/leadFormType';\r\n\r\nepic$.next(postBuildablePlanBrochureEpic);\r\nepic$.next(postCommunityBrochureEpic);\r\nepic$.next(postPlanBrochureEpic);\r\nepic$.next(postSpecBrochureEpic);\r\nepic$.next(postRecommendedBrochureEpic);\r\nepic$.next(getRecommendedBrochureEpicPaid);\r\nepic$.next(getRecommendedBrochureEpicBasic);\r\nepic$.next(postSpecBrochureBasicEpic);\r\nepic$.next(postPlanBrochureBasicEpic);\r\nepic$.next(postCommunityBrochureBasicEpic);\r\nepic$.next(postBasicLisitingBrochureBasicEpic);\r\n\r\nrequire('./components/wrapper');\r\n\r\nexport default LeadFormType;","import { \r\n leadsBasicCommunitySubmission, \r\n leadsBasicPlanSubmission, \r\n leadsBasicSpecSubmission, \r\n leadsBasicListingSubmission \r\n} from 'constants/routes';\r\n\r\nexport const postSpecBrochureBasic = (payload) => {\r\n const requestObject = {\r\n 'credentials': 'include',\r\n method: 'POST',\r\n body: JSON.stringify({\r\n leadCommand: {\r\n ...payload,\r\n },\r\n }),\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n },\r\n\r\n selector: (response) => response.text(),\r\n };\r\n\r\n fetch(leadsBasicSpecSubmission, requestObject);\r\n};\r\n\r\nexport const postPlanBrochureBasic = (payload) => {\r\n const requestObject = {\r\n 'credentials': 'include',\r\n method: 'POST',\r\n body: JSON.stringify({\r\n leadCommand: {\r\n ...payload,\r\n },\r\n }),\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n },\r\n selector: (response) => response.text(),\r\n };\r\n\r\n fetch(leadsBasicPlanSubmission, requestObject);\r\n};\r\n\r\nexport const postCommunityBrochureBasic = (payload) => {\r\n const requestObject = {\r\n 'credentials': 'include',\r\n method: 'POST',\r\n body: JSON.stringify({\r\n leadCommand: {\r\n ...payload,\r\n },\r\n }),\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n },\r\n selector: (response) => response.text(),\r\n };\r\n\r\n fetch(leadsBasicCommunitySubmission, requestObject);\r\n};\r\n\r\nexport const postBasicListingBrochureBasic = (payload) => {\r\n const requestObject = {\r\n 'credentials': 'include',\r\n method: 'POST',\r\n body: JSON.stringify({\r\n leadCommand: {\r\n ...payload,\r\n },\r\n }),\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n },\r\n selector: (response) => response.text(),\r\n };\r\n\r\n fetch(leadsBasicListingSubmission, requestObject);\r\n};\r\n","import { store$ } from \"@redux/store\";\r\nimport { distinctUntilChanged, map, skip } from \"rxjs\";\r\nimport { selectNextPageUrl, selectPreviousPageUrl } from \"../redux/selectors\";\r\n\r\n/**\r\n * createRelationElement: Creates a new Rel Element related to the paging.\r\n * @param {string} relationType It is the rel element type. It could be prev or next.\r\n * @returns An HTMLElement with the required rel information.\r\n */\r\nfunction createRelationElement(relationType) { \r\n const relationElement = document.createElement('link');\r\n relationElement.rel = relationType;\r\n document.head.appendChild(relationElement);\r\n\r\n return relationElement;\r\n}\r\n\r\n/**\r\n * getPageLink: Gets the DOM element that is going to be used as a page link.\r\n * @param {string} pageLinkType The page link type that is going to get.\r\n * @returns An HTMLElement related to the page link required.\r\n */\r\nconst getPageLink = (pageLinkType) => {\r\n const pageLink = document.querySelector(`[rel=\"${pageLinkType}\"]`);\r\n return pageLink ?? createRelationElement(pageLinkType);\r\n}\r\n\r\n/**\r\n * removePageLink: Removes the page link element from the DOM.\r\n * @param {string} pageLinkType The page link type that is going to remove.\r\n */\r\nconst removePageLink = (pageLinkType) => {\r\n const previousPageLink = document.querySelector(`[rel=\"${pageLinkType}\"]`);\r\n previousPageLink?.remove();\r\n}\r\n\r\n/**\r\n * \r\n * @param {string} pageLinkUrl The url related to the page url element.\r\n * @param {string} pageLinkType Page link type that will be updated.\r\n */\r\nconst updatePageLink = (pageLinkUrl, pageLinkType) => {\r\n const pageLinkElement = getPageLink(pageLinkType);\r\n pageLinkElement.href = pageLinkUrl;\r\n}\r\n\r\n/**\r\n * handlePreviousPageLink: Handles the changes related to the Previous Page Link element.\r\n * @param {string} previousPageLinkUrl The url for the previous page link element.\r\n */\r\nconst handlePreviousPageLink = (previousPageLinkUrl) => {\r\n if (previousPageLinkUrl) {\r\n updatePageLink(previousPageLinkUrl, 'prev');\r\n } else {\r\n removePageLink('prev');\r\n }\r\n}\r\n\r\n/**\r\n * handleNextPageLink: Handles the changes related to the Next Page Link element.\r\n * @param {string} nextPageLinkUrl The url for the next page link element.\r\n */\r\nconst handleNextPageLink = (nextPageLinkUrl) => {\r\n if (nextPageLinkUrl) {\r\n updatePageLink(nextPageLinkUrl, 'next');\r\n } else {\r\n removePageLink('next');\r\n }\r\n}\r\n\r\nconst nextPageUrlChange$ = store$.pipe(\r\n map(selectNextPageUrl),\r\n distinctUntilChanged(),\r\n skip(1)\r\n);\r\n\r\nnextPageUrlChange$.subscribe(handleNextPageLink);\r\n\r\nconst previousPageUrlChange$ = store$.pipe(\r\n map(selectPreviousPageUrl),\r\n distinctUntilChanged(),\r\n skip(1)\r\n);\r\n\r\npreviousPageUrlChange$.subscribe(handlePreviousPageLink);","import { ofType } from \"redux-observable\";\r\nimport { debounceTime, of, switchMap, map, distinctUntilChanged } from \"rxjs\";\r\nimport routingStateSlice from \"./slices\";\r\nimport { buildNewUrl } from '../services/urlBuilder'\r\nimport { urlComponentsSelector } from \"./selectors\";\r\n\r\nconst actions = routingStateSlice.actions;\r\nconst updateUrlEpic = (action$, state$) =>\r\n action$.pipe(\r\n ofType(\r\n actions.updatePagination,\r\n actions.updateSubdirectory,\r\n actions.updateLocation,\r\n actions.updateQueryString,\r\n actions.updateBuilderName,\r\n ),\r\n map(() => {\r\n const config = urlComponentsSelector(state$.value);\r\n const newUrl = buildNewUrl(config);\r\n return newUrl.href;\r\n }),\r\n distinctUntilChanged(),\r\n debounceTime(100),\r\n switchMap((url) => of(actions.updateUrl(url)))\r\n );\r\n\r\nexport default updateUrlEpic;","import { epic$, store } from \"@redux/store\";\r\nimport updateUrlEpic from \"./redux/epics\";\r\nimport {\r\n selectCurrentUrl,\r\n selectRoutingState,\r\n selectUrlLocation,\r\n urlComponentsSelector,\r\n urlFilterSelector,\r\n selectUrlSubdirectory,\r\n selectMapCoordinatesQueryString\r\n} from \"./redux/selectors\";\r\nimport routingStateSlice from \"./redux/slices\";\r\nimport { buildNewUrl, getPaging, getBrandName } from \"./services/urlBuilder\";\r\n\r\nrequire(\"./redux/listeners\");\r\nrequire(\"./components/pageLinkHandler\");\r\n\r\nconst { actions: routingStateActions, reducer } = routingStateSlice;\r\nepic$.next(updateUrlEpic);\r\nstore.injectReducer(\"routingState\", reducer);\r\n\r\nconst routingSelectors = {\r\n urlComponentsSelector,\r\n selectCurrentUrl,\r\n selectUrlLocation,\r\n};\r\n\r\nexport {\r\n routingStateActions,\r\n routingSelectors,\r\n selectUrlSubdirectory,\r\n getPaging,\r\n buildNewUrl,\r\n getBrandName,\r\n selectRoutingState,\r\n urlFilterSelector,\r\n selectCurrentUrl,\r\n selectMapCoordinatesQueryString\r\n};\r\n","import { createListenerMiddleware } from \"@reduxjs/toolkit\";\r\nimport { addMiddleware } from \"redux-dynamic-middlewares\";\r\nimport routingStateSlice from \"./slices\";\r\n\r\nconst routingActions = routingStateSlice.actions;\r\n\r\nconst listenerMiddleware = createListenerMiddleware();\r\n\r\n// This listener keeps the URL up to date on the window object.\r\nlistenerMiddleware.startListening({\r\n type: routingActions.updateUrl.type,\r\n effect: (action) => {\r\n const newUrl = action.payload;\r\n // This new URL is pushed into the window history state to be accessed through the browser's\r\n // back and forward buttons, however, those buttons won't trigger a page reload until the\r\n // the subscriber method in the backForwardHandler.js file is executed.\r\n window.history.pushState({}, \"\", newUrl);\r\n },\r\n});\r\n\r\naddMiddleware(listenerMiddleware.middleware);\r\n","import { createSelector } from \"@reduxjs/toolkit\";\r\n\r\nexport const selectUrlSubdirectory = (state) => state?.routingState?.urlSubdirectory;\r\nexport const selectUrlLocation = (state) => state?.routingState?.urlLocation;\r\nexport const selectUrlPagination = (state) => state?.routingState?.urlPaging;\r\nexport const selectUrlQueryString = (state) => state?.routingState?.urlQueryString;\r\nexport const selectNextPageUrl = (state) => state?.routingState?.nextPageUrl;\r\nexport const selectBuilderName = (state) => state?.routingState?.urlBuilderName;\r\nexport const selectPreviousPageUrl = (state) => state?.routingState?.previousPageUrl;\r\nexport const selectCurrentUrl = (state) => state?.routingState?.currentUrl;\r\nexport const selectRoutingState = (state) => state?.routingState;\r\nexport const selectMapCoordinatesQueryString = (state) => state?.routingState?.urlCoordinatesQueryString;\r\n\r\nexport const urlComponentsSelector = createSelector(\r\n selectUrlSubdirectory,\r\n selectUrlLocation,\r\n selectUrlPagination,\r\n selectUrlQueryString,\r\n selectBuilderName,\r\n selectMapCoordinatesQueryString,\r\n (urlSubdirectory, urlLocation, urlPaging, urlQueryString, urlBuilderName, urlCoordinatesQueryString) => ({\r\n urlSubdirectory,\r\n urlLocation,\r\n urlPaging,\r\n urlQueryString,\r\n urlBuilderName,\r\n urlCoordinatesQueryString,\r\n })\r\n);\r\n\r\nexport const urlFilterSelector = createSelector(\r\n selectUrlQueryString,\r\n selectUrlSubdirectory,\r\n (queryStringParameter, urlSubdirectory) => ({\r\n queryStringParameter,\r\n urlSubdirectory\r\n })\r\n);","const routingDataElement = document.querySelector('[data-component=\"routing-data\"]');\r\nconst routingData = JSON.parse(routingDataElement.innerHTML);\r\nconst currentUrl = new URL(window.location);\r\nconst initialState = {\r\n currentUrl,\r\n urlSubdirectory: routingData.urlSubdirectory,\r\n urlPaging: routingData.urlPaging,\r\n urlQueryString: currentUrl.searchParams.toString(),\r\n urlLocation: routingData.urlLocation,\r\n urlBuilderName: routingData.urlBuilderName,\r\n urlCoordinatesQueryString: routingData.urlCoordinatesQueryString,\r\n}\r\n\r\nexport default initialState;","import { createSlice } from '@reduxjs/toolkit';\r\nimport initialState from './initialState';\r\n\r\n/* Creating a slice of the state of the routing. */\r\nconst routingStateSlice = createSlice({\r\n name: 'routingState',\r\n initialState,\r\n reducers: {\r\n updateUrl: (state, action) => {\r\n const newUrl = action.payload;\r\n state.currentUrl = new URL(newUrl);\r\n },\r\n updatePagination: (state, action) => {\r\n state.urlPaging = action.payload;\r\n },\r\n updateBuilderName: (state, action) => {\r\n state.urlBuilderName = action.payload;\r\n },\r\n updateSubdirectory: (state, action) => {\r\n state.urlSubdirectory = action.payload;\r\n },\r\n updateLocation: (state, action) => {\r\n state.urlLocation = action.payload;\r\n },\r\n updateQueryString: (state, action) => {\r\n state.urlQueryString = action.payload;\r\n },\r\n updatePreviousPageUrl: (state, action) => {\r\n state.previousPageUrl = action.payload;\r\n },\r\n updateNextPageUrl: (state, action) => {\r\n state.nextPageUrl = action.payload;\r\n },\r\n updateRectangularSearchQueryString: (state, action) => {\r\n state.urlCoordinatesQueryString = action.payload;\r\n\r\n if (action.payload){\r\n state.urlLocation = 'map';\r\n }\r\n },\r\n },\r\n});\r\n\r\nexport default routingStateSlice;\r\n","import StringExtensions from \"utils/stringExtensions\";\r\n\r\n/**\r\n * buildUrlPathName: Builds the pathname of the new url.\r\n * @param {string} subdirectory Segment related to the search subdirectory.\r\n * @param {string} location Segments related to the search location. \r\n * @param {string} paging Segment related to the search page.\r\n * @returns An string with the pathname of the search.\r\n */\r\nfunction buildUrlPathName(subdirectory, location, paging, builderName) {\r\n // The order to build the current search results url pathname is\r\n // subdirectory segment, then the location segments and finally the paging segment.\r\n const urlSegments = [];\r\n if(subdirectory) {\r\n urlSegments.push(subdirectory);\r\n }\r\n\r\n if(location) {\r\n urlSegments.push(location);\r\n }\r\n\r\n if(builderName) {\r\n urlSegments.push(builderName);\r\n }\r\n\r\n if (paging) {\r\n urlSegments.push(paging);\r\n }\r\n\r\n return urlSegments.join('/');\r\n}\r\n\r\n/**\r\n * buildNewUrl: Builds the entire url for the new search.\r\n * @param {object} config configuration object, it includes the following fields:\r\n * subdirectory, location, pagination, queryString, builderName.\r\n * @returns \r\n */\r\nfunction buildNewUrl(config) {\r\n const { urlSubdirectory, urlLocation, urlPaging, urlQueryString, urlBuilderName } = config;\r\n\r\n const newPathName = buildUrlPathName(urlSubdirectory, urlLocation, urlPaging, urlBuilderName);\r\n const newUrl = new URL(newPathName, window.location.origin);\r\n\r\n newUrl.search = urlQueryString;\r\n\r\n return newUrl;\r\n}\r\n\r\n/**\r\n * getPaging: Gets the paging segment for the search.\r\n * @param {Number} pageNumber Number of the selected page.\r\n * @returns The segment related to the paging of the current search.\r\n */\r\nfunction getPaging(pageNumber) {\r\n // We only add the paging segment when the selected page is 2 or more.\r\n const shouldShowPagingOnUrl = pageNumber > 1;\r\n if (!shouldShowPagingOnUrl) {\r\n return '';\r\n }\r\n\r\n const newPaging = `page-${pageNumber}`;\r\n return newPaging;\r\n}\r\n\r\n/**\r\n * Returns a formatted brand name.\r\n *\r\n * @param {string} brandName - The name of the brand.\r\n * @param {number} brandId - The ID of the brand.\r\n * @returns {string} - The formatted brand name.\r\n */\r\nfunction getBrandName(brandName, brandId) {\r\n if (!brandName || !brandId) {\r\n // If either brandName or brandId is not provided, return an empty string\r\n return '';\r\n }\r\n\r\n // Remove any special characters from the brandName\r\n const name = StringExtensions.encodeNameToUrl(brandName);\r\n\r\n // Return the formatted brand name with the builder prefix and brandId\r\n return `builder-${name}-${brandId}`;\r\n}\r\n\r\nexport { buildNewUrl, getPaging, buildUrlPathName, getBrandName };","export default class LocationType {\r\n /**\r\n * This is a static method that returns a new instance of the LocationType class with the type\r\n * 'city'.\r\n * @returns A new instance of the `LocationType` class with the value of `'city'` as its parameter.\r\n */\r\n static get City() {\r\n return new LocationType('city');\r\n }\r\n\r\n/**\r\n * The above code defines a static getter function that returns a new instance of a LocationType object\r\n * with the type 'market'.\r\n * @returns A new instance of the `LocationType` class with the type `market` is being returned.\r\n */\r\n static get Market() {\r\n return new LocationType('market');\r\n }\r\n\r\n /**\r\n * The above code defines a static method that returns a new instance of a LocationType object with\r\n * the type 'rectangularArea'.\r\n * @returns A new instance of the `LocationType` class with the value `'rectangularArea'` is being\r\n * returned.\r\n */\r\n static get RectangularArea() {\r\n return new LocationType('rectangularArea');\r\n }\r\n\r\n/**\r\n * The function returns a new LocationType object with the type 'zip'.\r\n * @returns A new instance of the `LocationType` class with the argument `'zip'`.\r\n */\r\n static get Zip() {\r\n return new LocationType('zip');\r\n }\r\n\r\n /**\r\n * The function returns a new instance of a LocationType object with the type 'synthetic'.\r\n * @returns A new instance of the LocationType class with the type 'synthetic'.\r\n */\r\n static get Synthetic() {\r\n return new LocationType('syntheticGeo');\r\n }\r\n\r\n/**\r\n * The function returns a new instance of a LocationType object with the type 'county'.\r\n * @returns A new instance of the LocationType class with the type 'county'.\r\n */\r\n static get County() {\r\n return new LocationType('county');\r\n }\r\n\r\n static fromKey(key) {\r\n const locationType = {\r\n city: LocationType.City,\r\n market: LocationType.Market,\r\n rectangulararea: LocationType.RectangularArea,\r\n zip: LocationType.Zip,\r\n syntheticgeo: LocationType.Synthetic,\r\n county: LocationType.County,\r\n };\r\n return locationType[key.toLowerCase()];\r\n }\r\n\r\n constructor(name) {\r\n this.name = name;\r\n }\r\n\r\n /**\r\n * This is a toString() method in JavaScript that returns the name property of an object as a string.\r\n * @returns The `toString()` method is returning the value of the `name` property of the object.\r\n */\r\n toString() {\r\n return `${this.name}`;\r\n }\r\n}","export default class MoveInDate {\r\n static get OneToTwoMonths() {\r\n return new MoveInDate('1-2');\r\n }\r\n\r\n static get ThreeToSixMonths() {\r\n return new MoveInDate('3-6');\r\n }\r\n\r\n static get BuildablePlans() {\r\n return new MoveInDate(null);\r\n }\r\n\r\n constructor(name) {\r\n this.name = name;\r\n }\r\n\r\n toString() {\r\n return `${this.name}`;\r\n }\r\n}\r\n","export default class PlanStatus {\r\n static get AvailableNow() {\r\n return this.getInstance('A');\r\n }\r\n\r\n static get Model() {\r\n return this.getInstance('M');\r\n }\r\n\r\n static get ReadyToBuild() {\r\n return this.getInstance('R');\r\n }\r\n\r\n static get UnderConstruction() {\r\n return this.getInstance('UC');\r\n }\r\n\r\n static get HotDeals() {\r\n return this.getInstance('H');\r\n }\r\n\r\n static fromKey(key) {\r\n const statusMap = {\r\n R: PlanStatus.ReadyToBuild,\r\n A: PlanStatus.AvailableNow,\r\n UC: PlanStatus.UnderConstruction,\r\n M: PlanStatus.Model,\r\n H: PlanStatus.HotDeals,\r\n };\r\n return statusMap[key];\r\n }\r\n\r\n static getInstance(key) {\r\n if (!this.instances[key]) {\r\n this.instances[key] = new PlanStatus(key);\r\n }\r\n return this.instances[key];\r\n }\r\n\r\n constructor(name) {\r\n this.name = name;\r\n }\r\n\r\n toString() {\r\n return `${this.name}`;\r\n }\r\n}\r\n\r\nObject.defineProperty(PlanStatus, 'instances', { value: {} });\r\n","export default class ProductType {\r\n static get AllProducts() {\r\n return this.getInstance('AllProducts');\r\n }\r\n\r\n static get Custom() {\r\n return this.getInstance('custom');\r\n }\r\n\r\n static get Communities() {\r\n return this.getInstance('communities');\r\n }\r\n\r\n static get Homes() {\r\n return this.getInstance('homes');\r\n }\r\n\r\n static get BuildOnYourLot() {\r\n return this.getInstance('boyl');\r\n }\r\n\r\n static get Manufactured() {\r\n return this.getInstance('manufactured');\r\n }\r\n\r\n static fromKey(key) {\r\n const productTypeMap = {\r\n allProducts: ProductType.AllProducts,\r\n custom: ProductType.Custom,\r\n communities: ProductType.Communities,\r\n homes: ProductType.Homes,\r\n boyl: ProductType.BuildOnYourLot,\r\n manufactured: ProductType.Manufactured,\r\n };\r\n\r\n return productTypeMap[key];\r\n }\r\n\r\n static getInstance(key) {\r\n if (!this.instances[key]) {\r\n this.instances[key] = new ProductType(key);\r\n }\r\n return this.instances[key];\r\n }\r\n\r\n constructor(name) {\r\n this.name = name;\r\n }\r\n\r\n toString() {\r\n return `${this.name}`;\r\n }\r\n}\r\n\r\nObject.defineProperty(ProductType, 'instances', { value: {} });","export default class ResultType {\r\n static get Communities() {\r\n const configuration = {\r\n cssSelectorForNativeAds: '[data-list-view-element] .result__card:not([data-is-featured-listing])',\r\n name: 'communities',\r\n };\r\n\r\n return this.getInstance('communities', configuration);\r\n }\r\n\r\n static get Homes() {\r\n const configuration = {\r\n cssSelectorForNativeAds: '[data-list-view-element] .result__card:not([data-is-featured-listing])',\r\n name: 'homes',\r\n };\r\n\r\n return this.getInstance('homes', configuration);\r\n }\r\n\r\n static get Builders() {\r\n const configuration = {\r\n cssSelectorForNativeAds:\r\n '[data-list-view-element] .result__card:not([data-is-featured-listing]):not([data-basic-card])',\r\n };\r\n\r\n return this.getInstance('builders', configuration);\r\n }\r\n\r\n static get Locations() {\r\n const configuration = {\r\n cssSelectorForNativeAds: '[data-list-view-element] .result__card:not([data-is-featured-listing])',\r\n name: 'locations',\r\n };\r\n\r\n return this.getInstance('locations', configuration);\r\n }\r\n\r\n /**\r\n * The function returns a value from a map based on the input name.\r\n *\r\n * @param name - The name of the key in the `statusMap` object that we want to retrieve the value for.\r\n *\r\n * @returns the value of the `statusMap` object that corresponds to the `name` parameter passed to the function.\r\n * If `name` matches one of the keys in `statusMap`, the corresponding value is returned.\r\n */\r\n static fromKey(name) {\r\n const statusMap = {\r\n builders: ResultType.Builders,\r\n communities: ResultType.Communities,\r\n homes: ResultType.Homes,\r\n locations: ResultType.Locations,\r\n };\r\n\r\n return statusMap[name];\r\n }\r\n\r\n /**\r\n * Gets an instance of a ResultType object based on a given name.\r\n * If the instance does not already exist, it creates a new instance using the configuration provided.\r\n *\r\n * @param name a unique identifier used to retrieve or create an instance of the ResultType class.\r\n * @param configuration an object that contains various properties and values that are used to configure\r\n * the instance of the ResultType class that is being created.\r\n *\r\n * @returns an instance of `ResultType` that corresponds to the given `name`.\r\n */\r\n static getInstance(name, configuration) {\r\n configuration.name = name;\r\n\r\n if (!this.instances[name]) {\r\n this.instances[name] = new ResultType(configuration);\r\n }\r\n\r\n return this.instances[name];\r\n }\r\n\r\n /**\r\n * This is a constructor function that takes a configuration object as a parameter and sets the name\r\n * and CSS selector for native ads properties.\r\n * @param configuration - The `configuration` parameter is an object that contains the configuration\r\n * settings for the constructor. It may contain properties such as `name` and\r\n * `cssSelectorForNativeAds`. The `name` property is a string that represents the name of the\r\n * configuration, while `cssSelectorForNativeAds` is a\r\n */\r\n constructor(configuration) {\r\n this.name = configuration.name;\r\n this.cssSelectorForNativeAds = configuration.cssSelectorForNativeAds;\r\n }\r\n\r\n /**\r\n * Method that returns the name property of an object as a string.\r\n * @returns returns the `name` property of that object as a string.\r\n */\r\n toString() {\r\n return `${this.name}`;\r\n }\r\n}\r\n\r\nObject.defineProperty(ResultType, 'instances', { value: {} });\r\n","export default class SpecStatus {\r\n static get AvailableNow() {\r\n return this.getInstance('A');\r\n }\r\n\r\n static get Model() {\r\n return this.getInstance('M');\r\n }\r\n\r\n static get ReadyToBuild() {\r\n return this.getInstance('R');\r\n }\r\n\r\n static get UnderConstruction() {\r\n return this.getInstance('UC');\r\n }\r\n\r\n static get HotDeals() {\r\n return this.getInstance('H');\r\n }\r\n\r\n static fromKey(key) {\r\n const statusMap = {\r\n R: SpecStatus.ReadyToBuild,\r\n A: SpecStatus.AvailableNow,\r\n UC: SpecStatus.UnderConstruction,\r\n M: SpecStatus.Model,\r\n H: SpecStatus.HotDeals,\r\n };\r\n\r\n return statusMap[key];\r\n }\r\n\r\n static getInstance(key) {\r\n if (!this.instances[key]) {\r\n this.instances[key] = new SpecStatus(key);\r\n }\r\n return this.instances[key];\r\n }\r\n\r\n constructor(name) {\r\n this.name = name;\r\n }\r\n\r\n toString() {\r\n return `${this.name}`;\r\n }\r\n}\r\n\r\nObject.defineProperty(SpecStatus, 'instances', { value: {} });\r\n","import { createSelector } from '@reduxjs/toolkit';\r\nimport { isActive, isCloseOut, isComingSoon, isGrandOpening } from 'services/marketingStatusValidator';\r\nimport TypeaheadLocationType from 'enums/typeaheadLocationType';\r\nimport { getMovingDateFilterApplied, isMoveInDateApplied } from '../services/moveInDateService';\r\nimport ProductType from '../enums/productType';\r\nimport { hasModelHome } from '../services/homeStatusValidator';\r\nimport SpecStatus from '../enums/specStatus';\r\n\r\nconst selectAdult = (state) => state?.searchParameters?.features?.adult;\r\nconst selectAgeRestricted = (state) => state?.searchParameters?.features?.ageRestricted;\r\nconst isCustom = (state) => state?.searchParameters?.product?.productType === ProductType.Custom.toString();\r\nconst selectBrands = (state) => state?.searchParameters?.counts?.brands;\r\nconst selectFetchResultCountsStatus = (state) => state?.searchParameters?.fetchResultCountsStatus;\r\nconst selectCommunityName = (state) => state?.searchParameters?.facts?.communityName;\r\nconst selectMarketId = (state) => state?.searchParameters?.location?.marketId;\r\nconst selectMarketName = (state) => state?.searchParameters?.location?.marketName;\r\nconst selectStateAbbreviation = (state) => state?.searchParameters?.location?.marketState;\r\nconst selectCity = (state) => state?.searchParameters?.location?.city;\r\nconst selectZip = (state) => state?.searchParameters?.location?.zip;\r\nconst selectCounty = (state) => state?.searchParameters?.location?.county;\r\nconst selectSyntheticName = (state) => state?.searchParameters?.location?.syntheticGeographicName;\r\nconst selectContentTemplateType = (state) => state?.searchParameters?.contentTemplateType;\r\nconst selectSchoolDistrictName = (state) => state?.searchParameters?.features?.schoolDistrictName;\r\nconst selectHotDealsCount = (state) => state?.searchParameters?.counts?.hotDealsCount;\r\nconst selectAdultCount = (state) => state?.searchParameters?.counts?.adultCount;\r\nconst selectComingSoonCount = (state) => state?.searchParameters?.counts?.comingSoonCount;\r\nconst selectQuickMoveInCount = (state) => state?.searchParameters?.counts?.quickMoveInCount;\r\nconst selectBuildablePlansCount = (state) => state?.searchParameters?.counts?.buildablePlansCount;\r\nconst selectMultiFamilyCount = (state) => state?.searchParameters?.counts?.multiFamilyCount;\r\nconst isBuildOnYourLot = (state) =>\r\n state?.searchParameters?.product?.productType === ProductType.BuildOnYourLot.toString();\r\nconst isCustomHomes = createSelector(isCustom, isBuildOnYourLot, (custom, buildOnYourLot) =>\r\n Boolean(custom, buildOnYourLot)\r\n);\r\n /**\r\n * The function checks if a product is manufactured based on the search parameters in the state object.\r\n * @param state - The `state` parameter is an object that represents the current state of the\r\n * application. It may contain various properties and values that are relevant to the application's\r\n * functionality.\r\n */\r\nconst isManufactured = (state) =>\r\n state?.searchParameters?.product?.productType === ProductType.Manufactured.toString();\r\n\r\nexport const selectPriceReduction = (state) => state?.searchParameters?.facts?.priceReduction;\r\nexport const selectMoveInDateRange = (state) => state?.searchParameters?.facts?.moveInDateRange;\r\nexport const selectMinimumPrice = (state) => state?.searchParameters?.facts?.price?.minimumPrice;\r\nexport const selectMaximumPrice = (state) => state?.searchParameters?.facts?.price?.maximumPrice;\r\nexport const selectNatureAreas = (state) => state?.searchParameters?.features?.natureAreas;\r\nexport const selectPool = (state) => state?.searchParameters?.features?.pool;\r\nexport const selectGolfCourse = (state) => state?.searchParameters?.features?.golfCourse;\r\nexport const selectGreen = (state) => state?.searchParameters?.features?.green;\r\nexport const selectSportsFacilities = (state) => state?.searchParameters?.features?.sportsFacilities;\r\nexport const selectParks = (state) => state?.searchParameters?.features?.parks;\r\nexport const selectViews = (state) => state?.searchParameters?.features?.views;\r\nexport const selectWaterfront = (state) => state?.searchParameters?.features?.waterfront;\r\nexport const selectGatedCommunity = (state) => state?.searchParameters?.features?.gatedCommunity;\r\nexport const selectMarketingStatus = (state) => state?.searchParameters?.facts?.marketingStatus;\r\nexport const selectConsumerPromos = (state) => state?.searchParameters?.facts?.consumerPromos;\r\nexport const selectRvGarage = (state) => state?.searchParameters?.facts?.recreationalVehicleGarage;\r\nexport const selectHomeStatus = (state) => state?.searchParameters?.facts?.homeStatus;\r\nexport const selectBathrooms = (state) => state?.searchParameters?.facts?.minimumBathroom;\r\nexport const selectBedrooms = (state) => state?.searchParameters?.facts?.minimumBedroom;\r\nexport const selectSchools = (state) => state?.searchParameters?.features?.schoolDistrictIds;\r\nexport const selectBrandId = (state) => state?.searchParameters?.facts?.brandId;\r\nexport const selectBrandName = (state) => state?.searchParameters?.facts?.brandName;\r\nexport const selectLivingAreas = (state) => state?.searchParameters?.facts?.livingAreas;\r\nexport const selectStories = (state) => state?.searchParameters?.facts?.stories;\r\nexport const selectPrimaryBedroom = (state) => state?.searchParameters?.facts?.primaryBedroom;\r\nexport const selectGarages = (state) => state?.searchParameters?.facts?.garages;\r\nexport const selectSingleFamily = (state) => state?.searchParameters?.features?.singleFamily;\r\nexport const selectLuxury = (state) => state?.searchParameters?.features?.luxury;\r\nexport const selectCondosAndTownHomes = (state) => state?.searchParameters?.features?.condosAndTownHomes;\r\nexport const selectPage = (state) => Number(state?.searchParameters?.results?.paging?.page);\r\nexport const selectPaging = (state) => state?.searchParameters?.results?.paging;\r\nexport const selectPrice = (state) => state?.searchParameters?.facts?.price;\r\nexport const selectCounties = (state) => state?.searchParameters?.counts?.counties;\r\nexport const selectAppliedFacets = (state) => state?.facetsState?.appliedFilters;\r\nexport const selectListingCount = (state) => state?.searchParameters?.counts?.listingCount;\r\nexport const selectProductType = (state) => state?.searchParameters?.product?.productType;\r\nexport const selectLocation = (state) => state?.searchParameters?.location;\r\nexport const selectProduct = (state) => state?.searchParameters?.product;\r\nexport const selectResults = (state) => state?.searchParameters?.results;\r\nexport const selectFeatures = (state) => state?.searchParameters?.features;\r\nexport const selectFacts = (state) => state?.searchParameters?.facts;\r\nexport const selectResultsType = (state) => state?.searchParameters?.results.resultType;\r\nexport const selectResultsModifiers = (state) => state?.searchParameters?.resultsModifiers;\r\nexport const selectFetchResultListingsStatus = (state) => state?.searchParameters?.fetchResultListingsStatus;\r\nexport const selectResultType = (state) => state?.searchParameters?.results?.resultType;\r\nexport const selectLocationType = (state) => state?.searchParameters?.location?.locationType;\r\nexport const selectSearchParameters = (state) => state?.searchParameters;\r\nexport const selectSorting = (state) => state?.searchParameters?.results?.sorting;\r\nexport const selectPageSize = (state) => Number(state?.searchParameters?.results?.paging?.pageSize);\r\nexport const selectReviews = (state) => state?.searchParameters?.facts?.builderReviews;\r\nexport const isNotCommunityLocationType = (state) =>\r\n state?.searchParameters?.location?.locationType !== TypeaheadLocationType.Community.toString();\r\nexport const selectedMarkerId = (state) => state?.mapState?.selectedMarker?.id;\r\nexport const selectHomeOwnersAssociationFee = (state) => state?.searchParameters?.facts?.hasHomeOwnersAssociationFee;\r\n\r\n// Selector used to get the values from the brand as the ID and Name.\r\nconst selectBrandInformation = createSelector(selectBrandId, selectBrandName, (brandId, brandName) => ({\r\n brandId,\r\n brandName,\r\n}));\r\n\r\n/**\r\n * Selects the value of the excludeAdult feature from the search parameters in the Redux store state.\r\n * @param {Object} state - The current state of the application.\r\n * @returns {boolean} - The value of the excludeAdult parameter.\r\n */\r\nconst selectExcludeAdult = (state) => state?.searchParameters?.resultsModifiers?.excludeAdult;\r\n\r\n/**\r\n * Selects the value of the excludeAgeRestricted feature from the search parameters in the state.\r\n * @param {Object} state - The current state of the application.\r\n * @returns {boolean} - The value of the excludeAgeRestricted parameter.\r\n */\r\nconst selectExcludeAgeRestricted = (state) => state?.searchParameters?.resultsModifiers?.excludeAgeRestricted;\r\n\r\n/**\r\n * This selector aims to expose all the properties that we have in the housing options section in the All filters menu.\r\n */\r\nconst housingOptionsSelector = createSelector(\r\n selectSingleFamily,\r\n selectLuxury,\r\n selectCondosAndTownHomes,\r\n isCustomHomes,\r\n isManufactured,\r\n selectHomeStatus,\r\n (singleFamily, luxury, condosAndTownHomes, custom, manufactured, homeStatus) => {\r\n const filters = {singleFamily, luxury ,condosAndTownHomes, custom, manufactured, \r\n model_homes: hasModelHome(homeStatus)};\r\n return filters;\r\n }\r\n);\r\n\r\n/**\r\n * This selector aims to expose all the properties that we have in the community status selector \r\n * in the All filters menu.\r\n */\r\nconst communityStatusSelector = createSelector(\r\n selectMarketingStatus,\r\n (marketingStatus) => {\r\n const filters = {\r\n coming_soon: isComingSoon(marketingStatus),\r\n grand_opening: isGrandOpening(marketingStatus),\r\n active: isActive(marketingStatus),\r\n closeout: isCloseOut(marketingStatus),\r\n };\r\n return filters;\r\n }\r\n);\r\n\r\n/**\r\n * Selects information about listing counts and result type for the Advanced Filters confirmation button.\r\n */\r\nexport const selectCountsAndResultType = createSelector(\r\n selectListingCount,\r\n selectFetchResultListingsStatus,\r\n selectResultType,\r\n (\r\n listingCounts,\r\n resultCountsStatus,\r\n resultType,\r\n ) =>\r\n ({ \r\n listingCounts,\r\n resultCountsStatus,\r\n resultType,\r\n })\r\n );\r\n\r\n/**\r\n * This selector aims to expose the filtered brandId (if any) and the list of schools (if any) properties.\r\n */\r\nconst brandIdAndSchoolsSelector = createSelector(\r\n selectSchools,\r\n selectBrandId,\r\n (schools, brandId) => {\r\n const filters = {schools, brandId: Number(brandId)};\r\n return filters;\r\n}\r\n);\r\n\r\n/**\r\n * Returns an object with properties indicating the active adult communities based on the selected filters.\r\n *\r\n * @function\r\n * @name activeAdultCommunitiesSelector\r\n * @param {boolean} selectAdult - Indicates if adult communities are selected.\r\n * @param {boolean} selectAgeRestricted - Indicates if age-restricted communities are selected.\r\n * @param {boolean} selectExcludeAdult - Indicates if adult communities are excluded.\r\n * @param {boolean} selectExcludeAgeRestricted - Indicates if age-restricted communities are excluded.\r\n * @returns {Object} Object indicating the 55+ communities status based on the selected filters.\r\n */\r\nexport const activeAdultCommunitiesSelector = createSelector(\r\n selectAdult,\r\n selectAgeRestricted,\r\n selectExcludeAdult,\r\n selectExcludeAgeRestricted,\r\n (adult, ageRestricted, excludeAdult, excludeAgeRestricted) => {\r\n const only = adult === true && ageRestricted === true;\r\n const exclude = excludeAdult === true && excludeAgeRestricted === true;\r\n\r\n return {\r\n only,\r\n exclude,\r\n any: !only && !exclude,\r\n };\r\n }\r\n);\r\n\r\n/**\r\n * This selector aims to expose all the properties that we have in the other filters section in the All filters menu.\r\n * Such as; only with reviews, hotdeal and the different states of Active adult communities.\r\n */\r\nconst otherFiltersSelector = createSelector(\r\n selectReviews,\r\n selectConsumerPromos,\r\n selectPriceReduction,\r\n selectHomeOwnersAssociationFee,\r\n activeAdultCommunitiesSelector,\r\n ( reviews, consumerPromos, priceReduction, hasHomeOwnersAssociationFee, activeAdultCommunities) => {\r\n const {only, exclude, any } = activeAdultCommunities;\r\n const filters = {\r\n reviews,\r\n hotDeals: Boolean(consumerPromos),\r\n priceReduction: Boolean(priceReduction),\r\n hasHomeOwnersAssociationFee: Boolean(hasHomeOwnersAssociationFee),\r\n any,\r\n only,\r\n exclude,\r\n };\r\n return filters;\r\n }\r\n);\r\n\r\nexport const selectFetchCountsStatusAndsCounts = createSelector(\r\n selectListingCount,\r\n selectFetchResultCountsStatus,\r\n (listingCounts, resultCountsStatus) => ({ listingCounts, resultCountsStatus })\r\n );\r\n\r\nexport const fetchingResultsCallStatusesSelector = createSelector(\r\n selectFetchResultListingsStatus,\r\n selectFetchResultCountsStatus,\r\n (fetchResultListingsStatus, fetchResultCountsStatus) => ({ fetchResultListingsStatus, fetchResultCountsStatus })\r\n);\r\n\r\nexport const selectSnippetCommand = createSelector(\r\n selectLocation,\r\n selectProduct,\r\n selectResultType,\r\n selectContentTemplateType,\r\n (location, product, resultType, contentTemplateType) => ({\r\n location,\r\n product,\r\n results: { resultType },\r\n contentTemplateType,\r\n })\r\n);\r\n\r\nexport const selectProductAndResultType = createSelector(\r\n selectProductType,\r\n selectResultType,\r\n (productType, resultType) => ({ productType, resultType })\r\n);\r\n\r\nexport const selectSearchCount = createSelector(\r\n selectHotDealsCount,\r\n selectAdultCount,\r\n selectComingSoonCount,\r\n selectQuickMoveInCount,\r\n selectBuildablePlansCount,\r\n selectMultiFamilyCount,\r\n (hotDealsCount,\r\n adultCount,\r\n comingSoonCount,\r\n quickMoveInCount,\r\n buildablePlansCount,\r\n multiFamilyCount\r\n ) => ({ \r\n hotDealsCount,\r\n adultCount,\r\n comingSoonCount,\r\n quickMoveInCount,\r\n buildablePlansCount,\r\n multiFamilyCount\r\n })\r\n );\r\n\r\n\r\nexport const selectSearchCommandContext = createSelector(selectSearchParameters, (searchParameters) => ({\r\n searchParameters,\r\n}));\r\n\r\nexport const selectLocationContentContext = createSelector(\r\n selectLocationType,\r\n selectMarketId,\r\n selectMarketName,\r\n selectCity,\r\n selectCounty,\r\n selectSyntheticName,\r\n selectStateAbbreviation,\r\n selectZip,\r\n selectProductType,\r\n selectBrandId,\r\n selectBrandName,\r\n selectSchoolDistrictName,\r\n selectCommunityName,\r\n selectResultType,\r\n selectPage,\r\n selectSportsFacilities,\r\n selectMoveInDateRange,\r\n (\r\n geoLocationType,\r\n marketId,\r\n marketName,\r\n city,\r\n county,\r\n syntheticName,\r\n stateAbbreviation,\r\n zip,\r\n productType,\r\n brandId,\r\n brandName,\r\n schoolDistrictName,\r\n communityName,\r\n resultType,\r\n pageNumber,\r\n sportsFacilities,\r\n moveInDateRange\r\n ) => ({\r\n geoLocationType,\r\n marketId,\r\n marketName,\r\n city,\r\n county,\r\n syntheticName,\r\n stateAbbreviation,\r\n zip,\r\n productType,\r\n brandId,\r\n brandName,\r\n schoolDistrictName,\r\n communityName,\r\n resultType,\r\n pageNumber,\r\n sportsFacilities,\r\n moveInDateRange,\r\n })\r\n);\r\n\r\nexport const selectSubdirectory = createSelector(\r\n selectResultsType,\r\n selectCondosAndTownHomes,\r\n selectSingleFamily,\r\n selectHomeStatus,\r\n isCustom,\r\n isBuildOnYourLot,\r\n isManufactured,\r\n (resultType, condosAndTownHomes, singleFamily, homeStatus, custom, buildOnYourLot, manufactured) => ({\r\n resultType,\r\n condosAndTownHomes,\r\n singleFamily,\r\n homeStatus,\r\n custom,\r\n buildOnYourLot,\r\n manufactured,\r\n })\r\n);\r\n\r\nexport const selectBrand = createSelector(\r\n selectBrandName,\r\n selectBrandId,\r\n selectResultType,\r\n (brandName, brandId, resultType) => ({\r\n brandName,\r\n brandId,\r\n resultType,\r\n })\r\n);\r\n\r\nexport const selectBrandFilterContext = createSelector(selectBrands, selectBrandId, (brands, brandId) => ({\r\n brands,\r\n brandId,\r\n}));\r\n\r\n// selector created to tap into the features object in the store\r\n// and return the current values of the community amenities.\r\nexport const communityAmenitiesSelector = createSelector(\r\n selectNatureAreas,\r\n selectPool,\r\n selectGolfCourse,\r\n selectGreen,\r\n selectSportsFacilities,\r\n selectParks,\r\n selectViews,\r\n selectWaterfront,\r\n selectGatedCommunity,\r\n (natureAreas, pool, golfCourse, green, sportsFacilities, parks, views, waterfront, gatedCommunity) => ({\r\n natureAreas,\r\n pool,\r\n golfCourse,\r\n green,\r\n sportsFacilities,\r\n parks,\r\n views,\r\n waterfront,\r\n gatedCommunity,\r\n })\r\n);\r\n\r\nexport const selectContentTemplateTypeModifiers = createSelector(\r\n selectAppliedFacets,\r\n selectProductType,\r\n selectHomeStatus,\r\n selectBrandId,\r\n (appliedFacetList, productType, homeStatus, brandId) => ({ appliedFacetList, productType, homeStatus, brandId })\r\n);\r\n\r\nexport const selectPaginationContext = createSelector(\r\n selectPage,\r\n selectPageSize,\r\n selectListingCount,\r\n (pageNumber, pageSize, listingCount) => ({ pageNumber, pageSize, listingCount })\r\n);\r\n\r\nexport const pageCountSelector = createSelector(selectPageSize, selectListingCount, (pageSize, listingCount) =>\r\n Math.ceil(listingCount / pageSize)\r\n);\r\n\r\nexport const moveInDateSelector = createSelector(\r\n selectHomeStatus,\r\n selectMoveInDateRange,\r\n (homeStatus, moveInDateRange) => ({\r\n homeStatus,\r\n moveInDateRange,\r\n })\r\n);\r\n\r\nexport const isAnyHousingTypeActiveSelector = createSelector(\r\n selectSingleFamily,\r\n selectLuxury,\r\n selectCondosAndTownHomes,\r\n isCustom,\r\n isBuildOnYourLot,\r\n isManufactured,\r\n selectHomeStatus,\r\n (singleFamily, luxury, condosAndTownHomes, custom, buildOnYourLot, manufactured, homeStatus) =>\r\n Boolean(singleFamily || luxury || condosAndTownHomes ||\r\n custom || buildOnYourLot || manufactured || (homeStatus === SpecStatus.Model.toString()))\r\n);\r\n\r\n/**\r\n * selector used to get the facets' current state from the store\r\n * @param {object} state\r\n */\r\nexport const facetsSelector = createSelector(\r\n selectNatureAreas,\r\n selectPool,\r\n selectGolfCourse,\r\n selectGreen,\r\n selectSportsFacilities,\r\n selectParks,\r\n selectViews,\r\n selectWaterfront,\r\n selectGatedCommunity,\r\n selectRvGarage,\r\n selectReviews,\r\n selectConsumerPromos,\r\n selectPriceReduction,\r\n selectAdult,\r\n selectAgeRestricted,\r\n selectMinimumPrice,\r\n selectMaximumPrice,\r\n selectBathrooms,\r\n selectBedrooms,\r\n selectSchools,\r\n selectBrandId,\r\n selectGarages,\r\n selectMarketingStatus,\r\n selectPrimaryBedroom,\r\n selectStories,\r\n selectLivingAreas,\r\n selectSingleFamily,\r\n selectLuxury,\r\n selectCondosAndTownHomes,\r\n isCustomHomes,\r\n moveInDateSelector,\r\n selectCommunityName,\r\n isManufactured,\r\n selectHomeStatus,\r\n selectExcludeAdult,\r\n selectExcludeAgeRestricted,\r\n selectSorting,\r\n selectHomeOwnersAssociationFee,\r\n (\r\n natureAreas,\r\n pool,\r\n golfCourse,\r\n green,\r\n sportsFacilities,\r\n parks,\r\n views,\r\n waterfront,\r\n gatedCommunity,\r\n rvGarage,\r\n reviews,\r\n consumerPromos,\r\n priceReduction,\r\n adult,\r\n ageRestricted,\r\n minimumPrice,\r\n maximumPrice,\r\n bathrooms,\r\n bedrooms,\r\n schools,\r\n brand,\r\n garages,\r\n marketingStatus,\r\n primaryBedroom,\r\n stories,\r\n livingAreas,\r\n singleFamily,\r\n luxury,\r\n condosAndTownHomes,\r\n customHomes,\r\n moveInDate,\r\n communityName,\r\n manufactured,\r\n homeStatus,\r\n excludeAdult,\r\n excludeAgeRestricted,\r\n sorting,\r\n hasHomeOwnersAssociationFee,\r\n ) => {\r\n const filters = {\r\n natureAreas,\r\n comingsoon: isComingSoon(marketingStatus),\r\n grandOpening: isGrandOpening(marketingStatus),\r\n active: isActive(marketingStatus),\r\n closeOut: isCloseOut(marketingStatus),\r\n pool,\r\n golfCourse,\r\n green,\r\n sportsFacilities,\r\n parks,\r\n views,\r\n waterfront,\r\n gatedCommunity,\r\n rvGarage,\r\n reviews,\r\n hotDeals: consumerPromos,\r\n priceReduction,\r\n moveInDate: isMoveInDateApplied(moveInDate),\r\n modelHomes: hasModelHome(homeStatus),\r\n adult,\r\n ageRestricted,\r\n price: minimumPrice || maximumPrice,\r\n bathrooms: Number(bathrooms),\r\n bedrooms: Number(bedrooms),\r\n schoolDistrict: Boolean(schools?.length),\r\n builderBrand: Number(brand),\r\n garages: Number(garages),\r\n primaryBedroom: Number(primaryBedroom),\r\n stories: Number(stories),\r\n livingAreas: Number(livingAreas),\r\n singleFamily,\r\n luxury,\r\n condosAndTownHomes,\r\n customHomes,\r\n communityName,\r\n manufactured,\r\n exclude55: Boolean(excludeAdult && excludeAgeRestricted),\r\n sort: sorting?.sortBy,\r\n hasHomeOwnersAssociationFee,\r\n };\r\n\r\n return filters;\r\n }\r\n);\r\n\r\n/** this selector is intended to expose all the properties that should be included as common tracking properties.\r\n * the idea behind this is tha here should be placed the selectors/props that are usually used in tracking events.\r\n * then the consumers will filter and take the props they need, this will just serve the information.\r\n */\r\nexport const selectSearchResultFacetsTrackingCommonProperties = createSelector(\r\n selectLocation,\r\n selectBrandInformation,\r\n facetsSelector,\r\n selectPaginationContext,\r\n selectPrice,\r\n selectSchools,\r\n moveInDateSelector,\r\n (location, brandInformation, facetsList, paginationContext, price, schools, moveInDate) => {\r\n const { brandId, brandName } = brandInformation;\r\n const { pageNumber, listingCount } = paginationContext;\r\n return { location, brandId, brandName, facetsList, pageNumber, listingCount, price, schools, moveInDate };\r\n }\r\n);\r\n\r\n/**\r\n * This selector aims to expose all properties that can be used as a filter in a home.\r\n */\r\nexport const homeFactsSelectors = createSelector(\r\n selectRvGarage,\r\n selectBathrooms,\r\n selectBedrooms,\r\n selectGarages,\r\n selectPrimaryBedroom,\r\n selectStories,\r\n selectLivingAreas,\r\n (\r\n rvGarage,\r\n bathrooms,\r\n bedrooms,\r\n garages,\r\n primaryBedroom,\r\n stories,\r\n livingAreas,\r\n ) => {\r\n const filters = {\r\n rvGarage,\r\n bathrooms: Number(bathrooms),\r\n bedrooms: Number(bedrooms),\r\n garages: Number(garages),\r\n primaryBedroom: Number(primaryBedroom),\r\n stories: Number(stories),\r\n livingAreas: Number(livingAreas),\r\n }\r\n return filters;\r\n }\r\n);\r\n\r\n/**\r\n * This selector has the objective of displaying all the properties related to the filters in the SRP all filters menu.\r\n */\r\nexport const facetsPanelSelector = createSelector(\r\n communityAmenitiesSelector,\r\n selectPrice,\r\n homeFactsSelectors,\r\n brandIdAndSchoolsSelector,\r\n otherFiltersSelector,\r\n moveInDateSelector,\r\n housingOptionsSelector,\r\n communityStatusSelector,\r\n (\r\n communityAmenities,\r\n price,\r\n homeFacts,\r\n brandAndSchools,\r\n otherFilters,\r\n moveInDate,\r\n housingOptions,\r\n communityStatus,\r\n ) => {\r\n const filters = {\r\n amenities: communityAmenities,\r\n moveInDate: getMovingDateFilterApplied(moveInDate),\r\n price,\r\n homeFacts,\r\n brandAndSchools,\r\n housingOptions,\r\n communityStatus,\r\n otherFilters,\r\n };\r\n\r\n return filters;\r\n }\r\n);\r\n\r\n/**\r\n * This selector aims to display all the properties related to the filters in the popular search pills.\r\n * When the golf course pill is removed from the popular searches pills, please delete the amenities property from here.\r\n * Ticket where that pill will be removed: https://builderhomesite.atlassian.net/browse/NHS20-2391.\r\n */\r\nexport const selectLinkedPopularPillsFilters = createSelector(\r\n communityAmenitiesSelector,\r\n otherFiltersSelector,\r\n moveInDateSelector,\r\n housingOptionsSelector,\r\n selectMarketingStatus,\r\n (\r\n communityAmenities,\r\n otherFilters,\r\n moveInDate,\r\n housingOptions,\r\n marketingStatus,\r\n ) => {\r\n const filters = {\r\n amenities: communityAmenities,\r\n otherFilters,\r\n moveInDate: getMovingDateFilterApplied(moveInDate),\r\n housingOptions,\r\n comingsoon: isComingSoon(marketingStatus),\r\n };\r\n return filters;\r\n }\r\n);\r\n\r\n/**\r\n * This selectors maps the sorting value along with the result type value from Store.\r\n */\r\nexport const selectResultTypeAndSorting = createSelector(\r\n selectSorting,\r\n selectResultType,\r\n (\r\n sorting,\r\n resultType\r\n ) => ({\r\n sorting,\r\n resultType,\r\n })\r\n);\r\n\r\n/**\r\n * This selector maps all the state properties that can drive an user search.\r\n */\r\nexport const selectSearchModifiers = createSelector(\r\n selectFeatures,\r\n selectFacts,\r\n selectLocation,\r\n selectProduct,\r\n selectResults,\r\n selectResultsModifiers,\r\n selectFetchResultListingsStatus,\r\n (feature, facts, location, product, results, modifiers, fetchResultsListingStatus) => ({\r\n feature,\r\n facts,\r\n location,\r\n product,\r\n results,\r\n modifiers,\r\n fetchResultsListingStatus,\r\n })\r\n);","import PlanStatus from '../enums/planStatus';\r\nimport SpecStatus from '../enums/specStatus';\r\n\r\n/**\r\n * It checks if the homeStatus has AvailableNow (A).\r\n * @param homeStatus - The status of the home.\r\n */\r\nexport const hasAvailableNow = (homeStatus) => {\r\n const statusArray = homeStatus?.split?.(',');\r\n\r\n return statusArray?.some(\r\n (key) => PlanStatus.fromKey(key) === PlanStatus.AvailableNow || SpecStatus.fromKey(key) === SpecStatus.AvailableNow\r\n );\r\n};\r\n\r\n/**\r\n * It checks if the homeStatus has ReadyToBuild (R).\r\n * @param homeStatus - The status of the home.\r\n */\r\nexport const hasReadyToBuild = (homeStatus) => {\r\n const statusArray = homeStatus?.split?.(',');\r\n\r\n return statusArray?.some(\r\n (key) => PlanStatus.fromKey(key) === PlanStatus.ReadyToBuild || SpecStatus.fromKey(key) === SpecStatus.ReadyToBuild\r\n );\r\n};\r\n\r\n/**\r\n * It checks if the homeStatus has UnderConstruction (UC).\r\n * @param homeStatus - The status of the home.\r\n */\r\nexport const hasUnderConstruction = (homeStatus) => {\r\n const statusArray = homeStatus?.split?.(',');\r\n\r\n return statusArray?.some(\r\n (key) =>\r\n PlanStatus.fromKey(key) === PlanStatus.UnderConstruction ||\r\n SpecStatus.fromKey(key) === SpecStatus.UnderConstruction\r\n );\r\n};\r\n\r\n/**\r\n * It checks if the homeStatus has Model (M).\r\n * @param homeStatus - The status of the home.\r\n */\r\nexport const hasModelHome = (homeStatus) => {\r\n const statusArray = homeStatus?.split?.(',');\r\n\r\n return statusArray?.some((key) => SpecStatus.fromKey(key) === SpecStatus.Model);\r\n};\r\n\r\n/**\r\n * It checks if the homeStatus has Hot Deal (H)\r\n * @param homeStatus - The status of the home.\r\n */\r\nexport const hasHotDeal = (homeStatus) => {\r\n const statusArray = homeStatus?.split?.(',');\r\n\r\n return statusArray?.some(\r\n (key) => PlanStatus.fromKey(key) === PlanStatus.HotDeals || SpecStatus.fromKey(key) === SpecStatus.HotDeals\r\n );\r\n};\r\n\r\n/**\r\n * It checks if the homeStatus has Inventory status combination (A,UC).\r\n * @param homeStatus - The status of the home.\r\n */\r\nexport const hasInventoryStatusCombination = (homeStatus) => {\r\n const isAvailableNowIncluded = hasAvailableNow(homeStatus);\r\n const isUnderConstructionIncluded = hasUnderConstruction(homeStatus);\r\n\r\n return isAvailableNowIncluded && isUnderConstructionIncluded;\r\n};\r\n\r\n/**\r\n * Returns the Inventory status combination (A,UC).\r\n * @param homeStatus - The status of the home.\r\n */\r\nexport const getInventoryStatusCombination = () => {\r\n const inventoryStatuses = [SpecStatus.AvailableNow.name, SpecStatus.UnderConstruction.name];\r\n\r\n return inventoryStatuses.join(',');\r\n};","import MoveInDate from '../enums/moveInDate';\r\nimport PlanStatus from '../enums/planStatus';\r\nimport {\r\n getInventoryStatusCombination,\r\n hasAvailableNow,\r\n hasInventoryStatusCombination,\r\n hasReadyToBuild,\r\n} from './homeStatusValidator';\r\n\r\n/**\r\n * A function that verifies if move in date filters are applied.\r\n *\r\n * When the home status Available Now, Ready to Build or move in data range are applied\r\n * the move in date filter is applied. Otherwise false.\r\n */\r\nfunction isMoveInDateApplied(selector) {\r\n const { homeStatus, moveInDateRange } = selector;\r\n // For All Quick Move In option.\r\n if (hasInventoryStatusCombination(homeStatus)) {\r\n return true;\r\n }\r\n\r\n // For Move Now option.\r\n if (hasAvailableNow(homeStatus)) {\r\n return true;\r\n }\r\n\r\n // For Buildable plans option.\r\n if (hasReadyToBuild(homeStatus)) {\r\n return true;\r\n }\r\n\r\n // For Move In date ranges options.\r\n if (\r\n moveInDateRange === MoveInDate.OneToTwoMonths.toString() ||\r\n moveInDateRange === MoveInDate.ThreeToSixMonths.toString()\r\n ) {\r\n return true;\r\n }\r\n\r\n return false;\r\n}\r\n\r\n/**\r\n * Gets the home status filter applied from the state.\r\n * @param {string} homeStatus The home status search parameter value.\r\n * @returns The type of home status filter applied if any.\r\n */\r\nconst getHomeStatusFilterApplied = (homeStatus) => {\r\n if (hasInventoryStatusCombination(homeStatus)) {\r\n return getInventoryStatusCombination();\r\n }\r\n\r\n if (hasAvailableNow(homeStatus)) {\r\n return PlanStatus.AvailableNow.toString();\r\n }\r\n\r\n if (hasReadyToBuild(homeStatus)) {\r\n return PlanStatus.ReadyToBuild.toString();\r\n }\r\n\r\n return '';\r\n};\r\n\r\n/**\r\n * Gets the move in date filter applied from the state.\r\n * @param {string} moveInDateRange The move in date range search parameter value.\r\n * @returns the move in date filter applied if any.\r\n */\r\nconst getMoveInDateFilterApplied = (moveInDateRange) => {\r\n switch (moveInDateRange) {\r\n case MoveInDate.OneToTwoMonths.toString():\r\n return MoveInDate.OneToTwoMonths.toString();\r\n case MoveInDate.ThreeToSixMonths.toString():\r\n return MoveInDate.ThreeToSixMonths.toString();\r\n case MoveInDate.BuildablePlans.toString():\r\n return MoveInDate.BuildablePlans.toString();\r\n default:\r\n return '';\r\n }\r\n};\r\n\r\n/**\r\n * Return the move in date filter applied according to home status or moveInDateRange search parameters.\r\n */\r\nconst getMovingDateFilterApplied = (parameters) => {\r\n const { homeStatus, moveInDateRange } = parameters;\r\n const homeStatusFilterApplied = getHomeStatusFilterApplied(homeStatus);\r\n\r\n if (homeStatusFilterApplied) {\r\n return homeStatusFilterApplied;\r\n }\r\n\r\n const moveInDateFilterApplied = getMoveInDateFilterApplied(moveInDateRange);\r\n if (moveInDateFilterApplied) {\r\n return moveInDateFilterApplied;\r\n }\r\n\r\n return '';\r\n};\r\n\r\nexport { isMoveInDateApplied, getMovingDateFilterApplied, getHomeStatusFilterApplied };\r\n","/**\r\n * Represents the possible markers located on the map to show.\r\n */\r\nexport default class MarkerType {\r\n \r\n /**\r\n * It represents the Buildable Plan Pin on the map.\r\n */\r\n static get BuildablePlan() {\r\n return this.getInstance('buildeablePlan');\r\n }\r\n\r\n /**\r\n * It represents the Housing Development Pins, also called as Community Pins.\r\n */\r\n static get HousingDevelopment() {\r\n return this.getInstance('community');\r\n }\r\n\r\n /**\r\n * It represents the Plan Unit Pins.\r\n */\r\n static get PlanUnit() {\r\n return this.getInstance('plan');\r\n }\r\n\r\n /**\r\n * It represents the Spec Unit Pins.\r\n */\r\n static get SpecUnit() {\r\n return this.getInstance('spec');\r\n }\r\n\r\n static fromKey(key) {\r\n const map = {\r\n buildeablePlan: MarkerType.BuildablePlan,\r\n community: MarkerType.HousingDevelopment,\r\n plan: MarkerType.PlanUnit,\r\n spec: MarkerType.SpecUnit\r\n };\r\n return map[key];\r\n }\r\n\r\n static getInstance(key) {\r\n if (!this.instances[key]) {\r\n this.instances[key] = new MarkerType(key);\r\n }\r\n return this.instances[key];\r\n }\r\n\r\n constructor(name) {\r\n this.name = name;\r\n }\r\n\r\n toString() {\r\n return `${this.name}`;\r\n }\r\n}\r\n\r\nObject.defineProperty(MarkerType, 'instances', { value: {} });\r\n","import { createSelector } from '@reduxjs/toolkit';\r\nimport LoadingStatus from 'enums/loadingStatus';\r\nimport { selectLocation, selectPage } from 'features/searchResultsFacets';\r\nimport MarkerType from '../enums/markerType';\r\n\r\n/**\r\n * Returns true if search within map flag is on.\r\n * @param state - The state of the redux store\r\n */\r\nexport const selectIsSearchWithinMapReady = (state) => state?.mapState?.isSearchWithinMapReady;\r\n\r\n/**\r\n * Returns the geolocation of the point of interest listing.\r\n * @param state - The state of the redux store\r\n */\r\nexport const selectFocusedGeographicKey = (state) => state?.uiState?.focusedListing?.geographicKey;\r\n\r\n/**\r\n * Returns the Id of the listing being hovered.\r\n * @param state - The state of the redux store\r\n */\r\nexport const selectFocusedListingId = (state) => state?.uiState?.focusedListing?.id;\r\n\r\n/**\r\n * Returns the community Id of the listing being hovered.\r\n * @param state - The state of the redux store\r\n */\r\nexport const selectFocusedCommunityId = (state) => state?.uiState?.focusedListing?.communityId;\r\n\r\n/**\r\n * Returns true if the Geo Coordinates object has been defined.\r\n * @param state - The state of the redux store\r\n */\r\nexport const areMapBoundariesDefined = (state) => !!state?.mapState?.geoCoordinates;\r\n\r\n/**\r\n * If the state has a mapState property, and that property has a HomeResults property, then return true.\r\n * Otherwise, return false\r\n * @param state - The state of the Redux store.\r\n */\r\nexport const areMarkersAvailable = (state) => !!state?.mapState?.results;\r\n\r\n/**\r\n * It returns the Geo Coordinates from the mapState in the Redux store.\r\n * @param state - The state of the redux store\r\n */\r\nexport const geoCoordinates = (state) => state?.mapState?.geoCoordinates;\r\n\r\n/**\r\n * Returns true if the map is not fetching results from the server.\r\n * @param state - The state of the Redux store.\r\n */\r\nexport const isMapIdle = (state) => !state?.mapState?.isFetchingResults;\r\n\r\n/**\r\n * Returns true if the map is fetching results from the server.\r\n * @param state - The state of the Redux store.\r\n */\r\nexport const isFetchingResults = (state) => state?.mapState?.isFetchingResults;\r\n\r\n/**\r\n * Returns the map library status.\r\n * @param state - The state of the Redux store.\r\n */\r\nexport const selectMapLibraryStatus = (state) => state?.mapState?.mapLibraryStatus;\r\n\r\n/**\r\n * Returns true if the map library is fetching.\r\n * @param state - The state of the Redux store.\r\n */\r\nexport const isMapLibraryFetching = (state) => state?.mapState?.mapLibraryStatus === LoadingStatus.Loading.toString();\r\n\r\n/**\r\n * Returns true if the map library has been loaded.\r\n * @param state - The state of the Redux store.\r\n */\r\nexport const isMapLibraryLoaded = (state) => state?.mapState?.mapLibraryStatus === LoadingStatus.Succeeded.toString();\r\n\r\n/**\r\n * If the state has a mapState property,and the property has a isSearchWithinMap property, return that property.\r\n *\r\n * @param state - The state of the Redux store.\r\n */\r\nexport const isSearchWithinMapEnabled = (state) => state?.mapState?.isSearchWithinMap;\r\n\r\n/**\r\n * It returns the results from the mapState in the Redux store.\r\n * @param state - The state of the redux store\r\n */\r\nexport const mapMarkers = (state) => state?.mapState?.results;\r\n\r\n/**\r\n * Returns an array representing all of the current plan identifiers.\r\n * @param state - The state of the redux store\r\n */\r\nexport const selectAllPlansIds = (state) => state?.mapState?.allPlanIds;\r\n\r\n/**\r\n * If the user click a marker, it is store in this property.\r\n */\r\nexport const selectedMarker = (state) => state?.mapState?.selectedMarker;\r\n\r\n/**\r\n * the summary card information.\r\n */\r\nexport const selectedNearbyListingCarousel = (state) => state?.mapState?.nearbyListingsCarousel;\r\n\r\n/**\r\n * the summary card status information.\r\n */\r\nexport const selectedNearbyListingsCarouselStatus = (state) => state?.mapState?.nearbyListingsCarouselStatus;\r\n\r\n/**\r\n * the current map zoom level.\r\n */\r\nexport const selectZoomLevel = (state) => state?.mapState?.zoomLevel;\r\n\r\n/**\r\n * selects community site plans information.\r\n */\r\nexport const selectSitePlans = (state) => state?.mapState?.sitePlans;\r\n\r\n/**\r\n * selects interactive site plan information.\r\n */\r\nexport const selectInteractiveSitePlans = (state) => state?.interactiveSitePlanState?.interactiveSitePlans;\r\n\r\n/**\r\n * selects interactive site plan tracking information to understand which one are loaded.\r\n */\r\nexport const selectTrackedInteractiveSitePlans = (state) =>\r\n state?.interactiveSitePlanState?.loadedInteractiveSitePlans;\r\n\r\n/**\r\n * selects the lot number clicked by the user\r\n */\r\nexport const selectLotNumber = (state) => state?.interactiveSitePlanState?.lotNumber;\r\n\r\n/**\r\n * selects the lot identifier\r\n */\r\nexport const selectLotId = (state) => state?.interactiveSitePlanState?.lotId;\r\n\r\n/**\r\n * selects the community id of the current active lot\r\n */\r\nexport const selectLotCommunityId = (state) => state?.interactiveSitePlanState?.communityId;\r\n\r\n/**\r\n * select the available plans that can be built in a selected lot\r\n */\r\nexport const selectAvailablePlans = (state) => state?.interactiveSitePlanState?.availablePlans;\r\n\r\n/**\r\n * select the spec built in a selected lot\r\n */\r\nexport const selectAvailableSpec = (state) => state?.interactiveSitePlanState?.availableSpec;\r\n\r\n/**\r\n * select the active lot status of an interactive site plan\r\n */\r\nexport const selectLotStatus = (state) => state?.interactiveSitePlanState?.lotStatus;\r\n\r\n/**\r\n * selects information about lot summary card.\r\n */\r\nexport const selectedLotSummaryCard = (state) =>\r\n state?.interactiveSitePlanState?.interactiveSitePlanCard;\r\n\r\n/**\r\n * selects information about active lot, specifically: site plan id.\r\n */\r\nexport const selectedLotSitePlanId = (state) =>\r\n state?.interactiveSitePlanState?.sitePlanId;\r\n\r\n/**\r\n * selects the status of the lot listings carousel.\r\n */\r\nexport const selectedLotSummaryCardStatus = (state) =>\r\n state?.interactiveSitePlanState?.interactiveSitePlanCardStatus;\r\n\r\n/**\r\n * Gets the data for the summary card, and the marker that triggered\r\n */\r\nexport const selectNearbyListingsCarouselStatusAndMarkerData = createSelector(\r\n selectedNearbyListingsCarouselStatus,\r\n selectedMarker,\r\n (status, marker) => ({ status, marker })\r\n);\r\n\r\n/**\r\n * Gets data related to lot information.\r\n */\r\nexport const selectLotInformation = createSelector(\r\n selectLotId,\r\n selectLotCommunityId,\r\n selectedLotSummaryCard,\r\n selectedLotSummaryCardStatus,\r\n selectedLotSitePlanId,\r\n (\r\n lotId,\r\n communityId,\r\n summaryCard,\r\n summaryCardStatus,\r\n sitePlanId) => ({\r\n lotId,\r\n communityId,\r\n summaryCard,\r\n summaryCardStatus,\r\n sitePlanId\r\n })\r\n);\r\n\r\n/**\r\n * Gets the community id of the opened lot summary card along with the site plans.\r\n */\r\nexport const selectLotCommunityIdAndSitePlans = createSelector(\r\n selectLotCommunityId,\r\n selectSitePlans,\r\n (\r\n lotCommunityId,\r\n sitePlans) => ({\r\n lotCommunityId,\r\n sitePlans,\r\n })\r\n);\r\n\r\n/**\r\n * If the state has a mapState property, and the property has a hoveredMarker property, return that property.\r\n *\r\n * @param state - The state of the Redux store.\r\n */\r\nexport const selectHoveredMarker = (state) => state?.mapState?.hoveredMarker;\r\n\r\n\r\n/**\r\n * It returns the point of interest hovered by the user\r\n */\r\nexport const selectFocusedListing = createSelector(\r\n selectFocusedListingId,\r\n selectFocusedCommunityId,\r\n selectFocusedGeographicKey,\r\n (id, communityId, geographicKey) => ({\r\n id,\r\n communityId,\r\n geographicKey,\r\n })\r\n);\r\n\r\n/**\r\n * It returns the current map geo coordinates along with the current location.\r\n */\r\nexport const selectGeoCoordinatesAndLocation = createSelector(\r\n geoCoordinates,\r\n selectLocation,\r\n (coordinates, location) => ({\r\n coordinates,\r\n location,\r\n })\r\n);\r\n\r\nexport const selectSearchMapTrackingCommonProperties = createSelector(\r\n isSearchWithinMapEnabled,\r\n (isSearchWithinMap) => ({ isSearchWithinMap })\r\n);\r\n\r\nexport const selectedMarkerAndPage = createSelector(\r\n selectedMarker,\r\n selectPage,\r\n (marker, page) => (\r\n {\r\n marker, \r\n page\r\n }\r\n )\r\n);\r\n\r\n/**\r\n * selector that will retrieve information related with current map zoom level, map geo coordinates,\r\n * search within map status and map markers.\r\n */\r\nexport const selectSitePlansProperties = createSelector(\r\n selectZoomLevel,\r\n geoCoordinates,\r\n isSearchWithinMapEnabled,\r\n mapMarkers,\r\n isFetchingResults,\r\n isMapLibraryLoaded,\r\n selectSitePlans,\r\n (zoomLevel, coordinates, isSearchWithinMap, markers, isFetching, isMapLoaded, sitePlans) => (\r\n {\r\n zoomLevel,\r\n coordinates,\r\n isSearchWithinMap,\r\n markers,\r\n isFetching,\r\n isMapLoaded,\r\n sitePlans,\r\n }\r\n )\r\n);\r\n\r\n/**\r\n * selector that will retrieve information related with map markers and community site plans.\r\n */\r\nexport const selectMarkersAndSitePlans = createSelector(\r\n mapMarkers,\r\n selectSitePlans,\r\n (markers, sitePlans) => (\r\n {\r\n markers,\r\n sitePlans,\r\n }\r\n )\r\n);\r\n\r\n/**\r\n * selector that will retrieve information related with the focused listing card and community site plans.\r\n */\r\nexport const selectFocusedListingAndSitePlans = createSelector(\r\n selectFocusedListing,\r\n selectSitePlans,\r\n (focusedListing, sitePlans) => (\r\n {\r\n focusedListing,\r\n sitePlans,\r\n }\r\n )\r\n);\r\n\r\n/**\r\n * selector that will retrieve all specs and plans represented in the current results page.\r\n */\r\nexport const selectAllPlansAndSpecsIds = createSelector(\r\n mapMarkers,\r\n selectAllPlansIds,\r\n (markers, allPlans) => ({\r\n specs: markers?.filter((marker) => marker.type === MarkerType.SpecUnit.toString()).map((spec) => spec.id) || [],\r\n plans: allPlans || [],\r\n })\r\n);\r\n\r\n","import { store } from '@redux/store';\r\nimport { selectConfigurationSegmentApiKey } from 'layout/redux/selectors'\r\n\r\n/**\r\n * The getSegmentKey function returns the Segment API key from the Redux store.\r\n * key is taken from bhi config and expose through the store.\r\n * @return A string\r\n */\r\nconst getSegmentApiKey = () => {\r\n const state = store.getState();\r\n const segmentApiKey = selectConfigurationSegmentApiKey(state);\r\n\r\n return segmentApiKey;\r\n}\r\n\r\n/* `const analyticsInstance` is an object that stores the state of the analytics script. It has three\r\nproperties: `isAnalyticsScriptLoaded`, `isAnalyticsScriptLoading`, and `loadingAttemps`. */\r\nconst analyticsInstance = {\r\n isAnalyticsScriptLoaded: false,\r\n isAnalyticsScriptLoading: false,\r\n loadingAttemps: 0,\r\n};\r\n\r\n/**\r\n * The onAnalyticsError function is called when the analytics script fails to load.\r\n * \r\n *\r\n * @param reject Reject the promise\r\n *\r\n * @return A promise\r\n */\r\nconst onAnalyticsError = (reject) => {\r\n console.log('Unable to load analytics script.');\r\n analyticsInstance.isAnalyticsScriptLoaded = false;\r\n analyticsInstance.isAnalyticsScriptLoading = false;\r\n reject(new Error(`Unable to load analytics script.`));\r\n};\r\n \r\n/**\r\n * The onAnalyticsLoaded function is called when the analytics script has been loaded.\r\n * \r\n *\r\n * @param resolve Resolve the promise\r\n *\r\n * @return A promise\r\n */\r\nconst onAnalyticsLoaded = (resolve) => {\r\n analyticsInstance.isAnalyticsScriptLoaded = true;\r\n resolve();\r\n};\r\n\r\n\r\n/**\r\n * The isAnalyticsLoaded function checks if the analytics script has been loaded.\r\n * If it is, then it resolves the promise with a call to onAnalyticsLoaded. \r\n * Otherwise, if loadingAttemps is less than 10, then we increment loadingAttemps and try again in 100ms.\r\n * If loadingAttempts reaches 10 without resolving the promise, we reject it with a call to onAnalyticsError.\r\n *\r\n * @param resolve Call the onanalyticsloaded function\r\n * @param reject Reject the promise\r\n *\r\n * @return A promise\r\n */\r\nconst isAnalyticsLoaded = (resolve, reject) => { \r\n if (analyticsInstance.isAnalyticsScriptLoaded) {\r\n onAnalyticsLoaded(resolve);\r\n } else if (analyticsInstance.loadingAttemps < 10){\r\n analyticsInstance.loadingAttemps = + 1;\r\n setTimeout(isAnalyticsLoaded.bind(null, resolve, reject), 100);\r\n } else {\r\n onAnalyticsError(reject);\r\n }\r\n};\r\n\r\n\r\n/**\r\n * The waitForAnalytics function returns a Promise that resolves when the Segment Analytics library has loaded.\r\n * @return A promise\r\n */\r\nconst waitForAnalytics = () =>\r\nnew Promise((resolve, reject) => {\r\n setTimeout(isAnalyticsLoaded.bind(null, resolve, reject), 100);\r\n});\r\n\r\n\r\n/**\r\n * The appendAnalyticsScript function appends the analytics script to the DOM.\r\n * @param resolve Resolve the promise\r\n * @param reject Reject the promise\r\n *\r\n * @return A promise\r\n */\r\nconst appendAnalyticsScript = (resolve, reject) => {\r\n \r\n /** Segment script to laod analytics.js */\r\n var analytics=window.analytics=window.analytics||[];if(!analytics.initialize)if(analytics.invoked)window.console&&console.error&&console.error(\"Segment snippet included twice.\");else{analytics.invoked=!0;analytics.methods=[\"trackSubmit\",\"trackClick\",\"trackLink\",\"trackForm\",\"pageview\",\"identify\",\"reset\",\"group\",\"track\",\"ready\",\"alias\",\"debug\",\"page\",\"once\",\"off\",\"on\",\"addSourceMiddleware\",\"addIntegrationMiddleware\",\"setAnonymousId\",\"addDestinationMiddleware\"];analytics.factory=function(e){return function(){var t=Array.prototype.slice.call(arguments);t.unshift(e);analytics.push(t);return analytics}};for(var e=0;e {};\r\nconst segmentAnalyticsErrored = () => {};\r\n\r\nconst onConfigurationLoaded$ = store$.pipe(\r\n map(selectLoading),\r\n filter((loadingStatus) => loadingStatus === LoadingStatus.Succeeded.toString()),\r\n distinctUntilChanged()\r\n);\r\n\r\n// Loads segment analytics library\r\n/* `loadAnalytics(segmentAnalyticsLoaded, segmentAnalyticsErrored);` is calling the `loadAnalytics`\r\nfunction from the `segmentAnalyticsLibrary` module and passing two callback functions\r\n`segmentAnalyticsLoaded` and `segmentAnalyticsErrored` as arguments. These callback functions will\r\nbe executed depending on whether the analytics library is successfully loaded or if there is an\r\nerror during the loading process. */\r\nonConfigurationLoaded$.subscribe(() => loadAnalytics(segmentAnalyticsLoaded, segmentAnalyticsErrored));\r\n\r\nexport { segmentTrack, segmentImpression, segmentIdentify, segmentPageView };\r\n","import { createAction } from '@reduxjs/toolkit';\r\n\r\n// Event Action of type Track\r\n/* `const segmentTrack = createAction('segment/track');` is creating an action creator function using\r\nthe `createAction` function from the `@reduxjs/toolkit` library. This action creator function will\r\nreturn an action object with a `type` property set to `'segment/track'` when it is called. This\r\naction can then be dispatched to the Redux store to trigger a state update or other side effects. */\r\nconst segmentTrack = createAction('segment/track');\r\n\r\n// Event Action of type Impression\r\n/* `const segmentImpression = createAction('segment/impression');` is creating an action creator\r\nfunction using the `createAction` function from the `@reduxjs/toolkit` library. This action creator\r\nfunction will return an action object with a `type` property set to `'segment/impression'` when it\r\nis called. This action can then be dispatched to the Redux store to trigger a state update or other\r\nside effects. */\r\nconst segmentImpression = createAction('segment/impression');\r\n\r\n/* `const segmentIdentify = createAction('segment/identify');` is creating an action creator function\r\nusing the `createAction` function from the `@reduxjs/toolkit` library. This action creator function\r\nwill return an action object with a `type` property set to `'segment/identify'` when it is called.\r\nThis action can then be dispatched to the Redux store to trigger a state update or other side\r\neffects. */\r\nconst segmentIdentify = createAction('segment/identify');\r\n\r\n/* `const segmentPageView = createAction('segment/pageview');` is creating an action creator function\r\nusing the `createAction` function from the `@reduxjs/toolkit` library. This action creator function\r\nwill return an action object with a `type` property set to `'segment/pageview'` when it is called.\r\nThis action can then be dispatched to the Redux store to trigger a state update or other side\r\neffects. */\r\nconst segmentPageView = createAction('segment/pageview');\r\n\r\nexport { segmentTrack, segmentImpression, segmentIdentify, segmentPageView };\r\n","export default class SegmentEventType {\r\n /**\r\n * This is a static method that returns an instance of the \"Track\" class.\r\n * @returns The `Track` instance is being returned. It is obtained by calling the `getInstance`\r\n * method of the current class (`this`) and passing in the string `'Track'` as an argument.\r\n */\r\n static get Track() {\r\n return this.getInstance('Track');\r\n }\r\n\r\n /**\r\n * This is a static method that returns an instance of the \"Impression\" class.\r\n * @returns The `Impression` instance is being returned. It is obtained by calling the `getInstance`\r\n * method of the current class (`this`) and passing in the string `'Impression'` as an argument.\r\n */\r\n static get Impression() {\r\n return this.getInstance('Impression');\r\n }\r\n\r\n /**\r\n * This is a static method that returns an instance of the \"Identify\" class.\r\n * @returns The `Identify` instance is being returned. It is obtained by calling the `getInstance`\r\n * method of the current class (`this`) and passing in the string `'Identify'` as an argument.\r\n */\r\n static get Identify() {\r\n return this.getInstance('Identify');\r\n }\r\n\r\n /**\r\n * This is a static method that returns an instance of the \"PageView\" class.\r\n * @returns The `PageView` instance is being returned. It is obtained by calling the `getInstance`\r\n * method of the current class (`this`) and passing in the string `'PageView'` as an argument.\r\n */\r\n static get PageView() {\r\n return this.getInstance('PageView');\r\n }\r\n\r\n /**\r\n * The function returns a value from a map based on the input name.\r\n *\r\n * @param name - The name of the key in the `statusMap` object that we want to retrieve the value for.\r\n *\r\n * @returns the value of the `statusMap` object that corresponds to the `name` parameter passed to the function.\r\n * If `name` matches one of the keys in `statusMap`, the corresponding value is returned.\r\n */\r\n static fromKey(key) {\r\n const statusMap = {\r\n Track: SegmentEventType.Track,\r\n Impression: SegmentEventType.Impression,\r\n Identify: SegmentEventType.Identify,\r\n PageView: SegmentEventType.PageView,\r\n };\r\n return statusMap[key];\r\n }\r\n\r\n /**\r\n * Gets an instance of a SegmentEventType object based on a given name.\r\n * If the instance does not already exist, it creates a new instance using the configuration provided.\r\n *\r\n * @param name a unique identifier used to retrieve or create an instance of the SegmentEventType class.\r\n * @param configuration an object that contains various properties and values that are used to configure\r\n * the instance of the SegmentEventType class that is being created.\r\n *\r\n * @returns an instance of `SegmentEventType` that corresponds to the given `name`.\r\n */\r\n static getInstance(key) {\r\n if (!this.instances[key]) {\r\n this.instances[key] = new SegmentEventType(key);\r\n }\r\n return this.instances[key];\r\n }\r\n\r\n /**\r\n * This is a constructor function that takes a name as a parameter and sets the name\r\n * @param name -The `name` property is a string that represents the name of the\r\n * configuration\r\n */\r\n constructor(name) {\r\n this.name = name;\r\n }\r\n\r\n /**\r\n * Method that returns the name property of an object as a string.\r\n * @returns returns the `name` property of that object as a string.\r\n */\r\n toString() {\r\n return `${this.name}`;\r\n }\r\n}\r\n\r\nObject.defineProperty(SegmentEventType, 'instances', { value: {} });\r\n","import { IdleQueue } from 'idlize/IdleQueue';\r\n/* Class that represents the redux beacon target to track Segment events */\r\nclass Segment {\r\n constructor() {\r\n this.events = [];\r\n this.queue = new IdleQueue({ ensureTasksRun: true });\r\n\r\n this.target = (events) => {\r\n this.startTime = this.startTime || +new Date();\r\n this.events = [...this.events, ...events];\r\n this.queue.pushTask(this.trackEvent.bind(this));\r\n };\r\n\r\n this.hitTypeHandlers = {\r\n identify: (event) => window.analytics.identify(event.userId, event.traits, event.options),\r\n group: (event) => window.analytics.group(event.groupId, event.traits, event.options),\r\n pageview: (event) => window.analytics.page(event.page, event.name, event.properties, event.options),\r\n event: (event) => window.analytics.track(event.eventAction, event.properties, event.options),\r\n alias: (event) => window.analytics.alias(event.userId, event.previousId, event.options),\r\n reset: () => window.analytics.reset(),\r\n };\r\n }\r\n\r\n trackEvent() {\r\n const timeLapsed = +new Date() - this.startTime;\r\n const isTimeExpired = timeLapsed < 15000;\r\n\r\n /* If analytics is not defined and the time has not expired we shouldnt queue the event again */\r\n if (!window.analytics && isTimeExpired) {\r\n this.queue.pushTask(this.trackEvent.bind(this));\r\n return;\r\n }\r\n\r\n /* The event is not in queue anymore because the time has passed BUT the we need to continue to \r\n validate analytics */\r\n if (!window.analytics) {\r\n this.events = [];\r\n return;\r\n }\r\n\r\n while (this.events.length !== 0) {\r\n const event = this.events.shift();\r\n const handler = this.hitTypeHandlers[event.hitType];\r\n if (handler) {\r\n handler(event);\r\n }\r\n }\r\n\r\n this.startTime = +new Date();\r\n }\r\n\r\n getTarget() {\r\n return this.target;\r\n }\r\n}\r\n\r\nexport default Segment;\r\n","/**\r\n * Record actions your users perform\r\n * @param {string} eventAction - The name of the event you’re tracking.\r\n * @param {object} properties - Optional. A dictionary of properties for the event.\r\n * @param {object} options - Optional. A dictionary of options.\r\n */\r\nfunction trackEvent(eventDefinition) {\r\n return (action, previousState, nextState) => {\r\n const event = eventDefinition(action, previousState, nextState);\r\n return {\r\n hitType: 'event',\r\n eventAction: event.name,\r\n properties: event.properties,\r\n options: event.options,\r\n };\r\n };\r\n}\r\n\r\n/**\r\n * Link your users and their actions, to a recognizable userId and traits.\r\n * @param {string} userId - The database ID for the user.\r\n * @param {object} traits - A dictionary of traits you know about the user, like email or name.\r\n * @param {object} options - A dictionary of options.\r\n */\r\nfunction identifyUser(eventDefinition) {\r\n return (action, previousState, nextState) => {\r\n const event = eventDefinition(action, previousState, nextState);\r\n return {\r\n hitType: 'identify',\r\n userId: event.userId,\r\n traits: event.traits,\r\n options: event.options,\r\n };\r\n };\r\n}\r\n\r\n/**\r\n * Record page views on your website, along with optional extra information about the page viewed\r\n * by the user.\r\n * @param {string} page - The page type.\r\n * @param {object} name - The name of the page.\r\n * @param {object} properties - A dictionary of properties of the page\r\n * @param {object} options - A dictionary of options.\r\n */\r\nfunction trackPageView(eventDefinition) {\r\n return (action, previousState, nextState) => {\r\n const event = eventDefinition(action, previousState, nextState);\r\n return {\r\n hitType: 'pageview',\r\n page: event.category,\r\n name: event.name,\r\n properties: event.properties,\r\n options: event.options,\r\n };\r\n };\r\n}\r\n\r\n/**\r\n * Record page views on your website, along with optional extra information about the page viewed\r\n * by the user.\r\n * @param {string} groupId - The Group ID to associate with the current user.\r\n * @param {object} traits - A dictionary of traits for the group.\r\n * @param {object} options - A dictionary of options.\r\n */\r\nfunction setGroup(eventDefinition) {\r\n return (action, previousState, nextState) => {\r\n const event = eventDefinition(action, previousState, nextState);\r\n return {\r\n hitType: 'group',\r\n groupId: event.groupId,\r\n traits: event.traits,\r\n options: event.options,\r\n };\r\n };\r\n}\r\n\r\n/**\r\n * Combines two unassociated user identities.\r\n * @param {string} userId - The new user ID you want to associate with the user.\r\n * @param {object} previousId - The previous ID that the user was recognized by.\r\n * @param {object} options - A dictionary of options.\r\n */\r\nfunction setAlias(eventDefinition) {\r\n return (action, previousState, nextState) => {\r\n const event = eventDefinition(action, previousState, nextState);\r\n return {\r\n hitType: 'alias',\r\n userId: event.userId,\r\n previousId: event.previousId,\r\n options: event.options,\r\n };\r\n };\r\n}\r\n\r\n/* Calling reset resets the id, including anonymousId, and clears traits for the currently identified user and group. */\r\nfunction reset() {\r\n return () => ({\r\n hitType: 'reset',\r\n });\r\n}\r\n\r\nexport { trackEvent, identifyUser, trackPageView, setGroup, setAlias, reset };\r\n","/**\r\n* Class to work as a DTO to hold the information of a event dispatched to segment.\r\n*/\r\nclass SegmentEvent { \r\n constructor(name = '', customProperties = {}) {\r\n this.name = name;\r\n this.properties = customProperties;\r\n }\r\n }\r\n \r\n export default SegmentEvent;","/**\r\n* Class to work as a DTO to hold the information of a event dispatched to segment.\r\n*/\r\nclass SegmentIdentifyEvent { \r\n constructor(userId = '', traits = {}) {\r\n this.userId = userId;\r\n this.traits = traits;\r\n }\r\n }\r\n \r\n export default SegmentIdentifyEvent;","export default class DateExtensions {}\r\n/**\r\n * The formatDateFromStringTimestamp function takes an timestamp in a string format\r\n * as '1688009760000' and returns the date in a mm/dd/yyyy format\r\n * @param stringTimestamp string timestamp\r\n */\r\nObject.defineProperty(DateExtensions, \"formatDateFromStringTimestamp\", { value: dateString => {\r\n const date = new Date(dateString);\r\n const formattedDate = date.toLocaleDateString('en-US', {\r\n month: '2-digit',\r\n day: '2-digit',\r\n year: 'numeric'\r\n });\r\n return formattedDate;\r\n}});","/**\r\n * Class to work as a DTO to hold the information of a event dispatched to segment.\r\n * Read more at https://rangle.gitbook.io/redux-beacon/index/segment#identify\r\n */\r\nclass SegmentPageEvent {\r\n constructor(category, name, properties, options) {\r\n this.category = category;\r\n this.name = name;\r\n this.properties = properties;\r\n this.options = options;\r\n }\r\n\r\n /**\r\n * The above function returns the category of a segment page event.\r\n * @returns The category of the segment page event.\r\n */\r\n getCategory() {\r\n return this.category;\r\n }\r\n\r\n /**\r\n * The above function is a getter method that returns the value of the \"name\" property.\r\n * @returns The name property of the segment page event.\r\n */\r\n getName() {\r\n return this.name;\r\n }\r\n\r\n /**\r\n * The function returns the properties of a segment page event.\r\n * @returns The properties of the segment page event.\r\n */\r\n getProperties() {\r\n return this.properties;\r\n }\r\n\r\n /**\r\n * The function returns the options property.\r\n * @returns The options property is being returned.\r\n */\r\n getOptions() {\r\n return this.options;\r\n }\r\n}\r\n\r\nexport default SegmentPageEvent;\r\n","import { store } from '@redux/store';\r\nimport { trackEvent, identifyUser, trackPageView } from 'middlewares/segment';\r\nimport SegmentEvent from 'dataTransferObjects/segmentEvent';\r\nimport SegmentIdentifyEvent from 'dataTransferObjects/segmentIdentifyEvent';\r\nimport SegmentEventType from 'enums/segmentEventType';\r\nimport {\r\n hasAvailableNow,\r\n hasReadyToBuild,\r\n hasInventoryStatusCombination,\r\n MoveInDate,\r\n} from 'features/searchResultsFacets';\r\nimport getTrackingCommonProperties from 'features/trackingProperties';\r\nimport merge from 'deepmerge';\r\nimport cleanObjectsEmptyProperties from 'utils/cleanObject';\r\nimport DateExtensions from 'utils/dateExtensions';\r\nimport { FavoriteType } from 'features/userProfile';\r\nimport SegmentPageEvent from 'dataTransferObjects/segmentPageEvent';\r\nimport LocationType from '../features/searchResultsFacets/enums/locationType';\r\nimport { getTrackerClientId } from './googleAnalytics';\r\n\r\n/**\r\n * The getCommonProperties function returns an object containing the common properties\r\n * that are used in all Segment events.\r\n * @return An object\r\n */\r\nconst getCommonProperties = () => {\r\n const state = store.getState();\r\n const commonProperties = getTrackingCommonProperties(state);\r\n return commonProperties;\r\n};\r\n\r\n/**\r\n * The function filters the segment common properties, and take only the ones needed for Track events.\r\n * ex. track don't need user information. user information is available in common properties.\r\n * @returns object containing the common properties for a Track event.\r\n */\r\nconst getTrackCommonProperties = () => {\r\n const commonProperties = getCommonProperties();\r\n const marketNameProperty = (commonProperties.marketName && commonProperties.stateAbbreviation)\r\n ? `${commonProperties.marketName}, ${commonProperties.stateAbbreviation}`\r\n : undefined;\r\n\r\n const trackCommonProperties = {\r\n market_id: commonProperties.marketId?.toString(),\r\n market_name: marketNameProperty,\r\n city: commonProperties.city,\r\n state: commonProperties.stateAbbreviation,\r\n zip: commonProperties.zip,\r\n brand_id: commonProperties.brandId,\r\n brand_name: commonProperties.brandName,\r\n page_type: commonProperties.pageType,\r\n code_version: commonProperties.buildCodeVersion,\r\n test_version: commonProperties.testVersion,\r\n response_version: commonProperties.responseVersion,\r\n partner_id: commonProperties.partnerId,\r\n partner_name: commonProperties.partnerName,\r\n brand_partner_name_partner_name: commonProperties.brandPartnerName,\r\n };\r\n\r\n const cleanedTrackCommonProperties = cleanObjectsEmptyProperties(trackCommonProperties);\r\n return cleanedTrackCommonProperties;\r\n};\r\n\r\n/**\r\n * The createTrackEvent function is a helper function that creates an event object\r\n * for the Segment analytics library. The event object contains information about\r\n * the type of event, and any properties associated with it. This function returns\r\n * a redux-beacon middleware compatible action creator that can be dispatched to\r\n * trigger an analytics call to Segment's servers.\r\n * @param eventName Identify the event name\r\n * @param properties Pass in any additional properties that you want to be sent with the event\r\n *\r\n * @return A function that returns a segmentevent\r\n */\r\nconst createTrackEvent = ({ eventName, customProperties }) => {\r\n const commonProperties = getTrackCommonProperties();\r\n const properties = merge(commonProperties, customProperties);\r\n\r\n return trackEvent(() => new SegmentEvent(eventName, properties));\r\n};\r\n\r\n/** method formats user favorites.\r\n * @returns An object with the list of Communities, Homes and Builders that are already saved.\r\n */\r\nconst getUserSavedElements = (favorites) => {\r\n const communities = [];\r\n const homes = [];\r\n const builders = [];\r\n\r\n favorites.forEach((obj) => {\r\n const savedDate = DateExtensions.formatDateFromStringTimestamp(obj.dateChanged);\r\n const favoriteType = FavoriteType.fromKey(obj.type);\r\n // For the Community Saved Items\r\n if (favoriteType === FavoriteType.Community) {\r\n communities.push({\r\n communityId: obj.listingId,\r\n dateSaved: savedDate,\r\n });\r\n\r\n // For the Spec and Plan Saved Items\r\n } else if (favoriteType === FavoriteType.Spec || favoriteType === FavoriteType.Plan) {\r\n homes.push({\r\n homeId: obj.listingId,\r\n dateSaved: savedDate,\r\n });\r\n\r\n // For the Builder Saved Items\r\n } else if (favoriteType === FavoriteType.Builder) {\r\n builders.push({\r\n builderId: obj.builderInfo?.builderId,\r\n dateSaved: savedDate,\r\n });\r\n }\r\n });\r\n\r\n return {\r\n communities,\r\n homes,\r\n builders,\r\n };\r\n};\r\n\r\n/**\r\n * Checks the type and array length\r\n * @param array - the array to be checked.\r\n * @returns the array send on the parameters or null value if it's length is 0.\r\n */\r\n\r\nconst checkEmptyArray = (array) => {\r\n if (Array.isArray(array) && array.length) {\r\n return array;\r\n }\r\n return null;\r\n};\r\n\r\n/**\r\n * The function filters the segment identify common properties, and take only the ones needed for Identify events.\r\n * ex. track don't need user information. user information is available in common properties.\r\n * @returns object containing the common properties for a Track event.\r\n */\r\nconst getIdentifyProperties = () => {\r\n const state = store.getState();\r\n const commonProperties = getCommonProperties(state);\r\n const [firstName, lastName] = commonProperties.name.split(' ');\r\n const savedElements = getUserSavedElements(commonProperties.favorites);\r\n const userId = commonProperties.userId.replace(/[{}]/g, '');\r\n\r\n const identifyCommonProperties = {\r\n user_id: userId,\r\n email: commonProperties.email || null,\r\n first_name: firstName || null,\r\n last_name: lastName || null,\r\n zip: commonProperties.userZip || null,\r\n phone: commonProperties.phone || null,\r\n outside_us: commonProperties.livesOutside,\r\n saved_communities: checkEmptyArray(savedElements.communities),\r\n saved_homes: checkEmptyArray(savedElements.homes),\r\n saved_builders: checkEmptyArray(savedElements.builders),\r\n g_client_id: getTrackerClientId(),\r\n };\r\n\r\n // By biz rule, if the neustarSegment equals to 000, we don't have to send the values with _n prefix on the event.\r\n if (commonProperties.neustarSegment !== '000') {\r\n identifyCommonProperties.n_segment = commonProperties.neustarSegment;\r\n identifyCommonProperties.n_zip = commonProperties.neustarZip || null;\r\n identifyCommonProperties.n_year = commonProperties.neustarAge || null;\r\n identifyCommonProperties.n_gender = commonProperties.neustarGender || null;\r\n }\r\n\r\n const cleanedIdentifyCommonProperties = cleanObjectsEmptyProperties(identifyCommonProperties);\r\n return cleanedIdentifyCommonProperties;\r\n};\r\n\r\nconst createIdentifyEvent = ({ eventName }) => {\r\n const traits = getIdentifyProperties();\r\n traits.last_event = eventName;\r\n const userId = traits.user_id;\r\n\r\n return identifyUser(() => new SegmentIdentifyEvent(userId, traits));\r\n};\r\n\r\n/**\r\n * getMoveInDate: Sets the Move-In value depending on the selection on the dropdown\r\n * @param moveInInformation The move-in information that can be either the date range or home status\r\n * @returns The value with the move-in home status or range.\r\n */\r\nfunction getMoveInDate(moveInInformation) {\r\n const { moveInDateRange, homeStatus } = moveInInformation;\r\n /* return value for each QMI status */\r\n const moveNow = 'QMI_Now';\r\n const buildablePlans = 'R';\r\n const quickMoveIn = 'QMI';\r\n const oneToTwoMonths = 'QMI_1_2Months';\r\n const threeToSixMonths = 'QMI_3_6Months';\r\n\r\n /* All Quick Move-In */\r\n if (hasInventoryStatusCombination(homeStatus)) {\r\n return quickMoveIn;\r\n }\r\n\r\n /* Move now */\r\n if (hasAvailableNow(homeStatus)) {\r\n return moveNow;\r\n }\r\n\r\n /* Buildable Plans */\r\n if (hasReadyToBuild(homeStatus)) {\r\n return buildablePlans;\r\n }\r\n\r\n /* 1-2 months */\r\n if (moveInDateRange === MoveInDate.OneToTwoMonths.toString()) {\r\n return oneToTwoMonths;\r\n }\r\n\r\n /* 3-6 months */\r\n if (moveInDateRange === MoveInDate.ThreeToSixMonths.toString()) {\r\n return threeToSixMonths;\r\n }\r\n\r\n return undefined;\r\n}\r\n\r\n/**\r\n * getSearchLocation: Gets the search location information based on what's on the search box\r\n * @param locationInformation All the location information: market, state, zip\r\n * @returns The value with search location information.\r\n */\r\nfunction getSearchLocation(locationInformation) {\r\n const { locationType, marketName, city, marketState, zip, syntheticGeographicName, county } = locationInformation;\r\n const searchType = LocationType.fromKey(locationType);\r\n\r\n /* Search label depending on the different search types */\r\n const searchLocationLabelDictionary = {\r\n market: `${marketName} ${marketState}, Area`,\r\n city: `${city}, ${marketState}`,\r\n zip,\r\n syntheticGeo: `${syntheticGeographicName}, ${marketState}`,\r\n county: `${county} County, ${marketState}`,\r\n };\r\n\r\n if (locationType === searchType.name) {\r\n return searchLocationLabelDictionary[locationType];\r\n }\r\n\r\n return undefined;\r\n}\r\n\r\n/**\r\n * getMasterBedLocationLabel: Gets the primary bedroom location: Up - Down.\r\n * @param bedroom The primary bedroom location: 1 / 2\r\n * @returns The master bed location that as requested should be: Up as 2 and Down as 1.\r\n */\r\nfunction getMasterBedLocationLabel(bedroom) {\r\n switch (bedroom) {\r\n /* 1 value corresponds as second floor, but returns 2 since that was de value requested on ticket NHS20-2248 */\r\n case 1:\r\n return 2;\r\n /* 2 value corresponds as first floor, but returns 1 since that was de value requested on ticket NHS20-2248 */\r\n case 2:\r\n return 1;\r\n default:\r\n return undefined;\r\n }\r\n}\r\n\r\n/** This function handles the mapping of the object values in order to rename them\r\n * as requested with underscore.\r\n * This function will receive as parameters all the filters facets applied and as well\r\n * the price if is min or max.\r\n */\r\nfunction formatFiltersApplied(facets, price, schools, moveIn, search) {\r\n return {\r\n bathrooms: facets.bathrooms,\r\n bedrooms: facets.bedrooms,\r\n price_high: price?.maximumPrice,\r\n price_low: price?.minimumPrice,\r\n single_family: facets.singleFamily,\r\n model_homes: facets.modelHomes,\r\n luxury_homes: facets.luxury,\r\n condo_townhome: facets.condosAndTownHomes,\r\n living_areas: facets.livingAreas,\r\n master_bed_location: getMasterBedLocationLabel(facets.primaryBedroom),\r\n garages: facets.garages,\r\n stories: facets.stories,\r\n gated: facets.gatedCommunity,\r\n pool: facets.pool,\r\n golf_course: facets.golfCourse,\r\n green: facets.green,\r\n nature_areas: facets.natureAreas,\r\n parks: facets.parks,\r\n sports: facets.sportsFacilities,\r\n views: facets.views,\r\n waterfront: facets.waterfront,\r\n hot_deals: facets.hotDeals,\r\n price_reduction: facets.priceReduction,\r\n listings_hoa_info: facets.hasHomeOwnersAssociationFee,\r\n age_restricted: facets.adult,\r\n rv_garage: facets.rvGarage,\r\n school_district_ids: schools?.join(', '),\r\n brand_id: facets.builderBrand,\r\n move_in_date: getMoveInDate(moveIn),\r\n mfr: facets.manufactured,\r\n custom: facets.customHomes,\r\n search_location: getSearchLocation(search),\r\n coming_soon: facets.comingsoon,\r\n grand_opening: facets.grandOpening,\r\n active: facets.active,\r\n closeout: facets.closeOut,\r\n };\r\n}\r\n\r\n/**\r\n * facetsEntriesValues: Gets the active values from facets and converts them into an object\r\n * filters when an object is active or not.\r\n * @param facet The facet we are trying to filter and convert\r\n * @returns The active facet values as an object.\r\n */\r\n\r\nfunction facetsEntriesValues(facet) {\r\n const activeFacet = Object.entries(facet).filter(([, facetValue]) => Boolean(facetValue));\r\n\r\n const facetValues = Object.fromEntries(activeFacet);\r\n\r\n return facetValues;\r\n}\r\n\r\n/**\r\n * getImpressionBaseProperties: Gets all the only impression-shared properties to be used\r\n * on the impression events. It relates exactly to the common properties that are shown\r\n * on the impression events but not considering the track common properties.\r\n * @returns The properties that are shared for the impression events.\r\n */\r\n\r\nconst getImpressionBaseProperties = () => {\r\n const { facets, listingCount, pageNumber, price, schools, moveInDate, searchLocation } = getCommonProperties();\r\n\r\n const filtersValues = facetsEntriesValues(facets);\r\n\r\n const priceValues = facetsEntriesValues(price);\r\n\r\n const impressionCommonProperties = {\r\n filters_applied: formatFiltersApplied(filtersValues, priceValues, schools, moveInDate, searchLocation),\r\n result_count: listingCount,\r\n current_page_number: pageNumber,\r\n };\r\n return impressionCommonProperties;\r\n};\r\n\r\n/**\r\n * getImpressionProperties: Gets all the shared properties that should be used on\r\n * every impression event. It includes the track common properties.\r\n * @returns The impression properties that every impression event should use.\r\n */\r\nconst getImpressionProperties = () => {\r\n const trackCommonProperties = getTrackCommonProperties();\r\n const impressionCommonProperties = getImpressionBaseProperties();\r\n const properties = merge(trackCommonProperties, impressionCommonProperties);\r\n return properties;\r\n};\r\n/**\r\n * createImpressionEvent: Triggers the impression events with all the required properties.\r\n * @param eventName Identify the event name\r\n * @param properties Pass in any additional properties that you want to be sent with the event\r\n * @return A function that returns a segmentevent\r\n */\r\nconst createImpressionEvent = ({ eventName, customProperties }) => {\r\n const impressionProperties = getImpressionProperties();\r\n const properties = merge(impressionProperties, customProperties);\r\n return trackEvent(() => new SegmentEvent(eventName, properties));\r\n};\r\n\r\nconst createPageEvent = ({ category, name, customProperties = {}, options }) => {\r\n const commonProperties = getTrackCommonProperties();\r\n const properties = merge(commonProperties, customProperties);\r\n return trackPageView(() => new SegmentPageEvent(category, name, properties, options));\r\n};\r\n\r\n/**\r\n * The getSegmentEvent function returns a SegmentEvent object.\r\n * @param eventType Determine which type of event to create\r\n * @param eventName Identify the event name\r\n * @param customProperties Pass in custom properties to the event\r\n *\r\n * @return An SegmentEvent object\r\n */\r\nconst getSegmentEvent = (eventType, event) => {\r\n switch (eventType) {\r\n case SegmentEventType.Track:\r\n return createTrackEvent(event);\r\n case SegmentEventType.Identify:\r\n return createIdentifyEvent(event);\r\n case SegmentEventType.Impression:\r\n return createImpressionEvent(event);\r\n case SegmentEventType.PageView:\r\n return createPageEvent(event);\r\n\r\n default:\r\n // Default case\r\n return null;\r\n }\r\n};\r\n\r\nexport default getSegmentEvent;\r\n","import { createMiddleware } from 'redux-beacon';\r\nimport debounceEvent from '@redux-beacon/debounce-event';\r\nimport SegmentEventType from 'enums/segmentEventType';\r\nimport { Segment } from 'middlewares/segment';\r\nimport { addMiddleware } from 'redux-dynamic-middlewares';\r\nimport getSegmentEvent from 'services/segmentEventBuilder';\r\nimport { segmentIdentify, segmentImpression, segmentPageView, segmentTrack } from './actions';\r\n\r\n/**\r\n * The eventsMap function is a mapping of Redux actions to Segment events.\r\n * It returns an array of Segment events, which are objects with the following shape:\r\n * {\r\n * eventType: string, // The name of the event (e.g., 'track')\r\n * fieldsObj: object, // An object containing all properties for this event type (e.g., {eventName})\r\n * }\r\n *\r\n * @param action Determine which event to return\r\n *\r\n * @return An array of events\r\n */\r\nconst eventsMap = (action) => {\r\n switch (action.type) {\r\n case segmentTrack.type: {\r\n const payload = action.payload;\r\n const event = debounceEvent(\r\n 1000,\r\n getSegmentEvent(SegmentEventType.Track, {\r\n eventName: payload.eventName,\r\n customProperties: payload.customProperties,\r\n })\r\n );\r\n return event;\r\n }\r\n case segmentIdentify.type: {\r\n const payload = action.payload;\r\n const event = debounceEvent(1000, getSegmentEvent(SegmentEventType.Identify, { eventName: payload.eventName }));\r\n return event;\r\n }\r\n\r\n case segmentImpression.type: {\r\n const payload = action.payload;\r\n const event = debounceEvent(\r\n 1000,\r\n getSegmentEvent(SegmentEventType.Impression, {\r\n eventName: payload.eventName,\r\n customProperties: payload.customProperties,\r\n })\r\n );\r\n return event;\r\n }\r\n\r\n case segmentPageView.type: {\r\n const payload = action.payload;\r\n const event = debounceEvent(\r\n 1000,\r\n getSegmentEvent(SegmentEventType.PageView, {\r\n category: payload.category,\r\n name: payload.name,\r\n customProperties: payload.customProperties,\r\n options: payload.options,\r\n })\r\n );\r\n return event;\r\n }\r\n\r\n default:\r\n return [];\r\n }\r\n};\r\n\r\n/* `const segment = Segment();` is creating an instance of the `@redux-beacon/segment` library, which\r\nis used to send events to the Segment analytics platform. This instance is then passed as an\r\nargument to the `createMiddleware` function to create a middleware that listens for Redux actions\r\nand sends corresponding Segment events using the `segment` instance. */\r\nconst segment = new Segment();\r\n\r\n/* `const middleware = createMiddleware(eventsMap, segment);` is creating a middleware using\r\n`redux-beacon` library. The `createMiddleware` function takes two arguments: `eventsMap` and\r\n`segment`. `eventsMap` is a function that maps Redux actions to Segment events, and `segment` is an\r\ninstance of the `@redux-beacon/segment` library. The middleware created by `createMiddleware` will\r\nlisten for Redux actions and send corresponding Segment events using the `segment` instance. */\r\nconst middleware = createMiddleware(eventsMap, segment.getTarget());\r\n\r\n// registers the middleware in redux\r\n/* `addMiddleware(middleware)` is registering the middleware created by `createMiddleware` in the Redux\r\nstore. This allows the middleware to listen for Redux actions and send corresponding Segment events\r\nusing the `segment` instance. */\r\naddMiddleware(middleware);\r\n","/** Constant partner information\r\n * The `Object.freeze()` method is used to make the object immutable, meaning that\r\n * its properties cannot be modified or deleted.\r\n */\r\nconst NewHomeSourcePartner = Object.freeze({\r\n partnerId: 1,\r\n partnerName: 'NewHomeSource',\r\n brandPartnerName: 'NewHomeSource',\r\n});\r\n\r\nexport default NewHomeSourcePartner;\r\n","/**\r\n * Gets when the word \"Mobile\" exists inside of the string to match.\r\n * \"\\b\" matches a word boundary position. With double \"\\b\", we make sure it is a whole word and\r\n * not a substring from other word.\r\n * \"Mobile\" matches this same word on the string.\r\n * Regex used for the changes on {@link https://builderhomesite.atlassian.net/browse/NHS20-2125} to be able to\r\n * identify the mobile devices by its user agent.\r\n */\r\nconst isMobileUserAgent = /\\bMobile\\b/\r\n\r\n/**\r\n * Determines if the current device user agent is mobile.\r\n * The current way to determine it is to check the User Agent string, and verify\r\n * if it contains the word \"Mobile\" on there.\r\n * By business, we manage the tablet and desktop devices as desktop.\r\n * @returns A bool value indicating whether the device user agent is mobile.\r\n */\r\nconst matchesMobileUserAgent = () => isMobileUserAgent.test(navigator.userAgent);\r\n\r\nexport default matchesMobileUserAgent;","import { createSelector } from '@reduxjs/toolkit';\r\nimport { selectSearchResultFacetsTrackingCommonProperties } from 'features/searchResultsFacets';\r\nimport { selectSearchMapTrackingCommonProperties } from 'features/searchResultsMap';\r\nimport { selectUserLocation, selectUserProfileTrackingCommonProperties } from 'features/userProfile';\r\nimport { selectUtmTrackingCommonProperties } from 'features/utm';\r\n\r\n/** This code is defining a selector which its main purpuse is to combine in a single object\r\n * a set of properties from different features.\r\n * The selector takes two other selector as arguments.\r\n * these selctores provide a set of properties from different features\r\n * this selector is inteded to be consumed by different events builders such as segment ot g4.\r\n */\r\nexport const selectTrackingCommonProperties = createSelector(\r\n selectSearchResultFacetsTrackingCommonProperties,\r\n selectUserProfileTrackingCommonProperties,\r\n selectUserLocation,\r\n selectUtmTrackingCommonProperties,\r\n selectSearchMapTrackingCommonProperties,\r\n (facets, userProfile, userLocation, utm, map) => ({\r\n marketId: facets.location?.marketId,\r\n marketName: facets.location?.marketName,\r\n city: facets.location?.city,\r\n stateAbbreviation: facets.location?.marketState,\r\n stateName: facets.location?.marketStateName,\r\n zip: facets.location?.zip,\r\n brandId: facets.brandId,\r\n brandName: facets.brandName,\r\n userId: userProfile.userId,\r\n name: userProfile.name,\r\n email: userProfile.email,\r\n phone: userProfile.phone,\r\n userZip: userProfile.zip,\r\n livesOutside: userProfile.livesOutside,\r\n favorites: userProfile.favorites,\r\n neustarSegment: userProfile.neustarSegment,\r\n neustarZip: userProfile.neustarZip,\r\n neustarAge: userProfile.neustarAge,\r\n neustarGender: userProfile.neustarGender,\r\n facets: facets.facetsList,\r\n price: facets?.price,\r\n schools: facets.schools,\r\n listingCount: facets.listingCount,\r\n pageNumber: facets.pageNumber,\r\n moveInDate: facets.moveInDate,\r\n searchLocation: facets.location,\r\n userLocationCity: userLocation.userLocationCity,\r\n userLocationCountry: userLocation.userLocationCountry,\r\n userLocationMarketId: userLocation.userLocationMarketId,\r\n userLocationState: userLocation.userLocationState,\r\n userLocationZipCode: userLocation.userLocationZipCode,\r\n isLoggedIn: userProfile.isLoggedIn,\r\n referCode: utm.refer,\r\n isSearchWithinMap: map.isSearchWithinMap,\r\n })\r\n);\r\n\r\nexport default selectTrackingCommonProperties;\r\n","import merge from 'deepmerge';\r\nimport NewHomeSourcePartner from 'constants/partner';\r\nimport matchesMobileUserAgent from 'modules/deviceCapabilities';\r\nimport { selectUrlSubdirectory } from 'features/routing';\r\nimport PageType from 'enums/pageType';\r\nimport { selectTrackingCommonProperties } from './redux/selectors';\r\n\r\nconst businnessInformationElement = document.querySelector(\"[data-component='business-information-data']\");\r\nconst businnessInformation = JSON.parse(businnessInformationElement.innerHTML);\r\n\r\nconst getResponseVersion = (isMobileDevice) => (isMobileDevice ? 'M' : 'D');\r\n\r\n/**\r\n * The getCommonPropertiesFromOtherSources function returns an object containing the properties obtained from:\r\n * sources such as html, or consts.\r\n * @return An object with the properties not stored in redux.\r\n */\r\nconst getCommonPropertiesFromOtherSources = (store) => {\r\n const urlSubdirectory = selectUrlSubdirectory(store);\r\n const pageType = PageType.fromKey(urlSubdirectory).toString();\r\n const isMobileUserAgent = matchesMobileUserAgent();\r\n const properties = {\r\n pageType,\r\n buildCodeVersion: businnessInformation.buildCodeVersion,\r\n responseVersion: getResponseVersion(isMobileUserAgent),\r\n testVersion: NewHomeSourcePartner.testVersion,\r\n partnerId: NewHomeSourcePartner.partnerId,\r\n partnerName: NewHomeSourcePartner.partnerName,\r\n brandPartnerName: NewHomeSourcePartner.brandPartnerName,\r\n };\r\n\r\n return properties;\r\n};\r\n\r\n/**\r\n * The function returns common tracking properties that are stored in the redux store.\r\n * @param store - The `store` parameter is likely an object representing a store or a state management\r\n * @returns an object containing the properties stored in a redux store.\r\n */\r\nconst getCommonPropertiesFromStore = (store) => {\r\n const trackingCommonPropertiesFromStore = selectTrackingCommonProperties(store);\r\n\r\n return trackingCommonPropertiesFromStore;\r\n};\r\n\r\n/**\r\n * The getTrackingCommonProperties function returns tracking common properties from the Redux store.\r\n * this uses a selector which takes from other features selectors a set of properties and combines them.\r\n * The idea is that this selctor can be used for different tracking consumets such as segment, g4.\r\n * by a respective object builder which will filter that properties as needed.\r\n * @param store Access the redux store\r\n *\r\n * @return An object of properties.\r\n */\r\nconst getTrackingCommonProperties = (store) => {\r\n const trackingCommonPropertiesFromStore = getCommonPropertiesFromStore(store);\r\n const trackingCommonPropertiesFromOtherSources = getCommonPropertiesFromOtherSources(store);\r\n const trackingCommonProperties = merge(trackingCommonPropertiesFromStore, trackingCommonPropertiesFromOtherSources);\r\n\r\n return trackingCommonProperties;\r\n};\r\n\r\nexport default getTrackingCommonProperties;\r\n","import FavoriteType from \"../enums/favoriteType\";\r\n\r\n/**\r\n * getListingInformationForPaidSpec: Gets all the listing information that will be used to add a new Pending Save value.\r\n * @param {Object} dataset All the information related to the Paid Spec Card.\r\n * @returns An object with the required listing information for Paid Spec Listings for the new Pending Save value.\r\n */\r\nfunction getListingInformationForPaidSpec(dataset) {\r\n const {\r\n specId, marketId, marketName, builderId, brandName, communityName, communityId, imageUrl,\r\n price, city, stateAbbreviation, zip, homeStatus, isBasic\r\n } = dataset;\r\n\r\n return {\r\n marketId,\r\n marketName,\r\n builderId,\r\n brandName,\r\n communityId,\r\n communityName,\r\n imageUrl,\r\n isBasic,\r\n homeStatus,\r\n price,\r\n id: specId,\r\n city,\r\n stateAbbreviation,\r\n zip,\r\n };\r\n}\r\n\r\n/**\r\n * getListingInformationForPaidCommunity: Gets all the listing information that will be used to add a\r\n * new Pending Save value.\r\n * @param {Object} dataset All the information related to the Paid Community Card.\r\n * @returns An object with the required listing information for Paid Community Listings for the new Pending Save value.\r\n */\r\nfunction getListingInformationForPaidCommunity(dataset) {\r\n const {\r\n id, marketId, marketName, builderId, brandName, communityName, marketingStatusLabel, isBasic, imageUrl,\r\n priceHigh, priceLow, city, stateAbbreviation, zip\r\n } = dataset;\r\n\r\n return {\r\n id,\r\n marketId,\r\n marketName,\r\n builderId,\r\n brandName,\r\n name: communityName,\r\n marketingStatusLabel,\r\n isBasic,\r\n imageUrl,\r\n priceHigh,\r\n priceLow,\r\n city,\r\n stateAbbreviation,\r\n zip\r\n };\r\n}\r\n\r\n/**\r\n * getListingInformationForPaidPlan: Gets all the listing information that will be used to add a new Pending Save value.\r\n * @param {Object} dataset All the information related to the Paid Plan Card.\r\n * @returns An object with the required listing information for Paid Plan Listings for the new Pending Save value.\r\n */\r\nfunction getListingInformationForPaidPlan(dataset) {\r\n const {\r\n planId, marketId, marketName, builderId, brandName, communityName, communityId, imageUrl,\r\n price, city, stateAbbreviation, zip, homeStatus, isBasic\r\n } = dataset;\r\n\r\n return {\r\n marketId,\r\n marketName,\r\n builderId,\r\n brandName,\r\n communityId,\r\n communityName,\r\n imageUrl,\r\n isBasic,\r\n homeStatus,\r\n price,\r\n id: planId,\r\n city,\r\n stateAbbreviation,\r\n zip,\r\n };\r\n}\r\n\r\nconst listingInformationGetter = new Map();\r\n\r\nlistingInformationGetter.set(FavoriteType.Community, getListingInformationForPaidCommunity);\r\nlistingInformationGetter.set(FavoriteType.Spec, getListingInformationForPaidSpec);\r\nlistingInformationGetter.set(FavoriteType.Plan, getListingInformationForPaidPlan);\r\n\r\nexport default function getListingInformationFromDataset(dataset) {\r\n const listingType = FavoriteType.fromKey(dataset.type);\r\n const getListingInformation = listingInformationGetter.get(listingType);\r\n\r\n if (!getListingInformation) {\r\n return {}\r\n }\r\n\r\n return getListingInformation(dataset);\r\n}","import { map, filter, take, distinctUntilChanged } from 'rxjs';\r\nimport { store$, store } from '@redux/store';\r\nimport { userProfileSlice } from '../redux/slices';\r\nimport {\r\n selectFavorites,\r\n selectIsLoggedIn,\r\n selectIsProfileFavoritesLoaded,\r\n selectUserIdAndPendingSaves\r\n} from '../redux/selectors';\r\nimport FavoriteType from '../enums/favoriteType';\r\nimport onOpenModal from './modal';\r\nimport getListingInformationFromDataset from '../services/getListingInformationForPendingSave';\r\n\r\nconst actions = userProfileSlice.actions;\r\n\r\n// Get the favorite information from the card\r\nfunction getCardInformation(card) {\r\n const { type } = card.dataset;\r\n const url = new URL(card.querySelector('a').href).pathname;\r\n const listingInformation = getListingInformationFromDataset(card.dataset)\r\n\r\n return {\r\n listingInformation,\r\n type: FavoriteType.fromKey(type).type,\r\n url,\r\n };\r\n }\r\n\r\n// Check if a favorite is already saved\r\nfunction isFavoriteSaved(id, favorites) {\r\n return favorites.some(favorite => favorite.listingId === Number(id));\r\n}\r\n\r\n// Dispatch the save/delete action\r\nfunction dispatchSaveOrDeleteAction(payload, isSaved) {\r\n const action = isSaved ? actions.deleteFavorite(payload) : actions.saveFavorite(payload);\r\n store.dispatch(action);\r\n}\r\n\r\n/**\r\n * handles whether to save or delete a favorite from the user's profile on user's click.\r\n * @param {HTMLElement} icon the icon clicked by the user.\r\n */\r\nfunction toggleFavorite(icon){\r\n const card = icon.closest('[data-card]');\r\n const { userId, favorites } = store.getState().userProfile;\r\n const cardInfo = getCardInformation(card);\r\n const isSaved = isFavoriteSaved(cardInfo.listingInformation.id, favorites);\r\n const payload = { ...cardInfo, userId };\r\n\r\n dispatchSaveOrDeleteAction(payload, isSaved);\r\n}\r\n\r\n/**\r\n * updates the favorites icon on each card to show if the listing is already saved as a favorite.\r\n * @param {Array[Object]} favorites list of favorites from the user's profile.\r\n */\r\nfunction updateSavedFavorites(favorites) {\r\n const favoritesIds = favorites?.map(favorite => favorite.listingId) ?? [];\r\n\r\n const cards = document.querySelectorAll('[data-card]') ?? [];\r\n\r\n cards.forEach(card => {\r\n const { id } = card.dataset;\r\n const isSaved = favoritesIds.includes(Number(id));\r\n const favorite = card.querySelector('.icon__save');\r\n\r\n if(favorite){\r\n favorite.classList?.toggle('icon__saved', isSaved);\r\n if (isSaved) {\r\n favorite.setAttribute('data-qa', 'favorite_saved');\r\n }\r\n }\r\n })\r\n}\r\n\r\n// Save pending favorites on initial load to handle logged-out users \r\n// that have favorites saved in the cookie from before they logged-in.\r\nfunction savePendingFavorites(data) {\r\n const { userId, pendingSaves } = data;\r\n \r\n if(pendingSaves){\r\n pendingSaves.forEach(pendingSave => {\r\n\r\n // update the favorite with the new user id.\r\n store.dispatch(actions.saveFavorite({ ...pendingSave, userId }));\r\n });\r\n }\r\n}\r\n\r\n\r\n/*\r\nSubscribe to the store$ observable to listen for changes. When the user is logged in and the favorites profile\r\nis loaded, map the favorites and compare with the lasted version. If the favorites change, update the\r\nfavorite UI.\r\n*/\r\nstore$.pipe(\r\n filter(selectIsLoggedIn),\r\n filter(selectIsProfileFavoritesLoaded),\r\n map(selectFavorites),\r\n distinctUntilChanged((previous, current) => JSON.stringify(previous) === JSON.stringify(current))\r\n).subscribe(updateSavedFavorites);\r\n\r\n/*\r\nSubscribe to the store$ observable to listen for changes. When the user is logged in and the favorites profile\r\nis loaded, map the pending favorites and the user id, because this scenarios handles and save the pending favcorites\r\nwhen the user is not logged in. Take only the first value emmited in the observable.\r\n*/\r\nstore$.pipe(\r\n filter(selectIsLoggedIn),\r\n filter(selectIsProfileFavoritesLoaded),\r\n map(selectUserIdAndPendingSaves),\r\n take(1)\r\n).subscribe(savePendingFavorites);\r\n\r\n/**\r\n * Using event delegation to handle clicks on the favorites icon.\r\n */\r\ndocument.body.addEventListener('click', (event) => {\r\n const icon = event.target.closest('.icon__save');\r\n const state = store.getState();\r\n const isLogin = state?.userProfile?.isLogin;\r\n\r\n // if the click was inside the icon, save or delete the favorite.\r\n if (icon) {\r\n toggleFavorite(icon)\r\n\r\n if (!isLogin) {\r\n onOpenModal(event);\r\n }\r\n }\r\n});\r\n\r\nexport default updateSavedFavorites;","/**\r\n * This module encapsulates Google One Tap functionality.\r\n * Use this module as a facade so interactions with Google One Tap library are simplified for any subject interest\r\n * in accessing Google One Tap capabilities.\r\n * Google One Tap is a user authentication and sign-in solution provided by Google.\r\n * It allows users to sign in to websites and apps using their Google account with a single tap,\r\n * providing a streamlined and secure authentication experience. With Google One Tap, users can\r\n * easily access websites without the need to remember and enter complex passwords.\r\n */\r\n\r\nconst googleOneTapInstance = {\r\n isGoogleOneTapLoaded: false,\r\n isGoogleOneTapLoading: false,\r\n clientId: null,\r\n onAuthenticated: null,\r\n};\r\n\r\n// Interval to sample waiting for the load event; this number is arbitrary.\r\nconst googleOneTapLoadSampleRate = 100;\r\n\r\n/**\r\n * If the Google One Tap API fails to load, set the loading and loaded flags to false and reject the promise.\r\n * @param reject - A function that rejects the promise.\r\n */\r\nconst onGoogleOneTapError = (reject) => {\r\n googleOneTapInstance.isGoogleOneTapLoading = false;\r\n googleOneTapInstance.isGoogleOneTapLoaded = false;\r\n reject(new Error(`Unable to load Google One Tap API.`));\r\n};\r\n\r\n/**\r\n * When the Google One Tap API is loaded, set the isGoogleOneTapLoaded property of the googleOneTapInstance object to\r\n * true and resolve the promise.\r\n * @param resolve - A function that is called when the promise is resolved.\r\n */\r\nconst onGoogleOneTapLoaded = (resolve) => {\r\n window.google.accounts.id.initialize({\r\n client_id: googleOneTapInstance.clientId,\r\n callback: googleOneTapInstance.onAuthenticated,\r\n cancel_on_tap_outside: false,\r\n // Due to Intelligent Tracking Prevention (ITP), the normal One Tap UX doesn't work on\r\n // Chrome on iOS, Safari, or Firefox. A different UX is provided instead on these browsers.\r\n itp_support: true,\r\n use_fedcm_for_prompt: true,\r\n });\r\n googleOneTapInstance.isGoogleOneTapLoaded = true;\r\n resolve();\r\n};\r\n\r\n/**\r\n * Create a script element, set its source to the Google One Tap source,\r\n * set its onerror property to a function that rejects the promise,\r\n * set its onload property to a function that resolves the promise.\r\n * @param resolve - The function to call when the script has loaded.\r\n * @param reject - A function that is called when the promise is rejected.\r\n */\r\nconst appendGoogleOneTapScript = (resolve, reject) => {\r\n const script = document.createElement('script');\r\n script.src = 'https://accounts.google.com/gsi/client';\r\n script.async = true;\r\n script.defer = true;\r\n script.onerror = onGoogleOneTapError.bind(this, reject);\r\n script.onload = onGoogleOneTapLoaded.bind(this, resolve);\r\n document.head.appendChild(script);\r\n};\r\n\r\n/**\r\n * If the Google One Tap is loaded, resolve the promise.\r\n * If not, wait the amount of time from googleOneTapLoadSampleRate and try again.\r\n * @param resolve - The resolve function of the promise.\r\n */\r\nconst isGoogleOneTapLoaded = (resolve) => {\r\n if (googleOneTapInstance.isGoogleOneTapLoaded) {\r\n resolve();\r\n } else {\r\n setTimeout(isGoogleOneTapLoaded.bind(null, resolve), googleOneTapLoadSampleRate);\r\n }\r\n};\r\n\r\n/**\r\n * Wait the amount of time from googleOneTapLoadSampleRate for Google One Tap to load, and then resolve the promise.\r\n * @returns A promise that will resolve when the Google One Tap API is loaded.\r\n */\r\nconst waitForGoogleOneTap = () =>\r\n new Promise((resolve) => {\r\n setTimeout(isGoogleOneTapLoaded.bind(null, resolve), googleOneTapLoadSampleRate);\r\n });\r\n\r\n/**\r\n * loadGoogleOneTap: if the Google One Tap instance is not loading, then load it.\r\n * If it is loading, wait for it to load.\r\n * If it is loaded, resolve the promise\r\n * @param googleOneTapLoaded - A function that is called when the Google One Tap instance has loaded.\r\n * @param googleOneTapErrored - A function that will be called if the Google One Tap script fails to load.\r\n * @returns A promise.\r\n */\r\nexport function loadGoogleOneTap({ onLibraryLoaded, onLibraryErrored, onAuthenticated, clientId }) {\r\n googleOneTapInstance.clientId = clientId;\r\n googleOneTapInstance.onAuthenticated = onAuthenticated;\r\n\r\n if (!googleOneTapInstance.isGoogleOneTapLoading) {\r\n // Set the Google One Tap instance as loading to prevent multiple requests.\r\n googleOneTapInstance.isGoogleOneTapLoading = true;\r\n return new Promise(appendGoogleOneTapScript).then(onLibraryLoaded).catch(onLibraryErrored);\r\n }\r\n\r\n if (googleOneTapInstance.isGoogleOneTapLoaded) {\r\n // If the Google One Tap instance is already loaded resolve the promise.\r\n return Promise.resolve().then(onLibraryLoaded).catch(onLibraryErrored);\r\n }\r\n\r\n // Otherwise wait to review if the Google One Tap instance has loaded.\r\n return waitForGoogleOneTap().then(onLibraryLoaded).catch(onLibraryErrored);\r\n}\r\n\r\n/**\r\n * showGoogleOneTapModal: this function will prompt the google one tap login modal to the user.\r\n */\r\nexport function showGoogleOneTapModal() {\r\n window.google.accounts.id.prompt();\r\n}\r\n\r\n/**\r\n * Hides the Google One Tap modal.\r\n */\r\nexport function hideGoogleOneTapModal() {\r\n window.google?.accounts?.id?.cancel();\r\n}\r\n","import { catchError, switchMap } from 'rxjs';\r\nimport { fromFetch } from 'rxjs/fetch';\r\nimport { googleOneTapLogin } from 'constants/routes'\r\n\r\n/**\r\n * loginUserWithGoogleOneTap: this function returns a fromFetch observable. This observable is in charge of\r\n * posting user authentication information from Google One Tap to NewHomeSource so the page can sucessfully\r\n * authenticate an user coming from Google One Tap authentication widget.\r\n * @param {*} parameters a set of information retrieved from Google One Tap containing information used to\r\n * authenticate an user in NewHomeSource.\r\n * @returns \r\n */\r\nconst loginUserWithGoogleOneTap = (parameters) => fromFetch(googleOneTapLogin, {\r\n method: 'POST',\r\n body: JSON.stringify(parameters),\r\n headers: {\r\n 'Content-Type': 'application/json'\r\n }\r\n }).pipe(\r\n switchMap((response) => response.json()),\r\n catchError(() => {}),\r\n );\r\n\r\nexport default loginUserWithGoogleOneTap;","/**\r\n * parseJsonWebToken: This function is designed to parse a JSON Web Token (JWT) by extracting and decoding its payload.\r\n * JWTs consist of three parts: a header, a payload, and a signature, each separated by a period ('.').\r\n * This function focuses on the payload, which is base64-encoded.\r\n * The function decodes the base64-encoded payload and returns the corresponding JSON object.\r\n * @param {string} token the JWT from which the payload needs to be extracted and decoded.\r\n * @returns a json object containing the payload information retrieved from the JWT.\r\n */\r\nconst parseJsonWebToken = (token) => {\r\n const base64Url = token.split('.')[1];\r\n const base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/');\r\n const jsonPayload = decodeURIComponent(window.atob(base64)\r\n .split('')\r\n .map((character) => '%' + ('00' + character.charCodeAt(0).toString(16)).slice(-2))\r\n .join(''));\r\n\r\n return JSON.parse(jsonPayload);\r\n}\r\n\r\nexport default parseJsonWebToken;","/**\r\n * This component works together with the information streamed from the store to accomplish functionality\r\n * related with the authentication in NewHomeSource using Google One Tap as the provider.\r\n * Interactions with Google One Tap are encapsulated in the googleOneTapLibrary.js facade, use this\r\n * component as the link between the interaction of the user in the page and that facade.\r\n */\r\n\r\nimport { store$, store } from '@redux/store';\r\nimport LoadingStatus from 'enums/loadingStatus';\r\nimport { combineLatest, distinctUntilChanged, filter, fromEvent, map, take } from 'rxjs';\r\nimport { hideGoogleOneTapModal, loadGoogleOneTap, showGoogleOneTapModal } from 'libraries/googleOneTapLibrary';\r\nimport { selectConfigurationGoogleOneTapClientId, selectModal } from 'layout/redux/selectors';\r\nimport { selectIsLoggedIn, selectGoogleOneTapLibraryLoadingStatus } from '../redux/selectors';\r\nimport { authenticationSlice } from '../redux/slices';\r\nimport loginUserWithGoogleOneTap from '../apis/loginWithGoogleOneTap';\r\nimport parseJsonWebToken from '../services/parseJsonWebToken';\r\n\r\nconst authActions = authenticationSlice.actions;\r\n\r\nconst onLibraryLoaded = () => store.dispatch(authActions.googleOneTapLibraryLoadingStatus(LoadingStatus.Succeeded));\r\nconst onLibraryErrored = () => store.dispatch(authActions.googleOneTapLibraryLoadingStatus(LoadingStatus.Failed));\r\n\r\nconst onPageLoaded$ = fromEvent(window, 'load');\r\n\r\n/**\r\n * onAuthenticated: callback executed when Google One Tap successfully authenticated an user.\r\n * @param {object} googleResponse containing the information needed to authenticate the user in NewHomeSource.\r\n */\r\nconst onAuthenticated = async (googleResponse) => {\r\n const idToken = parseJsonWebToken(googleResponse.credential);\r\n const parameters = {\r\n payload: {\r\n locale: idToken.locale,\r\n picture: idToken.picture,\r\n email: idToken.email,\r\n name: idToken.name,\r\n givenName: idToken.given_name,\r\n familyName: idToken.family_name,\r\n subject: idToken.sub,\r\n audience: idToken.aud,\r\n emailVerified: idToken.email_verified,\r\n notBeforeTimeSeconds: idToken.nbf,\r\n hostedDomain: idToken.hd,\r\n issuer: idToken.iss,\r\n issuedAtTimeSeconds: idToken.iat,\r\n expirationTimeSeconds: idToken.exp,\r\n jwtId: idToken.jti,\r\n },\r\n keepMeLogged: true,\r\n };\r\n\r\n loginUserWithGoogleOneTap(parameters).subscribe((data) => {\r\n if (data?.Success) {\r\n window.location.reload();\r\n }\r\n });\r\n};\r\n\r\n/**\r\n * Subscribe to the store$ observable to listen for changes.\r\n * If the user is not logged in and the Google One Tap library is not loaded, we proceed\r\n * and load the library so we gain access to Google One Tap capabilities.\r\n * This obserbable streams just one time since every time a user logges in/out a full\r\n * page reload happens, so there is no need to keep listening to the store$ while the user\r\n * navigates in NewHomeSource.\r\n */\r\nconst googleOneTapConfiguration$ = store$.pipe(\r\n filter((state) => selectIsLoggedIn(state) === false),\r\n filter((state) => selectGoogleOneTapLibraryLoadingStatus(state) !== LoadingStatus.Succeeded.name),\r\n map((state) => ({\r\n onLibraryLoaded,\r\n onLibraryErrored,\r\n onAuthenticated,\r\n clientId: selectConfigurationGoogleOneTapClientId(state),\r\n })),\r\n distinctUntilChanged(),\r\n filter((googleOneTapInformation) => !!googleOneTapInformation.clientId),\r\n take(1)\r\n);\r\n\r\ncombineLatest([googleOneTapConfiguration$, onPageLoaded$])\r\n .pipe(map(([googleOneTapConfiguration]) => googleOneTapConfiguration))\r\n .subscribe(loadGoogleOneTap);\r\n\r\n/**\r\n * Subscribe to the store$ observable to listen for changes.\r\n * If the user is not logged in and Google One Tap library is loaded, then we prompt the modal\r\n * inviting the user to log in using Google One Tap.\r\n * This obserbable streams just one time since every time a user logges in/out a full\r\n * page reload happens, so there is no need to keep listening to the store$ while the user\r\n * navigates in NewHomeSource.\r\n */\r\nstore$\r\n .pipe(\r\n filter((state) => selectIsLoggedIn(state) === false),\r\n filter((state) => selectGoogleOneTapLibraryLoadingStatus(state) === LoadingStatus.Succeeded.name),\r\n take(1)\r\n )\r\n .subscribe(showGoogleOneTapModal);\r\n\r\n/**\r\n * Subscribe to the store$ observable to hide the Google One Tap modal\r\n * when a modal is opened.\r\n */\r\nstore$\r\n .pipe(\r\n filter((state) => Boolean(selectModal(state))),\r\n take(1)\r\n )\r\n .subscribe(hideGoogleOneTapModal);\r\n","/**\r\n * @public\r\n * getValidationCallback: get the validator callback to each fields in Sign Up modal.\r\n * @param {Object} signUpField with the information of the field \r\n * \r\n * @returns {Function} that will be execute when form need to be validate.\r\n */\r\nfunction getValidationCallback(signUpField) {\r\n switch(signUpField.name) {\r\n case 'FirstName':\r\n case 'LastName': {\r\n const regex = new RegExp(signUpField.validator.pattern);\r\n const hint = signUpField.validator.hint;\r\n return (name) => ({\r\n valid: regex.test(name) && name.length >= 2,\r\n hint\r\n });\r\n }\r\n case 'PostalCode': {\r\n const hint = signUpField.validator.hint;\r\n return (name) => ({\r\n valid: name.length === 0 || name.length === 5,\r\n hint\r\n });\r\n }\r\n default:\r\n return () => (true);\r\n }\r\n}\r\n\r\nexport default getValidationCallback;","import getValidationCallback from \"./signUpValidator\";\r\n\r\nconst configElement = document.querySelector('[data-auth0-parameter]');\r\nconst keepMeLoggedSection = document.querySelector('[data-keep-me-logged-section]');\r\nconst legalContentSection = document.querySelector('[data-legal-section]');\r\nconst configObject = JSON.parse(configElement.innerText);\r\nconfigObject.keepMeLoggedSection = keepMeLoggedSection;\r\nconfigObject.legalContentSection = legalContentSection;\r\nconfigObject.options.additionalSignUpFields.forEach((signUpField) => {\r\n const callback = getValidationCallback(signUpField);\r\n signUpField.validator = callback;\r\n});\r\n\r\n/**\r\n * @public\r\n * getBaseConfig: get the configuration object to show authentication modal.\r\n *\r\n * @returns { Object } with the configuration of authentication.\r\n */\r\nfunction getBaseConfig() {\r\n return Object.assign({}, configObject);\r\n}\r\n\r\nexport default getBaseConfig;\r\n","import { store$, store } from '@redux/store';\r\nimport { distinctUntilChanged, filter, map } from 'rxjs';\r\nimport { createAuthInstance, showModal } from 'libraries/authLibrary';\r\nimport { isAuthLibraryLoaded, isAuthModalOpen } from '../constants/auth0Constants';\r\nimport { modalSlice, authenticationSlice } from '../redux/slices';\r\nimport getBaseConfig from './auth0BaseConfiguration';\r\n\r\nconst { actions: modalActions, reducer: modalReducers } = modalSlice;\r\nconst { reducer: authenticationReducers } = authenticationSlice\r\n\r\nconst configuration = getBaseConfig();\r\nconst onCloseModal = () => store.dispatch(modalActions.onClose());\r\nconst initAuthentication = () => createAuthInstance(configuration, onCloseModal);\r\nconst openModal = () => showModal();\r\nconst userIdSelector = (state) => state?.userProfile?.userId;\r\nconst invalidValuesFilter = (value) => !!value;\r\n\r\nconst storeUserId = (userId) => { \r\n localStorage.setItem('UserId', userId)\r\n };\r\n\r\n // We have to execute initAuthentication when the modal is not opened.\r\n // So it means we need to track isAuthModalOpen.\r\n // Where if it was already on true, we should not continue the flow.\r\n // If it was on false, so we should check if the new isAuthModalOpen value is true or false to determine\r\n // whether to continue the flow.\r\nstore$.pipe(\r\n filter(isAuthLibraryLoaded),\r\n map(isAuthModalOpen),\r\n distinctUntilChanged(),\r\n filter(Boolean))\r\n .subscribe(initAuthentication);\r\n\r\nstore$.pipe(\r\n filter(isAuthModalOpen),\r\n distinctUntilChanged())\r\n .subscribe(openModal);\r\n\r\nstore$.pipe(\r\n map(userIdSelector),\r\n distinctUntilChanged(),\r\n filter(invalidValuesFilter)\r\n ).subscribe(storeUserId);\r\n\r\nstore.injectReducer('modal', modalReducers);\r\nstore.injectReducer('authentication', authenticationReducers);","import { store, store$ } from \"@redux/store\";\r\nimport { loadAuth0 } from \"libraries/authLibrary\";\r\nimport { filter, fromEvent, take } from \"rxjs\";\r\nimport { authenticationSlice, modalSlice } from '../redux/slices';\r\nimport { isAuthLibraryNotLoaded } from '../constants/auth0Constants';\r\n\r\nconst { actions: authenticationActions } = authenticationSlice;\r\nconst { actions: modalActions } = modalSlice;\r\n\r\n// Dispatch the redux slices.\r\nconst onAuthLibraryLoaded = () => store.dispatch(authenticationActions.authLibraryLoaded());\r\nconst onAuthLibraryErrored = (value) => store.dispatch(authenticationActions.authLibraryErrored(value));\r\nconst openModal = () => store.dispatch(modalActions.onOpen());\r\n\r\n// check if user is logged in\r\nconst isUserNotLogin = (state) => state?.userProfile?.isLogin === false;\r\n\r\n// check if the target for the event is a sign-in component.\r\nconst isSignInElement = (event) => event?.target?.closest('[data-component=\"sign-in\"]');\r\n\r\n/**\r\n * @private\r\n * onOpenModal: open the authentication modal.\r\n *\r\n */\r\nfunction onOpenModal(event) {\r\n event.preventDefault();\r\n loadAuth0(onAuthLibraryLoaded, onAuthLibraryErrored).then(openModal);\r\n}\r\n\r\n/**\r\n * @private\r\n * attachSignUpClick: method to attach when user is not loging and need to open auth0 modal.\r\n * \r\n */\r\nconst attachSignUpClick = () => {\r\n // user event delegation listen to click on a sign-in component\r\n fromEvent(document.body, 'click').pipe(\r\n filter(isSignInElement),\r\n filter(Boolean)\r\n ).subscribe(onOpenModal);\r\n}\r\n\r\nstore$.pipe(\r\n filter(isUserNotLogin),\r\n filter(isAuthLibraryNotLoaded),\r\n take(1))\r\n .subscribe(attachSignUpClick);\r\n\r\nexport default onOpenModal;","import { fromEvent, map } from 'rxjs';\r\nimport { store } from '@redux/store';\r\nimport { userProfileSlice } from '../redux/slices';\r\n\r\nconst actions = userProfileSlice.actions;\r\n\r\nconst updateNeustarInformation = (response) => store.dispatch(actions.updateNeustarInformation(response));\r\n\r\nfromEvent(document.body, 'neustarLoaded')\r\n .pipe(map((event) => event.detail))\r\n .subscribe(updateNeustarInformation);\r\n","import { debounce, fromEvent, interval } from 'rxjs';\r\nimport { readCookie, createCookieByMins } from 'modules/cookieManager';\r\n\r\n/**\r\n * @public\r\n * initUserInteractions: init the interactions between user and login cookie,\r\n * to notice when the interaction with the site is lost.\r\n * In a certain time, check the value of @see sessionAliveElement, if that number of minuts already happen and\r\n * the user don't interact the user need to be log out, for this reason we need to check the cookie IsUserLoggedIn\r\n */\r\nconst documentClicks$ = fromEvent(document, 'click')\r\n.pipe(\r\n debounce(() => interval(3000))\r\n);\r\nconst sessionAliveElement = document.querySelector('[data-session-alive-minutes]');\r\nconst sessionAliveMin = (sessionAliveElement && sessionAliveElement.value) || 10; \r\n\r\nconst updateSession = {\r\n next: () => {\r\n const isUserLoggedIn = readCookie('IsUserLoggedIn', true);\r\n if (isUserLoggedIn === 'True') {\r\n createCookieByMins('IsUserLoggedIn', 'True', sessionAliveMin, true);\r\n }\r\n }\r\n};\r\n\r\ndocumentClicks$.subscribe(updateSession);","const { store$ } = require(\"@redux/store\");\r\nconst { map, distinctUntilChanged, filter } = require(\"rxjs\");\r\n\r\nconst subMenuAccountList = document.querySelector('[data-sub-menu-account-list]');\r\nconst subMenuAccountContainer = document.querySelector('[data-sub-menu-account-container]');\r\nconst linkSelector = (state) => state?.userProfile?.links;\r\nconst invalidValuesFilter = (value) => !!value && value.length > 0;\r\nconst drawMenu = (links) => { \r\n links.forEach(link => {\r\n const li = document.createElement('li');\r\n li.classList.add('padding--link');\r\n li.dataset.component = link?.component;\r\n const anchor = document.createElement('a');\r\n anchor.href = link?.url;\r\n anchor.innerText = link.text;\r\n if (link.ShouldOpenNewTab) {\r\n anchor.target = '_blank';\r\n anchor.rel = 'noopener noreferrer';\r\n }\r\n anchor.dataset.qa = link?.component;\r\n li.appendChild(anchor);\r\n subMenuAccountList.appendChild(li);\r\n });\r\n subMenuAccountContainer.removeAttribute('hidden')\r\n };\r\n\r\nstore$.pipe(\r\n map(linkSelector),\r\n distinctUntilChanged(),\r\n filter(invalidValuesFilter)\r\n).subscribe(drawMenu);","/**\r\n * @public\r\n * isAuthLibraryLoaded: verify if the authetication library is loaded\r\n * @param {Object} state of the Redux store. \r\n *\r\n * @returns true when the library is already loaded otherwise false.\r\n */\r\nexport const isAuthLibraryLoaded = (state) => !!state?.authentication?.isAuthLibraryLoaded;\r\n\r\n/**\r\n * @public\r\n * isAuthLibraryNotLoaded: verify if the authetication library is not loaded\r\n * @param {Object} state of the Redux store. \r\n *\r\n * @returns true when the library is not already loaded otherwise false.\r\n */\r\nexport const isAuthLibraryNotLoaded = (state) => state?.authentication?.isAuthLibraryLoaded === false;\r\n\r\n/**\r\n * @public\r\n * isAuthModalOpen: verify if the authetication modal is currently open in the user screen.\r\n * @param {Object} state of the Redux store. \r\n *\r\n * @returns true when modal is opening otherwise false.\r\n */\r\nexport const isAuthModalOpen = (state) => !!state?.modal?.isAuthModalOpen;","export const pendingSavesSessionStorageKey = 'pendingFavorites';\r\nexport const favoritesSessionStorageKey = 'favorites';\r\n","/**\r\n * FavoriteType enum\r\n * Contains the different types of favorites that can be saved.\r\n */\r\nexport default class FavoriteType {\r\n static get Plan() {\r\n return this.getInstance('HomePlan');\r\n }\r\n\r\n static get Spec() {\r\n return this.getInstance('HomeSpec');\r\n }\r\n\r\n static get Community() {\r\n return this.getInstance('Community');\r\n }\r\n\r\n static get Builder() {\r\n return this.getInstance('Builder');\r\n }\r\n\r\n static fromKey(key) {\r\n const typeMap = {\r\n plan: FavoriteType.Plan,\r\n spec: FavoriteType.Spec,\r\n community: FavoriteType.Community,\r\n builder: FavoriteType.Builder,\r\n };\r\n return typeMap[key.toLowerCase()];\r\n }\r\n\r\n static getInstance(key) {\r\n if (!this.instances[key]) {\r\n this.instances[key] = new FavoriteType(key);\r\n }\r\n return this.instances[key];\r\n }\r\n\r\n constructor(type) {\r\n this.type = type;\r\n }\r\n\r\n toString() {\r\n return `${this.type}`;\r\n }\r\n}\r\n\r\nObject.defineProperty(FavoriteType, 'instances', { value: {} });\r\n","import FavoriteType from './enums/favoriteType';\r\nimport { \r\n deleteFavoriteEpic, \r\n fetchUserFavoritesEpic, \r\n fetchUserProfileEpic, \r\n saveFavoriteEpic } from './redux/epics';\r\nimport {\r\n selectEmail,\r\n selectFavorites,\r\n selectIsLoggedIn,\r\n selectIsProfileFavoritesLoaded,\r\n selectPendingSaves,\r\n selectUserProfileTrackingCommonProperties,\r\n selectUserLocation,\r\n selectNeustarSegment,\r\n selectNeustarStatus,\r\n selectNeustarInformation,\r\n} from './redux/selectors';\r\nimport { userProfileSlice } from './redux/slices';\r\n\r\nrequire('./components/userMenu');\r\nrequire('./components/sessionAliveInteraction');\r\nrequire('./components/mainAuthentication');\r\nrequire('./components/modal');\r\nrequire('./components/favorites');\r\nrequire('./redux/listeners');\r\nrequire('./components/neustarListener');\r\nrequire('./components/googleOneTapAuthentication');\r\n\r\nconst { actions: userProfileActions, reducer: userProfileReducers } = userProfileSlice;\r\n\r\nexport {\r\n selectPendingSaves,\r\n selectFavorites,\r\n selectIsProfileFavoritesLoaded,\r\n fetchUserProfileEpic,\r\n fetchUserFavoritesEpic,\r\n saveFavoriteEpic,\r\n deleteFavoriteEpic,\r\n userProfileActions,\r\n userProfileReducers,\r\n selectUserProfileTrackingCommonProperties,\r\n FavoriteType,\r\n selectIsLoggedIn,\r\n selectEmail,\r\n selectUserLocation,\r\n selectNeustarSegment,\r\n selectNeustarInformation,\r\n selectNeustarStatus,\r\n};\r\n","import { createListenerMiddleware, isAnyOf } from '@reduxjs/toolkit';\r\nimport { addMiddleware } from 'redux-dynamic-middlewares';\r\nimport { store } from '@redux/store';\r\nimport onListViewPaint from 'pages/searchResults/redux/actions';\r\nimport { userProfileSlice } from './slices';\r\nimport { favoritesSessionStorageKey, pendingSavesSessionStorageKey } from '../constants/sessionStorageConstants';\r\nimport { selectFavorites, selectIsLoggedIn } from './selectors';\r\nimport updateSavedFavorites from '../components/favorites';\r\n\r\nconst actions = userProfileSlice.actions;\r\nconst listenerMiddleware = createListenerMiddleware();\r\n\r\n// update the favorites data on session storage.\r\n// this is done when a save / delete is successful.\r\nlistenerMiddleware.startListening({\r\n matcher: isAnyOf(actions.deleteFavoriteFullfilled, actions.saveFavoriteFulfilled),\r\n effect: async () => {\r\n const state = store.getState();\r\n const { favorites } = state.userProfile;\r\n sessionStorage.setItem(favoritesSessionStorageKey, JSON.stringify(favorites));\r\n },\r\n});\r\n\r\n// update the pending saves data on session storage.\r\n// this is done when a save / delete hasn't been completed yet.\r\nlistenerMiddleware.startListening({\r\n matcher: isAnyOf(actions.saveFavorite, actions.deleteFavorite, actions.saveFavoriteFulfilled),\r\n effect: async () => {\r\n const state = store.getState();\r\n const { pendingSaves } = state.userProfile;\r\n\r\n sessionStorage.setItem(pendingSavesSessionStorageKey, JSON.stringify(pendingSaves));\r\n },\r\n});\r\n\r\n/* When the list view is paint, update the favorites if the user is login. */\r\nlistenerMiddleware.startListening({\r\n matcher: isAnyOf(onListViewPaint),\r\n effect: async () => {\r\n const state = store.getState();\r\n const isLoggedIn = selectIsLoggedIn(state);\r\n if (isLoggedIn) {\r\n const favorites = selectFavorites(state);\r\n updateSavedFavorites(favorites);\r\n }\r\n },\r\n});\r\n\r\naddMiddleware(listenerMiddleware.middleware);\r\n","import { createSelector } from '@reduxjs/toolkit';\r\n\r\nexport const selectIsLoggedIn = (state) => state?.userProfile?.isLogin;\r\nexport const selectFavorites = (state) => state?.userProfile?.favorites;\r\nexport const selectPendingSaves = (state) => state?.userProfile?.pendingSaves;\r\nexport const selectIsProfileFavoritesLoaded = (state) => state?.userProfile?.isProfileFavoritesLoaded;\r\nexport const selectUserId = (state) => state?.userProfile?.userId;\r\nexport const selectEmail = (state) => state?.userProfile?.email;\r\nexport const selectName = (state) => state?.userProfile?.name;\r\nexport const selectPhone = (state) => state?.userProfile?.phone;\r\nexport const selectZip = (state) => state?.userProfile?.zip;\r\nexport const selectlivesOutside = (state) => state?.userProfile?.livesOutside;\r\n\r\nexport const selectNeustarStatus = (state) => state?.userProfile?.neustarStatus;\r\nexport const selectNeustarSegment = (state) => state?.userProfile?.neustarInformation?.s;\r\nexport const selectNeustarZip = (state) => state?.userProfile?.neustarInformation?.z;\r\nexport const selectNeustarAge = (state) => state?.userProfile?.neustarInformation?.a;\r\nexport const selectNeustarGender = (state) => state?.userProfile?.neustarInformation?.g;\r\nexport const selectNeustarInformation = (state) => state?.userProfile?.neustarInformation;\r\n\r\nexport const selectUserLocationCity = (state) => state?.userProfile?.userLocation?.userCity;\r\nexport const selectUserLocationCountry = (state) => state?.userProfile?.userLocation?.userCountry;\r\nexport const selectUserLocationMarketId = (state) => state?.userProfile?.userLocation?.userMarketId;\r\nexport const selectUserLocationState = (state) => state?.userProfile?.userLocation?.userState;\r\nexport const selectUserLocationZipCode = (state) => state?.userProfile?.userLocation?.userZipCode;\r\n\r\n/**\r\n * @public\r\n * selectGoogleOneTapLibraryLoadingStatus: returns the loading status of the Google One Tap Library.\r\n * @param {Object} state of the Redux store.\r\n *\r\n * @returns the loading status of the Google One Tap Library.\r\n */\r\nexport const selectGoogleOneTapLibraryLoadingStatus = (state) =>\r\n state?.authentication?.googleOneTapLibraryLoadingStatus;\r\n\r\n/** this selector is intended to expose useful properties when the user use the save to favorites feature\r\n * but it is not logged in.\r\n */\r\nexport const selectUserIdAndPendingSaves = createSelector(selectUserId, selectPendingSaves, (userId, pendingSaves) => ({\r\n userId,\r\n pendingSaves,\r\n}));\r\n\r\n/* It is using the `createSelector` function from the `@reduxjs/toolkit`\r\nlibrary to create a memoized selector. It takes in multiple input selectors\r\n(`selectUserLocationCity`, `selectUserLocationCountry`, `selectUserLocationMarketId`,\r\n`selectUserLocationState`, `selectUserLocationZipCode`) and a result function. */\r\nexport const selectUserLocation = createSelector(\r\n selectUserLocationCity,\r\n selectUserLocationCountry,\r\n selectUserLocationMarketId,\r\n selectUserLocationState,\r\n selectUserLocationZipCode,\r\n (userLocationCity, userLocationCountry, userLocationMarketId, userLocationState, userLocationZipCode) => ({\r\n userLocationCity,\r\n userLocationCountry,\r\n userLocationMarketId,\r\n userLocationState,\r\n userLocationZipCode,\r\n })\r\n);\r\n\r\n/** this selector is intended to expose all the properties that should be included as common tracking properties.\r\n * the idea behind this is tha here should be placed the selectors/props that are usually used in tracking events.\r\n * then the consumers will filter and take the props they need, this will just serve the information.\r\n */\r\nexport const selectUserProfileTrackingCommonProperties = createSelector(\r\n selectUserId,\r\n selectEmail,\r\n selectName,\r\n selectPhone,\r\n selectZip,\r\n selectlivesOutside,\r\n selectFavorites,\r\n selectNeustarSegment,\r\n selectNeustarZip,\r\n selectNeustarAge,\r\n selectNeustarGender,\r\n selectIsLoggedIn,\r\n (\r\n userId,\r\n email,\r\n name,\r\n phone,\r\n zip,\r\n livesOutside,\r\n favorites,\r\n neustarSegment,\r\n neustarZip,\r\n neustarAge,\r\n neustarGender,\r\n isLoggedIn\r\n ) => ({\r\n userId,\r\n email,\r\n name,\r\n phone,\r\n zip,\r\n livesOutside,\r\n favorites,\r\n neustarSegment,\r\n neustarZip,\r\n neustarAge,\r\n neustarGender,\r\n isLoggedIn,\r\n })\r\n);\r\n","import LoadingStatus from \"enums/loadingStatus\";\r\nimport { favoritesSessionStorageKey, pendingSavesSessionStorageKey } from \"../constants/sessionStorageConstants\";\r\n\r\n// Read \"pendingSaves\" session storage on initial load\r\nconst pendingSavesData= sessionStorage.getItem(pendingSavesSessionStorageKey, false);\r\n// Assign value to a list\r\nconst pendingSaves = pendingSavesData ? JSON.parse(pendingSavesData) : [];\r\n\r\n// Read \"favorites\" information on initial load\r\nconst favoritesData = sessionStorage.getItem(favoritesSessionStorageKey, false);\r\nconst favorites = favoritesData ? JSON.parse(favoritesData) : [];\r\n\r\nexport default {\r\n name: '',\r\n email: '',\r\n phone: '',\r\n zip: '',\r\n livesOutside: false,\r\n pendingSaves,\r\n favorites,\r\n hasUserOptedIntoRecommendationEmail: true,\r\n realtorQuestion : '',\r\n neustarStatus: LoadingStatus.Idle.toString()\r\n}","import { createSlice } from '@reduxjs/toolkit';\r\nimport { camelCaseObjectKeys } from 'utils/camelCase';\r\nimport LoadingStatus from 'enums/loadingStatus';\r\nimport userProfileInitialState from './initialState';\r\n\r\nconst userProfileSlice = createSlice({\r\n name: 'userProfile',\r\n initialState: userProfileInitialState,\r\n reducers: {\r\n apply: (state, action) => \r\n // return the new state with camel case object keys and isLoading set to false\r\n {\r\n\r\n const profile = camelCaseObjectKeys(action.payload);\r\n\r\n state.email = profile.email;\r\n state.id = profile.id;\r\n state.imageProfile = profile.imageProfile;\r\n state.isLogin = profile.isLogin;\r\n state.links = profile.links;\r\n state.livesOutside = profile.livesOutside;\r\n state.name = profile.name?.trim().replace(/\\s+/g, ' ');\r\n state.phone = profile.phone;\r\n state.preferredContactMethod = profile.preferredContactMethod;\r\n state.hasUserOptedIntoRecommendationEmail = profile.hasUserOptedIntoRecommendationEmail;\r\n state.realtorQuestion = profile.realtorQuestion;\r\n state.userId = profile.userId;\r\n state.userLocation = profile.userLocation;\r\n state.zip = profile.zip;\r\n state.isLoading = false;\r\n },\r\n applyFavorites: (state, action) => {\r\n const payload = camelCaseObjectKeys(action.payload);\r\n state.favorites = payload?.favorites;\r\n state.isProfileFavoritesLoaded = true;\r\n },\r\n update: (state, action) => {\r\n const userInfo = {...state, ...action.payload};\r\n state.name = userInfo.name?.trim().replace(/\\s+/g, ' ');\r\n state.email = userInfo.email;\r\n state.phone = userInfo.phone;\r\n state.zip = userInfo.zip;\r\n state.livesOutside = userInfo.livesOutside;\r\n state.preferredContactMethod = userInfo.preferredContactMethod || state.preferredContactMethod;\r\n state.hasUserOptedIntoRecommendationEmail = userInfo.hasUserOptedIntoRecommendationEmail ??\r\n state.hasUserOptedIntoRecommendationEmail;\r\n state.realtorQuestion = userInfo.realtorQuestion || state.realtorQuestion;\r\n },\r\n fetch: (state) => {\r\n state.isLoading = true;\r\n },\r\n handleError: (state) => {\r\n state.isLoading = false;\r\n },\r\n saveFavorite: (state, action) => {\r\n // check if the action.payload.id is already in the pendingSaves array, if not, add it.\r\n const pendingSaveExists = state.pendingSaves.some((favorite) => \r\n Number(favorite.listingInformation.id) === Number(action.payload.listingInformation.id)\r\n );\r\n\r\n if (!pendingSaveExists) {\r\n\r\n // add the favorite to the pending array, in case the API call fails or the user is logged out\r\n // and we need to retry the API call once the user logs in.\r\n state.pendingSaves.push(action.payload);\r\n }\r\n\r\n },\r\n deleteFavorite: () => {},\r\n deleteFavoriteFullfilled: (state, action) => {\r\n const payload = action.payload;\r\n state.favorites = state.favorites.filter((favorite) => favorite.listingId !== payload.listingId);\r\n },\r\n saveFavoriteFulfilled: (state, action) => {\r\n const newFavorite = action.payload.data.favorite;\r\n\r\n // remove the favorite from the pending array\r\n state.pendingSaves = state.pendingSaves.filter(\r\n (favorite) => Number(favorite.listingInformation.id) !== Number(newFavorite.listingId)\r\n );\r\n \r\n const favoriteExists = state.favorites.find((favorite) => favorite.listingId === newFavorite.listingId);\r\n \r\n if (!favoriteExists) {\r\n // add the favorite to the favorites array\r\n state.favorites = [...state.favorites, newFavorite];\r\n }\r\n },\r\n updateNeustarInformation: (state, action) => {\r\n const neustarInformation = action.payload;\r\n state.neustarInformation = neustarInformation;\r\n state.neustarStatus = LoadingStatus.Succeeded.toString()\r\n },\r\n}});\r\n\r\nconst authenticationSlice = createSlice({\r\n name: 'authentication',\r\n initialState: {\r\n isAuthLibraryLoaded: false,\r\n isAuthModalOpen: false,\r\n googleOneTapLibraryLoadingStatus: null,\r\n },\r\n reducers: {\r\n authLibraryLoaded: (state) => {\r\n state.isAuthLibraryLoaded = true;\r\n },\r\n authLibraryErrored: (state) => {\r\n state.isAuthLibraryLoaded = false;\r\n },\r\n googleOneTapLibraryLoadingStatus: (state, action) => {\r\n state.googleOneTapLibraryLoadingStatus = action.payload.name;\r\n },\r\n },\r\n});\r\n\r\nconst modalSlice = createSlice({\r\n name: 'modal',\r\n initialState: {\r\n isAuthModalOpen: false\r\n },\r\n reducers: {\r\n onOpen: (state) => {\r\n state.isAuthModalOpen = true;\r\n },\r\n onClose: (state) => {\r\n state.isAuthModalOpen = false;\r\n }\r\n },\r\n});\r\n\r\n// Extract the action creators object and the reducer\r\nexport { userProfileSlice, authenticationSlice, modalSlice };\r\n","import { createSelector } from '@reduxjs/toolkit';\r\n\r\nexport const selectUtmSource = (state) => state?.utmParameters?.utmSource;\r\nexport const selectUtmMedium = (state) => state?.utmParameters?.utmMedium;\r\nexport const selectUtmCampaign = (state) => state?.utmParameters?.utmCampaign;\r\nexport const selectUtmTerm = (state) => state?.utmParameters?.utmTerm;\r\nexport const selectUtmContent = (state) => state?.utmParameters?.utmContent;\r\nexport const selectEntranceUrl = (state) => state?.utmParameters?.entranceUrl;\r\nexport const selectGoogleClickId = (state) => state?.utmParameters?.googleClickId;\r\nexport const selectHttpReferer = (state) => state?.utmParameters?.httpReferer;\r\nexport const selectRefer = (state) => state?.utmParameters?.refer;\r\n\r\n/**\r\n * Returns true if the map is fetching results from the server.\r\n * @param state - The state of the Redux store.\r\n */\r\nexport const isLoading = (state) => state?.utmParameters?.isLoading;\r\n\r\nexport const selectUtmTrackingCommonProperties = createSelector(selectRefer, (refer) => ({ refer }));\r\n","export default class PageLayout {\r\n static get Communities() {\r\n return this.getInstance('communities-communities');\r\n }\r\n\r\n static get Homes() {\r\n return this.getInstance('homes-homes');\r\n }\r\n\r\n static get Builders() {\r\n return this.getInstance('AllProducts-builders');\r\n }\r\n \r\n static get BoylLocations() {\r\n return this.getInstance('boyl-locations');\r\n }\r\n\r\n static get CustomHomes() {\r\n return this.getInstance('custom-homes');\r\n }\r\n\r\n static get ManufacturedLocations() {\r\n return this.getInstance('manufactured-locations');\r\n }\r\n\r\n static get ManufacturedHomes() {\r\n return this.getInstance('manufactured-homes');\r\n }\r\n\r\n static fromKey(key) {\r\n const statusMap = {\r\n 'communities-communities': PageLayout.Communities,\r\n 'homes-homes': PageLayout.Homes,\r\n 'AllProducts-builders': PageLayout.Builders,\r\n 'boyl-locations': PageLayout.BoylLocations,\r\n 'custom-homes': PageLayout.CustomHomes,\r\n 'manufactured-locations': PageLayout.ManufacturedLocations,\r\n 'manufactured-homes': PageLayout.ManufacturedHomes\r\n };\r\n return statusMap[key];\r\n }\r\n\r\n static getInstance(key) {\r\n if (!this.instances[key]) {\r\n this.instances[key] = new PageLayout(key);\r\n }\r\n return this.instances[key];\r\n }\r\n\r\n constructor(name) {\r\n this.name = name;\r\n }\r\n\r\n toString() {\r\n return `${this.name}`;\r\n }\r\n}\r\n\r\nObject.defineProperty(PageLayout, 'instances', { value: {} });\r\n","export default class ResultPresentationType {\r\n\r\n /**\r\n * The static get Pagination function returns an instance of the 'Pagination' class.\r\n * @returns The method is returning an instance of the 'Pagination' class.\r\n */\r\n static get Pagination() {\r\n return this.getInstance('Pagination');\r\n }\r\n \r\n /**\r\n * The function returns an instance of the 'InfiniteScrolling' class.\r\n * @returns The method `get InfiniteScrolling()` is returning the result of calling the `getInstance`\r\n * method with the argument `'InfiniteScrolling'`.\r\n */\r\n static get InfiniteScrolling() {\r\n return this.getInstance('InfiniteScrolling');\r\n }\r\n \r\n /**\r\n * The function \"fromKey\" takes a key as input and returns the corresponding value from a\r\n * predefined map.\r\n * @param key - The `key` parameter is a string that represents a key in the `statusMap` object.\r\n * @returns The value associated with the given key in the statusMap object is being returned.\r\n */\r\n static fromKey(key) {\r\n const statusMap = {\r\n 'Pagination': ResultPresentationType.Pagination,\r\n 'InfiniteScrolling': ResultPresentationType.InfiniteScrolling,\r\n };\r\n return statusMap[key];\r\n }\r\n \r\n /**\r\n * Gets an instance of a ResultPresentationType object based on a given name.\r\n * If the instance does not already exist, it creates a new instance using the configuration provided.\r\n *\r\n * @param name a unique identifier used to retrieve or create an instance of the ResultPresentationType class.\r\n * @param configuration an object that contains various properties and values that are used to configure\r\n * the instance of the ResultPresentationType class that is being created.\r\n *\r\n * @returns an instance of `ResultPresentation` that corresponds to the given `name`.\r\n */\r\n static getInstance(key) {\r\n if (!this.instances[key]) {\r\n this.instances[key] = new ResultPresentationType(key);\r\n }\r\n return this.instances[key];\r\n }\r\n \r\n /**\r\n * This is a constructor function that takes a name as a parameter and sets the name\r\n * @param name -The `name` property is a string that represents the name of the\r\n * configuration\r\n */\r\n constructor(name) {\r\n this.name = name;\r\n }\r\n \r\n /**\r\n * Method that returns the name property of an object as a string.\r\n * @returns returns the `name` property of that object as a string.\r\n */\r\n toString() {\r\n return `${this.name}`;\r\n }\r\n }\r\n \r\n Object.defineProperty(ResultPresentationType, 'instances', { value: {} });\r\n ","import { createSelector } from '@reduxjs/toolkit';\r\n\r\nexport const selectUiState = (state) => state?.uiState;\r\nexport const selectFetchingModal = (state) => state?.uiState.isFetchingModal;\r\nexport const selectDisplaySkeleton = (state) => state?.uiState?.displayCardGridSkeleton;\r\nexport const selectPageLayout = (state) => state?.uiState?.pageLayout;\r\nexport const selectResultsPresentationType = (state) => state?.uiState?.resultsPresentationType;\r\nexport const selectModal = (state) => state?.uiState?.modalInformation;\r\nexport const selectModalListingInformation = (state) => state?.uiState?.modalInformation?.listingInformation;\r\nexport const selectLoading = (state) => state?.configuration?.loading;\r\nexport const selectConfigurationResourceDomain = (state) => state?.configuration?.resourceDomain;\r\nexport const selectConfigurationSegmentApiKey = (state) => state?.configuration?.segmentApiKey;\r\nexport const selectConfigurationNeustarApiKey = (state) => state?.configuration?.neustarApiKey;\r\nexport const selectConfigurationImageResizeService = (state) => state?.configuration?.imageResizeService;\r\nexport const selectConfigurationGoogleOneTapClientId = (state) => state?.configuration?.googleOneTapClientId;\r\nexport const selectIsMarkerAutoScrollFeatureEnabled = (state) => state?.configuration?.isMarkerAutoScrollFeatureEnabled;\r\nexport const selectLayoutBreakpoint = (state) => state?.uiState?.layoutBreakpoint;\r\n\r\n/**\r\n * Selector to get all the host name used in NewHomeSource site.\r\n */\r\nexport const selectResourcesHostNames = createSelector(\r\n selectConfigurationResourceDomain,\r\n selectConfigurationImageResizeService,\r\n (resourceDomain, imageResizeService) => ({\r\n staticImagesHostName: resourceDomain,\r\n imageResizeService,\r\n })\r\n);","import PageLayout from \"layout/constants/pageLayoutNames\";\r\nimport ResultPresentationType from \"layout/constants/resultPresentationType\";\r\n\r\nconst lookup = {\r\n [PageLayout.Communities]: ResultPresentationType.Pagination.toString(),\r\n [PageLayout.Homes]: ResultPresentationType.Pagination.toString(),\r\n [PageLayout.Builders]: ResultPresentationType.InfiniteScrolling.toString(),\r\n [PageLayout.BoylLocations]: ResultPresentationType.Pagination.toString(),\r\n [PageLayout.CustomHomes]: ResultPresentationType.Pagination.toString(),\r\n [PageLayout.ManufacturedLocations]: ResultPresentationType.Pagination.toString(),\r\n [PageLayout.ManufacturedHomes]: ResultPresentationType.Pagination.toString(),\r\n};\r\n\r\nconst getResultPresentationByLayoutName = (layoutName) => lookup[layoutName];\r\n\r\nexport default getResultPresentationByLayoutName;","import { createSlice } from '@reduxjs/toolkit';\r\nimport LoadingStatus from 'enums/loadingStatus';\r\nimport getResultPresentationByLayoutName from 'layout/services/resultsPresentationService';\r\n\r\nconst uiStateSlice = createSlice({\r\n name: 'uiState',\r\n initialState: {\r\n isFetchingModal: false,\r\n modalInformation: null,\r\n },\r\n reducers: {\r\n clearModal: (state) => {\r\n state.isFetchingModal = false;\r\n state.modalInformation = null;\r\n },\r\n fetchModal: (state, action) => {\r\n state.isFetchingModal = action.payload.isFetchingModal;\r\n },\r\n fetchModalError: (state) => {\r\n state.isFetchingModal = false;\r\n },\r\n fetchModalFulfilled: (state) => {\r\n state.isFetchingModal = false;\r\n },\r\n updatePageLayout: (state, action) => {\r\n state.pageLayout = action.payload;\r\n state.resultsPresentationType = getResultPresentationByLayoutName(action.payload);\r\n },\r\n updateCardGridSkeleton: (state, action) => {\r\n state.displayCardGridSkeleton = action.payload === LoadingStatus.Loading;\r\n },\r\n focusedListingInformation: (state, action) => {\r\n state.focusedListing = action.payload;\r\n },\r\n modalInformation: (state, action) => {\r\n const previousName = state.modalInformation?.name;\r\n const newModalInformation = {...action.payload};\r\n // We don't need to save the events information into the state. So\r\n // we are removing them before assigning to the state.\r\n delete newModalInformation.googleAnalyticsDTO;\r\n\r\n state.modalInformation = {\r\n ...state.modalInformation,\r\n ...newModalInformation,\r\n };\r\n\r\n // the \"previousName\" property should change only when a new name is being set\r\n if (previousName) {\r\n state.modalInformation.previousName = previousName;\r\n }\r\n },\r\n updateLayoutBreakpoint: (state, action) => {\r\n state.layoutBreakpoint = action.payload;\r\n },\r\n /* A reducer that does nothing because it's used for Google Analytics Redux Beacon. */\r\n trackUserEvent: () => {},\r\n },\r\n});\r\n\r\nexport default uiStateSlice;\r\n","import { Subject } from 'rxjs';\r\n\r\nconst subject = new Subject();\r\n\r\nexport default {\r\n getMessage: () => subject.asObservable(),\r\n sendMessage: (message) => subject.next(message),\r\n}","import { Subject } from 'rxjs';\r\n\r\nconst subject = new Subject();\r\n\r\nexport default {\r\n clearHtml: () => subject.next({ action: 'clearHtml' }),\r\n getHtml: () => subject.asObservable(),\r\n onHtmlReady: (data) => subject.next({ action: 'onHtmlReady', ...data }),\r\n onHtmlRemoved: (data) => subject.next({ action: 'onHtmlRemoved', ...data }),\r\n setHtml: (data) => subject.next({ action: 'setHtml', value: data.payload }),\r\n setPreviousHtml: () => subject.next({ action: 'setPreviousHtml' }),\r\n};\r\n","const authObject = {\r\n isAuth0Loaded: false,\r\n isAuth0Loading: false,\r\n lock: null,\r\n settings: null,\r\n Auth0Lock: null,\r\n};\r\n\r\nconst authLoadSampleRate = 300;\r\n\r\n/**\r\n * @private\r\n * onAuth0Error: reject the promise when authetication library is loaded.\r\n *\r\n * @param {Function} reject the promise.\r\n */\r\nconst onAuth0Error = (reject) => {\r\n authObject.isAuth0Loading = false;\r\n authObject.isAuth0Loaded = false;\r\n reject(new Error(`Unable to load Auth0 API.`));\r\n};\r\n\r\n/**\r\n * @private\r\n * onAuth0Loaded: resolve the promise when authentication library is loaded \r\n * @param {Function} resolve the promise.\r\n */\r\nconst onAuth0Loaded = (resolve) => {\r\n authObject.isAuth0Loaded = true;\r\n resolve();\r\n};\r\n\r\n/**\r\n * @private\r\n * loadAuth0Module: import the auth0 lock module.\r\n *\r\n * @param {Function} resolve the promise\r\n * @param {Function} reject the promise\r\n */\r\nconst loadAuth0Module = async (resolve, reject) => {\r\n await import('../../styles/components/auth0.scss');\r\n import('auth0-lock').then(({ Auth0Lock }) => {\r\n authObject.Auth0Lock = Auth0Lock;\r\n onAuth0Loaded.call(this, resolve);\r\n })\r\n .catch(onAuth0Error.bind(this, reject));\r\n};\r\n\r\n/**\r\n * @private\r\n * isAuthLoaded: resolve the promise when auth0 is loaded. Retry when auth0 is loading.\r\n *\r\n * @param {Function} resolve the promise. \r\n */\r\nconst isAuthLoaded = (resolve) => {\r\n if (authObject.isAuth0Loaded) {\r\n resolve();\r\n } else {\r\n setTimeout(isAuthLoaded.bind(null, resolve), authLoadSampleRate);\r\n }\r\n};\r\n\r\n/**\r\n * @private\r\n * waitForAuth: wait for Authentication library, waiting a @see authLoadSampleRate milliseconds.\r\n * \r\n * @returns {Promise} notify that authentication library is loaded.\r\n */\r\nconst waitForAuth = () =>\r\n new Promise((resolve) => {\r\n setTimeout(isAuthLoaded.bind(null, resolve), authLoadSampleRate);\r\n});\r\n\r\n/**\r\n * @private\r\n * getSignUpFieldByName: get the sign up field by name in setting authetication object.\r\n * @param {String} name of the sign up field.\r\n * \r\n * @returns {Object} with the sign up field information. \r\n */\r\nconst getSignUpFieldByName = (name) => authObject.settings.options\r\n.additionalSignUpFields.find(item => item.name === name) || {};\r\n\r\n/**\r\n * @private\r\n * goToNextPageAfterLogIn: redirect to the next page after user is autheticated.\r\n * @param {String} config with the next page to go.\r\n * \r\n */\r\nconst goToNextPageAfterLogIn = (nextPage) => {\r\n if (nextPage) {\r\n window.location = nextPage;\r\n } else {\r\n window.location.reload();\r\n }\r\n};\r\n\r\n/**\r\n * @private\r\n * onSignUpReady: method to execute when sign up form is visible to the user.\r\n * This method helps to:\r\n * Avoid numbers in zip code input\r\n * Disable zip code when user is outside of United States.\r\n */\r\nconst onSignUpReady = () => {\r\n const zip = document.querySelector('[name=\"PostalCode\"]');\r\n zip.setAttribute('maxlength', 5);\r\n zip.onkeypress = function (evt) {\r\n const charCode = (evt.which) ? evt.which : evt.keyCode;\r\n if (charCode > 31 && (charCode < 48 || charCode > 57)) { return false; }\r\n return true;\r\n };\r\n const outsideUS = document.querySelector('[name=\"OutsideUS\"]');\r\n outsideUS.onchange = function () {\r\n zip.disabled = outsideUS.checked;\r\n };\r\n const outSideUsItem = getSignUpFieldByName(\"OutsideUS\");\r\n if (outSideUsItem.prefill === 'true') {\r\n zip.disabled = true;\r\n }\r\n\r\n const outsideUSContainer = outsideUS.closest('div');\r\n const fieldsContainer = outsideUSContainer.parentElement;\r\n const lastFormElement = fieldsContainer.lastElementChild;\r\n\r\n lastFormElement.after(authObject.settings.legalContentSection.content.cloneNode(true));\r\n};\r\n\r\n/**\r\n * @private\r\n * onAuthenticated: method to execute after user is autheticated.\r\n * It helps to request NHS servers to create the cookies and get the main information of the user.\r\n * \r\n * @param {Object} authResult information with the user token. \r\n */\r\nconst onAuthenticated = async (authResult) => {\r\n document.querySelectorAll('.auth0-lock-close-button').forEach((element) => {\r\n element.remove();\r\n });\r\n\r\n const accessToken = authResult.accessToken;\r\n const keepMeLogged = document.querySelector('[name=\"KeepMeLogged\"]');\r\n let keepMeLoggedValue = false;\r\n if (keepMeLogged) {\r\n keepMeLoggedValue = keepMeLogged.checked;\r\n }\r\n const url = authObject.settings.basic.auth0Authenticated;\r\n const parameters = {\r\n accessToken,\r\n keepMeLogged: keepMeLoggedValue\r\n };\r\n\r\n const response = await fetch(url, {\r\n method: 'POST',\r\n body: JSON.stringify(parameters),\r\n headers: {\r\n 'Content-Type': 'application/json'\r\n }\r\n });\r\n\r\n if (response.ok) {\r\n const data = await response.json();\r\n\r\n if (data.Success) {\r\n if (authObject.settings.afterLogin) {\r\n authObject.settings.afterLogin();\r\n }\r\n goToNextPageAfterLogIn(authObject.settings.nextPage);\r\n }\r\n }\r\n};\r\n\r\n/**\r\n * @private\r\n * onSigninReady: method to execute when sign in form is visible to the user.\r\n * This method helps to:\r\n * Create the keep me login checkbox from authentication modal.\r\n */\r\nconst onSigninReady = () => {\r\n const referenceElement = document.querySelector('.auth0-lock-alternative');\r\n const parentContainer = referenceElement.parentElement;\r\n parentContainer.insertBefore(\r\n authObject.settings.keepMeLoggedSection.content.cloneNode(true),\r\n referenceElement);\r\n referenceElement.after(authObject.settings.legalContentSection.content.cloneNode(true));\r\n};\r\n\r\n/**\r\n * @public\r\n * loadAuth0: load the auth0 library.\r\n * @param {Function} authLoaded to be executed when the promise is resolved.\r\n * @param {*} authError to be executed when the promise is reject.\r\n *\r\n * @returns {Promise} that will be resolved. \r\n */\r\nexport function loadAuth0(authLoaded, authError) {\r\n if (!authObject.isAuth0Loading) {\r\n authObject.isAuth0Loading = true;\r\n return new Promise(loadAuth0Module).then(authLoaded).catch(authError);\r\n }\r\n\r\n if (authObject.isAuth0Loaded) {\r\n return Promise.resolve().then(authLoaded).catch(authError);\r\n }\r\n\r\n return waitForAuth().then(authLoaded).catch(authError);\r\n};\r\n\r\n/**\r\n * @public\r\n * createAuthInstance: create the authetication instance\r\n * @param {Object} settings of the authentication modal.\r\n * @param {Function} onCloseModal callback to be execute in hide event.\r\n */\r\nexport function createAuthInstance(settings, onCloseModal) {\r\n authObject.settings = settings;\r\n authObject.lock = new authObject.Auth0Lock(\r\n settings.basic.auth0ClientId,\r\n settings.basic.auth0Domain,\r\n settings.options);\r\n authObject.lock.on('signup ready', onSignUpReady);\r\n authObject.lock.on('authenticated', onAuthenticated);\r\n authObject.lock.on('signin ready', onSigninReady);\r\n authObject.lock.on('hide', onCloseModal);\r\n\r\n}\r\n\r\n/**\r\n * @public\r\n * showModal: open the authentication modal.\r\n *\r\n */\r\nexport function showModal() {\r\n authObject.lock.show();\r\n}","import { IdleQueue } from 'idlize/IdleQueue';\r\n/* Class that represents the redux beacon target to track Google Tag Manager events */\r\nclass GoogleTagManager {\r\n constructor() {\r\n this.events = [];\r\n this.queue = new IdleQueue({ ensureTasksRun: true });\r\n\r\n this.target = (events) => {\r\n this.startTime = this.startTime || +new Date();\r\n this.events = [...this.events, ...events];\r\n this.queue.pushTask(this.trackEvent.bind(this));\r\n };\r\n }\r\n\r\n /* Function to track the event that will have the time from when starts to queue and will stop after 15000ms */\r\n trackEvent() {\r\n const timeLapsed = +new Date() - this.startTime;\r\n const isTimeExpired = timeLapsed < 15000;\r\n\r\n /* If data layer is not defined and the time has not expired we shouldnt queue the event again */\r\n if (!window.dataLayer && isTimeExpired) {\r\n this.queue.pushTask(this.trackEvent.bind(this));\r\n return;\r\n }\r\n\r\n /* The event is not in queue anymore because the time has passed BUT the we need to continue to \r\n validate the datalayer */\r\n if (!window.dataLayer) {\r\n this.events = [];\r\n return;\r\n }\r\n\r\n while (this.events.length !== 0) {\r\n const event = this.events.shift();\r\n window.dataLayer.push(event);\r\n window.dataLayer.push({ params: null });\r\n }\r\n\r\n this.startTime = +new Date();\r\n }\r\n\r\n /* Gets event target */\r\n getTarget() {\r\n return this.target;\r\n }\r\n}\r\n\r\nexport default GoogleTagManager;\r\n","import GoogleTagManager from \"./services/googleTagManager\";\r\n\r\nexport default GoogleTagManager;","/**\r\n * Module to manage cookies in the site.\r\n * \r\n * The main difference of this cookieManager between legacies files in GlobalResources14 is that\r\n * those older modules should only be used on pages that use vanillaJS and requireJS for module loading.\r\n */\r\nconst partnerIdElement = document.querySelector('[data-cookie-partner]');\r\n\r\nfunction getCookieName(name, isPartnerCookie) {\r\n if (isPartnerCookie && partnerIdElement) {\r\n return `${name}_${partnerIdElement.value}`\r\n }\r\n return name;\r\n}\r\n\r\n/**\r\n * @public\r\n * readCookie: searches for a cookie and returns its value.\r\n *\r\n * @param {string} name of the cookie to be retrieved.\r\n * @param {boolean} isPartnerCookie true if the cookie name should include the partner ID information,\r\n * otherwise false.\r\n */\r\nfunction readCookie(name, isPartnerCookie) {\r\n let cookieName = getCookieName(name, isPartnerCookie);\r\n cookieName += '=';\r\n\r\n const items = document.cookie.split(';') || [];\r\n const nameLength = cookieName.length;\r\n const cookieFound = items.find((item) => {\r\n if (item.trim().indexOf(cookieName) === 0) {\r\n return item;\r\n }\r\n return null;\r\n });\r\n\r\n if (!cookieFound) {\r\n return null;\r\n }\r\n\r\n return cookieFound.trim().substring(nameLength);\r\n}\r\n\r\n/**\r\n * @public\r\n * createCookieByMins: creates a new cookie for the domain, expering in minutes.\r\n *\r\n * @param {string} name of the cookie.\r\n * @param {any} value that will be stored in the cookie.\r\n * @param {number} minutes of expiration time for the cookie.\r\n * @param {boolean} isPartnerCookie true if the cookie name should include the partner ID information,\r\n * otherwise false.\r\n */\r\nfunction createCookieByMins(name, value, mins, isPartnerCookie) {\r\n let expires = '';\r\n const cookieName = getCookieName(name, isPartnerCookie);\r\n\r\n if (mins) {\r\n const date = new Date();\r\n date.setTime(date.getTime() + (mins * 60 * 1000));\r\n expires = '; expires=' + date.toGMTString();\r\n }\r\n\r\n document.cookie = `${cookieName}=${value}${expires}; path=/; secure`;\r\n}\r\n\r\nexport {\r\n readCookie,\r\n createCookieByMins\r\n};\r\n","import Typeahead from '@components/typeahead/typeahead';\r\nimport { getArticleSuggestions, learningCenter } from 'constants/routes'\r\nimport { debounceTime } from \"rxjs\";\r\nimport { redirectToBlogArticlePage } from './redirectHandler';\r\n\r\n/**\r\n * Retrieves a value from a data attribute named `data-from-page-slug`\r\n * on a specific element in the document.\r\n * @returns The function `getFromPageSlug` is returning the value of the `data-from-page-slug`\r\n * attribute from the element selected by the query selector `[data-from-page-slug]`.\r\n */\r\nconst getFromPage = function(){\r\n const fromPageSlugElement = document.querySelector('[data-from-page]');\r\n if (fromPageSlugElement){\r\n const fromPageSlugValue = fromPageSlugElement.dataset.fromPage;\r\n return fromPageSlugValue;\r\n }\r\n \r\n return '';\r\n} \r\n\r\n/**\r\n * Takes a search term and a page reference, constructs a URL with the\r\n * search term and page reference, and opens the URL in the current window.\r\n * @param searchTerm - Search term entered by the user to search in the learning center.\r\n */\r\nconst submitButtonClick = function(searchTerm) {\r\n const fromPage = getFromPage();\r\n if (learningCenter && searchTerm && fromPage) {\r\n const url = `${learningCenter}?searchTerm=${searchTerm}&frompage=${fromPage}`;\r\n window.open(url, '_self');\r\n }\r\n}\r\n\r\nconst setting = {\r\n searchInputQuerySelector: '[data-search-box-article]',\r\n suggestionsListQuerySelector: '[data-search-box-article-suggestions]',\r\n errorContainerQuerySelector: '[data-search-box-article-error]',\r\n clearButtonQuerySelector: '[data-search-box-article-clear]',\r\n submitButtonQuerySelector: '[data-search-box-article-submit]',\r\n sourceUrl: getArticleSuggestions,\r\n suggestionValueKey: 'Title'\r\n};\r\n\r\nconst typeahead = new Typeahead();\r\ntypeahead.setTypeaheadSetting(setting);\r\n\r\n// debounceTime 100 to wait events dispatches before performing the redirect\r\nconst suggestionListClicked$ = typeahead.getSuggestionListClickedObserver().pipe(debounceTime(100));\r\nsuggestionListClicked$.subscribe((suggestion) => redirectToBlogArticlePage(suggestion.dataset.slug));\r\n\r\n// debounceTime 100 to wait events dispatches before performing the redirect\r\nconst submitEventObserver$ = typeahead.getSubmitEventObserver().pipe(debounceTime(100));\r\nsubmitEventObserver$.subscribe(submitButtonClick);\r\n\r\nexport default typeahead;","import { fromEvent } from 'rxjs';\r\nimport Carousel from '@components/carousel/dynamicCarousel';\r\n\r\nconst onDocumentContentLoaded$ = fromEvent(document, 'DOMContentLoaded');\r\nconst categorizedSectionSelector= \"[data-section-name='categoryArticles']\";\r\nconst categorizedSectionContainer = document.querySelector(categorizedSectionSelector);\r\n\r\n/* The `const settings` object is defining the configuration settings for the carousel component. It\r\nspecifies the query selectors for different elements within the categorized section of the webpage\r\nwhere the carousel will be implemented. */\r\nconst settings = {\r\n itemListQuerySelector: `${categorizedSectionSelector} [data-blog-article-cards-list]`,\r\n previousQuerySelector: `${categorizedSectionSelector} [data-left-arrow]`,\r\n nextQuerySelector: `${categorizedSectionSelector} [data-right-arrow]`,\r\n};\r\n\r\nconst carousel = new Carousel();\r\ncarousel.setSettings(settings);\r\n\r\n/**\r\n * Sets up a carousel for articles within a categorized section container.\r\n * @returns If the `categorizedSectionContainer` is not found, the function will return nothing\r\n * (undefined).\r\n */\r\nconst setCategoryArticleCarousel = function() {\r\n if (!categorizedSectionContainer) {\r\n return;\r\n }\r\n\r\n carousel.create();\r\n}\r\n\r\n/* Setting up a subscription to the `onDocumentContentLoaded$` observable. When the document\r\nis fully loaded (DOMContentLoaded event), the `setCategoryArticleCarousel` function\r\nwill be called, which in turn creates and sets up a carousel for articles within a\r\ncategorized section container on the webpage. This subscription ensures that\r\nthe carousel setup is triggered when the document is ready. */\r\nonDocumentContentLoaded$.subscribe(setCategoryArticleCarousel);","import Carousel from '@components/carousel/dynamicCarousel';\r\nimport { getCommunitiesForYouContent$, getHomesForYouContent$ } from 'api/getListingsForYouContent';\r\nimport { LocationType, ResultType } from 'features/searchResultsFacets';\r\nimport { readCookie } from 'modules/cookieManager';\r\nimport { filter, fromEvent, map, switchMap } from 'rxjs';\r\nimport { camelCaseObjectKeys } from 'utils/camelCase';\r\n\r\nconst onDocumentContentLoaded$ = fromEvent(document, 'DOMContentLoaded');\r\nconst listingsForYouQuerySelector = '[data-listings-for-you-container]';\r\n\r\n/* The `const settings` object is defining properties that store specific query selectors for elements\r\nwithin the listings section on a webpage. */\r\nconst settings = {\r\n itemListQuerySelector: `${listingsForYouQuerySelector} [data-blog-listing-cards-list]`,\r\n previousQuerySelector: `${listingsForYouQuerySelector} [data-left-arrow]`,\r\n nextQuerySelector: `${listingsForYouQuerySelector} [data-right-arrow]`,\r\n};\r\n\r\n/* The object is defining two properties: `communities` and `homes`,\r\neach of which is assigned a function that retrieves content for listings related to communities and\r\nhomes, respectively. These functions are `getCommunitiesForYouContent$` and\r\n`getHomesForYouContent$`. This object essentially serves as a mapping between different types of\r\nlistings content retrieval functions based on the type of listing (communities or homes). */\r\nconst getListingForYouSection = {\r\n communities: getCommunitiesForYouContent$,\r\n homes: getHomesForYouContent$,\r\n};\r\n\r\n/**\r\n * Initializes a section on a webpage with listings data and\r\n * loads necessary modules for lead generation and modal form display.\r\n * @param listingsForYouData - The `listingsForYouData` parameter in the `initListingsFourYouSection`\r\n * function likely contains data related to listings that are meant to be displayed in a section on a\r\n * webpage. This data could include information such as property details, images, prices, and any other\r\n * relevant information about the\r\n */\r\nconst initListingsFourYouSection = function (listingsForYouData) {\r\n const listingsForYouContainer = document.querySelector(listingsForYouQuerySelector);\r\n\r\n if (listingsForYouData && listingsForYouContainer) {\r\n const fragment = document.createRange().createContextualFragment(listingsForYouData);\r\n listingsForYouContainer.appendChild(fragment);\r\n\r\n // loading modules needed to dispatch the lead and modal form\r\n require('features/leadGenerators');\r\n require(\"./standardCard\");\r\n\r\n const carousel = new Carousel();\r\n\r\n carousel.setSettings(settings);\r\n carousel.create();\r\n }\r\n};\r\n\r\n/**\r\n * Reads personal information from a cookie and\r\n * updates the blog listings filters search command object accordingly.\r\n * @param blogListingsFiltersSearchCommand - Takes in a `blogListingsFiltersSearchCommand` object\r\n * as a parameter and updates its properties based\r\n * on values retrieved from a personal cookie. Here's a breakdown of how the properties are updated:\r\n * @returns Returns the `blogListingsFiltersSearchCommand` object after updating its properties based on the values\r\n * retrieved from the `personalCookie` extracted from the 'Personal' cookie. The properties being\r\n * updated are `locationType`, `marketId`, `marketStateAbbreviation`, and `marketIds`. The updated\r\n * `blogListingsFiltersSearchCommand`\r\n */\r\nfunction UpdateBlogListingsFiltersSearchCommand(blogListingsFiltersSearchCommand) {\r\n\r\n // Take the context from personal cookie (varnish does not allow take it from service side)\r\n const personalCookie = readCookie('Personal', true);\r\n const parameters = new URLSearchParams(personalCookie);\r\n\r\n blogListingsFiltersSearchCommand.locationType = parameters.get('market') ? LocationType.Market.toString() : '';\r\n blogListingsFiltersSearchCommand.marketId = parameters.get('market') || '';\r\n blogListingsFiltersSearchCommand.marketStateAbbreviation = parameters.get('state');\r\n blogListingsFiltersSearchCommand.marketIds = blogListingsFiltersSearchCommand.marketIds || [];\r\n\r\n return blogListingsFiltersSearchCommand;\r\n}\r\n\r\n/* This block of code is using RxJS operators to handle asynchronous data flow in a reactive manner. */\r\nonDocumentContentLoaded$.pipe(\r\n map(() => document.querySelector(\"[data-component='search-command-data']\")),\r\n filter(blogListingsFiltersSearchCommand => Boolean(blogListingsFiltersSearchCommand)),\r\n map((blogListingsFiltersSearchCommand) => camelCaseObjectKeys(\r\n JSON.parse(blogListingsFiltersSearchCommand.innerHTML))),\r\n filter(blogListingsFiltersSearchCommand => Boolean(ResultType.fromKey(blogListingsFiltersSearchCommand.resultType))),\r\n switchMap((blogListingsFiltersSearchCommand) => {\r\n\r\n // Business Rule: When we don't have any market information from server,\r\n // we will use the Personal Cookie information.\r\n UpdateBlogListingsFiltersSearchCommand(blogListingsFiltersSearchCommand);\r\n\r\n return getListingForYouSection[blogListingsFiltersSearchCommand.resultType](blogListingsFiltersSearchCommand);\r\n })\r\n).subscribe(initListingsFourYouSection);\r\n\r\n","import { fromFetch } from 'rxjs/fetch';\r\nimport { switchMap, of, catchError } from 'rxjs';\r\nimport { getCommunitiesForYou, getHomesForYou } from 'constants/routes'\r\n\r\n/**\r\n * getCommunitiesForYouContent: observable to fetch the communities for you content from blog controller.\r\n * response.text() to map the partial result\r\n */\r\nexport const getCommunitiesForYouContent$ = (CommunitiesSearchParameters) => {\r\n const requestObject = {\r\n method: 'POST',\r\n body: JSON.stringify({\r\n BlogListingsFiltersSearchCommand: {\r\n ...CommunitiesSearchParameters,\r\n },\r\n }),\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n 'Accept': 'application/json'\r\n }\r\n };\r\n\r\n return fromFetch(getCommunitiesForYou, requestObject).pipe(\r\n switchMap((response) => response.text()),\r\n catchError(() => of(''))\r\n );\r\n}\r\n\r\n/**\r\n * getListingForYouContent: observable to fetch the homes for you content from blog controller.\r\n * response.text() to map the partial result\r\n */\r\nexport const getHomesForYouContent$ = (homeSearchParameters) => {\r\n const requestObject = {\r\n method: 'POST',\r\n body: JSON.stringify({\r\n BlogListingsFiltersSearchCommand: {\r\n ...homeSearchParameters,\r\n },\r\n }),\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n 'Accept': 'application/json'\r\n }\r\n };\r\n\r\n return fromFetch(getHomesForYou, requestObject).pipe(\r\n switchMap((response) => response.text()),\r\n catchError(() => of(''))\r\n );\r\n}\r\n","import { fromFetch } from 'rxjs/fetch';\r\nimport { switchMap, of, catchError } from 'rxjs';\r\nimport { getMetroSpecificArticles } from 'constants/routes'\r\n\r\n/**\r\n * getMetroSpecifics: observable to fetch the metro specific article section\r\n * response.text() to map the partial result\r\n */\r\n const getMetroSpecifics$ = (metroAreaSectionCommand) => {\r\n const requestObject = {\r\n method: 'POST',\r\n body: JSON.stringify({\r\n buildMetroAreaSectionCommand: {\r\n ...metroAreaSectionCommand,\r\n },\r\n }),\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n 'Accept': 'application/json'\r\n }\r\n };\r\n\r\n return fromFetch(getMetroSpecificArticles, requestObject).pipe(\r\n switchMap((response) => response.text()),\r\n catchError(() => of(''))\r\n );\r\n}\r\n\r\nexport default getMetroSpecifics$;","import Carousel from '@components/carousel/dynamicCarousel';\r\nimport getMetroSpecifics$ from 'api/getMetroSpecificArticles';\r\nimport { readCookie } from 'modules/cookieManager';\r\nimport { filter, fromEvent, map, switchMap } from 'rxjs';\r\nimport { camelCaseObjectKeys } from 'utils/camelCase';\r\n\r\nconst onDocumentContentLoaded$ = fromEvent(document, 'DOMContentLoaded');\r\nconst metroSpecificContainerSelector = \"[data-metro-specific-subjects-container]\";\r\nconst metroSpecificSectionSelector = \"[data-section-name='metroSpecificSubjects']\"\r\n\r\n/* Object is defining selectors for different elements within a specific section\r\nof the webpage to set up the Carousel. */\r\nconst settings = {\r\n itemListQuerySelector: `${metroSpecificSectionSelector} [data-blog-article-cards-list]`,\r\n previousQuerySelector: `${metroSpecificSectionSelector} [data-left-arrow]`,\r\n nextQuerySelector: `${metroSpecificSectionSelector} [data-right-arrow]`,\r\n};\r\n\r\n/**\r\n * Function to render metro area content based on location and initializes a carousel component.\r\n * @param metroAreaContentByLocation - The `metroAreaContentByLocation` parameter is a string that\r\n * contains the content specific to a metro area location. This content will be rendered in a specific\r\n * section of the webpage based on the location provided. If this parameter has a value, the existing\r\n * content in that section will be replaced with the new one.\r\n */\r\nconst renderMetroSpecificSection = function (metroAreaContentByLocation){\r\n const metroSpecificMainContainer = document.querySelector(metroSpecificContainerSelector);\r\n\r\n if (metroSpecificMainContainer){\r\n\r\n // By default we are loading the Metro Area Section, if \"data\" has value we are retriving\r\n // the content by location, we remove the previous content to load the new one\r\n if (metroAreaContentByLocation){\r\n metroSpecificMainContainer.innerHTML = '';\r\n }\r\n \r\n const fragment = document.createRange().createContextualFragment(metroAreaContentByLocation);\r\n metroSpecificMainContainer.appendChild(fragment);\r\n\r\n const carousel = new Carousel();\r\n carousel.setSettings(settings);\r\n carousel.create();\r\n }\r\n}\r\n\r\n/* Observable to get the a new metro specific article section based on the personal user session */\r\nonDocumentContentLoaded$\r\n.pipe(\r\n map(() => document.querySelector(\"[data-component='metro-area-section-command-data']\")),\r\n filter(metroAreaSectionCommand => Boolean(metroAreaSectionCommand)),\r\n map((metroAreaSectionCommand) => camelCaseObjectKeys(\r\n JSON.parse(metroAreaSectionCommand.innerHTML))),\r\n switchMap((metroAreaSectionCommand) => {\r\n\r\n const personalCookie = readCookie('Personal', true);\r\n const urlParams = new URLSearchParams(personalCookie);\r\n\r\n metroAreaSectionCommand.marketId = urlParams.get('market') || 0;\r\n metroAreaSectionCommand.marketStateAbbreviation =urlParams.get('state') || '';\r\n \r\n return getMetroSpecifics$(metroAreaSectionCommand);\r\n })\r\n)\r\n.subscribe(renderMetroSpecificSection);","import { fromEvent } from 'rxjs';\r\nimport Carousel from '@components/carousel/dynamicCarousel';\r\n\r\nconst onDocumentContentLoaded$ = fromEvent(document, 'DOMContentLoaded');\r\nconst mostPopularSectionSelector= \"[data-section-name='mostPopularArticles']\";\r\nconst mostPopularSectionContainer = document.querySelector(mostPopularSectionSelector);\r\n\r\n/* The `const settings` object is defining the configuration settings for the carousel component. */\r\nconst settings = {\r\n itemListQuerySelector: `${mostPopularSectionSelector} [data-blog-article-cards-list]`,\r\n previousQuerySelector: `${mostPopularSectionSelector} [data-left-arrow]`,\r\n nextQuerySelector: `${mostPopularSectionSelector} [data-right-arrow]`,\r\n};\r\n\r\nconst carousel = new Carousel();\r\ncarousel.setSettings(settings);\r\n\r\n/**\r\n * Sets up a carousel for the most popular section if the container exists.\r\n * @returns If the `mostPopularSectionContainer` is not found, the function will return nothing\r\n * (undefined).\r\n */\r\nconst setMostPopularCarousel = function() {\r\n if (!mostPopularSectionContainer) {\r\n return;\r\n }\r\n\r\n carousel.create();\r\n}\r\n\r\n/* Subscribing to the `onDocumentContentLoaded$` observable, which emits an event when the DOM\r\ncontent has been fully loaded (DOMContentLoaded event). When this event occurs, the\r\n`setMostPopularCarousel` function will be called, which in turn creates and initializes\r\nthe carousel for the most popular articles section on the webpage. This ensures that\r\nthe carousel setup is triggered once the DOM content is ready. */\r\nonDocumentContentLoaded$.subscribe(setMostPopularCarousel);","import { debounceTime, distinctUntilChanged, filter, fromEvent, map, skip } from 'rxjs';\r\nimport Carousel from '@components/carousel/dynamicCarousel';\r\n\r\nconst settings = {\r\n itemListQuerySelector: '[data-section-name=\"popularPills\"] [data-popular-pills-list]',\r\n previousQuerySelector: '[data-section-name=\"popularPills\"] [data-left-arrow]',\r\n nextQuerySelector: '[data-section-name=\"popularPills\"] [data-right-arrow]',\r\n};\r\n\r\n/**\r\n * updatePopularPillContainerLeftPadding: Adjusts the padding of the popular pills container based on the visibility \r\n * of the left arrow control in the specified popular pills section.\r\n * @param {HTMLElement} popularPillsSection - The main container element \r\n * representing the popular pills section. It should contain the arrows \r\n * and the pills container as its child elements.\r\n */\r\nconst updatePopularPillContainerLeftPadding = function(prevButtonVisibility, popularPillsSection) {\r\n const popularPillsContainer = popularPillsSection.querySelector('[data-popular-pills-container]');\r\n popularPillsContainer?.classList.toggle('padding-left--0', prevButtonVisibility === 'hidden');\r\n popularPillsContainer?.classList.toggle('padding-left--30', prevButtonVisibility === 'visible');\r\n};\r\n\r\n/**\r\n * updatePopularPillContainerRightPadding: Adjusts the padding of the popular pills container based on the visibility \r\n * of the right arrow control in the specified popular pills section.\r\n * @param {HTMLElement} popularPillsSection - The main container element \r\n * representing the popular pills section. It should contain the arrows \r\n * and the pills container as its child elements.\r\n */\r\nconst updatePopularPillContainerRightPadding = function(nextButtonVisibility, popularPillsSection) {\r\n const popularPillsContainer = popularPillsSection.querySelector('[data-popular-pills-container]');\r\n popularPillsContainer?.classList.toggle('padding-right--0', nextButtonVisibility === 'hidden');\r\n\r\n if(nextButtonVisibility === 'visible'){\r\n const popularPillList = popularPillsSection.querySelector('[data-popular-pills-list]');\r\n popularPillList.scrollBy({ left: 28, behavior: 'smooth' });\r\n }\r\n};\r\n\r\n// listen for the DOMContentLoaded event to ensure the DOM is fully loaded before updating the popular pills.\r\nconst onDomContentLoaded$ = fromEvent(document, 'DOMContentLoaded').pipe(\r\n map(() => document.querySelector('[data-section-name=\"popularPills\"]')),\r\n filter(Boolean)\r\n);\r\n\r\nonDomContentLoaded$.subscribe((popularPillsSection) => {\r\n const carousel = new Carousel();\r\n carousel.setSettings(settings);\r\n carousel.create();\r\n\r\n // debouce to get only last interaction on scroll animation\r\n const newVisibleElements$ = carousel.visibleElementsSubject$.pipe(debounceTime(200));\r\n newVisibleElements$.pipe(\r\n map(() => popularPillsSection.querySelector('[data-left-arrow]')?.style.visibility),\r\n filter(Boolean),\r\n distinctUntilChanged(),\r\n skip(1)\r\n ).subscribe((prevButtonVisibility) => \r\n updatePopularPillContainerLeftPadding(prevButtonVisibility, popularPillsSection));\r\n\r\n newVisibleElements$.pipe(\r\n map(() => popularPillsSection.querySelector('[data-right-arrow]')?.style.visibility),\r\n filter(Boolean),\r\n distinctUntilChanged(),\r\n skip(1)\r\n ).subscribe((nextButtonVisibility) => \r\n updatePopularPillContainerRightPadding(nextButtonVisibility, popularPillsSection));\r\n});\r\n","/**\r\n * redirectToBlogArticlePage: redirect to blog article page based on slug of the article\r\n */\r\nexport const redirectToBlogArticlePage = function (slug) {\r\n window.open(`learn/${slug}/`, '_self');\r\n}\r\n\r\n/**\r\n * redirectToSearchCommunityResults: redirect to Search Community Result Page based on \r\n * the search endpoint result\r\n */\r\nexport const redirectToSearchCommunityResults = function (searchText) {\r\n window.open(`Search?SearchText=${searchText}&ToPage=communities`, '_blank');\r\n}\r\n\r\n/**\r\n * redirectToSearchHomesResults: redirect to Search Homes Result Page based on search endpoint result\r\n */\r\nexport const redirectToSearchHomesResults = function (searchText) {\r\n window.open(`Search?SearchText=${searchText}&ToPage=homes`, '_blank');\r\n}\r\n\r\n\r\n\r\n","import { store } from '@redux/store';\r\nimport { fromEvent, map, filter } from 'rxjs';\r\nimport LoadingStatus from 'enums/loadingStatus';\r\nimport { selectLoading, selectConfigurationImageResizeService } from 'layout/redux/selectors';\r\nimport generateRandomNumber from 'utils/randomNumber';\r\n\r\n/**\r\n * Generates a random number and returns a URL string for a lifestyle image based on that number.\r\n * @param imageResizeService - is a string representing the domain Image Resize Service.\r\n * @returns a string that represents the URL of a randomly selected lifestyle image.\r\n */\r\nconst getLifeStyleImage = (imageResizeService) => {\r\n const randomNumber = generateRandomNumber(1, 20);\r\n return `${imageResizeService}/images/Lifestyle/lifestyle_${randomNumber}.jpg`;\r\n};\r\n\r\n/**\r\n * Removes all `` elements within the closest `` element of a given image.\r\n * @param image - is a reference to an HTML `img` element.\r\n */\r\nconst removeSource = (image) => {\r\n const picture = image.closest('picture');\r\n if (picture) {\r\n picture.querySelectorAll('source').forEach((element) => element.remove());\r\n }\r\n};\r\n\r\n/**\r\n * Replaces the source of an image element with a placeholder image if the original image fails to load.\r\n * @param image - is the HTML `img` element that needs to be replaced with a new image source in case of an error.\r\n * @param selectResourcesHostNames - is an object that contains the IRS and resource domain URLs.\r\n */\r\nconst onErrorImage = (image) => {\r\n const state = store.getState();\r\n if(selectLoading(state) === LoadingStatus.Succeeded.toString()){\r\n const imageResizeService = selectConfigurationImageResizeService(state);\r\n removeSource(image);\r\n const imageSrc = getLifeStyleImage(imageResizeService);\r\n \r\n image.src = imageSrc;\r\n image.onerror = null;\r\n }\r\n};\r\n\r\n/**\r\n * handlerErrorImages: active an observer when any image dispatch the on error event\r\n */\r\nconst handlerErrorImages = function (container) {\r\n if(container){\r\n const errorObservable = fromEvent(container, 'error', true).pipe(\r\n filter(event => event.target.dataset.cardElement === 'image'),\r\n map((event) => event.target)\r\n );\r\n errorObservable.subscribe(onErrorImage);\r\n } \r\n};\r\n\r\nexport default handlerErrorImages;\r\n","import { store } from '@redux/store';\r\nimport uiStateSlice from 'layout/redux/uiStateSlice';\r\nimport { fromEvent, filter, map } from \"rxjs\";\r\nimport handlerErrorImages from './handlerErrorImages';\r\n\r\nconst listingForYouContainer = document.querySelector('[data-listings-for-you-container]');\r\n\r\n// fix images with error.\r\nhandlerErrorImages(listingForYouContainer);\r\n\r\nconst containerClick$ = fromEvent(listingForYouContainer, 'click');\r\n\r\nconst isStandardCard = (event) => !!event.target.closest('[data-standard-card]');\r\nconst isAnchorElement = (event) => event.target instanceof HTMLAnchorElement;\r\nconst isFavoriteIcon = (event) => !!event.target.closest('.icon__save');\r\nconst isLeadOpener = (event) => !!event.target.closest('[data-lead-generator-opener]');\r\n\r\nconst cardClick$ = containerClick$.pipe(\r\n filter(isStandardCard), \r\n filter(event => !isFavoriteIcon(event)),\r\n filter(event => !isAnchorElement(event)),\r\n filter(event => !isLeadOpener(event)),\r\n);\r\n\r\nconst leadOpenerClick$ = containerClick$.pipe(\r\n filter(event => isLeadOpener(event)),\r\n map((event) => event.target.closest('[data-card]'))\r\n);\r\n\r\nconst openLeadModal = function(id, type){\r\n store.dispatch(uiStateSlice.actions.modalInformation({ id, type, name: 'leadModal' }));\r\n}\r\n\r\nconst redirectToDetailPage = function(event){\r\n const standardCardElement = event.target.closest('[data-standard-card]');\r\n const url = event.target?.dataset?.url ?? standardCardElement?.querySelector('a')?.href;\r\n\r\n window.open(url, '_blank');\r\n}\r\n\r\ncardClick$.subscribe(redirectToDetailPage);\r\nleadOpenerClick$.subscribe((leadOpener) => openLeadModal(leadOpener.dataset.id, leadOpener.dataset.type));","import { store, store$ } from '@redux/store';\r\nimport HousingProductType from 'constants/housingProductType';\r\nimport googleAnalytics4Event from 'features/googleAnalytics4';\r\nimport typeahead from 'pages/blog/components/articleSearchBox';\r\nimport { filter, fromEvent, map, merge, distinctUntilChanged } from 'rxjs';\r\nimport { selectModal, selectFetchingModal } from 'layout/redux/selectors';\r\n\r\nconst getPopularPillElement = (event) => event.target.closest('[data-pill]');\r\nconst getStandardCardElement = (event) => event.target.closest(\"[data-card]\");\r\nconst getLinkableArticleElement = (event) => event.target.closest(\"[data-link]\");\r\nconst isBreadcrumbItemElement = (event) => event.target?.closest('[data-breadcrumb-item]');\r\nconst seeAllArticlesButton = document.querySelector('[data-see-all-articles]');\r\nconst isListingForYouSection = (event) => !!event.target.closest(\"[data-listings-for-you-container]\");\r\nconst isFavoriteIcon = (event) => !!event.target.closest(\".icon__save\");\r\nconst isCallToAction = (event) => !!event.target.closest(\"[data-lead-generator-opener]\");\r\nconst isStandardCard = (event) => !!event.target.closest(\"[data-standard-card]\");\r\nconst isMostPopularSection = (event) => !!event.target.closest('[data-section-name=\"mostPopularArticles\"]');\r\nconst isCategorySection = (event) => !!event.target.closest('[data-section-name=\"categoryArticles\"]');\r\nconst isMetroSpecificSection = (event) => !!event.target.closest('[data-section-name=\"metroSpecificSubjects\"]');\r\nconst isCommunityStandardCard = (dataset) => dataset.type === HousingProductType.Community().getName();\r\nconst isPlanStandardCard = (dataset) => dataset.type === HousingProductType.Plan().getName();\r\nconst isSpecStandardCard = (dataset) => dataset.type === HousingProductType.Spec().getName();\r\n\r\n/* Observable that listens for click events on the document.body */\r\nconst bodyClick$ = fromEvent(document.body, 'click');\r\n\r\nconst listingForYouSectionClick$ = bodyClick$.pipe(\r\n filter((event) => isListingForYouSection(event))\r\n );\r\n\r\nconst breadcrumbItems = Array.from(document.querySelectorAll('[data-breadcrumb-item]'));\r\n\r\n// *************** Breadcrumb GA Events Handlers. ***************\r\n/* An observable stream that listens for click events. It then maps each click event to the closest\r\nancestor element of the clicked target that has a `data-breadcrumb-item` attribute. \r\nThe `filter(Boolean)` function is used to filter out any falsy values. */\r\nconst onBreadcrumbClick$ = bodyClick$.pipe(\r\n map(isBreadcrumbItemElement),\r\n filter(Boolean)\r\n );\r\n\r\n /**\r\n * Dispatches a Google Analytics 4 event when a breadcrumb link is clicked.\r\n * @param breadcrumbLink - is the link element that represents a\r\n * breadcrumb item in a website's navigation.\r\n */\r\nconst triggerBreadcrumbClickEvent = (breadcrumbLink) => {\r\n const breadcrumbIndex = breadcrumbItems.findIndex((item) => item === breadcrumbLink);\r\n const customProperties = {\r\n breadcrumb_position: breadcrumbIndex + 1,\r\n destination: breadcrumbLink.href,\r\n link_text: breadcrumbLink.innerText,\r\n };\r\n \r\n store.dispatch(googleAnalytics4Event({ eventName: 'breadcrumb_click', customProperties }));\r\n };\r\n \r\nonBreadcrumbClick$.subscribe(triggerBreadcrumbClickEvent);\r\n\r\n/**\r\n * Dispatches a Google Analytics 4 event when a\r\n * \"See All Articles\" link is clicked, capturing the link text and destination URL as custom\r\n * properties.\r\n * @param element - The `element` parameter in the `triggerSeeAllArticlesLinkClickedEvent` function\r\n * is a reference to the HTML element that represents the \"See All Articles\" link.\r\n */\r\nconst triggerSeeAllArticlesLinkClickedEvent = (element) => {\r\n const customProperties = {\r\n button_text: 'See All Articles',\r\n destination_url: element.href,\r\n };\r\n store.dispatch(googleAnalytics4Event({ eventName: 'button_click', customProperties }));\r\n};\r\n\r\n/* Creating an observable stream `seeAllArticlesLinkClicked$` that listens for\r\nclick events on the `seeAllArticlesLink` element. When a click event is detected, the code maps\r\nthe event to the closest ancestor element with the attribute `[data-see-all-articles]`. */\r\nconst seeAllArticlesLinkClicked$ = fromEvent(seeAllArticlesButton, 'click').pipe(\r\n map((event) => event.target),\r\n);\r\n\r\nseeAllArticlesLinkClicked$.subscribe(triggerSeeAllArticlesLinkClickedEvent);\r\n\r\n// *************** Search Box GA Events Handlers. ***************\r\n/**\r\n * Dispatches a Segment event when a search is done.\r\n * @param suggestion - is the suggestion element that represents the element clicked\r\n * in the typeahead.\r\n */\r\nconst triggerSearchExecutedEvent = (suggestion) => {\r\n const customProperties = {\r\n search_value: suggestion.dataset.title,\r\n page_type: 'Learning_Center',\r\n click_target: 'Learn more about Pop Pills',\r\n };\r\n \r\n store.dispatch(googleAnalytics4Event({ eventName: \"searchterm_events\", customProperties }) );\r\n };\r\n \r\n typeahead\r\n .getSuggestionListClickedObserver()\r\n .subscribe(triggerSearchExecutedEvent);\r\n\r\n// *************** Recommended Article Events Handlers. ***************\r\n /**\r\n * Dispatches a Segment event when an article is clicked.\r\n * @param article - is the article that represents the element clicked.\r\n */\r\n const triggerRecomendedArticlesClick = (article) => {\r\n const customProperties = {\r\n content_id: article.dataset.slug,\r\n content_title: article.dataset.title,\r\n recommendation_type: \"similar articles\",\r\n page_type: 'Learning_Center',\r\n };\r\n \r\n store.dispatch(googleAnalytics4Event({ eventName: \"recommendation_click\", customProperties }));\r\n };\r\n \r\n /* Observable stream that listens for click events on the document body.\r\n It then filters those events to only include ones where the clicked\r\n element is identified as being in the most popular section (determined by the `isMostPopularSection`\r\n function). */\r\n const onMostPopularArticleClick$ = bodyClick$.pipe(\r\n filter(isMostPopularSection),\r\n map(getLinkableArticleElement),\r\n filter(Boolean)\r\n );\r\n \r\n onMostPopularArticleClick$.subscribe(triggerRecomendedArticlesClick);\r\n \r\n /* Observable stream that listens for click events on the `document.body`.\r\n It then filters those events to only include ones where the clicked\r\n element is identified as being in the category articles section (determined by the\r\n `isCategorySection` function). */\r\n const onCategoryArticlesClick$ = bodyClick$.pipe(\r\n filter(isCategorySection),\r\n map(getLinkableArticleElement),\r\n filter(Boolean)\r\n );\r\n \r\n onCategoryArticlesClick$.subscribe(triggerRecomendedArticlesClick);\r\n\r\n// *************** Metro Specific Article Events Handlers. ***************\r\n/**\r\n * Dispatches a Google Analytics 4 event for tracking article\r\n * clicks with custom properties.\r\n * @param article - Reference to an HTML element that represents an\r\n * article on a webpage. It likely has `dataset` properties such as `data-slug` and `data-title` that\r\n * store additional information about the article.\r\n */\r\nconst triggerArticlesClick = (article) => {\r\n const customProperties = {\r\n article_id: article.dataset.slug,\r\n article_title: article.dataset.title,\r\n page_type: 'Learning_Center',\r\n };\r\n \r\n store.dispatch(googleAnalytics4Event({ eventName: \"article_click\", customProperties }));\r\n };\r\n\r\n/* Observable stream `onMetroSpecificArticlesClick$` that listens\r\n for click events on the `document.body`. Here's a breakdown of what each part of the code is\r\n doing: */\r\n const onMetroSpecificArticlesClick$ = bodyClick$.pipe(\r\n filter(isMetroSpecificSection),\r\n map(getLinkableArticleElement),\r\n filter(Boolean)\r\n );\r\n\r\n /* Observable stream `metroSpecificSectionReady$` that listens for a custom event\r\n named 'metroSpecificSectionReady' triggered on the `document.body`. */\r\nonMetroSpecificArticlesClick$.subscribe(triggerArticlesClick);\r\n\r\n/**\r\n * Checks if a price is valid and not equal to zero.\r\n * @param price - is a variable that represents the price of a listing\r\n */\r\nconst isPriced = (price) => price && price !== '0';\r\n\r\n/**\r\n * getAreaClickedName: function to get the click target event based on the element clicked\r\n * @param {HTMLElement} element target element\r\n * @returns an string object\r\n */\r\nconst getAreaClickedName = function(element){\r\n const areaClickedPerCardElement = {\r\n image: 'Listings Image Clicked',\r\n communityName: 'Listing text link',\r\n planName: 'Listing text link',\r\n specAddress: 'Listing text link',\r\n favoriteButton: 'Listing favorite',\r\n default: 'Card Clicked',\r\n };\r\n \r\n const elementName = element.dataset.cardElement;\r\n return areaClickedPerCardElement[elementName] || areaClickedPerCardElement.default;\r\n}\r\n\r\n/**\r\n * getModalClosePaidCommunityCustomProperties: function to get the custom properties of close button click\r\n * based on the community listing card information\r\n * @param {object} data object with the information of the event\r\n * @returns custom properties object\r\n */\r\nconst getModalClosePaidCommunityCustomProperties = function(data){\r\n const dataset = data.listingInformation;\r\n const destionationUrl = data.url\r\n\r\n const customProperties = {\r\n page_type: 'Learning_Center',\r\n click_target: 'Learn Center Listings Cards',\r\n destination: destionationUrl,\r\n trustbuilder_reviews: dataset.hasBuilderReviews,\r\n min_price: dataset.priceLow,\r\n max_price: dataset.priceHigh,\r\n market_id: dataset.marketId,\r\n market_name: `${dataset.marketName}, ${dataset.stateAbbreviation}`,\r\n community_name: dataset.communityName,\r\n community_id: dataset.communityId,\r\n position: dataset.index,\r\n price_reduction: dataset.priceReductionLabel,\r\n is_limited_availability: dataset.hasLimitedInformation,\r\n is_priced: isPriced(dataset.priceLow) || isPriced(dataset.priceHigh) ? 'True' : 'False',\r\n is_paid: 'True',\r\n zip_code: dataset.zip,\r\n builder_id: dataset.builderId,\r\n builder_name: dataset.brandName\r\n };\r\n\r\n return customProperties;\r\n}\r\n\r\n/**\r\n* getModalClosePaidPlanCustomProperties: function to get the custom properties of close button click\r\n* based on the plan listing card information\r\n* @param {object} data object with the information of the event\r\n* @returns custom properties object\r\n*/\r\nconst getModalClosePaidPlanCustomProperties = function(data){\r\n const dataset = data.listingInformation;\r\n const destionationUrl = data.url\r\n\r\n const customProperties = {\r\n page_type: 'Learning_Center',\r\n click_target: 'Learn Center Listings Cards',\r\n destination: destionationUrl,\r\n trustbuilder_reviews: dataset.hasBuilderReviews,\r\n min_price: dataset.price,\r\n market_id: dataset.marketId,\r\n market_name: `${dataset.marketName}, ${dataset.stateAbbreviation}`,\r\n community_name: dataset.communityName,\r\n community_id: dataset.communityId,\r\n plan_id: dataset.planId,\r\n home_status: dataset.homeStatus,\r\n position: dataset.index,\r\n price_reduction: dataset.priceReductionLabel,\r\n is_limited_availability: dataset.hasLimitedInformation,\r\n is_priced: isPriced(dataset.price) ? 'True' : 'False',\r\n is_paid: 'True',\r\n is_spec: 'False',\r\n is_plan: 'True',\r\n zip_code: dataset.zip,\r\n builder_id: dataset.builderId,\r\n builder_name: dataset.brandName\r\n };\r\n\r\n return customProperties;\r\n}\r\n\r\n/**\r\n* getModalClosePaidSpecCustomProperties: function to get the custom properties of close button click\r\n* based on the spec listing card information\r\n* @param {object} data object with the information of the event\r\n* @returns custom properties object\r\n*/\r\nconst getModalClosePaidSpecCustomProperties = function(data){\r\n const dataset = data.listingInformation;\r\n const destionationUrl = data.url\r\n\r\n const customProperties = {\r\n page_type: 'Learning_Center',\r\n click_target: 'Learn Center Listings Cards', \r\n destination: destionationUrl,\r\n trustbuilder_reviews: dataset.hasBuilderReviews,\r\n min_price: dataset.price,\r\n market_id: dataset.marketId,\r\n market_name: `${dataset.marketName}, ${dataset.stateAbbreviation}`,\r\n community_name: dataset.communityName,\r\n community_id: dataset.communityId,\r\n spec_id: dataset.specId,\r\n home_status: dataset.homeStatus,\r\n position: dataset.index,\r\n price_reduction: dataset.priceReductionLabel,\r\n is_limited_availability: dataset.hasLimitedInformation,\r\n is_priced: isPriced(dataset.price) ? 'True' : 'False',\r\n is_paid: 'True',\r\n is_spec: 'True',\r\n is_plan: 'False',\r\n zip_code: dataset.zip,\r\n builder_id: dataset.builderId,\r\n builder_name: dataset.brandName\r\n };\r\n\r\n return customProperties;\r\n}\r\n\r\n/**\r\n * getRecommendedSubmittedPaidCommunityCustomProperties: function to get custom properties of Recommended button click\r\n * based on the community listing card information\r\n * @param {object} data object with the information of the event\r\n * @returns custom properties object\r\n */\r\nconst getRecommendedSubmittedPaidCommunityCustomProperties = function(modalInformation){\r\n const { selectedRecommendedCommunities } = modalInformation;\r\n selectedRecommendedCommunities.forEach((dataset) => {\r\n const customProperties = {\r\n page_type: 'Learning_Center',\r\n click_target: 'Learn Center Listings Cards',\r\n button_name: 'Get More Info',\r\n event_type: 'TDV Events',\r\n currency_value: 'USD',\r\n value: 30,\r\n trustbuilder_reviews: dataset.HasBuilderReviews,\r\n min_price: dataset.PriceLow,\r\n max_price: dataset.PriceHigh,\r\n market_id: dataset.MarketId,\r\n market_name: `${dataset.MarketName}, ${dataset.StateAbbreviation}`,\r\n community_name: dataset.CommunityName,\r\n community_status: dataset.MarketingStatus || 'Normal',\r\n community_id: dataset.CommunityId, \r\n price_reduction: dataset.PriceReductionLabel,\r\n is_limited_availability: dataset.HasLimitedInformation,\r\n is_priced: isPriced(dataset.PriceLow) || isPriced(dataset.PriceHigh) ? 'True' : 'False',\r\n is_paid: 'True',\r\n zip_code: dataset.Zip,\r\n builder_id: dataset.BuilderId,\r\n builder_name: dataset.BrandName\r\n };\r\n\r\n store.dispatch(googleAnalytics4Event({ eventName: 'direct_rec_lead', customProperties }));\r\n })\r\n}\r\n\r\n/**\r\n * getModalSubmittedPaidCommunityCustomProperties: function to get the custom properties of submitted button click\r\n * based on the community listing card information\r\n * @param {object} data object with the information of the event\r\n * @returns custom properties object\r\n */\r\nconst getModalSubmittedPaidCommunityCustomProperties = function(data){\r\n const dataset = data.listingInformation;\r\n const destionationUrl = data.url\r\n\r\n const customProperties = {\r\n page_type: 'Learning_Center',\r\n click_target: 'Learn Center Listings Cards',\r\n button_name: 'Download Brochure',\r\n event_type: 'TDV Events',\r\n currency_value: 'USD',\r\n value: 30,\r\n destination: destionationUrl,\r\n trustbuilder_reviews: dataset.hasBuilderReviews,\r\n min_price: dataset.priceLow,\r\n max_price: dataset.priceHigh,\r\n market_id: dataset.marketId,\r\n market_name: `${dataset.marketName}, ${dataset.stateAbbreviation}`,\r\n community_name: dataset.communityName,\r\n community_id: dataset.communityId,\r\n position: dataset.index,\r\n price_reduction: dataset.priceReductionLabel,\r\n is_limited_availability: dataset.hasLimitedInformation,\r\n is_priced: isPriced(dataset.priceLow) || isPriced(dataset.priceHigh) ? 'True' : 'False',\r\n is_paid: 'True',\r\n zip_code: dataset.zip,\r\n builder_id: dataset.builderId,\r\n builder_name: dataset.brandName\r\n };\r\n\r\n return customProperties;\r\n}\r\n\r\n/**\r\n* getModalSubmittedPaidPlanCustomProperties: function to get the custom properties of Submitted button click\r\n* based on the plan listing card information\r\n* @param {object} data object with the information of the event\r\n* @returns custom properties object\r\n*/\r\nconst getModalSubmittedPaidPlanCustomProperties = function(data){\r\n const dataset = data.listingInformation;\r\n const destionationUrl = data.url\r\n\r\n const customProperties = {\r\n page_type: 'Learning_Center',\r\n click_target: 'Learn Center Listings Cards',\r\n button_name: 'Download Brochure',\r\n event_type: 'TDV Events',\r\n currency_value: 'USD',\r\n value: 30,\r\n destination: destionationUrl,\r\n trustbuilder_reviews: dataset.hasBuilderReviews,\r\n min_price: dataset.price,\r\n market_id: dataset.marketId,\r\n market_name: `${dataset.marketName}, ${dataset.stateAbbreviation}`,\r\n community_name: dataset.communityName,\r\n community_id: dataset.communityId,\r\n plan_id: dataset.planId,\r\n home_status: dataset.homeStatus,\r\n position: dataset.index,\r\n price_reduction: dataset.priceReductionLabel,\r\n is_limited_availability: dataset.hasLimitedInformation,\r\n is_priced: isPriced(dataset.price) ? 'True' : 'False',\r\n is_paid: 'True',\r\n is_spec: 'False',\r\n is_plan: 'True',\r\n zip_code: dataset.zip,\r\n builder_id: dataset.builderId,\r\n builder_name: dataset.brandName\r\n };\r\n\r\n return customProperties;\r\n}\r\n\r\n/**\r\n* getModalSubmittedPaidSpecCustomProperties: function to get the custom properties of Submitted button click\r\n* based on the spec listing card information\r\n* @param {object} data object with the information of the event\r\n* @returns custom properties object\r\n*/\r\nconst getModalSubmittedPaidSpecCustomProperties = function(data){\r\n const dataset = data.listingInformation;\r\n const destionationUrl = data.url\r\n\r\n const customProperties = {\r\n page_type: 'Learning_Center',\r\n click_target: 'Learn Center Listings Cards',\r\n button_name: 'Download Brochure',\r\n event_type: 'TDV Events',\r\n currency_value: 'USD',\r\n value: 30,\r\n destination: destionationUrl,\r\n trustbuilder_reviews: dataset.hasBuilderReviews,\r\n min_price: dataset.price,\r\n market_id: dataset.marketId,\r\n market_name: `${dataset.marketName}, ${dataset.stateAbbreviation}`,\r\n community_name: dataset.communityName,\r\n community_id: dataset.communityId,\r\n spec_id: dataset.specId,\r\n home_status: dataset.homeStatus,\r\n position: dataset.index,\r\n price_reduction: dataset.priceReductionLabel,\r\n is_limited_availability: dataset.hasLimitedInformation,\r\n is_priced: isPriced(dataset.price) ? 'True' : 'False',\r\n is_paid: 'True',\r\n is_spec: 'True',\r\n is_plan: 'False',\r\n zip_code: dataset.zip,\r\n builder_id: dataset.builderId,\r\n builder_name: dataset.brandName\r\n };\r\n\r\n return customProperties;\r\n}\r\n\r\n/**\r\n * getLeadButtonClickedPaidCommunityCustomProperties: function to get the custom properties of lead button click\r\n * based on the community listing card information\r\n * @param {object} data object with the information of the event\r\n * @returns custom properties object\r\n */\r\nconst getLeadButtonClickedPaidCommunityCustomProperties = function(standarCommunityCard){\r\n const dataset = standarCommunityCard.dataset;\r\n const destionationUrl = dataset?.url ?? standarCommunityCard?.querySelector('a')?.href;\r\n\r\n const customProperties = {\r\n page_type: 'Learning_Center',\r\n click_target: 'Learn Center Listings Cards',\r\n button_name: 'Download Brochure',\r\n destination: destionationUrl,\r\n trustbuilder_reviews: dataset.hasBuilderReviews,\r\n min_price: dataset.priceLow,\r\n max_price: dataset.priceHigh,\r\n market_id: dataset.marketId,\r\n market_name: `${dataset.marketName}, ${dataset.stateAbbreviation}`,\r\n community_name: dataset.communityName,\r\n community_id: dataset.communityId,\r\n position: dataset.index,\r\n price_reduction: dataset.priceReductionLabel,\r\n is_limited_availability: dataset.hasLimitedInformation,\r\n is_priced: isPriced(dataset.priceLow) || isPriced(dataset.priceHigh) ? 'True' : 'False',\r\n is_paid: 'True',\r\n zip_code: dataset.zip,\r\n builder_id: dataset.builderId,\r\n builder_name: dataset.brandName\r\n };\r\n\r\n return customProperties;\r\n}\r\n\r\n/**\r\n* getLeadButtonClickedPaidPlanCustomProperties: function to get the custom properties of lead button click\r\n* based on the plan listing card information\r\n* @param {object} data object with the information of the event\r\n* @returns custom properties object\r\n*/\r\nconst getLeadButtonClickedPaidPlanCustomProperties = function(standarPlanCard){\r\n const dataset = standarPlanCard.dataset;\r\n const destionationUrl = dataset?.url ?? standarPlanCard?.querySelector('a')?.href;\r\n\r\n const customProperties = {\r\n page_type: 'Learning_Center',\r\n click_target: 'Learn Center Listings Cards',\r\n button_name: 'Download Brochure',\r\n destination: destionationUrl,\r\n trustbuilder_reviews: dataset.hasBuilderReviews,\r\n min_price: dataset.price,\r\n market_id: dataset.marketId,\r\n market_name: `${dataset.marketName}, ${dataset.stateAbbreviation}`,\r\n community_name: dataset.communityName,\r\n community_id: dataset.communityId,\r\n plan_id: dataset.planId,\r\n home_status: dataset.homeStatus,\r\n position: dataset.index,\r\n price_reduction: dataset.priceReductionLabel,\r\n is_limited_availability: dataset.hasLimitedInformation,\r\n is_priced: isPriced(dataset.price) ? 'True' : 'False',\r\n is_paid: 'True',\r\n is_spec: 'False',\r\n is_plan: 'True',\r\n zip_code: dataset.zip,\r\n builder_id: dataset.builderId,\r\n builder_name: dataset.brandName\r\n };\r\n\r\n return customProperties;\r\n}\r\n\r\n/**\r\n* getLeadButtonClickedPaidSpecCustomProperties: function to get the custom properties of lead button click\r\n* based on the spec listing card information\r\n* @param {object} data object with the information of the event\r\n* @returns custom properties object\r\n*/\r\nconst getLeadButtonClickedPaidSpecCustomProperties = function(specStandardCard){\r\n const dataset = specStandardCard.dataset;\r\n const destionationUrl = dataset?.url ?? specStandardCard?.querySelector('a')?.href;\r\n\r\n const customProperties = {\r\n page_type: 'Learning_Center',\r\n click_target: 'Learn Center Listings Cards',\r\n button_name: 'Download Brochure',\r\n destination: destionationUrl,\r\n trustbuilder_reviews: dataset.hasBuilderReviews,\r\n min_price: dataset.price,\r\n market_id: dataset.marketId,\r\n market_name: `${dataset.marketName}, ${dataset.stateAbbreviation}`,\r\n community_name: dataset.communityName,\r\n community_id: dataset.communityId,\r\n spec_id: dataset.specId,\r\n home_status: dataset.homeStatus,\r\n position: dataset.index,\r\n price_reduction: dataset.priceReductionLabel,\r\n is_limited_availability: dataset.hasLimitedInformation,\r\n is_priced: isPriced(dataset.price) ? 'True' : 'False',\r\n is_paid: 'True',\r\n is_spec: 'True',\r\n is_plan: 'False',\r\n zip_code: dataset.zip,\r\n builder_id: dataset.builderId,\r\n builder_name: dataset.brandName\r\n };\r\n\r\n return customProperties;\r\n}\r\n\r\n/**\r\n * getPaidCommunityCardProperties : function to return the respective custom properties\r\n * @param {dataset} dataset from the standard community card element\r\n * @returns custom properties object\r\n */\r\nconst getPaidCommunityCardProperties = function (data){\r\n const dataset = data.card.dataset;\r\n const destionationUrl = dataset?.url ?? data.card?.querySelector('a')?.href;\r\n\r\n const customProperties = {\r\n page_type: 'Learning_Center',\r\n click_target: 'Learn Center Listings Cards',\r\n click_target1: data.clickTarget,\r\n destination: destionationUrl,\r\n trustbuilder_reviews: dataset.hasBuilderReviews,\r\n min_price: dataset.priceLow,\r\n max_price: dataset.priceHigh,\r\n market_id: dataset.marketId,\r\n market_name: `${dataset.marketName}, ${dataset.stateAbbreviation}`,\r\n community_name: dataset.communityName,\r\n community_id: dataset.communityId,\r\n position: dataset.index,\r\n price_reduction: dataset.priceReductionLabel,\r\n is_limited_availability: dataset.hasLimitedInformation,\r\n is_priced: isPriced(dataset.priceLow) || isPriced(dataset.priceHigh) ? 'True' : 'False',\r\n is_paid: 'True',\r\n zip_code: dataset.zip,\r\n builder_id: dataset.builderId,\r\n builder_name: dataset.brandName\r\n };\r\n\r\n return customProperties;\r\n }\r\n\r\n/**\r\n * getPaidPlanCardProperties: function to return the respective custom properties\r\n * @param {dataset} dataset from the standard plan card element\r\n * @returns custom properties object\r\n */\r\nconst getPaidPlanCardProperties = function (data){\r\n\r\n const dataset = data.card.dataset;\r\n const destionationUrl = dataset?.url ?? data.card?.querySelector('a')?.href;\r\n\r\n const customProperties = {\r\n page_type: 'Learning_Center',\r\n click_target: 'Learn Center Listings Cards',\r\n click_target1: data.clickTarget,\r\n destination: destionationUrl,\r\n trustbuilder_reviews: dataset.hasBuilderReviews,\r\n min_price: dataset.price,\r\n market_id: dataset.marketId,\r\n market_name: `${dataset.marketName}, ${dataset.stateAbbreviation}`,\r\n community_name: dataset.communityName,\r\n community_id: dataset.communityId,\r\n plan_id: dataset.planId,\r\n home_status: dataset.homeStatus,\r\n position: dataset.index,\r\n price_reduction: dataset.priceReductionLabel,\r\n is_limited_availability: dataset.hasLimitedInformation,\r\n is_priced: isPriced(dataset.price) ? 'True' : 'False',\r\n is_paid: 'True',\r\n is_spec: 'False',\r\n is_plan: 'True',\r\n zip_code: dataset.zip,\r\n builder_id: dataset.builderId,\r\n builder_name: dataset.brandName\r\n };\r\n\r\n return customProperties;\r\n}\r\n\r\n/**\r\n * getPaidSpecCardProperties: function to return the respective custom properties\r\n * @param {dataset} dataset from the standard plan card element\r\n * @returns custom properties object\r\n */\r\nconst getPaidSpecCardProperties = function (data){\r\n\r\n const dataset = data.card.dataset;\r\n const destionationUrl = dataset?.url ?? data.card?.querySelector('a')?.href;\r\n \r\n const customProperties = {\r\n page_type: 'Learning_Center',\r\n click_target: 'Learn Center Listings Cards',\r\n click_target1: data.clickTarget,\r\n destination: destionationUrl,\r\n trustbuilder_reviews: dataset.hasBuilderReviews,\r\n min_price: dataset.price,\r\n market_id: dataset.marketId,\r\n market_name: `${dataset.marketName}, ${dataset.stateAbbreviation}`,\r\n community_name: dataset.communityName,\r\n community_id: dataset.communityId,\r\n spec_id: dataset.specId,\r\n home_status: dataset.homeStatus,\r\n position: dataset.index,\r\n price_reduction: dataset.priceReductionLabel,\r\n is_limited_availability: dataset.hasLimitedInformation,\r\n is_priced: isPriced(dataset.price) ? 'True' : 'False',\r\n is_paid: 'True',\r\n is_spec: 'True',\r\n is_plan: 'False',\r\n zip_code: dataset.zip,\r\n builder_id: dataset.builderId,\r\n builder_name: dataset.brandName\r\n };\r\n\r\n return customProperties;\r\n}\r\n\r\n/**\r\n * Dispatches a Analytics Event event when a popular pill is clicked.\r\n * @param pill - is the pill clicked in popular pill section.\r\n */\r\nconst triggerPopularPillClick = function(pill) {\r\n const customProperties = {\r\n page_type: 'Learning_Center',\r\n tag_text: pill.dataset.pillText,\r\n destination: pill.dataset.pillUrl,\r\n };\r\n\r\n store.dispatch(googleAnalytics4Event({ eventName: 'tag_click', customProperties }));\r\n};\r\n\r\n/**\r\n * Dispatches a Segment event when listing card is clicked.\r\n * @param data - is the data card on the listings section.\r\n */\r\nconst triggerListingCardClick = (event) => {\r\n store.dispatch(googleAnalytics4Event({ eventName: event.name, customProperties: event.customProperties }));\r\n};\r\n\r\n/**\r\n * Dispatches a Analytics Event When the call to action is clicked.\r\n * @param customProperties - is the custom properties of the event.\r\n */\r\nconst triggerLeadButtonClickedEvent = function(customProperties) {\r\n store.dispatch(googleAnalytics4Event({ eventName: 'form_open', customProperties }));\r\n}\r\n\r\n/**\r\n* Dispatches a Analytics Event When the Submitt Lead Button is clicked.\r\n* @param customProperties - is the custom properties of the event.\r\n*/\r\nconst triggerModalSubmittedEvent = function(customProperties) {\r\n store.dispatch(googleAnalytics4Event({ eventName: 'generate_lead', customProperties }));\r\n}\r\n\r\n/**\r\n* Dispatches a Analytics Event When the modal is closed.\r\n* @param customProperties - is the custom properties of the event.\r\n*/\r\nconst triggermodalCloseEvent = function(customProperties) {\r\n store.dispatch(googleAnalytics4Event({ eventName: 'form_close', customProperties }));\r\n}\r\n\r\n// Observers to popular pill section Events Logic\r\nconst onPopularPillClick$ = bodyClick$.pipe(\r\n map(getPopularPillElement),\r\n filter(Boolean)\r\n);\r\n\r\nonPopularPillClick$.subscribe(triggerPopularPillClick);\r\n\r\n// Observers to Listing For You Section Events Logic\r\n/* Stream of click events on standard cards within a \"Listing For You\"\r\nsection. It filters out events that are not standard cards, do not involve clicking on a favorite\r\nicon, and are not call-to-action events. It then maps these filtered events to an object containing\r\nthe event name \"card_clicked\", the area clicked on the card, and the standard card element that was\r\nclicked. */\r\nconst cardClickEvent$ = listingForYouSectionClick$.pipe(\r\n filter(event => isStandardCard(event) && !isFavoriteIcon(event) && !isCallToAction(event)),\r\n map(event => ({\r\n eventName: 'card_clicked',\r\n clickTarget: getAreaClickedName(event.target),\r\n card: getStandardCardElement(event)\r\n }))\r\n);\r\n\r\n/* Observable stream `favoriteIconClickEvent$` that listens for click\r\nevents in the `listingForYouSectionClick$` stream. It filters out events where the click target is a\r\nfavorite icon, then maps those events to an object with properties `eventName` set to 'saved',\r\n`clickTarget` set to the name of the area clicked, and `card` set to the standard card element\r\nassociated with the event. */\r\nconst favoriteIconClickEvent$ = listingForYouSectionClick$.pipe(\r\n filter(event => isFavoriteIcon(event)),\r\n map(event => ({\r\n eventName: 'saved',\r\n clickTarget: getAreaClickedName(event.target),\r\n card: getStandardCardElement(event)\r\n }))\r\n);\r\n\r\nconst standardCardClickEvent$ = merge(cardClickEvent$, favoriteIconClickEvent$);\r\n\r\n/* Observable stream `standardSpecCardClick$` by piping the\r\n`standardCardClickEvent$` observable stream. It filters the data to only include events where the\r\ncard is a special standard card using the `isSpecStandardCard` function. It then maps the data to\r\ninclude custom properties obtained from `getPaidSpecCardProperties` function and the event name. */\r\nconst standardSpecCardClick$ = standardCardClickEvent$.pipe(\r\n filter((data) => isSpecStandardCard(data.card.dataset)),\r\n map((data) => ({\r\n customProperties: getPaidSpecCardProperties(data),\r\n name: data.eventName\r\n })),\r\n);\r\n\r\n/* Observable stream `standardPlanCardClick$` that listens for click\r\nevents on standard cards (`standardCardClickEvent$`). When a click event is detected on a standard\r\ncard, the code filters the data to check if the card is a standard plan card using the\r\n`isPlanStandardCard` function. If the card is a standard plan card, the code then maps the data to\r\nextract custom properties using the `getPaidPlanCardProperties` function and assigns the event name\r\nto the `name` property. */\r\nconst standardPlanCardClick$ = standardCardClickEvent$.pipe(\r\n filter((data) => isPlanStandardCard(data.card.dataset)),\r\n map((data) => ({\r\n customProperties: getPaidPlanCardProperties(data),\r\n name: data.eventName\r\n })),\r\n);\r\n\r\n/* Observable stream `standardCommunityCardClick$` by filtering the\r\n`standardCardClickEvent$` stream to only include events with community standard cards. It then maps\r\nthe data from these events to include custom properties obtained from\r\n`getPaidCommunityCardProperties` function and the event name. */\r\nconst standardCommunityCardClick$ = standardCardClickEvent$.pipe(\r\n filter((data) => isCommunityStandardCard(data.card.dataset)),\r\n map((data) => ({\r\n customProperties: getPaidCommunityCardProperties(data),\r\n name: data.eventName\r\n })),\r\n);\r\n\r\nconst standardCardClickMerged$ = merge(standardSpecCardClick$, standardPlanCardClick$, standardCommunityCardClick$);\r\nstandardCardClickMerged$.subscribe(triggerListingCardClick);\r\n\r\n// Observers to Lead Button Clicked Event Logic\r\nconst callToActionStandardCardClick$ = listingForYouSectionClick$.pipe(\r\n filter(isCallToAction),\r\n map(getStandardCardElement),\r\n filter(Boolean),\r\n);\r\nconst callToActionSpecClick$ = callToActionStandardCardClick$.pipe(\r\n filter((standardCard) => isSpecStandardCard(standardCard.dataset)),\r\n map(getLeadButtonClickedPaidSpecCustomProperties)\r\n);\r\n\r\nconst callToActionPlanClick$ = callToActionStandardCardClick$.pipe(\r\n filter((standardCard) => isPlanStandardCard(standardCard.dataset)),\r\n map(getLeadButtonClickedPaidPlanCustomProperties)\r\n);\r\n\r\nconst callToActionCommunityClick$ = callToActionStandardCardClick$.pipe(\r\n filter((standardCard) => isCommunityStandardCard(standardCard.dataset)),\r\n map(getLeadButtonClickedPaidCommunityCustomProperties)\r\n);\r\n\r\nmerge(\r\n callToActionSpecClick$,callToActionPlanClick$,callToActionCommunityClick$\r\n).subscribe(triggerLeadButtonClickedEvent);\r\n\r\n// Observers to ModalSubmitted Event Logic\r\nconst modalSubmittedClick$ = store$.pipe(\r\n filter(selectFetchingModal),\r\n map(selectModal),\r\n filter(Boolean),\r\n filter((modalInformation) => modalInformation.name === 'leadGenerator'),\r\n map((modalInformation) => ({\r\n listingInformation: modalInformation.listingInformation,\r\n url: modalInformation.url\r\n })),\r\n);\r\n\r\nconst modalSubmittedSpecClick$ = modalSubmittedClick$.pipe(\r\n filter((data) => isSpecStandardCard(data.listingInformation)),\r\n map(getModalSubmittedPaidSpecCustomProperties)\r\n);\r\n\r\nconst modalSubmittedPlanClick$ = modalSubmittedClick$.pipe(\r\n filter((data) => isPlanStandardCard(data.listingInformation)),\r\n map(getModalSubmittedPaidPlanCustomProperties)\r\n);\r\n\r\nconst modalSubmittedCommunityClick$ = modalSubmittedClick$.pipe(\r\n filter((data) => isCommunityStandardCard(data.listingInformation)),\r\n map(getModalSubmittedPaidCommunityCustomProperties)\r\n);\r\n\r\nmerge(\r\n modalSubmittedSpecClick$,modalSubmittedPlanClick$,modalSubmittedCommunityClick$\r\n).subscribe(triggerModalSubmittedEvent);\r\n\r\n// Observers to ModalSubmitted Event Logic\r\nconst recommendedSubmitted$ = store$.pipe(\r\n map(selectModal),\r\n filter(Boolean),\r\n filter((modalInformation) => modalInformation.previousName === 'recommendedScreen'),\r\n filter((modalInformation) => Boolean(modalInformation.selectedRecommendedCommunities)),\r\n distinctUntilChanged()\r\n);\r\n\r\nrecommendedSubmitted$.subscribe(getRecommendedSubmittedPaidCommunityCustomProperties);\r\n\r\nconst modalCloseButtonClicked$ = fromEvent(document.body, \"modalClosed\").pipe(\r\n map((event) => event?.detail?.modalInformation),\r\n filter(Boolean)\r\n);\r\n\r\nconst modalCloseSpecClick$ = modalCloseButtonClicked$.pipe(\r\n filter((data) => isSpecStandardCard(data.listingInformation)),\r\n map(getModalClosePaidSpecCustomProperties)\r\n);\r\n\r\nconst modalClosePlanClick$ = modalCloseButtonClicked$.pipe(\r\n filter((data) => isPlanStandardCard(data.listingInformation)),\r\n map(getModalClosePaidPlanCustomProperties)\r\n);\r\n\r\nconst modalCloseCommunityClick$ = modalCloseButtonClicked$.pipe(\r\n filter((data) => isCommunityStandardCard(data.listingInformation)),\r\n map(getModalClosePaidCommunityCustomProperties)\r\n);\r\n\r\nmerge(\r\n modalCloseSpecClick$,modalClosePlanClick$,modalCloseCommunityClick$\r\n).subscribe(triggermodalCloseEvent);","import { store, store$ } from '@redux/store';\r\nimport { segmentPageView, segmentTrack, segmentIdentify } from \"features/segment\";\r\nimport typeahead from \"blog/components/articleSearchBox\";\r\nimport { filter, fromEvent, map, merge } from \"rxjs\";\r\nimport { selectModal, selectFetchingModal } from 'layout/redux/selectors';\r\nimport HousingProductType from \"constants/housingProductType\";\r\n\r\nconst getPopularPillElement = (event) => event.target.closest('[data-pill]');\r\nconst getStandardCardElement = (event) => event.target.closest(\"[data-card]\");\r\nconst isMetroSpecificSection = (event) => !!event.target.closest('[data-section-name=\"metroSpecificSubjects\"]');\r\nconst isMostPopularSection = (event) => !!event.target.closest('[data-section-name=\"mostPopularArticles\"]');\r\nconst isCategorySection = (event) => !!event.target.closest('[data-section-name=\"categoryArticles\"]');\r\nconst isCommunityStandardCard = (dataset) => dataset.type === HousingProductType.Community().getName();\r\nconst isPlanStandardCard = (dataset) => dataset.type === HousingProductType.Plan().getName();\r\nconst isSpecStandardCard = (dataset) => dataset.type === HousingProductType.Spec().getName();\r\nconst getLinkableArticleElement = (event) => event.target.closest(\"[data-link]\");\r\nconst isListingForYouSection = (event) => !!event.target.closest(\"[data-listings-for-you-container]\");\r\nconst isLinkableListingElement = (event) => event.target instanceof HTMLAnchorElement;\r\nconst isFavoriteIcon = (event) => !!event.target.closest(\".icon__save\");\r\nconst isCallToAction = (event) => !!event.target.closest(\"[data-lead-generator-opener]\");\r\nconst isStandardCard = (event) => !!event.target.closest(\"[data-standard-card]\");\r\nconst breadcrumbItems = Array.from(document.querySelectorAll('[data-breadcrumb-item]'));\r\nconst seeAllArticlesButton = document.querySelector('[data-see-all-articles]');\r\n\r\n/* Observable that listens for click events on the document.body */\r\nconst bodyClick$ = fromEvent(document.body, \"click\");\r\nconst listingForYouSectionClick$ = bodyClick$.pipe(\r\n filter((event) => isListingForYouSection(event))\r\n);\r\nconst onWindowLoad$ = fromEvent(window, \"load\");\r\n\r\n/**\r\n * triggerPaidSpecModalSubmitted: Triggers the event when the modal form is submitted.\r\n * This event only applies for the following forms:\r\n * - Free Brochure\r\n * - Get More Information\r\n * @param {object} modalInformation The information related to the modal opened.\r\n */\r\nfunction triggerPaidSpecModalSubmitted(modalInformation) {\r\n const { listingInformation } = modalInformation;\r\n const customProperties = {\r\n builder_id: listingInformation.builderId,\r\n builder_name: listingInformation.brandName,\r\n button_action: modalInformation.buttonAction,\r\n city: listingInformation.city,\r\n community_id: listingInformation.id,\r\n community_name: listingInformation.communityName,\r\n home_price: listingInformation.price,\r\n home_type: listingInformation.homeStatus,\r\n market_id: listingInformation.marketId,\r\n market_name: listingInformation.marketName,\r\n primary_image_url: listingInformation.imageUrl,\r\n state: listingInformation.stateAbbreviation,\r\n spec_id: listingInformation.specId,\r\n zip: listingInformation.zip,\r\n };\r\n\r\n return customProperties;\r\n}\r\n\r\n/**\r\n * triggerPaidCommunityModalSubmitted: Triggers the event when the modal form is submitted.\r\n * This event only applies for the following forms:\r\n * - Free Brochure\r\n * - Get More Information\r\n * @param {object} modalInformation The information related to the modal opened.\r\n */\r\nfunction triggerPaidCommunityModalSubmitted(modalInformation) {\r\n const { listingInformation } = modalInformation;\r\n const customProperties = {\r\n market_id: listingInformation.marketId,\r\n market_name: listingInformation.marketName,\r\n builder_id: listingInformation.builderId,\r\n builder_name: listingInformation.brandName,\r\n community_id: listingInformation.id,\r\n community_name: listingInformation.communityName,\r\n community_status: listingInformation.marketingStatusLabel,\r\n primary_image_url: listingInformation.imageUrl,\r\n community_low_price: listingInformation.priceLow,\r\n community_high_price: listingInformation.priceHigh,\r\n city: listingInformation.city,\r\n state: listingInformation.stateAbbreviation,\r\n zip: listingInformation.zip,\r\n button_action: modalInformation.buttonAction,\r\n };\r\n\r\n return customProperties;\r\n}\r\n\r\n/**\r\n * triggerPaidPlanModalSubmitted: Triggers the event when the modal form is submitted.\r\n * This event only applies for the following forms:\r\n * - Free Brochure\r\n * - Get More Information\r\n * @param {object} modalInformation The information related to the modal opened.\r\n */\r\nfunction triggerPaidPlanModalSubmitted(modalInformation) {\r\n const { listingInformation } = modalInformation;\r\n const customProperties = {\r\n builder_id: listingInformation.builderId,\r\n builder_name: listingInformation.brandName,\r\n button_action: modalInformation.buttonAction,\r\n city: listingInformation.city,\r\n community_id: listingInformation.id,\r\n community_name: listingInformation.communityName,\r\n home_price: listingInformation.price,\r\n home_type: listingInformation.homeStatus,\r\n market_id: listingInformation.marketId,\r\n market_name: listingInformation.marketName,\r\n plan_id: listingInformation.planId,\r\n primary_image_url: listingInformation.imageUrl,\r\n state: listingInformation.stateAbbreviation,\r\n zip: listingInformation.zip,\r\n };\r\n\r\n return customProperties;\r\n}\r\n\r\n/* An observable stream that listens for click events. It then maps each click event to the closest\r\nancestor element of the clicked target that has a `data-breadcrumb-item` attribute. \r\nThe `filter(Boolean)` function is used to filter out any falsy values. */\r\nconst onBreadcrumbClick$ = bodyClick$.pipe(\r\n map((event) => event.target?.closest('[data-breadcrumb-item]')),\r\n filter(Boolean)\r\n);\r\n\r\n/**\r\n * Dispatches a Google Analytics 4 event when a breadcrumb link is clicked.\r\n * @param breadcrumbLink - is the link element that represents a\r\n * breadcrumb item in a website's navigation.\r\n */\r\nconst triggerBreadcrumbClickEvent = (breadcrumbLink) => {\r\n const breadcrumbIndex = breadcrumbItems.findIndex((item) => item === breadcrumbLink);\r\n const customProperties = {\r\n breadcrumb_position: breadcrumbIndex + 1,\r\n destination_url: breadcrumbLink.href,\r\n link_text: breadcrumbLink.innerText,\r\n };\r\n\r\n store.dispatch(segmentTrack({ eventName: 'Breadcrumb_clicked', customProperties }));\r\n};\r\n\r\nonBreadcrumbClick$.subscribe(triggerBreadcrumbClickEvent);\r\n\r\n/**\r\n * Dispatches a tracking event when a \"See All Articles\" link is clicked.\r\n * @param element - The `element` parameter in the `triggerSeeAllArticlesLinkClickedEvent` function is\r\n * a reference to the HTML element that triggered the event.\r\n */\r\nconst triggerSeeAllArticlesLinkClickedEvent = (element) => {\r\n const customProperties = {\r\n button_text: 'See All Articles',\r\n destination_url: element.href,\r\n };\r\n store.dispatch(segmentTrack({ eventName: 'Button_Clicked', customProperties }));\r\n};\r\n\r\n/* Observable stream `seeAllArticlesLinkClicked$` that listens for click\r\nevents on the `seeAllArticlesButton` element. When a click event occurs, the code maps the event to\r\nthe event target (i.e., the element that was clicked) and emits it as a value in the observable\r\nstream. */\r\nconst seeAllArticlesLinkClicked$ = fromEvent(seeAllArticlesButton, 'click').pipe(\r\n map((event) => event.target),\r\n);\r\n\r\nseeAllArticlesLinkClicked$.subscribe(triggerSeeAllArticlesLinkClickedEvent);\r\n\r\n/**\r\n * triggerPageViewEvent: Dispatch the page view on window load.\r\n */\r\nconst triggerPageViewEvent = function () {\r\n const customProperties = {\r\n section: \"Learning Center\",\r\n };\r\n store.dispatch(segmentPageView({ customProperties }));\r\n};\r\n\r\nonWindowLoad$.subscribe(triggerPageViewEvent);\r\n\r\n/**\r\n * The getCardImageUrls function takes a cardElement as an argument and returns an object with the following properties:\r\n * primaryImage, secondaryImage, terciaryImage.\r\n * if there are no images in the cardElement then each property will be assigned to an empty string.\r\n * This can be used to other events in the list view section.\r\n * @param cardElement Get the image elements from the card element\r\n *\r\n * @return An object with primaryImage, secondaryImage, terciaryImage.\r\n */\r\nconst getCardImageUrls = (cardElement) => {\r\n const imageElements = cardElement.querySelectorAll('img');\r\n\r\n if (imageElements) {\r\n return {\r\n primaryImage: imageElements[0]?.src || '',\r\n secondaryImage: imageElements[1]?.src || '',\r\n terciaryImage: imageElements[2]?.src || '',\r\n };\r\n }\r\n\r\n return {};\r\n};\r\n\r\n/**\r\n* Retrieves custom properties Paid Plan cards\r\n* related to a lead button click on a paid plan within a card element.\r\n* @param cardData - The `cardData` parameter in the\r\n* `getLeadButtonClickedCallToActionPaidPlanCustomProperties` function is expected to be an HTML\r\n* element that represents a card containing data attributes related to a property listing. The\r\n* function extracts specific data attributes from this element to create custom properties for\r\n* tracking user interactions with\r\n* @returns Returns an object * containing custom properties related to a lead button click action\r\n* on a paid plan. The custom properties include information to be logged\r\n*/\r\nconst getLeadButtonClickedCallToActionPaidPlanCustomProperties = function (cardData){\r\n\r\n const leadButton = cardData.querySelector('[data-lead-generator-opener]');\r\n const leadButtonDataset = leadButton.dataset || [];\r\n const cardDataset = cardData.dataset;\r\n\r\n const primaryImageUrl = cardDataset.imageUrl !== ''\r\n ? cardDataset.imageUrl\r\n : getCardImageUrls(cardData).primaryImage;\r\n \r\n const customProperties = {\r\n pageType: 'Learning Center',\r\n market_id: cardDataset.marketId,\r\n market_name: cardDataset.marketName,\r\n city: cardDataset.city,\r\n state: cardDataset.stateAbbreviation,\r\n zip: cardDataset.zip,\r\n builder_id: cardDataset.builderId,\r\n builder_name: cardDataset.brandName,\r\n community_id: cardDataset.communityId,\r\n community_name: cardDataset.communityName,\r\n primary_image_url: primaryImageUrl,\r\n button_action: leadButtonDataset.buttonAction,\r\n plan_id: cardDataset.planId,\r\n home_type: cardDataset.homeStatus,\r\n home_price: cardDataset.price,\r\n };\r\n\r\n return customProperties;\r\n}\r\n\r\n/**\r\n* Retrieves custom properties Paid Spec cards\r\n* related to a lead button click on a card element.\r\n* @param cardData - HTML element that represents a card\r\n* containing various data attributes\r\n* @returns Returns an object containing custom properties related to a lead button click\r\n* action on a card element. The custom properties include information to be used for Segment events.\r\n*/\r\nconst getLeadButtonClickedCallToActionPaidSpecCustomProperties = function (cardData){\r\n\r\n const leadButton = cardData.querySelector('[data-lead-generator-opener]');\r\n const leadButtonDataset = leadButton.dataset || [];\r\n const cardDataset = cardData.dataset;\r\n\r\n const primaryImageUrl = cardDataset.imageUrl !== ''\r\n ? cardDataset.imageUrl\r\n : getCardImageUrls(cardData).primaryImage;\r\n \r\n const customProperties = {\r\n pageType: 'Learning Center',\r\n market_id: cardDataset.marketId,\r\n market_name: cardDataset.marketName,\r\n city: cardDataset.city,\r\n state: cardDataset.stateAbbreviation,\r\n zip: cardDataset.zip,\r\n builder_id: cardDataset.builderId,\r\n builder_name: cardDataset.brandName,\r\n community_id: cardDataset.communityId,\r\n community_name: cardDataset.communityName,\r\n primary_image_url: primaryImageUrl,\r\n button_action: leadButtonDataset.buttonAction,\r\n spec_id: cardDataset.spec_id,\r\n home_type: cardDataset.homeStatus,\r\n home_price: cardDataset.price,\r\n };\r\n\r\n return customProperties;\r\n}\r\n\r\n/**\r\n* Retrieves custom properties for Paid Community card\r\n* related to a lead button click on a card element.\r\n* @param cardData - HTML element that represents a card\r\n* containing various data attributes\r\n* @returns Returns an object containing custom properties related to a lead button click\r\n* action on a card element. The custom properties include information to be used for Segment events.\r\n*/\r\nconst getLeadButtonClickedPaidCommunityCustomProperties = function (cardData){\r\n\r\n const leadButton = cardData.querySelector('[data-lead-generator-opener]');\r\n const leadButtonDataset = leadButton.dataset || [];\r\n const cardDataset = cardData.dataset;\r\n\r\n const primaryImageUrl = cardDataset.imageUrl !== ''\r\n ? cardDataset.imageUrl\r\n : getCardImageUrls(cardData).primaryImage;\r\n \r\n const customProperties = {\r\n pageType: 'Learning Center',\r\n market_id: cardDataset.marketId,\r\n market_name: cardDataset.marketName,\r\n city: cardDataset.city,\r\n state: cardDataset.stateAbbreviation,\r\n zip: cardDataset.zip,\r\n builder_id: cardDataset.builderId,\r\n builder_name: cardDataset.brandName,\r\n community_id: cardDataset.communityId,\r\n community_name: cardDataset.communityName,\r\n primary_image_url: primaryImageUrl,\r\n button_action: leadButtonDataset.buttonAction,\r\n home_type: cardDataset.homeStatus,\r\n home_price: cardDataset.price,\r\n };\r\n\r\n return customProperties;\r\n}\r\n\r\n/**\r\n * Dispatches a Segment event when an article is clicked.\r\n * @param article - is the article that represents the element clicked.\r\n */\r\nconst triggerRecomendedArticlesClick = (article) => {\r\n const customProperties = {\r\n content_id: article.dataset.slug,\r\n content_title: article.dataset.title,\r\n recommendation_type: \"similar articles\",\r\n };\r\n\r\n store.dispatch(\r\n segmentTrack({ eventName: \"Recommendation_Clicked\", customProperties })\r\n );\r\n};\r\n\r\n/* Observable stream that listens for click events on the document body.\r\nIt then filters those events to only include ones where the clicked\r\nelement is identified as being in the most popular section (determined by the `isMostPopularSection`\r\nfunction). */\r\nconst onMostPopularArticleClick$ = bodyClick$.pipe(\r\n filter(isMostPopularSection),\r\n map(getLinkableArticleElement),\r\n filter(Boolean)\r\n);\r\n\r\nonMostPopularArticleClick$.subscribe(triggerRecomendedArticlesClick);\r\n\r\n/* Observable stream that listens for click events on the `document.body`.\r\n It then filters those events to only include ones where the clicked\r\n element is identified as being in the category articles section (determined by the\r\n `isCategorySection` function). */\r\nconst onCategoryArticlesClick$ = bodyClick$.pipe(\r\n filter(isCategorySection),\r\n map(getLinkableArticleElement),\r\n filter(Boolean)\r\n);\r\n\r\nonCategoryArticlesClick$.subscribe(triggerRecomendedArticlesClick);\r\n\r\n/**\r\n * Dispatches a Analytics Event event when a popular pill is clicked.\r\n * @param pill - is the pill clicked in popular pill section.\r\n */\r\nconst triggerPopularPillClick = function(pill) {\r\n const customProperties = {\r\n page_type: 'Learning_Center',\r\n tag_text: pill.dataset.pillText,\r\n destination_url: pill.dataset.pillUrl,\r\n };\r\n\r\n store.dispatch(segmentTrack({ eventName: 'Tag_Clicked', customProperties }));\r\n}\r\n\r\n/**\r\n * Dispatches a Segment event when a search is done.\r\n * @param suggestion - is the suggestion element that represents the element clicked\r\n * in the typeahead.\r\n */\r\nconst triggerSearchExecutedEvent = (suggestion) => {\r\n const customProperties = {\r\n search_term: suggestion.dataset.title,\r\n search_location: \"Learning Center\",\r\n };\r\n\r\n store.dispatch(\r\n segmentTrack({ eventName: \"Search_Executed\", customProperties })\r\n );\r\n};\r\n\r\ntypeahead\r\n .getSuggestionListClickedObserver()\r\n .subscribe(triggerSearchExecutedEvent);\r\n\r\n/**\r\n * Dispatches a Segment Event When the submitt button is clicked.\r\n * @param customProperties - is the custom properties of the event.\r\n */\r\nconst triggerModalSubmittedEvent = function(customProperties) {\r\n store.dispatch(segmentTrack({ eventName: 'Lead Modal Form Submitted', customProperties }));\r\n}\r\n\r\nconst triggerIdentifyModalSubmission = () => {\r\n store.dispatch(segmentIdentify({ eventName: 'Lead Modal Form Submitted' }));\r\n};\r\n\r\n/**\r\n * Dispatches a Segment event when metro specific article is clicked.\r\n * @param article - is the article metro specific article articles section.\r\n */\r\nconst triggerArticlesClick = (article) => {\r\n const customProperties = {\r\n article_id: article.dataset.slug,\r\n article_title: article.dataset.title,\r\n };\r\n\r\n store.dispatch(\r\n segmentTrack({ eventName: \"Article_Clicked\", customProperties })\r\n );\r\n};\r\n\r\n/**\r\n * Dispatches a Segment event when listing card is clicked.\r\n * @param data - is the data card on the listings section.\r\n */\r\nconst triggerListingClick = (data) => {\r\n const customProperties = {\r\n listing_id: data.card.dataset.id,\r\n listing_name: data.card.dataset.name,\r\n interaction_type: data.interactionType,\r\n };\r\n\r\n store.dispatch(\r\n segmentTrack({ eventName: \"Listing_Interacted\", customProperties })\r\n );\r\n};\r\n\r\n// Observers to popular pill section Events Logic\r\nconst onPopularPillClick$ = bodyClick$.pipe(\r\n map(getPopularPillElement),\r\n filter(Boolean)\r\n);\r\n\r\nonPopularPillClick$.subscribe(triggerPopularPillClick);\r\n\r\n// Metro Specific Section Observers\r\n\r\n/* Observable stream `onMetroSpecificArticlesClick$` that listens\r\n for click events on the `document.body`. Here's a breakdown of what each part of the code is\r\n doing: */\r\nconst onMetroSpecificArticlesClick$ = bodyClick$.pipe(\r\n filter(isMetroSpecificSection),\r\n map(getLinkableArticleElement),\r\n filter(Boolean)\r\n);\r\n\r\n// Listing For You Section Observers\r\n\r\n/**\r\n * Dispatches a tracking event when the lead button is\r\n * clicked.\r\n * @param customProperties - The `customProperties` parameter in the `triggerLeadButtonClickedEvent`\r\n * function is likely intended to be an object that can hold additional properties or data related to\r\n * the event. These properties could include information such as the user's ID, timestamp, or any other\r\n * relevant details that you may want to track\r\n */\r\nconst triggerLeadButtonClickedEvent = function (customProperties){\r\n store.dispatch(segmentTrack({ eventName: 'Lead Button Clicked', customProperties }));\r\n}\r\n\r\n/* Observable stream `callToActionStandardCardClick$` that listens for\r\nclick events in the `listingForYouSectionClick$` stream. It filters out events that are considered\r\ncall-to-action events, then maps the event to the corresponding standard card element. It then\r\nfilters out any falsy values before emitting the final result. */\r\nconst callToActionStandardCardClick$ = listingForYouSectionClick$.pipe(\r\n filter(isCallToAction),\r\n map(getStandardCardElement),\r\n filter(Boolean),\r\n);\r\n\r\n/* Observable stream `callToActionCommunityCardClick$` that listens for\r\nclick events in the `listingForYouSectionClick$` stream. It filters the events to only include those\r\nthat are both a call to action and a community standard card. It then maps the event to get the\r\nstandard card element, filters out any falsy values, and finally maps the event to get custom\r\nproperties for a lead button clicked in a paid community. */\r\nconst callToActionCommunityCardClick$ = callToActionStandardCardClick$.pipe(\r\n filter((standardCard) => isCommunityStandardCard(standardCard.dataset)),\r\n map(getLeadButtonClickedPaidCommunityCustomProperties)\r\n);\r\n\r\n/* Observable stream `callToActionSpecCardClick$` that listens for click\r\nevents in the `listingForYouSectionClick$` stream. It filters the events to only include those that\r\nare both a call to action and a standard card, then maps the event to extract the standard card\r\nelement. It then filters out any falsy values, maps the event to extract custom properties related\r\nto a lead button click on a paid spec, and returns the final observable stream\r\n`callToActionSpecCardClick$`. */\r\nconst callToActionSpecCardClick$ = callToActionStandardCardClick$.pipe(\r\n filter((standardCard) => isSpecStandardCard(standardCard.dataset)),\r\n map(getLeadButtonClickedCallToActionPaidSpecCustomProperties)\r\n);\r\n\r\n/* Observable stream `callToActionPlanCardClick$` that listens for click\r\nevents in the `listingForYouSectionClick$` stream. It filters the events to only include those that\r\nare both a call to action and a standard plan card. It then maps the event to get the standard card\r\nelement, filters out any falsy values, and finally maps the event to get custom properties for a\r\npaid plan call to action button click. */\r\nconst callToActionPlanCardClick$ = callToActionStandardCardClick$.pipe(\r\n filter((standardCard) => isPlanStandardCard(standardCard.dataset)),\r\n map(getLeadButtonClickedCallToActionPaidPlanCustomProperties)\r\n);\r\n\r\nmerge(\r\n callToActionCommunityCardClick$,\r\n callToActionSpecCardClick$,\r\n callToActionPlanCardClick$).subscribe(triggerLeadButtonClickedEvent);\r\n\r\n/* Observable stream is set up to track when a user clicks on\r\n the favorite icon within a standard card element in the listing for you section and triggers the\r\n `triggerListingClick` function with the appropriate custom properties. */\r\nconst favoriteIconClick$ = listingForYouSectionClick$.pipe(\r\n filter((event) => isFavoriteIcon(event)),\r\n map((event) => ({\r\n interactionType: \"favorite\",\r\n card: getStandardCardElement(event),\r\n }))\r\n);\r\n\r\n/* Observable stream that listens for click events within the listing for you section.\r\n It filters the events to only include those where the clicked element is a linkable\r\n listing element (determined by the `isLinkableListingElement`\r\n function). */\r\nconst linkableListingElementClick$ = listingForYouSectionClick$.pipe(\r\n filter((event) => isLinkableListingElement(event)),\r\n map((event) => ({\r\n interactionType: \"link_click\",\r\n card: getStandardCardElement(event),\r\n }))\r\n);\r\n\r\n/* The `cardClick$` constant is creating an observable stream that listens for click events within\r\n the listing for you section. It filters the events to only include those where the clicked element\r\n is a standard card element (determined by the `isStandardCard` function). */\r\nconst cardClick$ = listingForYouSectionClick$.pipe(\r\n filter((event) => isStandardCard(event)),\r\n map((event) => ({\r\n interactionType: \"card_click\",\r\n card: getStandardCardElement(event),\r\n }))\r\n);\r\n\r\n/* Observable stream `listingForYouSectionReady$` that listens for\r\n a custom event named 'listingForYouSectionReady' triggered on the `document.body`. Once this\r\n custom event is detected, the subsequent `subscribe` function is called. Within the `subscribe`\r\n function, it sets up subscriptions for different observable streams (`favoriteIconClick$`,\r\n `linkableListingElementClick$`, `cardClick$`) to trigger the\r\n `triggerListingClick` function when specific conditions are met. */\r\nmerge(\r\n favoriteIconClick$,\r\n linkableListingElementClick$,\r\n cardClick$\r\n).subscribe(triggerListingClick);\r\n\r\n/* Observable stream `metroSpecificSectionReady$` that listens for a custom event\r\n named 'metroSpecificSectionReady' triggered on the `document.body`. */\r\nonMetroSpecificArticlesClick$.subscribe(triggerArticlesClick);\r\n\r\n// Observers to ModalSubmitted Event Logic\r\nconst modalSubmittedClick$ = store$.pipe(\r\n filter(selectFetchingModal),\r\n map(selectModal),\r\n filter(Boolean),\r\n filter((modalInformation) => modalInformation.name === 'leadGenerator'),\r\n);\r\n\r\nconst modalSubmittedSpecClick$ = modalSubmittedClick$.pipe(\r\n filter((modalInformation) => isSpecStandardCard(modalInformation.listingInformation)),\r\n map(triggerPaidSpecModalSubmitted)\r\n);\r\n\r\nconst modalSubmittedPlanClick$ = modalSubmittedClick$.pipe(\r\n filter((modalInformation) => isPlanStandardCard(modalInformation.listingInformation)),\r\n map(triggerPaidPlanModalSubmitted)\r\n);\r\n\r\nconst modalSubmittedCommunityClick$ = modalSubmittedClick$.pipe(\r\n filter((modalInformation) => isCommunityStandardCard(modalInformation.listingInformation)),\r\n map(triggerPaidCommunityModalSubmitted)\r\n);\r\n\r\nmerge(\r\n modalSubmittedSpecClick$,modalSubmittedPlanClick$,modalSubmittedCommunityClick$\r\n).subscribe((customProperties) => {\r\n triggerModalSubmittedEvent(customProperties)\r\n triggerIdentifyModalSubmission()\r\n});\r\n","require('features/routing');\r\nrequire('../components/listingsForYouSection');\r\nrequire('../components/mostPopularArticleSection');\r\nrequire('../components/articleSearchBox');\r\nrequire('../components/categoryArticlesSection');\r\nrequire('../components/metroSpecificSection');\r\nrequire('features/segment');\r\nrequire('./components/eventTracking/googleAnalytics4EventsHandler');\r\nrequire('./components/eventTracking/segmentEventsHandler');\r\nrequire('../components/popularPillsCarousel');","export default class UrlSubdirectoryTypes {\r\n /**\r\n * The function return the Url Subdirectory name for Communities.\r\n * @returns The method `Communities` is returning an instance of the class\r\n * `communities`.\r\n */\r\n static get Communities() {\r\n const configuration = {\r\n name: 'communities',\r\n pageType: 'Community_Results',\r\n luxLabel: 'Community Results',\r\n };\r\n return this.getInstance('communities', configuration);\r\n }\r\n\r\n /**\r\n * The function return the Url Subdirectory name for Homes.\r\n * @returns The method `Homes` is returning an instance of the class\r\n * `homes`.\r\n */\r\n static get Homes() {\r\n const configuration = {\r\n name: 'homes',\r\n pageType: 'Home_Results',\r\n luxLabel: 'Home Results',\r\n };\r\n return this.getInstance('homes', configuration);\r\n }\r\n\r\n /**\r\n * The function return the Url Subdirectory name for Builder Directory.\r\n * @returns The method `Builders` is returning an instance of the class\r\n * `builders`.\r\n */\r\n static get Builders() {\r\n const configuration = {\r\n name: 'builders',\r\n pageType: 'Builders',\r\n luxLabel: 'Builder Directory',\r\n };\r\n return this.getInstance('builders', configuration);\r\n }\r\n\r\n /**\r\n * The function return the Url Subdirectory name for Condo Developments.\r\n * @returns The method `CondoDevelopment` is returning an instance of the class\r\n * `condo-developments`.\r\n */\r\n static get CondoDevelopment() {\r\n const configuration = {\r\n name: 'condo-developments',\r\n pageType: 'Condo_Developments',\r\n luxLabel: 'Community Results',\r\n };\r\n return this.getInstance('condo-developments', configuration);\r\n }\r\n\r\n /**\r\n * The function return the Url Subdirectory name for Condo Townhomes.\r\n * @returns The method `CondosAndTownHomes` is returning an instance of the class\r\n * `condo-townhomes`.\r\n */\r\n static get CondosAndTownHomes() {\r\n const configuration = {\r\n name: 'condo-townhomes',\r\n pageType: 'Condo_Townhomes',\r\n luxLabel: 'Home Results',\r\n };\r\n return this.getInstance('condo-townhomes', configuration);\r\n }\r\n\r\n /**\r\n * The function return the Url Subdirectory name for Single Family Homes.\r\n * @returns The method `SingleFamilyHomes` is returning an instance of the class\r\n * `single-family-homes`.\r\n */\r\n static get SingleFamilyHomes() {\r\n const configuration = {\r\n name: 'single-family-homes',\r\n pageType: 'Single_Family_Homes',\r\n luxLabel: 'Home Results',\r\n };\r\n return this.getInstance('single-family-homes', configuration);\r\n }\r\n\r\n /**\r\n * The function return the Url Subdirectory name for Single Family Communities.\r\n * @returns The method `SingleFamilyCommunties` is returning an instance of the class\r\n * `single-family-communities`.\r\n */\r\n static get SingleFamilyCommunities() {\r\n const configuration = {\r\n name: 'single-family-communities',\r\n pageType: 'Single_Family_Communities',\r\n luxLabel: 'Community Results',\r\n };\r\n return this.getInstance('single-family-communities', configuration);\r\n }\r\n\r\n /**\r\n * The function return the Url Subdirectory name for Custom Homes.\r\n * @returns The method `CustomHomes` is returning an instance of the class\r\n * `custom-homes`.\r\n */\r\n static get CustomHomes() {\r\n const configuration = {\r\n name: 'custom-homes',\r\n pageType: 'Custom_Homes',\r\n luxLabel: 'Custom Home Results',\r\n };\r\n return this.getInstance('custom-homes', configuration);\r\n }\r\n\r\n /**\r\n * The function return the Url Subdirectory name for Build On Your Lot.\r\n * @returns The method `OnYourLot` is returning an instance of the class\r\n * `on-your-lot`.\r\n */\r\n static get OnYourLot() {\r\n const configuration = {\r\n name: 'on-your-lot',\r\n pageType: 'BoylResults',\r\n luxLabel: 'Build On Your Lot Results',\r\n };\r\n return this.getInstance('on-your-lot', configuration);\r\n }\r\n\r\n /**\r\n * The function return the Url Subdirectory name for Custom Builders.\r\n * @returns The method `CustomBuilders` is returning an instance of the class\r\n * `builders`.\r\n */\r\n static get CustomBuilders() {\r\n const configuration = {\r\n name: 'custom-builders',\r\n pageType: 'CustomBuilders',\r\n luxLabel: 'Custom Builder Results',\r\n };\r\n return this.getInstance('custom-builders', configuration);\r\n }\r\n\r\n /**\r\n * The function return the Url Subdirectory name for Manufactured Homes.\r\n * @returns The method `ManufacturedHomes` is returning an instance of the class\r\n * `manufactured-homes`.\r\n */\r\n static get ManufacturedHomes() {\r\n const configuration = {\r\n name: 'manufactured-homes',\r\n pageType: 'Manufactured_Homes',\r\n luxLabel: 'Manufactured Home Results',\r\n };\r\n return this.getInstance('manufactured-homes', configuration);\r\n }\r\n\r\n /**\r\n * The function return the Url Subdirectory name for Manufactured Locations.\r\n * @returns The method `ManufacturedLocations` is returning an instance of the class\r\n * `manufactured`.\r\n */\r\n static get ManufacturedLocations() {\r\n const configuration = {\r\n name: 'manufactured',\r\n pageType: 'Manufactured_Results',\r\n luxLabel: 'Manufactured Results',\r\n };\r\n return this.getInstance('manufactured', configuration);\r\n }\r\n\r\n /**\r\n * The function return the Url Subdirectory name for Floor Plans.\r\n * @returns The method `FloorPlans` is returning an instance of the class\r\n * `floor-plans`.\r\n */\r\n static get FloorPlans() {\r\n const configuration = {\r\n name: 'floor-plans',\r\n pageType: 'FloorPlans',\r\n luxLabel: 'Home Results',\r\n };\r\n return this.getInstance('floor-plans', configuration);\r\n }\r\n\r\n /**\r\n * The function return the Url Subdirectory name for Model Homes.\r\n * @returns The method `ModelHomes` is returning an instance of the class\r\n * `model-homes`.\r\n */\r\n static get ModelHomes() {\r\n const configuration = {\r\n name: 'model-homes',\r\n pageType: 'ModelHomes',\r\n luxLabel: 'Home Results',\r\n };\r\n return this.getInstance('model-homes', configuration);\r\n }\r\n\r\n /**\r\n * The function return the Url Subdirectory name for Learning Center.\r\n * @returns The method `LearningCenter` is returning an instance of the class\r\n * `learn`.\r\n */\r\n static get LearningCenter() {\r\n const configuration = {\r\n pageType: 'Learning Center',\r\n luxLabel: 'Blog',\r\n };\r\n return this.getInstance('learn', configuration);\r\n }\r\n\r\n static fromKey(key) {\r\n const subDirectoryTypeMap = {\r\n communities: UrlSubdirectoryTypes.Communities,\r\n homes: UrlSubdirectoryTypes.Homes,\r\n builders: UrlSubdirectoryTypes.Builders,\r\n 'condo-developments': UrlSubdirectoryTypes.CondoDevelopment,\r\n 'condo-townhomes': UrlSubdirectoryTypes.CondosAndTownHomes,\r\n 'single-family-homes': UrlSubdirectoryTypes.SingleFamilyHomes,\r\n 'single-family-communities': UrlSubdirectoryTypes.SingleFamilyCommunities,\r\n 'custom-homes': UrlSubdirectoryTypes.CustomHomes,\r\n 'on-your-lot': UrlSubdirectoryTypes.OnYourLot,\r\n 'custom-builders': UrlSubdirectoryTypes.CustomBuilders,\r\n 'manufactured-homes': UrlSubdirectoryTypes.ManufacturedHomes,\r\n manufactured: UrlSubdirectoryTypes.ManufacturedLocations,\r\n 'floor-plans': UrlSubdirectoryTypes.FloorPlans,\r\n 'model-homes': UrlSubdirectoryTypes.ModelHomes,\r\n [UrlSubdirectoryTypes.LearningCenter.toString()]: UrlSubdirectoryTypes.LearningCenter,\r\n };\r\n\r\n return subDirectoryTypeMap[key];\r\n }\r\n\r\n /**\r\n * The getInstance function returns an instance of the SubDirectoryTypes class based on the\r\n * provided key, creating a new instance if one does not already exist.\r\n * @param key - The \"name\" parameter is a unique identifier used to determine which instance of the\r\n * \"SubDirectoryTypes\" class to create or retrieve.\r\n * @param configuration an object that contains various properties and values that are used to configure\r\n * the instance of the UrlSubdirectoryTypes class that is being created.\r\n * @returns The instance of the SubDirectoryTypes class with the specified key.\r\n */\r\n static getInstance(key, configuration) {\r\n configuration.name = key;\r\n\r\n if (!this.instances[key]) {\r\n this.instances[key] = new UrlSubdirectoryTypes(configuration);\r\n }\r\n return this.instances[key];\r\n }\r\n\r\n /**\r\n * The constructor function initializes an object with a given name property.\r\n * @param configuration - The `configuration` parameter is an object that contains the configuration\r\n * settings for the constructor. It may contain properties such as `name` and\r\n * `pageType`. The `name` property is a string that represents the name of the\r\n * configuration.\r\n */\r\n constructor(configuration) {\r\n this.name = configuration.name;\r\n this.pageType = configuration.pageType;\r\n this.luxLabel = configuration.luxLabel;\r\n }\r\n\r\n /**\r\n * The toString() function returns the name property of an object as a string.\r\n * @returns The name property of the object.\r\n */\r\n toString() {\r\n return `${this.name}`;\r\n }\r\n}\r\n\r\nObject.defineProperty(UrlSubdirectoryTypes, 'instances', { value: {} });\r\n","import { createAction } from '@reduxjs/toolkit';\r\n\r\n/* Action dispatched after the list view is paitend in the DOM to handler side effects.\r\n */\r\nconst onListViewPaint = createAction('searchResults/listViewPaint');\r\n\r\nexport default onListViewPaint;\r\n","import { fromFetch } from 'rxjs/fetch';\r\nimport UrlExtensions from 'utils/urlExtension';\r\n\r\n/**\r\n * @private\r\n *\r\n * The function returns a the User profile URL.\r\n *\r\n * @returns user profile URL string with parameters for the user's profile page, including IP address.\r\n */\r\nfunction getUserProfileUrl() {\r\n const location = window.location;\r\n const path = '/getUserProfile';\r\n const ip = UrlExtensions.getParameterValue(location, 'ip');\r\n\r\n const url = UrlExtensions.setParameters(path, {\r\n ip,\r\n });\r\n return url;\r\n}\r\n\r\nexport default fromFetch(getUserProfileUrl(),\r\n {\r\n 'credentials': 'include',\r\n headers: {\r\n 'Accept': 'application/json',\r\n }\r\n });\r\n","import { fromFetch } from 'rxjs/fetch';\r\nimport { userProfileGetFavorites } from 'constants/routes';\r\n\r\nexport default fromFetch(userProfileGetFavorites, {\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n // disabling cache to always get the latest favorites\r\n 'Cache-Control': 'no-cache',\r\n 'Accept': 'application/json',\r\n },\r\n});\r\n","import { switchMap, map } from 'rxjs';\r\nimport { fromFetch } from 'rxjs/fetch';\r\nimport { userSaveFavorite } from 'constants/routes';\r\nimport { camelCaseObjectKeys } from 'utils/camelCase';\r\n\r\nfunction saveUserFavorite(payload) {\r\n const url = `${userSaveFavorite}`;\r\n\r\n return fromFetch(url, {\r\n method: 'POST',\r\n body: JSON.stringify(payload),\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n 'Accept': 'application/json',\r\n },\r\n }).pipe(\r\n switchMap((response) => response.json()),\r\n map((response) => camelCaseObjectKeys(response))\r\n );\r\n}\r\n\r\nexport default saveUserFavorite;\r\n","import { switchMap } from 'rxjs';\r\nimport { fromFetch } from 'rxjs/fetch';\r\nimport { userDeleteFavorite } from 'constants/routes';\r\n\r\nfunction deleteUserFavorite(id) {\r\n const url = `${userDeleteFavorite}?id=${id}`;\r\n\r\n return fromFetch(url, {\r\n method: 'GET',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n 'Accept': 'application/json',\r\n },\r\n }).pipe(switchMap((response) => response.json()));\r\n}\r\n\r\nexport default deleteUserFavorite;\r\n","import FavoriteType from \"../enums/favoriteType\";\r\nimport SpecProductType from \"../models/specProductType\";\r\nimport PlanProductType from \"../models/planProductType\";\r\nimport CommunityProductType from \"../models/communityProductType\";\r\n\r\nconst housingProductConstructor = new Map();\r\n\r\nhousingProductConstructor.set(FavoriteType.Spec.toString(), SpecProductType);\r\nhousingProductConstructor.set(FavoriteType.Plan.toString(), PlanProductType);\r\nhousingProductConstructor.set(FavoriteType.Community.toString(), CommunityProductType)\r\n\r\n/**\r\n * Returns the class constructor with the listing information according to the type.\r\n *\r\n * @param type - The type of listing (Spec, plan, community).\r\n * @param listingInformation - The listing (Spec, plan, community) information.\r\n */\r\n\r\nexport default (type, listingInformation) => {\r\n const generator = housingProductConstructor.get(type);\r\n \r\n if (!generator) {\r\n return null;\r\n }\r\n \r\n return new generator.prototype.constructor(listingInformation);\r\n };\r\n ","import GoogleAnalyticsEvent from 'dataTransferObjects/googleAnalyticsEvent';\r\nimport GoogleAnalyticsCustomDimensions from 'constants/googleAnalyticsCustomDimension';\r\n\r\nconst tdvEvents = 'TDV Events';\r\n\r\n/* Creates a new instance for housing product type. */\r\nexport default class SpecProductType {\r\n constructor(listing) {\r\n this.id = listing.id;\r\n this.brandName = listing.brandName;\r\n this.communityName = listing.communityName;\r\n this.communityId = listing.communityId;\r\n this.isBasic = listing.isBasic === \"true\";\r\n }\r\n\r\n /**\r\n * This function returns a new GoogleAnalyticsEvent object with the event category, event action,\r\n * event label and custom dimensions set.\r\n * @returns A new instance of the GoogleAnalyticsEvent class for favorites.\r\n */\r\n getFavoriteGoogleAnalyticsEvent() {\r\n const customDimensions = { \r\n [GoogleAnalyticsCustomDimensions.SpecId().getName()] :\r\n this.id,\r\n [GoogleAnalyticsCustomDimensions.BrandName().getName()] :\r\n this.brandName,\r\n [GoogleAnalyticsCustomDimensions.CommunityName().getName()] :\r\n this.communityName,\r\n [GoogleAnalyticsCustomDimensions.CommunityId().getName()] :\r\n this.communityId,\r\n [GoogleAnalyticsCustomDimensions.IsPaid().getName()] :\r\n !this.isBasic,\r\n };\r\n return new GoogleAnalyticsEvent(tdvEvents, 'SRP Listing Card', 'Listing Saved', customDimensions);\r\n }\r\n}\r\n","import GoogleAnalyticsEvent from 'dataTransferObjects/googleAnalyticsEvent';\r\nimport GoogleAnalyticsCustomDimensions from 'constants/googleAnalyticsCustomDimension';\r\n\r\nconst tdvEvents = 'TDV Events';\r\n\r\n/* Creates a new instance for housing product type. */\r\nexport default class PlanProductType {\r\n constructor(listing) {\r\n this.brandName = listing.brandName;\r\n this.communityName = listing.communityName;\r\n this.id = listing.id;\r\n this.communityId = listing.communityId;\r\n this.isBasic = listing.isBasic === \"true\";\r\n }\r\n\r\n /**\r\n * This function returns a new GoogleAnalyticsEvent object with the event category, event action,\r\n * event label and custom dimensions set.\r\n * @returns A new instance of the GoogleAnalyticsEvent class for favorites.\r\n */\r\n getFavoriteGoogleAnalyticsEvent() {\r\n const customDimensions = { \r\n [GoogleAnalyticsCustomDimensions.BrandName().getName()] :\r\n this.brandName,\r\n [GoogleAnalyticsCustomDimensions.CommunityName().getName()] :\r\n this.communityName,\r\n [GoogleAnalyticsCustomDimensions.PlanId().getName()] :\r\n this.id,\r\n [GoogleAnalyticsCustomDimensions.CommunityId().getName()] :\r\n this.communityId,\r\n [GoogleAnalyticsCustomDimensions.IsPaid().getName()] : \r\n !this.isBasic,\r\n };\r\n return new GoogleAnalyticsEvent(tdvEvents, 'SRP Listing Card', 'Listing Saved', customDimensions);\r\n }\r\n}\r\n","import GoogleAnalyticsEvent from 'dataTransferObjects/googleAnalyticsEvent';\r\nimport GoogleAnalyticsCustomDimensions from 'constants/googleAnalyticsCustomDimension';\r\n\r\nconst tdvEvents = 'TDV Events';\r\n\r\n/* Creates a new instance of a community listing. */\r\nexport default class CommunityProductType {\r\n constructor(listing) {\r\n this.brandName = listing.brandName;\r\n this.name = listing.name;\r\n this.id = listing.id;\r\n this.isBasic = listing.isBasic === \"true\";\r\n }\r\n\r\n /**\r\n * This function returns a new GoogleAnalyticsEvent object with the event category, event action, and\r\n * event label set.\r\n * @returns A new instance of the GoogleAnalyticsEvent class.\r\n */\r\n getFavoriteGoogleAnalyticsEvent() {\r\n const customDimensions = { \r\n [GoogleAnalyticsCustomDimensions.BrandName().getName()] :\r\n this.brandName,\r\n [GoogleAnalyticsCustomDimensions.CommunityName().getName()] :\r\n this.name,\r\n [GoogleAnalyticsCustomDimensions.CommunityId().getName()] :\r\n this.id,\r\n [GoogleAnalyticsCustomDimensions.IsPaid().getName()] : \r\n !this.isBasic,\r\n };\r\n return new GoogleAnalyticsEvent(tdvEvents, 'SRP Listing Card', 'Listing Saved', customDimensions);\r\n }\r\n}\r\n","import { catchError, from, of, mergeMap, switchMap, map, filter } from 'rxjs';\r\nimport { ofType } from 'redux-observable';\r\nimport getUserProfile$ from '../apis/getUserProfile';\r\nimport getUserFavorites$ from '../apis/getUserFavorites';\r\nimport { userProfileSlice } from './slices';\r\nimport saveUserFavorite from '../apis/saveFavorite';\r\nimport deleteUserFavorite from '../apis/deleteFavorite';\r\nimport getFavoriteFromState from '../services/getFavoriteFromState';\r\nimport housingProductConstructor from '../services/getHousingProductType';\r\n\r\nconst actions = userProfileSlice.actions;\r\n\r\n// this epic requests the profile data for logged in users.\r\nexport const fetchUserProfileEpic = (action$) =>\r\n action$.pipe(\r\n ofType(actions.fetch.type),\r\n switchMap(() =>\r\n getUserProfile$.pipe(\r\n switchMap((response) => from(response.json()).pipe(mergeMap((data) =>\r\n of(actions.apply(data))))),\r\n catchError((err) => of(actions.handleError(err)))\r\n )\r\n )\r\n );\r\n\r\n// this epic requests the profile data for logged in users.\r\nexport const fetchUserFavoritesEpic = (action$) =>\r\n action$.pipe(\r\n ofType(actions.apply.type),\r\n filter((action) => action.payload && action.payload.IsLogin === true),\r\n switchMap(() =>\r\n getUserFavorites$.pipe(\r\n switchMap((response) => from(response.json()).pipe(mergeMap((data) =>\r\n of(actions.applyFavorites(data))))),\r\n catchError((err) => of(actions.handleError(err)))\r\n )\r\n )\r\n );\r\n\r\n// this epic is triggered when the user profile is loaded\r\n// it loads the user's favorites into the favorites slice.\r\nexport const getUserFavoritesEpic = (action$) =>\r\n action$.pipe(\r\n ofType(actions.apply.type),\r\n map((action) => actions.loadFavorites(action.payload))\r\n );\r\n\r\n// this epic is triggered when the user clicks on the favorite icon on a card \r\n// that is not already a favorite. \r\nexport const saveFavoriteEpic = (action$, state$) => \r\naction$.pipe( \r\n ofType(actions.saveFavorite.type),\r\n filter(() => state$.value?.userProfile?.isLogin),\r\n mergeMap((action) => { \r\n const { listingInformation, type, url, userId } = action.payload;\r\n const housingProductType = housingProductConstructor(type, listingInformation);\r\n const saveInformation = {\r\n id: listingInformation.id,\r\n type,\r\n url,\r\n userId\r\n };\r\n return saveUserFavorite(saveInformation).pipe(\r\n switchMap((data) => of(actions.saveFavoriteFulfilled({data, housingProductType})))\r\n );\r\n}));\r\n\r\n// this epic is triggered when the user clicks on the favorite icon on a card\r\n// that is already a favorite.\r\nexport const deleteFavoriteEpic = (action$, state$) =>\r\n action$.pipe(\r\n ofType(actions.deleteFavorite.type),\r\n switchMap((action) => {\r\n const payload = action.payload;\r\n \r\n // get the favorite from the state that matches the action.payload.id\r\n const favorite = getFavoriteFromState(state$.value, Number(payload.listingInformation.id));\r\n\r\n return deleteUserFavorite(favorite.id).pipe(\r\n switchMap(() => of(actions.deleteFavoriteFullfilled(favorite)))\r\n );\r\n }));","import { BehaviorSubject, mergeMap } from 'rxjs';\r\nimport { \r\n fetchUserProfileEpic,\r\n saveFavoriteEpic, \r\n deleteFavoriteEpic,\r\n fetchUserFavoritesEpic,\r\n} from 'features/userProfile';\r\nimport { combineEpics } from 'redux-observable';\r\n\r\nconst combinedUserProfileEpic = combineEpics(\r\n fetchUserProfileEpic,\r\n saveFavoriteEpic,\r\n deleteFavoriteEpic,\r\n fetchUserFavoritesEpic,\r\n );\r\n// Exports the Observable of 'epic' to allow other modules to dynamically register their epic.\r\nexport const epic$ = new BehaviorSubject(combinedUserProfileEpic);\r\n\r\nexport const rootEpic = (action$, state$) => epic$.pipe(mergeMap((epic) => epic(action$, state$)));","\r\n\r\n// this function is used to get the favorite from the state that matches the id of the action.payload.id\r\nexport default function getFavoriteFromState(state, id) {\r\n return state.userProfile?.favorites?.find((fav) => fav.listingId === id);\r\n }","import { distinctUntilChanged, from } from 'rxjs';\r\nimport { createEpicMiddleware } from 'redux-observable';\r\nimport { combineReducers, configureStore } from '@reduxjs/toolkit';\r\nimport dynamicMiddlewares from 'redux-dynamic-middlewares'\r\nimport { rootEpic } from './rootEpics';\r\n\r\n// Register global reducers if needed.\r\nconst staticReducers = {};\r\n\r\n// Function need to allow other modules to dynamically register their reducers.\r\nfunction createReducer(asyncReducers) {\r\n return combineReducers({\r\n ...staticReducers,\r\n ...asyncReducers,\r\n });\r\n}\r\n\r\n// Epic Middleware allow RxJS to work with Redux via Redux-Observable.\r\nconst epicMiddleware = createEpicMiddleware();\r\n\r\n// Creates, configure, and export the global store.\r\nexport const store = configureStore({\r\n reducer: staticReducers,\r\n middleware: (getDefaultMiddleware) => getDefaultMiddleware().concat(epicMiddleware).concat(dynamicMiddlewares),\r\n});\r\n\r\n// Observable store that notifies the latest changes.\r\n\r\nexport const store$ = from(store).pipe(distinctUntilChanged());\r\n// Add a dictionary to keep track of the registered async reducers.\r\nstore.asyncReducers = {};\r\n\r\n// Create an inject reducer function.\r\n// This function adds the async reducer, and creates a new combined reducer.\r\nstore.injectReducer = (key, asyncReducer) => {\r\n store.asyncReducers[key] = asyncReducer;\r\n store.replaceReducer(createReducer(store.asyncReducers));\r\n};\r\n\r\n// Run the root 'epic'.\r\nepicMiddleware.run(rootEpic);\r\nexport { epic$ } from './rootEpics';\r\n","import { UrlSubdirectoryTypes } from \"features/searchResultsFacets\";\r\n\r\nfunction getTrackerName() {\r\n const nhsTrackingId = 'UA-40843711-4';\r\n const trackers = window.ga.getAll().filter((element) => element.get('trackingId') === nhsTrackingId);\r\n const tracker = trackers[0].get('name');\r\n return tracker;\r\n}\r\n\r\nfunction getTrackerClientId() {\r\n const nhsTrackingId = 'UA-40843711-4';\r\n const trackers = window.ga.getAll().filter((element) => element.get('trackingId') === nhsTrackingId);\r\n const clientId = trackers[0].get('clientId');\r\n return clientId\r\n}\r\n\r\n/**\r\n * A function that returns a value the page type to be track in Google Analytics custom dimensions.\r\n * for instance, in Homes searches it will return `Home_Results`, in Single Family cases `Single_Family_Homes`.\r\n */\r\nconst getPageType = (page) => UrlSubdirectoryTypes.fromKey(page)?.pageType || '';\r\n\r\nexport { getTrackerName, getPageType, getTrackerClientId };\r\n","/**\r\n * Class to work as a DTO to hold the information of a event dispatched to Google Analytics 4.\r\n */\r\nclass GoogleAnalytics4Event {\r\n constructor(eventName, params = {}) {\r\n this.eventName = eventName;\r\n this.params = params;\r\n this.event = 'GA4Event';\r\n }\r\n\r\n /**\r\n * The function returns the value of the eventName property.\r\n * @returns The value of the variable `eventName`.\r\n */\r\n getEventName() {\r\n return this.eventName;\r\n }\r\n\r\n /**\r\n * The function returns the value of the \"params\" property.\r\n * @returns The `params` property is being returned.\r\n */\r\n getParams() {\r\n return this.params;\r\n }\r\n}\r\n\r\nexport default GoogleAnalytics4Event;\r\n","/**\r\n * get Central Standard Time (Austin time).\r\n *\r\n */\r\nconst getCentralStandardTime = () => {\r\n // Get current time\r\n const date = new Date();\r\n\r\n // The difference, in minutes, between the date as evaluated in the UTC time zone and\r\n // as evaluated in the local time zone. The actual local time algorithm is implementation-defined,\r\n // and the return value is allowed to be zero in runtimes without appropriate data.\r\n const browsertTimeZone = date.getTimezoneOffset();\r\n\r\n // convert browsertTimeZone to milliseconds\r\n // get UTC time in milliseconds\r\n const utc = date.getTime() + browsertTimeZone * 60000;\r\n\r\n // Get the number of milliseconds of central standard time.\r\n // 3600000 is the conversion of hours to milliseconds\r\n // -5 is the GMT-5 time zone of austin. We just need to multply the value.\r\n // 3600000 * -5 = -18000000 milliseconds\r\n const centralStandardTimeZone = -18000000;\r\n\r\n // Calculate the new date with the central standard timezone.\r\n const now = new Date(utc + centralStandardTimeZone);\r\n\r\n return (\r\n `${now.getFullYear()}-${now.getMonth() + 1}-${now.getDate()}` +\r\n `T${now.getHours()}:${now.getMinutes()}:${now.getSeconds()}.${now.getMilliseconds()}-05:00`\r\n );\r\n};\r\n\r\nexport default getCentralStandardTime;\r\n","import { store } from '@redux/store';\r\nimport getTrackingCommonProperties from 'features/trackingProperties';\r\nimport merge from 'deepmerge';\r\nimport cleanObjectsEmptyProperties from 'utils/cleanObject';\r\nimport GoogleAnalytics4EventType from 'enums/googleAnalytics4EventType';\r\nimport GoogleAnalytics4Event from 'dataTransferObjects/googleAnalytics4Event';\r\nimport getCentralStandardTime from 'modules/getCentralStandardTime';\r\n\r\n/**\r\n * The getCommonProperties function returns an object containing the common properties\r\n * that are used in all Google Analytics 4 events.\r\n * @return An object\r\n */\r\nconst getCommonProperties = () => {\r\n const state = store.getState();\r\n const commonProperties = getTrackingCommonProperties(state);\r\n return commonProperties;\r\n};\r\n\r\n/**\r\n * concatenates a market name and a state abbreviation with a comma in between.\r\n * @param marketName - is a string representing the name of a market.\r\n * @param stateAbbreviation - represents a state. For example, \"CA\" for California or \"NY\" for New York.\r\n * @returns a string that concatenates the marketName and stateAbbreviation\r\n * with a comma and space in between. If `marketName` is falsy, the function returns `null`.\r\n */\r\nconst getMarketName = (marketName, stateAbbreviation) => {\r\n if (marketName) {\r\n return `${marketName}, ${stateAbbreviation}`;\r\n }\r\n return null;\r\n};\r\n\r\n/**\r\n * It takes in a market ID and market name as parameters and returns a\r\n * string that combines the market name and ID.\r\n * @param marketId - is used to identify a specific market. It could be a unique\r\n * identifier or a code that represents the market.\r\n * @param marketName - is a string that represents the name of a market.\r\n * @param stateAbbreviation - is a string that represents the abbreviation name of the state.\r\n * @returns a string that concatenates the `marketName` and\r\n * `marketId` with a hyphen in between. If both `marketId` and `marketName` are provided, the function\r\n * returns the concatenated string. Otherwise, it returns an empty string.\r\n */\r\nexport const getMarketSession = (marketId, marketName, stateAbbreviation) => {\r\n if (marketId && marketName) {\r\n return `${marketName}, ${stateAbbreviation} - ${marketId}`;\r\n }\r\n return null;\r\n};\r\n\r\n/**\r\n * The getLocation function returns a string that represents the location, including the city and state\r\n * name if provided.\r\n * @param city - The `city` parameter represents the name of a city.\r\n * @param stateName - The `stateName` parameter represents the name of a state.\r\n * @returns If the `city` parameter is provided, the function will return a string in the format \"city,\r\n * stateName\". If the `city` parameter is not provided, the function will return just the `stateName`.\r\n */\r\nexport const getLocation = (city, stateName) => {\r\n if (city) {\r\n return `${city}, ${stateName}`;\r\n }\r\n return stateName;\r\n};\r\n\r\n/**\r\n * The function filters the Google Analytics 4 common properties, and take only the ones needed for Track events.\r\n * ex. track don't need user information. user information is available in common properties.\r\n * @returns object containing the common properties for a Track event.\r\n */\r\nconst getTrackCommonProperties = () => {\r\n const commonProperties = getCommonProperties();\r\n\r\n const trackCommonProperties = {\r\n brandPartnerName: commonProperties.brandPartnerName,\r\n pageType: commonProperties.pageType,\r\n partnerId: commonProperties.partnerId,\r\n partnerName: commonProperties.partnerName,\r\n userMarketId: commonProperties.userLocationMarketId,\r\n userStatus: commonProperties.isLoggedIn ? 1 : 0,\r\n userZipCode: commonProperties.userLocationZipCode,\r\n user: commonProperties.userId,\r\n brandPartnerNamePartnerName: `${commonProperties.brandPartnerName}-${commonProperties.partnerName}`,\r\n gaUserId: commonProperties.userId,\r\n time: getCentralStandardTime(),\r\n neustarResponse: JSON.stringify({\r\n s: commonProperties.neustarSegment,\r\n z: commonProperties.neustarZip,\r\n a: commonProperties.neustarAge,\r\n g: commonProperties.neustarGender,\r\n }),\r\n referCode: commonProperties.referCode,\r\n market_id: commonProperties.marketId?.toString() || null,\r\n market_name: getMarketName(commonProperties.marketName, commonProperties.stateAbbreviation),\r\n market_session: getMarketSession(\r\n commonProperties.marketId?.toString(),\r\n commonProperties.marketName,\r\n commonProperties.stateAbbreviation\r\n ),\r\n location: getLocation(commonProperties.city, commonProperties.stateName),\r\n current_page_number: commonProperties.pageNumber || null,\r\n search_within_map: commonProperties.isSearchWithinMap || null,\r\n page_number: commonProperties.pageNumber || null,\r\n };\r\n\r\n const cleanedTrackCommonProperties = cleanObjectsEmptyProperties(trackCommonProperties);\r\n\r\n return cleanedTrackCommonProperties;\r\n};\r\n\r\n/**\r\n * The createTrackEvent function is a helper function that creates an event object\r\n * for the Google Analytics 4. The event object contains information about\r\n * the type of event, and any properties associated with it. This function returns\r\n * a redux-beacon middleware compatible action creator that can be dispatched to\r\n * trigger an analytics call to Google Analytics 4's servers.\r\n * @param eventName Identify the event name\r\n * @param customParams Pass in any additional properties that you want to be sent with the event\r\n *\r\n * @return A function that returns a GoogleAnalytics4Event\r\n */\r\nconst createTrackEvent = (eventName, customParams) => {\r\n const commonProperties = getTrackCommonProperties();\r\n const properties = merge(commonProperties, customParams);\r\n\r\n return () => new GoogleAnalytics4Event(eventName, properties);\r\n};\r\n\r\n/**\r\n * The getGoogleAnalytics4Event function returns a GoogleAnalytics4Event object.\r\n * @param eventType Determine which type of event to create\r\n * @param eventName Identify the event name\r\n * @param customParams Send custom parameters to the event.\r\n *\r\n * @return An GoogleAnalytics4Event object\r\n */\r\nexport const getGoogleAnalytics4Event = (eventType, eventName, customParams) => {\r\n if (eventType === GoogleAnalytics4EventType.Event) {\r\n return createTrackEvent(eventName, customParams);\r\n }\r\n\r\n return null;\r\n};\r\n","import MarketingStatus from 'enums/marketingStatus';\r\n\r\n/**\r\n * Checks if the marketingStatus has the Coming Soon (C) code.\r\n * @param {string} marketingStatus The status of the community.\r\n * @returns a flag indicating whether marketing Status has Coming Soon or not.\r\n */\r\nexport function isComingSoon(marketingStatus) {\r\n const statusArray = marketingStatus?.split?.(',');\r\n\r\n return statusArray?.some((key) => MarketingStatus.fromKey(key) === MarketingStatus.ComingSoon);\r\n}\r\n\r\n/**\r\n * Checks if the marketingStatus has the Close Out (X) code.\r\n * @param {string} marketingStatus The status of the community.\r\n * @returns a flag indicating whether marketing Status has Close Out or not.\r\n */\r\nexport function isCloseOut(marketingStatus) {\r\n const statusArray = marketingStatus?.split?.(',');\r\n\r\n return statusArray?.some((key) => MarketingStatus.fromKey(key) === MarketingStatus.CloseOut);\r\n}\r\n\r\n/**\r\n * Checks if the marketingStatus has the Grand Opening (G) code.\r\n * @param {string} marketingStatus The status of the community.\r\n * @returns a flag indicating whether marketing Status has Grand Opening or not.\r\n */\r\nexport function isGrandOpening(marketingStatus) {\r\n const statusArray = marketingStatus?.split?.(',');\r\n\r\n return statusArray?.some((key) => MarketingStatus.fromKey(key) === MarketingStatus.GrandOpening);\r\n}\r\n\r\n/**\r\n * Checks if the marketingStatus has the Active (N) code.\r\n * @param {string} marketingStatus The status of the community.\r\n * @returns a flag indicating whether marketing Status has Active or not.\r\n */\r\nexport function isActive(marketingStatus) {\r\n const statusArray = marketingStatus?.split?.(',');\r\n\r\n return statusArray?.some((key) => MarketingStatus.fromKey(key) === MarketingStatus.Active);\r\n}","/**\r\n * Recursively converts object keys to camel case\r\n */\r\nexport const camelCaseObjectKeys = (object) => {\r\n if (typeof object !== 'object' || !object) {\r\n return object;\r\n }\r\n\r\n // eslint-disable-next-line no-use-before-define\r\n const camelCaseObject = camelCaseArray(object) || {};\r\n\r\n if (object && !camelCaseObject.length) {\r\n Object.keys(object).forEach((key) => {\r\n const camelCaseKey = key.charAt(0).toLowerCase() + key.slice(1);\r\n camelCaseObject[camelCaseKey] = camelCaseObjectKeys(object[key]);\r\n });\r\n }\r\n\r\n return camelCaseObject;\r\n};\r\n\r\n/**\r\n * Recursively converts object keys to camel case\r\n * This function just change the properties of your object, not the value or the types of your properties.\r\n */\r\nexport const camelCaseArray = (object) => {\r\n if (Array.isArray(object)) {\r\n object.forEach((element, index) => {\r\n object[index] = camelCaseObjectKeys(element);\r\n });\r\n return object;\r\n }\r\n\r\n return null;\r\n};\r\n","/**\r\n * The cleanObjectsEmptyProperties function takes an object as a parameter\r\n * and returns the same object with all empty properties removed.\r\n * @param objectToClean Pass in the object that you want to clean\r\n *\r\n * @return Object without empty or null properties.\r\n */\r\nconst cleanObjectsEmptyProperties = (objectToClean) =>\r\n Object.fromEntries(Object.entries(objectToClean).filter(([, value]) => value !== null && value !== undefined));\r\n\r\nmodule.exports = cleanObjectsEmptyProperties;\r\n","/**\r\n * The function generates a random number between a given minimum and maximum value.\r\n * @param min - The minimum value that the random number can be.\r\n * @param max - The maximum value that the random number can be.\r\n * @returns a random integer between the minimum and maximum values provided as arguments.\r\n */\r\nexport default function generateRandomNumber(min, max) {\r\n const random = Math.random();\r\n return Math.floor(random * (max - min + 1)) + min;\r\n}\r\n","export default class StringExtensions {\r\n static toCamelCase(stringObject) {\r\n return stringObject.charAt(0).toLowerCase() + stringObject.slice(1);\r\n }\r\n\r\n /**\r\n * Method used to convert a string into kebab case\r\n * yeah, that's the name :P, you can read more about different type of cases here:\r\n * https://www.freecodecamp.org/news/snake-case-vs-camel-case-vs-pascal-case-vs-kebab-case-whats-the-difference/\r\n * @param {string} stringObject \r\n * @returns a new string in kebab case\r\n */\r\n static toKebabCase(stringObject) {\r\n if (!stringObject){\r\n return stringObject;\r\n }\r\n\r\n return stringObject.replace(/[^a-zA-Z0-9]/g, '-');\r\n }\r\n\r\n /**\r\n * Method used to remove special characters from a string\r\n * @param {string} stringObject \r\n * @returns a new string without special characters\r\n */\r\n static removeSpecialCharacters(stringObject, replace = '') {\r\n // Replace any non-alphanumeric characters except for spaces and the forward slash (\"/\") \r\n // character with an empty string\r\n if (!stringObject){\r\n return stringObject;\r\n }\r\n\r\n return stringObject.replace(/[^\\w\\s-]+/g, '').replace(/[\\s]+/g, replace).replace(/[-]+/g, '-').trim();\r\n }\r\n\r\n /**\r\n * Method used to encode a name string to be used in a URL\r\n * @param {string} stringObject \r\n * @returns a new string without special characters, kebab case and lower case\r\n */\r\n static encodeNameToUrl(stringObject) {\r\n if (!stringObject) {\r\n return '';\r\n }\r\n\r\n const nameWithoutSpecialCharacters = this.removeSpecialCharacters(stringObject, '-');\r\n const kebabCase = this.toKebabCase(nameWithoutSpecialCharacters);\r\n const name = kebabCase.replace(\"'\", '').replace('/', '');\r\n return name.toLowerCase();\r\n } \r\n\r\n/**\r\n * The function removes a specified word from a given string and returns the updated string.\r\n * @param {string} stringObject - A string that contains the word to be removed.\r\n * @param {string} wordToRemove - The word that needs to be removed from the string.\r\n * @returns a new string with the specified `wordToRemove` removed from the original `stringObject`.\r\n */\r\n static removeWordFromString(stringObject, wordToRemove){\r\n const startInIndex = stringObject.indexOf(wordToRemove) - 1;\r\n const newValue = stringObject.substring(0, startInIndex)\r\n\r\n return newValue;\r\n }\r\n\r\n/**\r\n * Adds a comma seperated value to a string if it does not already contain it.\r\n * @param existingString - The existing comma seperated value string.\r\n * @param targetValue - The new value to conditionally add.\r\n * @returns The new comma seperated value string.\r\n * @example \r\n * StringExtensions.addComaSeperatedValue('A,D,GG,Z,K', 'X') // 'A,D,GG,Z,K,X'\r\n * StringExtensions.addComaSeperatedValue('A,D,GG,Z,K', 'A') // 'A,D,GG,Z,K'\r\n */\r\n static addCommaSeperatedValue(existingString, targetValue){\r\n if(!existingString) {\r\n return targetValue\r\n }\r\n\r\n const valueArray = existingString?.split?.(',');\r\n\r\n const hasTargetValue = valueArray?.some(\r\n (key) => key === targetValue\r\n );\r\n\r\n return hasTargetValue ? existingString : existingString?.concat(',', targetValue)\r\n};\r\n\r\n/**\r\n* Removes a comma seperated value from a string if it contains it.\r\n* @param existingString - The existing comma seperated value string.\r\n* @param targetValue - The new value to conditionally remove.\r\n* @returns The new comma seperated value string.\r\n* @example\r\n* StringExtensions.removeCommaSeperatedValue('A,D,GG,Z,K', 'X') // 'A,D,GG,Z,K'\r\n* StringExtensions.removeCommaSeperatedValue('A,D,GG,Z,K', 'A') // 'D,GG,Z,K'\r\n*/\r\n static removeCommaSeperatedValue(existingString, targetValue){\r\n const valueArray = existingString?.split?.(',');\r\n\r\n const newValueArray = valueArray?.filter((value) => value !== targetValue)\r\n\r\n return newValueArray?.join(',');\r\n };\r\n\r\n}\r\n","/**\r\n * A utility class for working with URLs.\r\n */\r\nexport default class UrlExtensions {\r\n\r\n /**\r\n * Gets the subdirectory of a URL.\r\n * @param {URL} url - The URL to get the subdirectory from.\r\n * @returns {string|null} The subdirectory of the URL, or null if there is none.\r\n */\r\n static getSubdirectory(url) {\r\n const firstSegment = url.pathname?.split('/')?.[1];\r\n const subdirectory = firstSegment || null;\r\n\r\n return subdirectory;\r\n }\r\n\r\n /**\r\n * Removes the query string from a URL.\r\n * @param {string} url - The URL to remove the query string from.\r\n * @returns {string} The URL without the query string.\r\n */\r\n static removeQueryString(url) {\r\n if(!url){\r\n return url;\r\n }\r\n \r\n const urlWithoutQueryString = url?.split('?')[0];\r\n return urlWithoutQueryString;\r\n }\r\n\r\n /**\r\n * Gets the value of a query parameter from a URL.\r\n * @param {URL} url - The URL to get the parameter value from.\r\n * @param {string} parameter - The name of the parameter to get the value of.\r\n * @returns {string|null} The value of the parameter, or null if it doesn't exist.\r\n */\r\n static getParameterValue(url, parameter) {\r\n const searchParams = new URLSearchParams(url.search);\r\n return searchParams.get(parameter) ?? null;\r\n }\r\n\r\n /**\r\n * Gets the value of a query parameter from the URL hash.\r\n * @param {URL} url - The URL to get the parameter value from.\r\n * @param {string} parameter - The name of the parameter to get the value of.\r\n * @returns {string|null} The value of the parameter, or null if it doesn't exist.\r\n */\r\n static getParameterValueFromHash(url, parameter) {\r\n const search = url.hash.replace('#', '?');\r\n const searchParams = new URLSearchParams(search);\r\n return searchParams.get(parameter) ?? null;\r\n }\r\n\r\n /**\r\n * Sets query parameters on a URL.\r\n * @param {string} url - The URL to set the parameters on.\r\n * @param {Object.} parameters - An object containing the parameter names and values to set.\r\n * @returns {string} The URL with the new parameters set.\r\n */\r\n static setParameters(url, parameters) {\r\n const separator = url.includes('?') ? '&' : '?';\r\n const query = [];\r\n Object.keys(parameters).forEach((key) => {\r\n const value = parameters[key];\r\n if (value !== null) {\r\n query.push(`${key}=${encodeURIComponent(value)}`);\r\n }\r\n });\r\n\r\n if (query.length) {\r\n return `${url}${separator}${query.join('&')}`;\r\n }\r\n\r\n return `${url}`;\r\n }\r\n}\r\n","module.exports = \"\"","module.exports = \"\""],"names":["toggleArrowControllElements","this","itemListElement","visibleElementIndexes","firstElement","firstElementChild","lastElement","lastElementChild","lastElementIndex","children","length","shouldDisplayPreviousArrow","has","shouldDisplayNextArrow","previousElement","style","visibility","nextElement","setUpdateControllsEvent","visibleElementsSubject$","updateControllsSubscription","subscribe","bind","observerSubscriptions","push","scrollTo","scrollX","scroll","left","behavior","scrollBy","setPreviousArrowObserver","previousButtonSubscription","pipe","position","getVisibleElementIndexes","previous","elementToScroll","of","getBoundingClientRect","right","scrollLeft","setNextArrowObserver","nextButtonSubscription","next","setIntersectionObserver","elementsToObserve","Array","from","intersectionObserver","IntersectionObserver","entries","forEach","entry","isIntersecting","add","target","index","delete","root","threshold","element","observe","indexes","visibleElementsCount","size","itemListElementCount","visibleIndexesArray","lastPossibleElementIndex","possiblePreviousIndex","Math","min","possibleNextIndex","max","updateIntersectionObserver","disconnect","Set","setSettings","settings","itemListQuerySelector","document","querySelector","undefined","previousQuerySelector","nextQuerySelector","destroy","sub","unsubscribe","create","refresh","url","headers","switchMap","response","json","catchError","getSourceUrl","searchTerm","separator","sourceUrl","includes","encodeURIComponent","displayErrorMessage","errorContainer","removeAttribute","setInitialSearchInputValue","searchInput","dataset","value","closeErrorMessage","setAttribute","clearSuggestions","suggestionsList","innerHTML","clearSearchInput","autoSelectSuggestion","searchInputValue","trim","click","displaySuggestions","suggestions","fragment","createDocumentFragment","suggestion","content","suggestionValueKey","li","createElement","textContent","Object","keys","key","appendChild","scrollTop","setSearchResultEvent","searchInput$","fromEvent","searchFocus$","searchEvent$","merge","searchResult$","debounceTime","event","trimmedUserInput","displaySuggestions$","displayErrorMessage$","partition","list","setSuggestionListClickedEvent","suggestionListClicked$","filter","closest","map","innerText","setSubmitButtonClickedEvent","submitButton","submitButtonClicked$","enterKeydown$","autoSelectSuggestion$","preventDefault","selectSuggestion$","submitSuggestion$","submitEventObserver$","setClearButtonClickedEvent","clearButton","setInputOutClickedEvent","setkeyDownHandler","keyDownHandler","typeaheadKeyboardHandler","suggestList","selectedOptionIndex","searchObserver","setTypeaheadSetting","setting","searchInputQuerySelector","suggestionsListQuerySelector","errorContainerQuerySelector","submitButtonQuerySelector","clearButtonQuerySelector","getSuggestionListClickedObserver","E","getSubmitEventObserver","config","updateOptionsStatus","activeOptionIndex","options","classList","ariaSelected","remove","setSelectedOptionInTypeahead","optionIndex","optionSelected","getAttribute","end","setSelectionRange","scrollToOption","scrollIntoViewIfNeeded","keyHandlers","ArrowDown","optionSize","childElementCount","ArrowUp","Enter","currentSearch","suggestedOption","arrowHandler","GoogleAnalyticsCustomDimensions","static","constructor","dimension","getName","HousingProductType","type","baseElementUrl","attributes","href","configuration","window","location","origin","getBreadcrumbContent","getCommunitiesResults","getHousingProductSnippetContent","getListingCounts","getOnPageContent","getResultFacets","getTypeaheadOptions","leadsBasicCommunitySubmission","leadsBasicPlanSubmission","leadsBasicSpecSubmission","leadsBasicListingSubmission","leadsGetRecommendedCommunities","leadsPaidCommunitySubmission","leadsPaidPlanSubmission","leadsPaidSpecSubmission","leadsRecommendedCommunitySubmission","mapGetCommunitiesPoints","mapGetHomesPoints","totalDeliveryValueCommunityLogger","totalDeliveryValuePlanLogger","totalDeliveryValueSpecLogger","userDeleteFavorite","userProfileGetFavorites","userSaveFavorite","marketingcampaignUnsubscribe","marketingcampaignUnsubscribeFeedback","googleOneTapLogin","getCommunityNearbyListingsInfo","getBuildablePlanNearbylistingsInfo","getPlanNearbyListingsInfo","getSpecNearbyListingsInfo","listingCounts","getArticleSuggestions","getCommunitiesForYou","getHomesForYou","getMetroSpecificArticles","getMostRecentArticles","blogRequestAccessToCacheManager","deleteItemInAllServers","purgeCdnCache","learningCenter","getArticleSearchResults","getArticleCountResults","searchCommunitySitePlans","getCommunityInteractiveSitePlanMarkers","getCommunitySummaryCard","getHousingUnitSummaryCard","backArrowSvg","closeIconSvg","closeModalIconSvg","priceReducedIconSvg","thanksContentIconSvg","locationIconSvg","interactiveSitePlanSvg","thankYouHeartSvg","thankYouEmailSvg","thankYouPhoneSvg","thankYouSuccessSvg","callForPriceCommunityIconSvg","callForPriceHomeIconSvg","circleCheckSvg","circleWarningSvg","category","action","label","customDimensions","eventCategory","eventAction","eventLabel","assign","GoogleAnalytics4EventType","Event","getInstance","instances","name","toString","defineProperty","LoadingStatus","Failed","Idle","Loading","Succeeded","failed","idle","loading","succeeded","MarketingStatus","ComingSoon","Active","GrandOpening","CloseOut","ComingSoonGrandOpening","C","N","G","X","CG","PageType","Homes","Communities","Builders","BuildOnYorLotLocations","CustomHomes","ManufacturedHomes","Manufactured","LearningCenter","TypeaheadLocationType","City","Market","Community","MasterPlannedCommunity","Zip","Synthetic","County","googleTagManager","searchResultsGoogleTagManagerMiddleware","payload","eventName","customProperties","getTarget","ThankScreenVariation","AskQuestion","Brochure","Tour","LimitedAvailability","Basic","comingSoon","askQuestion","brochure","tour","limitedAvailability","basic","DetailsAnchor","anchorId","bindEvents","getAnchor","addEventListener","onClickEvent","body","dispatchEvent","CustomEvent","detail","listingId","listingType","setUrl","setListingId","id","setListingType","getElementById","getHtml","SchedulerAnchor","PhoneAnchor","buttonId","setPhoneNumber","phoneNumber","replaceAll","userFriendlyPhone","revealPhone","anchor","getPhoneAnchor","getPhoneButton","PhoneAnchorCallTracking","CreateAccountAnchor","ReturnToSearchAnchor","getContactBuilderAnchor","modalInformation","listingInformation","schedulerUrl","hasCallTracking","anchors","schedulerAnchor","condition","phoneCallTrackingAnchor","phoneAnchor","detailAnchor","find","getInternalBrowsingAnchor","isLoggedIn","backButton","privacyPolicyParagraph","closeButton","recommendedPolicyParagraph","CommunityInformationLead","formData","communityId","comments","includeRecommendations","includeRecommended","mailAddress","email","userPhoneNumber","phone","leadAction","fromPage","excludeRecommendations","realtorQuestionAnswerId","realtorQuestion","postalCode","userPostalCode","livesOutside","setHousingInformation","properties","marketId","marketName","builderName","brandName","communityName","PlanInformationLead","planId","RecommendedBrochureLead","recoComms","getRecommendedCommunities","zip","international","firstName","lastName","builderId","recommendations","JSON","parse","SpecInformationLead","specId","leadConstructor","Map","set","preferredContactMethod","date","super","xxTrustedFormCertUrl","data","generator","get","prototype","GoogleAnalyticsEventAction","DirectLeads","NonDirectLeads","Leads","R","A","GoogleAnalyticsEventCategory","TdvMetrics","TdvEvents","RealtimeEvents","EventTrackingTdvEventsMixin","model","getGoogleAnalyticsData","BasicLeadTrackingEvents","events","googleAnalytics","EventTrackingNonDirectLeadsMixin","EventTrackingRealTimeEventsMixin","EventTrackingTdvMetricsMixin","BrochureTrackingEvents","InformationTrackingEvents","TourTrackingEvents","AskQuestionTrackingEvent","postRecommendedLeadForm","leadInformation","store","uiStateSlice","isFetchingModal","parameters","postLeadBrochureForm","googleAnalyticsDTO","updateModalProgress","BrochureButton","getNode","CommentsTextArea","input","EmailInput","valueInput","errorMessageId","errorCssClass","errorMessage","matchingPattern","newValue","getOnChangeEvent","setInvalidState","node","setValidState","validate","cleanedValue","replace","isValid","test","NameInput","pattern","RegExp","focus","PhoneInput","required","screenReaderMessage","phoneInput","maskPattern","removeRequired","placeholder","setRequired","isEmpy","isRequired","RecommendedCheckbox","hasUserOptedIntoRecommendationEmail","checked","ZipInput","isInternationalInput","idForOutside","idForZip","labelForOutside","labelForZipCode","isInternational","getOutsideUsNode","onOutsideUsChanged","getZipNode","outSideNode","zipNode","onOutSideChange$","startWith","onZipChange$","combineLatest","zipInput","livesOutsideInput","skip","isOutsideUs","isValidZipCode","currentTarget","RealtorDropdown","selectedValue","realtorDropdown","setSelectedValue","realtorDropdownNode","optionsArray","selectedIndex","findIndex","option","isEmpty","BrochureFormPaid","state","userProfile","uiState","getBrochureButton","commentsTextArea","emailAddressInput","formId","fullNameInput","phoneNumberInput","postalCodeInput","recommendedCheckbox","stateAbbreviation","city","setHousingData","housingData","submitBrochureForm","validateNode","some","disabled","FormData","getForm","brochureInformation","fromEntries","brochureLeadObject","bindChangeEvents","unbindEvents","removeEventListener","BasicContactVendor","OpCity","PrimeStreet","CoffmanProperties","Dezka","MarketplaceHomes","NewHomeExpertsDetroit","NewHomeExpertsLasVegas","NewHomeExpertsSarasota","NHSAustin","defaultPrivacyPolicyParagraph","contactVendorName","InformationButtonBasic","InformationFormBasic","moreInformationButton","setPrivacyPolicyText","container","basicPrivacyPolicyParagraph","firstChild","outerHTML","submitInformationForm","leadObject","postLeadInformationFormBasic","InformationButton","InformationFormPaid","isPersistent","buttonText","postLeadInformationForm","ContactRadioGroup","idEmail","idPhone","idText","radioInputSelector","labelEmail","labelPhone","labelText","onChange","callback","querySelectorAll","DateInput","tomorrow","Date","toDateString","tomorrowIsoString","toISOString","split","error","SubmitRequestButton","TourRadioOptions","idContactOneOnOne","idVideoChat","radioChecked","inputContactOneOne","labelContactOneOne","inputVideoChat","labelVideoChat","getCheckedNode","getVideoChatLabelNode","getOneOnOnetLabelNode","nodeVideoChat","nodeOneOnOne","RequestTourForm","requestButton","contactRadioGroup","tourRadioOptions","dateInput","postLeadTourForm","onPreferredContactMethodChange","setRequiredAttributeInPhone","BrochureFormLimitedAvailability","AskQuestionButton","AskQuestionFormPaid","getAskQuestionButton","submitAskQuestionForm","formInformation","postLeadAskQuestionForm","ManufacturedBrochureFormPaid","leadGeneratorConstructors","RecommendedButton","SkipButton","closeModalSvg","thanksContentSvg","thankYouEmail","thankYouHeart","thankYouPhone","thankYouSuccess","RecommendedScreen","recommendationsHtml","closeAttribute","onSkipEvent","recommendedCheckAttribute","skipButton","submitRecommendationsForm","userName","slice","join","getThankYouModalInformation","skipModal","closeModal","elem","onRecommendationChecked","modalService","recommendedCommunities","selectedRecommendedCommunities","getRecommendedBrands","brandElements","DOMParser","parseFromString","brands","el","brand","RecommendedButtonBasic","RecommendedScreenBasic","getBrochureButtonBasic","getRecomendedBrands","ThankScreenAskQuestion","moreDetailsAnchor","emitMoreDetailsClickEvent","detailsLink","ThankScreenBasic","setInternalBrowsingAnchor","internalBrowsingAnchor","ThankScreenBrochure","closeBtnId","setContactBuilderAnchor","contactBuilderAnchor","getCloseBtn","clearHtml","ThankScreenComingSoon","ThankScreenLimitedAvailability","ThankScreenTour","message$","messageService","hasFinishedLoading","leadGeneratorInstance","recommendationsInstance","getFreeBrochureThankYouScreen","brochureThankYouScreen","getThankYouScreen","screenVariation","variation","comingSoonThankYouScreen","getComingSoonThankYouScreen","thankYouScreenBasic","getThankScreenBasicScreen","openerKey","leadGeneratorOpener","leadGenerator","leadGeneratorName","validListingInformation","Boolean","getGoogleAnalyticsEventCallback","getFormOpenedAnalyticsData","getGoogleAnalyticsDTOCallback","newState","initialState","fn","overlayElement","store$","distinctUntilChanged","screen","distinctUntilKeyChanged","html","msg","messageType","message","isBasic","LeadFormType","getRecommendedCommunities$","requestObject","method","stringify","leadCommand","selector","text","postCommunityBrochure","fetch","actions","action$","fetchModal","tap","fetchModalFulfilled","postPlanBrochure","postSpecBrochure","postRecommendedCommunities","err","fetchModalError","postSpecBrochureBasic","postPlanBrochureBasic","postCommunityBrochureBasic","postBasicListingBrochureBasic","getPageLink","pageLinkType","relationType","relationElement","rel","head","createRelationElement","removePageLink","updatePageLink","pageLinkUrl","nextPageLinkUrl","previousPageLinkUrl","state$","updatePagination","updateSubdirectory","updateLocation","updateQueryString","updateBuilderName","updateUrl","routingStateActions","reducer","routingSelectors","urlComponentsSelector","selectCurrentUrl","selectUrlLocation","routingActions","listenerMiddleware","startListening","effect","newUrl","history","pushState","middleware","selectUrlSubdirectory","routingState","urlSubdirectory","urlLocation","selectUrlQueryString","urlQueryString","selectNextPageUrl","nextPageUrl","selectPreviousPageUrl","previousPageUrl","currentUrl","selectRoutingState","selectMapCoordinatesQueryString","urlCoordinatesQueryString","urlPaging","urlBuilderName","urlFilterSelector","queryStringParameter","routingDataElement","routingData","URL","searchParams","reducers","updatePreviousPageUrl","updateNextPageUrl","updateRectangularSearchQueryString","buildNewUrl","newPathName","subdirectory","paging","urlSegments","buildUrlPathName","search","getPaging","pageNumber","getBrandName","brandId","LocationType","RectangularArea","market","rectangulararea","syntheticgeo","county","toLowerCase","MoveInDate","OneToTwoMonths","ThreeToSixMonths","BuildablePlans","PlanStatus","AvailableNow","Model","ReadyToBuild","UnderConstruction","HotDeals","UC","M","H","ProductType","AllProducts","Custom","BuildOnYourLot","allProducts","custom","communities","homes","boyl","manufactured","ResultType","cssSelectorForNativeAds","Locations","builders","locations","SpecStatus","selectAdult","searchParameters","features","adult","selectAgeRestricted","ageRestricted","isCustom","product","productType","selectFetchResultCountsStatus","fetchResultCountsStatus","selectCommunityName","facts","isBuildOnYourLot","isCustomHomes","buildOnYourLot","isManufactured","selectPriceReduction","priceReduction","selectMoveInDateRange","moveInDateRange","selectMinimumPrice","price","minimumPrice","selectMaximumPrice","maximumPrice","selectNatureAreas","natureAreas","selectPool","pool","selectGolfCourse","golfCourse","selectGreen","green","selectSportsFacilities","sportsFacilities","selectParks","parks","selectViews","views","selectWaterfront","waterfront","selectGatedCommunity","gatedCommunity","selectMarketingStatus","marketingStatus","selectConsumerPromos","consumerPromos","selectRvGarage","recreationalVehicleGarage","selectHomeStatus","homeStatus","selectBathrooms","minimumBathroom","selectBedrooms","minimumBedroom","selectSchools","schoolDistrictIds","selectBrandId","selectBrandName","selectLivingAreas","livingAreas","selectStories","stories","selectPrimaryBedroom","primaryBedroom","selectGarages","garages","selectSingleFamily","singleFamily","selectLuxury","luxury","selectCondosAndTownHomes","condosAndTownHomes","selectPage","Number","results","page","selectPaging","selectPrice","selectCounties","counts","counties","selectAppliedFacets","facetsState","appliedFilters","selectListingCount","listingCount","selectProductType","selectLocation","selectProduct","selectResults","selectFeatures","selectFacts","selectResultsType","resultType","selectResultsModifiers","resultsModifiers","selectFetchResultListingsStatus","fetchResultListingsStatus","selectResultType","selectLocationType","locationType","selectSearchParameters","selectSorting","sorting","selectPageSize","pageSize","selectReviews","builderReviews","isNotCommunityLocationType","selectHomeOwnersAssociationFee","hasHomeOwnersAssociationFee","selectBrandInformation","selectExcludeAdult","excludeAdult","selectExcludeAgeRestricted","excludeAgeRestricted","housingOptionsSelector","model_homes","communityStatusSelector","coming_soon","grand_opening","active","closeout","selectCountsAndResultType","resultCountsStatus","brandIdAndSchoolsSelector","schools","activeAdultCommunitiesSelector","only","exclude","any","otherFiltersSelector","reviews","activeAdultCommunities","hotDeals","selectFetchCountsStatusAndsCounts","fetchingResultsCallStatusesSelector","selectSnippetCommand","contentTemplateType","selectProductAndResultType","selectSearchCount","hotDealsCount","adultCount","comingSoonCount","quickMoveInCount","buildablePlansCount","multiFamilyCount","selectSearchCommandContext","selectLocationContentContext","syntheticGeographicName","marketState","schoolDistrictName","geoLocationType","syntheticName","selectSubdirectory","selectBrand","selectBrandFilterContext","communityAmenitiesSelector","selectContentTemplateTypeModifiers","appliedFacetList","selectPaginationContext","pageCountSelector","ceil","moveInDateSelector","isAnyHousingTypeActiveSelector","facetsSelector","rvGarage","bathrooms","bedrooms","customHomes","moveInDate","comingsoon","grandOpening","closeOut","modelHomes","schoolDistrict","builderBrand","exclude55","sort","sortBy","selectSearchResultFacetsTrackingCommonProperties","brandInformation","facetsList","paginationContext","homeFactsSelectors","facetsPanelSelector","communityAmenities","homeFacts","brandAndSchools","otherFilters","housingOptions","communityStatus","amenities","selectLinkedPopularPillsFilters","selectResultTypeAndSorting","selectSearchModifiers","feature","modifiers","fetchResultsListingStatus","hasAvailableNow","statusArray","hasReadyToBuild","hasModelHome","hasInventoryStatusCombination","isAvailableNowIncluded","isUnderConstructionIncluded","hasUnderConstruction","getInventoryStatusCombination","isMoveInDateApplied","getHomeStatusFilterApplied","getMovingDateFilterApplied","homeStatusFilterApplied","moveInDateFilterApplied","getMoveInDateFilterApplied","MarkerType","BuildablePlan","HousingDevelopment","PlanUnit","SpecUnit","buildeablePlan","community","plan","spec","selectIsSearchWithinMapReady","mapState","isSearchWithinMapReady","areMapBoundariesDefined","geoCoordinates","areMarkersAvailable","isMapIdle","isFetchingResults","selectMapLibraryStatus","mapLibraryStatus","isMapLibraryFetching","isMapLibraryLoaded","isSearchWithinMapEnabled","isSearchWithinMap","mapMarkers","selectedMarker","selectedNearbyListingCarousel","nearbyListingsCarousel","selectedNearbyListingsCarouselStatus","nearbyListingsCarouselStatus","selectZoomLevel","zoomLevel","selectSitePlans","sitePlans","selectInteractiveSitePlans","interactiveSitePlanState","interactiveSitePlans","selectTrackedInteractiveSitePlans","loadedInteractiveSitePlans","selectLotNumber","lotNumber","selectLotId","lotId","selectLotCommunityId","selectAvailablePlans","availablePlans","selectAvailableSpec","availableSpec","selectLotStatus","lotStatus","selectedLotSummaryCard","interactiveSitePlanCard","selectedLotSummaryCardStatus","interactiveSitePlanCardStatus","selectNearbyListingsCarouselStatusAndMarkerData","status","marker","selectLotInformation","sitePlanId","summaryCard","summaryCardStatus","selectLotCommunityIdAndSitePlans","lotCommunityId","selectHoveredMarker","hoveredMarker","selectFocusedListing","focusedListing","geographicKey","selectGeoCoordinatesAndLocation","coordinates","selectSearchMapTrackingCommonProperties","selectedMarkerAndPage","selectSitePlansProperties","markers","isFetching","isMapLoaded","selectMarkersAndSitePlans","selectFocusedListingAndSitePlans","selectAllPlansAndSpecsIds","allPlanIds","allPlans","specs","plans","analyticsInstance","isAnalyticsScriptLoaded","isAnalyticsScriptLoading","loadingAttemps","onAnalyticsError","reject","console","log","Error","onAnalyticsLoaded","resolve","isAnalyticsLoaded","setTimeout","appendAnalyticsScript","analytics","initialize","invoked","methods","factory","e","t","call","arguments","unshift","load","async","src","n","getElementsByTagName","parentNode","insertBefore","_loadOptions","_writeKey","SNIPPET_VERSION","getSegmentApiKey","loadAnalytics","analyticsLoaded","analyticsErrored","Promise","then","catch","segmentAnalyticsLoaded","segmentAnalyticsErrored","loadingStatus","segmentTrack","segmentImpression","segmentIdentify","segmentPageView","SegmentEventType","Track","Impression","Identify","PageView","queue","IdleQueue","ensureTasksRun","startTime","pushTask","trackEvent","hitTypeHandlers","identify","userId","traits","group","groupId","pageview","track","alias","previousId","reset","isTimeExpired","shift","handler","hitType","eventDefinition","previousState","nextState","DateExtensions","dateString","toLocaleDateString","month","day","year","getCategory","getProperties","getOptions","getCommonProperties","getTrackCommonProperties","commonProperties","marketNameProperty","trackCommonProperties","market_id","market_name","brand_id","brand_name","page_type","pageType","code_version","buildCodeVersion","test_version","testVersion","response_version","responseVersion","partner_id","partnerId","partner_name","partnerName","brand_partner_name_partner_name","brandPartnerName","checkEmptyArray","array","isArray","getIdentifyProperties","savedElements","favorites","obj","savedDate","formatDateFromStringTimestamp","dateChanged","favoriteType","dateSaved","homeId","builderInfo","getUserSavedElements","identifyCommonProperties","user_id","first_name","last_name","userZip","outside_us","saved_communities","saved_homes","saved_builders","g_client_id","neustarSegment","n_segment","n_zip","neustarZip","n_year","neustarAge","n_gender","neustarGender","getMoveInDate","moveInInformation","getSearchLocation","locationInformation","searchLocationLabelDictionary","syntheticGeo","getMasterBedLocationLabel","bedroom","formatFiltersApplied","facets","moveIn","price_high","price_low","single_family","luxury_homes","condo_townhome","living_areas","master_bed_location","gated","golf_course","nature_areas","sports","hot_deals","price_reduction","listings_hoa_info","age_restricted","rv_garage","school_district_ids","move_in_date","mfr","search_location","facetsEntriesValues","facet","activeFacet","facetValue","getImpressionProperties","impressionCommonProperties","searchLocation","filters_applied","result_count","current_page_number","getImpressionBaseProperties","eventType","createTrackEvent","last_event","createIdentifyEvent","impressionProperties","createImpressionEvent","createPageEvent","freeze","isMobileUserAgent","navigator","userAgent","selectTrackingCommonProperties","userLocation","utm","stateName","marketStateName","userLocationCity","userLocationCountry","userLocationMarketId","userLocationState","userLocationZipCode","referCode","refer","businnessInformationElement","businnessInformation","trackingCommonPropertiesFromStore","getCommonPropertiesFromStore","trackingCommonPropertiesFromOtherSources","isMobileDevice","getCommonPropertiesFromOtherSources","listingInformationGetter","marketingStatusLabel","imageUrl","priceHigh","priceLow","getCardInformation","card","pathname","getListingInformation","getListingInformationFromDataset","toggleFavorite","icon","cardInfo","isSaved","favorite","isFavoriteSaved","deleteFavorite","saveFavorite","dispatchSaveOrDeleteAction","updateSavedFavorites","favoritesIds","toggle","current","take","pendingSaves","pendingSave","isLogin","googleOneTapInstance","isGoogleOneTapLoaded","isGoogleOneTapLoading","clientId","onAuthenticated","onGoogleOneTapError","onGoogleOneTapLoaded","google","accounts","client_id","cancel_on_tap_outside","itp_support","use_fedcm_for_prompt","appendGoogleOneTapScript","script","defer","onerror","onload","token","base64","jsonPayload","decodeURIComponent","atob","character","charCodeAt","authActions","onLibraryLoaded","googleOneTapLibraryLoadingStatus","onLibraryErrored","onPageLoaded$","googleResponse","idToken","credential","locale","picture","givenName","given_name","familyName","family_name","subject","audience","aud","emailVerified","email_verified","notBeforeTimeSeconds","nbf","hostedDomain","hd","issuer","iss","issuedAtTimeSeconds","iat","expirationTimeSeconds","exp","jwtId","jti","keepMeLogged","Success","reload","googleOneTapConfiguration$","googleOneTapInformation","googleOneTapConfiguration","prompt","cancel","signUpField","regex","validator","hint","valid","configElement","keepMeLoggedSection","legalContentSection","configObject","additionalSignUpFields","modalActions","modalReducers","authenticationReducers","onCloseModal","onClose","localStorage","setItem","authenticationActions","onAuthLibraryLoaded","authLibraryLoaded","onAuthLibraryErrored","authLibraryErrored","openModal","onOpen","isSignInElement","onOpenModal","updateNeustarInformation","documentClicks$","sessionAliveElement","sessionAliveMin","updateSession","subMenuAccountList","subMenuAccountContainer","links","link","component","ShouldOpenNewTab","qa","isAuthLibraryLoaded","authentication","isAuthLibraryNotLoaded","isAuthModalOpen","modal","pendingSavesSessionStorageKey","favoritesSessionStorageKey","FavoriteType","Plan","Spec","Builder","builder","userProfileActions","userProfileReducers","matcher","deleteFavoriteFullfilled","saveFavoriteFulfilled","sessionStorage","selectIsLoggedIn","selectFavorites","selectPendingSaves","selectIsProfileFavoritesLoaded","isProfileFavoritesLoaded","selectUserId","selectEmail","selectNeustarStatus","neustarStatus","selectGoogleOneTapLibraryLoadingStatus","selectUserIdAndPendingSaves","selectUserLocation","userCity","userCountry","userMarketId","userState","userZipCode","selectUserProfileTrackingCommonProperties","neustarInformation","s","z","a","g","pendingSavesData","getItem","favoritesData","userProfileSlice","apply","profile","camelCase","imageProfile","isLoading","applyFavorites","update","userInfo","handleError","newFavorite","authenticationSlice","modalSlice","utmParameters","selectUtmTrackingCommonProperties","PageLayout","BoylLocations","ManufacturedLocations","ResultPresentationType","Pagination","InfiniteScrolling","selectUiState","selectFetchingModal","selectDisplaySkeleton","displayCardGridSkeleton","selectResultsPresentationType","resultsPresentationType","selectModal","selectLoading","selectConfigurationSegmentApiKey","segmentApiKey","selectConfigurationImageResizeService","imageResizeService","selectConfigurationGoogleOneTapClientId","googleOneTapClientId","selectIsMarkerAutoScrollFeatureEnabled","isMarkerAutoScrollFeatureEnabled","selectLayoutBreakpoint","layoutBreakpoint","selectResourcesHostNames","resourceDomain","staticImagesHostName","lookup","layoutName","clearModal","updatePageLayout","pageLayout","updateCardGridSkeleton","focusedListingInformation","previousName","newModalInformation","updateLayoutBreakpoint","trackUserEvent","getMessage","asObservable","sendMessage","onHtmlReady","onHtmlRemoved","setHtml","setPreviousHtml","authObject","isAuth0Loaded","isAuth0Loading","lock","Auth0Lock","onAuth0Error","onAuth0Loaded","loadAuth0Module","isAuthLoaded","onSignUpReady","onkeypress","evt","charCode","which","keyCode","outsideUS","onchange","item","prefill","parentElement","after","cloneNode","authResult","accessToken","keepMeLoggedValue","auth0Authenticated","ok","afterLogin","nextPage","onSigninReady","referenceElement","loadAuth0","authLoaded","authError","createAuthInstance","auth0ClientId","auth0Domain","on","showModal","show","dataLayer","params","partnerIdElement","getCookieName","isPartnerCookie","readCookie","cookieName","items","cookie","nameLength","cookieFound","indexOf","substring","createCookieByMins","mins","expires","setTime","getTime","toGMTString","typeahead","slug","fromPageSlugElement","getFromPage","open","onDocumentContentLoaded$","categorizedSectionSelector","categorizedSectionContainer","carousel","listingsForYouQuerySelector","getListingForYouSection","CommunitiesSearchParameters","BlogListingsFiltersSearchCommand","homeSearchParameters","blogListingsFiltersSearchCommand","personalCookie","URLSearchParams","marketStateAbbreviation","marketIds","UpdateBlogListingsFiltersSearchCommand","listingsForYouData","listingsForYouContainer","createRange","createContextualFragment","metroAreaSectionCommand","buildMetroAreaSectionCommand","metroSpecificSectionSelector","urlParams","metroAreaContentByLocation","metroSpecificMainContainer","mostPopularSectionSelector","mostPopularSectionContainer","popularPillsSection","newVisibleElements$","prevButtonVisibility","popularPillsContainer","updatePopularPillContainerLeftPadding","nextButtonVisibility","updatePopularPillContainerRightPadding","redirectToBlogArticlePage","redirectToSearchCommunityResults","searchText","onErrorImage","image","removeSource","imageSrc","getLifeStyleImage","cardElement","listingForYouContainer","containerClick$","isLeadOpener","cardClick$","isFavoriteIcon","HTMLAnchorElement","isAnchorElement","leadOpenerClick$","standardCardElement","leadOpener","openLeadModal","getStandardCardElement","getLinkableArticleElement","seeAllArticlesButton","isCallToAction","isCommunityStandardCard","isPlanStandardCard","isSpecStandardCard","bodyClick$","listingForYouSectionClick$","isListingForYouSection","breadcrumbItems","breadcrumbLink","breadcrumb_position","destination","link_text","button_text","destination_url","search_value","title","click_target","triggerRecomendedArticlesClick","article","content_id","content_title","recommendation_type","article_id","article_title","isPriced","getAreaClickedName","areaClickedPerCardElement","planName","specAddress","favoriteButton","default","getPaidCommunityCardProperties","destionationUrl","click_target1","clickTarget","trustbuilder_reviews","hasBuilderReviews","min_price","max_price","community_name","community_id","priceReductionLabel","is_limited_availability","hasLimitedInformation","is_priced","is_paid","zip_code","builder_id","builder_name","getPaidPlanCardProperties","plan_id","home_status","is_spec","is_plan","getPaidSpecCardProperties","spec_id","pill","tag_text","pillText","pillUrl","cardClickEvent$","isStandardCard","favoriteIconClickEvent$","standardCardClickEvent$","standardSpecCardClick$","standardPlanCardClick$","standardCommunityCardClick$","callToActionStandardCardClick$","callToActionSpecClick$","standardCard","specStandardCard","button_name","callToActionPlanClick$","standarPlanCard","callToActionCommunityClick$","standarCommunityCard","modalSubmittedClick$","modalSubmittedSpecClick$","event_type","currency_value","modalSubmittedPlanClick$","modalSubmittedCommunityClick$","HasBuilderReviews","PriceLow","PriceHigh","MarketId","MarketName","StateAbbreviation","CommunityName","community_status","CommunityId","PriceReductionLabel","HasLimitedInformation","BuilderId","BrandName","modalCloseButtonClicked$","modalCloseSpecClick$","modalClosePlanClick$","modalCloseCommunityClick$","onWindowLoad$","section","getCardImageUrls","imageElements","primaryImage","secondaryImage","terciaryImage","search_term","onMetroSpecificArticlesClick$","callToActionCommunityCardClick$","cardData","leadButtonDataset","cardDataset","primaryImageUrl","primary_image_url","button_action","buttonAction","home_type","home_price","callToActionSpecCardClick$","callToActionPlanCardClick$","favoriteIconClick$","interactionType","linkableListingElementClick$","isLinkableListingElement","listing_id","listing_name","interaction_type","community_low_price","community_high_price","triggerModalSubmittedEvent","UrlSubdirectoryTypes","luxLabel","CondoDevelopment","CondosAndTownHomes","SingleFamilyHomes","SingleFamilyCommunities","OnYourLot","CustomBuilders","FloorPlans","ModelHomes","ip","getUserProfileUrl","housingProductConstructor","listing","getFavoriteGoogleAnalyticsEvent","combinedUserProfileEpic","getUserProfile","mergeMap","housingProductType","saveInformation","fav","IsLogin","getUserFavorites","epic$","BehaviorSubject","rootEpic","epic","staticReducers","epicMiddleware","getDefaultMiddleware","concat","asyncReducers","injectReducer","asyncReducer","replaceReducer","combineReducers","run","getTrackerClientId","ga","getAll","getPageType","getEventName","getParams","browsertTimeZone","getTimezoneOffset","utc","now","getFullYear","getMonth","getDate","getHours","getMinutes","getSeconds","getMilliseconds","getMarketSession","getLocation","userStatus","user","brandPartnerNamePartnerName","gaUserId","time","neustarResponse","market_session","search_within_map","page_number","getGoogleAnalytics4Event","customParams","isComingSoon","isCloseOut","isGrandOpening","isActive","camelCaseObjectKeys","object","camelCaseObject","camelCaseArray","camelCaseKey","charAt","module","exports","objectToClean","generateRandomNumber","random","floor","StringExtensions","stringObject","nameWithoutSpecialCharacters","removeSpecialCharacters","toKebabCase","wordToRemove","startInIndex","existingString","targetValue","valueArray","hasTargetValue","newValueArray","UrlExtensions","firstSegment","urlWithoutQueryString","parameter","hash","query"],"sourceRoot":""}