{"version":3,"file":"assets/js/chunks/6484.158e1b34b2ede0a144f8.js","mappings":"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","sources":["webpack://web-pwa/./src/domain/header/SearchInput.less?f742","webpack://web-pwa/./src/domain/header/QuickSearchInput.jsx","webpack://web-pwa/./src/domain/header/QuickSearchInput.less?9e32","webpack://web-pwa/./src/domain/search/SearchInputIcon.less?d80b","webpack://web-pwa/./src/domain/search/SearchInputIcon.jsx","webpack://web-pwa/./src/domain/header/SearchInput.jsx","webpack://web-pwa/./src/domain/utils/usePrevious.js","webpack://web-pwa/./src/domain/seo/MetaTags.jsx","webpack://web-pwa/./src/domain/seo/seo.constants.js","webpack://web-pwa/./src/domain/seo/CityService.js","webpack://web-pwa/./src/domain/seo/DepartmentService.js","webpack://web-pwa/./src/store/seo/seo-address.actions.js","webpack://web-pwa/./src/domain/seo/footer/common/topSearchCities.js"],"sourcesContent":["// extracted by mini-css-extract-plugin\nexport default {\"container\":\"ptu98\",\"homePageContainer\":\"i7nEr\",\"prefix\":\"PeGRg\",\"field\":\"SLh43\",\"greenPlaceholder\":\"o0B0M\",\"whitePlaceholder\":\"xoOtT\",\"throbber\":\"HB2G0\",\"withIcon\":\"SY57p\",\"btnOk\":\"CN2Sb\"};","import React, { useCallback, useRef } from 'react'\nimport s from './QuickSearchInput.less'\n\nconst QuickSearchInput = ({ searchInputRef, onChange }) => {\n const quickInputRef = useRef()\n\n const handleChange = useCallback(\n event => {\n searchInputRef.current.focus()\n onChange({ value: event.target.value })\n quickInputRef.current.value = ''\n },\n [searchInputRef, onChange, quickInputRef]\n )\n return \n}\n\nexport default QuickSearchInput\n","// extracted by mini-css-extract-plugin\nexport default {\"root\":\"ofhDU\"};","// extracted by mini-css-extract-plugin\nexport default {\"common\":\"XwtJj\",\"icon\":\"ngGSR\"};","import React from 'react'\nimport SVGIcon from '../svg/SVGIcon'\nimport classnames from 'classnames'\nimport s from './SearchInputIcon.less'\nimport { useSelector } from 'react-redux'\nimport { selectGeoentityIconDataForSearch } from '../../store/poiassets/poiassets.selectors'\n\nfunction SearchInputIcon() {\n const { iconId, mob_roundImage } = useSelector(selectGeoentityIconDataForSearch)\n if (iconId) return \n if (mob_roundImage) return \n return <>\n}\n\nexport default SearchInputIcon\n","import React, { forwardRef, useCallback, useEffect, useImperativeHandle, useRef, useState } from 'react'\nimport { useSelector } from 'react-redux'\nimport { isPagelessRoute } from '../router/routeUtils'\nimport { suggest } from '../../store/suggest/suggest.actions'\nimport { setCurrentSearch } from '../../store/ui/ui.actions'\nimport { navigateTo } from '../../store/history/history.actions'\nimport s from './SearchInput.less'\nimport Throbber from '../loading/Throbber'\nimport classNames from 'classnames'\nimport { ROUTE_SUGGEST } from '../../routes'\nimport { selectCurrentHistoryRoute, selectIsHomePage } from '../../store/history/history.selectors'\nimport { useAction } from '../utils/react-redux'\nimport useDebounce from '../utils/useDebounce'\nimport { usePrevious } from '../utils/usePrevious'\nimport { isGE } from '../Device'\nimport TagActionButton from '../genericComponents/TagActionButton'\nimport { PUB_TAG } from '../analytics/PublisherTagsService'\nimport { TAG_PUBLISHER } from '../../store/analytics/analytics.actionTypes'\nimport QuickSearchInput from './QuickSearchInput'\nimport SearchInputIcon from '../search/SearchInputIcon'\nimport { selectHasSearchIcon } from '../../store/poiassets/poiassets.selectors'\nimport useUIDisplay from '../ui/useUIDisplay'\nimport { UI_ELEMENTS } from '../../store/ui/ui.constants'\n\nconst SearchInput = forwardRef((props, ref) => {\n const {\n value,\n loading,\n onChange,\n onFocus,\n suggestFilterType,\n className,\n placeholder,\n idx = 0,\n prefix,\n hasGreenPlaceholder = false,\n navigateToSuggestOnFocus = true,\n isFirstStepToFill = true\n } = props\n\n const [hasFocus, setFocus] = useState(false)\n const route = useSelector(selectCurrentHistoryRoute)\n const hasIcon = useSelector(selectHasSearchIcon)\n const prevRoute = usePrevious(route)\n const execSuggest = useAction(suggest)\n const execSetCurrentSearch = useAction(setCurrentSearch)\n const execNavigateTo = useAction(navigateTo)\n const [isReady, setIsReady] = useState(false)\n const inputRef = useRef()\n const debouncedValue = useDebounce(value, 250)\n const hasDebouncedValueChangeOnce = useRef(false) // to ignore suggest on first render\n const isBtnOkDisplayed = isGE() && route === ROUTE_SUGGEST && !loading\n const isQuickSearch = isGE() && !hasFocus && (!value || value === '') && isFirstStepToFill\n const inputId = `SearchInput${idx}`\n const { showUI } = useUIDisplay(UI_ELEMENTS.SUGGEST)\n const isHomePage = useSelector(selectIsHomePage)\n\n const onSubmit = useCallback(() => {\n execSetCurrentSearch(value)\n return Promise.resolve().then(() => blur())\n }, [value])\n\n useImperativeHandle(ref, () => {\n return { onSubmit }\n })\n\n useEffect(() => {\n if (__BROWSER__) setIsReady(true)\n }, [__BROWSER__])\n\n useEffect(() => {\n if (route !== prevRoute && isPagelessRoute(prevRoute) && !isPagelessRoute(route)) {\n blur()\n }\n }, [route])\n\n const doSuggest = val => {\n execSetCurrentSearch(val)\n return execSuggest({ terms: val, suggestFilterType })\n }\n\n useEffect(() => {\n if (hasDebouncedValueChangeOnce.current && hasFocus) {\n doSuggest(debouncedValue)\n }\n hasDebouncedValueChangeOnce.current = true\n }, [hasFocus, debouncedValue])\n\n const handleChange = event => {\n onChange && onChange({ value: event.target.value })\n }\n\n const handleFocus = useCallback(\n e => {\n setTimeout(() => {\n if (value.length !== 0) e.target.select()\n }, 0)\n if (navigateToSuggestOnFocus) execNavigateTo({ route: ROUTE_SUGGEST })\n showUI()\n onFocus && onFocus()\n setFocus(true)\n },\n [execNavigateTo, showUI, doSuggest, onFocus, setFocus]\n )\n\n const blur = useCallback(() => {\n inputRef?.current?.blur()\n setFocus(false)\n }, [inputRef, setFocus])\n\n return (\n \n {prefix && (\n \n )}\n {hasIcon && }\n \n {loading && (\n \n \n \n )}\n {isBtnOkDisplayed && (\n \n OK\n \n )}\n {isQuickSearch && }\n \n )\n})\n\nSearchInput.displayName = 'SearchInput'\nexport default SearchInput\n","import { useEffect, useRef } from 'react'\n\nexport const usePrevious = value => {\n const ref = useRef()\n useEffect(() => {\n ref.current = value\n })\n return ref.current\n}\n","import React from 'react'\nimport { Helmet } from 'react-helmet'\nimport logo from './Mappy-310.png'\nimport { selectLocale } from '../../store/locale/locale.selectors'\nimport translations from './MetaTags.json'\n\nimport { isAbsoluteUrl } from '../utils/url'\nimport { generateAbsoluteBaseUrl } from './seo'\nimport { getHrefLangBySubdomain, SUBDOMAINS, SUBDOMAIN_EN } from '../i18n'\nimport { useSelector } from 'react-redux'\n\nconst getImageUrl = ({ image, locale, logo }) => {\n const img = image || logo\n if (!isAbsoluteUrl(img)) return `${generateAbsoluteBaseUrl(locale)}${img}`\n if (img.startsWith('//')) return `https:${img}`\n return img\n}\n\nconst getAlternateLinks = ({ alternateLinkPath, shouldIgnoreEn }) =>\n SUBDOMAINS.map((subdomain, idx) => {\n // not returning an empty React fragment here `<>` so returning array\n // is not filling alternate links with irrelevant and undefined components\n if (subdomain === SUBDOMAIN_EN && shouldIgnoreEn) return undefined\n\n return (\n \n )\n })\n\nconst MetaTags = ({\n title: givenTitle,\n description: givenDescription,\n image,\n url,\n alternateLinkPath,\n canonical,\n type,\n shouldIgnoreEn\n}) => {\n const locale = useSelector(selectLocale)\n const { title: defaultTitle, description: defaultDescription } = translations?.[locale] ?? {}\n const title = givenTitle || defaultTitle\n const description = givenDescription || defaultDescription\n const img = getImageUrl({ locale, image, logo })\n const typ = type || 'website'\n\n return (\n \n {title}\n \n \n \n \n {url && }\n \n \n {alternateLinkPath && getAlternateLinks({ alternateLinkPath, shouldIgnoreEn })}\n {canonical && }\n \n )\n}\n\nexport default MetaTags\n","export const DIRECTORY_LINKS_PER_PAGE = 200\n\nexport const COUNT_CITIES_TO_DISCOVER = 30\nexport const COUNT_CITIES_FOOTER_HP = 192\nexport const COUNT_CITIES_FOOTER_OTHER = 20\n\nexport const FRONT_SERVICES_LINK_HP = '/hp'\nexport const FRONT_SERVICES_LINK_ITINERARY_HP = '/hp-itinerary'\n","\n export default function () {\n return null\n }\n ","import departments from '../../node/static/seo/departments-250-fr-FR.json'\nimport { isFranceCountryCode } from '../../routes/address/Countries'\n\nexport const getDepartments = () => {\n return departments\n}\n\nexport default class DepartmentService {\n static findDepartmentByCode(departmentCode) {\n return getDepartments().find(department => department.code === departmentCode.toString())\n }\n\n static findBorderingDepartments(departmentCode, countryCode) {\n if (isFranceCountryCode(countryCode)) {\n const department = this.findDepartmentByCode(departmentCode)\n const borderingDepartments = []\n department?.nextTo.forEach(borderDepartmentCode => {\n const borderDepartment = this.findDepartmentByCode(borderDepartmentCode)\n if (borderDepartment) borderingDepartments.push(borderDepartment)\n })\n\n return borderingDepartments\n }\n }\n\n static findDepartmentsFromRegionCode(regionCode, countryCode) {\n if (isFranceCountryCode(countryCode))\n return getDepartments().filter(department => department.regionId === regionCode)\n }\n}\n","import { selectLocale } from '../locale/locale.selectors'\nimport { SET_SEO_CITIES_FOR_FOOTER, SET_SEO_TOWN_DETAILS, SET_CITIES_TO_DISCOVER_LINKS } from './seo.actionTypes'\nimport { selectFirstAddress } from '../address/address.selectors'\nimport { citiesWithDistricts, getSeoTownFromLocation } from '../../domain/seo/seo'\nimport debug from 'debug'\nimport { selectSeoTownDetails, selectIsSeoCityWithDistricts, selectSeoTownDetailsId } from './seo.selectors'\nimport { getSeoFooterCitiesPositions } from '../../domain/seo/seo-modulo'\n\nimport { localeCountryIsBelgium, localeCountryIsFrance } from '../../domain/i18n'\nimport { MINIMAL_NB_OF_POI_TO_OPEN_CITY } from '../../parameters'\nimport { isFranceCountryCode, isFranceOrBelgiumCountryCode } from '../../routes/address/Countries'\nimport CityService from '../../domain/seo/CityService'\nimport { isCityWithDistrict } from '../../domain/utils/location'\nimport DepartmentService from '../../domain/seo/DepartmentService'\nimport { uniqBy } from '../../utils/array'\nimport { COUNT_CITIES_FOOTER_OTHER, COUNT_CITIES_TO_DISCOVER } from '../../domain/seo/seo.constants'\nimport { formatCitiesLinks } from '../../domain/seo/footer/common/topSearchCities'\n\nconst d = debug('seo')\n\nexport const searchSeoCityData = () => (dispatch, getState) => {\n const address = selectFirstAddress(getState())\n const seoTownFromLocation = getSeoTownFromLocation(address)\n if (!seoTownFromLocation || !isFranceOrBelgiumCountryCode(address.countryCode)) return Promise.resolve()\n\n const locale = selectLocale(getState())\n const town = CityService.findCityByPostCodeAndTownSlugified({ ...seoTownFromLocation, locale })\n const townWithMorePoiAndSameTownCode = CityService.findCityByTownCode({ towncode: address.towncode, locale })\n\n if (!town && !townWithMorePoiAndSameTownCode) return Promise.resolve()\n\n const townPlainObject = town\n ? {\n ...town,\n townWithMorePoiAndSameTownCode:\n (town?.poicount ?? 0) < MINIMAL_NB_OF_POI_TO_OPEN_CITY &&\n (townWithMorePoiAndSameTownCode?.poicount ?? 0) > MINIMAL_NB_OF_POI_TO_OPEN_CITY\n ? townWithMorePoiAndSameTownCode\n : null\n }\n : townWithMorePoiAndSameTownCode\n\n dispatch({\n type: SET_SEO_TOWN_DETAILS,\n // N.B.: for old towns, townWithoutDistrict is the new name\n payload: {\n ...townPlainObject,\n townWithoutDistrict: address.town\n }\n })\n return Promise.resolve()\n}\n\nexport const setSeoCityDataFromGeocode = zip => (dispatch, getState) => {\n const address = selectFirstAddress(getState())\n\n dispatch({\n type: SET_SEO_TOWN_DETAILS,\n payload: {\n ...address,\n postcode: isCityWithDistrict(zip) ? zip : address.postcode,\n townWithoutDistrict: address.town\n }\n })\n}\n\nexport const searchSeoCitiesForFooter = () => (dispatch, getState) => {\n const locale = selectLocale(getState())\n if (!localeCountryIsFrance(locale) && !localeCountryIsBelgium(locale)) return Promise.resolve()\n\n const hasDistrict = selectIsSeoCityWithDistricts(getState())\n if (d.enabled) d('searchSeoCitiesForFooter, hasDistrict:', hasDistrict)\n\n const searchMethod = hasDistrict ? searchSeoDistrictsForCity : searchSeoCitiesByPositions\n\n const cities = searchMethod()(dispatch, getState).map(({ town, postcode, district }) => ({\n town,\n postcode,\n district\n }))\n\n dispatch({\n type: SET_SEO_CITIES_FOR_FOOTER,\n payload: cities\n })\n}\n\nexport const searchSeoCitiesByPositions = () => (dispatch, getState) => {\n const locale = selectLocale(getState())\n const count = CityService.findCityCountByLocale({ locale })\n\n const cityId = selectSeoTownDetailsId(getState())\n if (d.enabled) d('searchSeoCitiesByPositions, cityId', cityId)\n if (!cityId) return []\n\n const index = CityService.getIndexByPositionByPoi({ locale, cityId })\n if (d.enabled) d('searchSeoCitiesByPositions, index', index)\n\n const positions = getSeoFooterCitiesPositions(index, count, locale)\n if (d.enabled) d('searchSeoCitiesByPositions, positions', positions)\n\n const cities = CityService.findCitiesByPositionByPoi({ locale, positions })\n if (d.enabled)\n d(\n 'searchSeoCitiesByPositions, cities',\n cities.map(({ towncode, town }) => `${town} (${towncode})`)\n )\n\n if (localeCountryIsFrance(locale)) {\n return uniqBy(\n [...citiesWithDistricts.map(city => ({ ...city, district: false })), ...cities],\n item => item.postcode\n )\n } else {\n return [...cities]\n }\n}\n\nexport const searchSeoDistrictsForCity = () => (dispatch, getState) => {\n const address = selectFirstAddress(getState())\n if (!isFranceCountryCode(address.countryCode)) return Promise.resolve()\n\n const locale = selectLocale(getState())\n const postcode = selectSeoTownDetails(getState())?.postcode\n return CityService.findDistrictsByCityPostcode({ locale, postcode })\n}\n\nexport const cleanCities = cities => cities.map(({ town, postcode, district }) => ({ town, postcode, district }))\n\nexport const searchFirstCities =\n ({ offset = 0, limit = COUNT_CITIES_FOOTER_OTHER }) =>\n (dispatch, getState) => {\n const locale = selectLocale(getState())\n const cities = CityService.findCitiesOrderedByPoi({ locale, offset, limit })\n dispatch({\n type: SET_SEO_CITIES_FOR_FOOTER,\n payload: cleanCities(cities)\n })\n }\n\nexport const loadCitiesToDiscover = () => (dispatch, getState) => {\n const locale = selectLocale(getState())\n const cities = CityService.findCitiesOrderedByPoi({ locale, offset: 0, limit: COUNT_CITIES_TO_DISCOVER })\n const payload = formatCitiesLinks(cleanCities(cities), locale)\n dispatch({\n type: SET_CITIES_TO_DISCOVER_LINKS,\n payload\n })\n}\n\nexport const searchDepartmentCities = () => (dispatch, getState) => {\n const { departmentCode, countryCode } = selectFirstAddress(getState())\n const cities = CityService.findTopCitiesFromDepartmentWithCode({\n departmentCode,\n countryCode\n })\n dispatch({\n type: SET_SEO_CITIES_FOR_FOOTER,\n payload: cities?.map(({ town, postcode, district }) => ({ town, postcode, district }))\n })\n}\n\nexport const searchRegionCities = () => (dispatch, getState) => {\n const { regionCode, countryCode } = selectFirstAddress(getState())\n const departmentsFromRegionsList = DepartmentService.findDepartmentsFromRegionCode(regionCode, countryCode)\n const departmentCodes = departmentsFromRegionsList?.map(department => department.code)\n const cities = CityService.findTopCitiesFromDepartmentsWithCode({\n departmentCodes,\n countryCode\n })\n dispatch({\n type: SET_SEO_CITIES_FOR_FOOTER,\n payload: cities?.map(({ town, postcode, district }) => ({ town, postcode, district }))\n })\n}\n\nexport const searchCountryCities = () => (dispatch, getState) => {\n const { countryCode } = selectFirstAddress(getState())\n if (!isFranceOrBelgiumCountryCode(countryCode)) return\n const locale = selectLocale(getState())\n const cities = CityService.findCitiesOrderedByPoi({ locale })\n dispatch({\n type: SET_SEO_CITIES_FOR_FOOTER,\n payload: cities?.map(({ town, postcode, district }) => ({ town, postcode, district }))\n })\n}\n","import {\n ROUTE_ADDRESS_HOME,\n ROUTE_HOME,\n ROUTE_SEO_ADDRESS,\n ROUTE_SEO_DIRECTORY_CITY_OVM_POIS\n} from '../../../../routes'\nimport { isFranceCountryCode } from '../../../../routes/address/Countries'\nimport { selectFirstAddress, selectZone } from '../../../../store/address/address.selectors'\nimport { isCountryRoute, selectCurrentHistoryRoute } from '../../../../store/history/history.selectors'\nimport { selectLocale } from '../../../../store/locale/locale.selectors'\nimport { getAppOrFreeAppLabel, selectGeoentityTypeDataForSearch } from '../../../../store/poiassets/poiassets.selectors'\nimport { searchServiceCtx } from '../../../../store/search/search.service.constants'\nimport {\n selectSeoAppsForFooter,\n selectSeoCitiesForActivitiesFooter,\n selectSeoCitiesForFooter,\n selectSeoTown\n} from '../../../../store/seo/seo.selectors'\nimport { compact } from '../../../../utils/array'\nimport { slugify } from '../../../../utils/string'\nimport { getCountryByLocale, localeCountryIsFrance } from '../../../i18n'\nimport { translate } from '../../../i18n/T'\nimport { generateFullRoute } from '../../../router/routeUtils'\nimport { getPostCodeFromTown, getSeoCityPostcode, getTownForDistrict } from '../../seo'\nimport { selectSeoCityLinkLabelPrefixKey } from '../seo-footer.selectors'\n\nexport const formatCitiesLinks = (links, locale, labelPrefixKey = 'footer.cityLink.label.default') =>\n links\n .map(({ postcode, town, district }) => {\n if (!district) return { postcode, town }\n const townForDistrict = getTownForDistrict({ postcode })\n return { postcode, town: townForDistrict.town, label: town }\n })\n .map(({ town, postcode, label }) => {\n if (!label) label = town\n return { label: translate(locale)(labelPrefixKey, [label]), url: `/plan/${postcode}-${slugify(town)}` }\n })\n\nexport const buildCitiesLinks = (store, cityDirectoryLink, countryLink) => {\n const locale = selectLocale(store)\n const labelPrefixKey = selectSeoCityLinkLabelPrefixKey(store)\n const cities = selectSeoCitiesForFooter(store)\n const citiesForLinks = formatCitiesLinks(cities, locale, labelPrefixKey)\n const zone = selectZone(store)\n const route = selectCurrentHistoryRoute(store)\n\n if (isCountryRoute(route)) {\n const localeIsFr = localeCountryIsFrance(locale)\n const zoneIsFr = isFranceCountryCode(zone?.countryCode)\n\n if ((localeIsFr && !zoneIsFr) || (!localeIsFr && zoneIsFr)) return {}\n }\n\n return {\n title: translate(locale)('footer.top-search.cities.title', [zone?.countryLabel ?? getCountryByLocale(locale)]),\n contents: compact([\n cityDirectoryLink ? { label: 'Villes de France', url: '/annuaire-ville/page1' } : null,\n countryLink ? { label: 'Carte de France', url: '/plan/pays/250-france' } : null,\n ...citiesForLinks\n ])\n }\n}\n\nexport const buildCitiesAppLinks = (store, minimumToDisplay = 0) => {\n const locale = selectLocale(store)\n const { appOrRubricIds, label: appLabel } = selectGeoentityTypeDataForSearch(store)\n const cities = selectSeoCitiesForFooter(store)\n\n if (cities.length >= minimumToDisplay) {\n const citiesForLinks = cities.map(({ town, label: cityLabel, slug: eventuallySlug }) => ({\n label: `${appLabel} ${cityLabel ?? town}`,\n url: `/app/${appOrRubricIds}/${slugify(eventuallySlug)}`\n }))\n\n return {\n title: translate(locale)('footer.top-search.cities-app.title'),\n contents: compact(citiesForLinks)\n }\n }\n}\n\nexport const buildCitiesActivitiesLinks = (store, minimumToDisplay = 0) => {\n const locale = selectLocale(store)\n const { appOrRubricIds, label: appLabel } = selectGeoentityTypeDataForSearch(store)\n const cities = selectSeoCitiesForActivitiesFooter(store)\n\n if (appOrRubricIds === 'hotel' || cities.length < minimumToDisplay) return {}\n\n const citiesForLinks = cities.map(({ town, label: cityLabel, slug: eventuallySlug }) => ({\n label: `${appLabel} ${cityLabel ?? town}`,\n url: `/activite/${appOrRubricIds}/${slugify(eventuallySlug)}`\n }))\n\n return {\n title: translate(locale)('footer.top-search.cities-activity.title', [appLabel]),\n contents: compact(citiesForLinks)\n }\n}\n\nexport const buildAppsCitiesLinks = (store, minimumToDisplay = 0) => {\n const locale = selectLocale(store)\n const { town, postcode, townWithoutDistrict } = selectSeoTown(store)\n const { postcode: addressPostcode } = selectFirstAddress(store)\n const cityLink = `${postcode ?? addressPostcode} ${townWithoutDistrict ?? town}`\n const apps = selectSeoAppsForFooter(store)\n\n if (apps.length >= minimumToDisplay) {\n const appsForLinks = apps.map(app => ({\n label: `${getAppOrFreeAppLabel(store, { id: app })} ${town ?? townWithoutDistrict}`,\n url: `/app/${app}/${slugify(cityLink)}`\n }))\n\n return {\n title: translate(locale)('footer.top-search.app-cities.title', [town ?? townWithoutDistrict]),\n contents: compact(appsForLinks)\n }\n }\n}\n\nexport const generateBreadcrumbForDirectoryCityFooter = (store, route, translationSuffix, ovm = false) => {\n const { geocode_level, label, town, postcode } = selectFirstAddress(store)\n const sluggedTown = slugify(town)\n\n const links = [\n { labelKey: 'breadcrumb.homepage', url: generateFullRoute(ROUTE_HOME) },\n { labelKey: 'breadcrumb.pageplan', url: generateFullRoute(ROUTE_ADDRESS_HOME) }\n ]\n\n if (geocode_level === searchServiceCtx.geocodeLevel.district) {\n const breadcrumbs = [\n ...links,\n {\n labelKey: town,\n url: generateFullRoute(ROUTE_SEO_ADDRESS, { location: `${getSeoCityPostcode(postcode)}-${sluggedTown}` })\n },\n {\n labelKey: label,\n url: generateFullRoute(ROUTE_SEO_ADDRESS, { location: `${postcode}-${sluggedTown}` })\n },\n {\n labelKey: `breadcrumb.directory.city-${translationSuffix}`,\n labelArgs: [town],\n url: generateFullRoute(route, {\n zip: getSeoCityPostcode(postcode),\n city: sluggedTown,\n pageIdx: 1\n })\n },\n {\n labelKey: `breadcrumb.directory.city-${translationSuffix}`,\n labelArgs: [label],\n url: generateFullRoute(route, { zip: postcode, city: sluggedTown, pageIdx: 1 })\n }\n ]\n return ovm\n ? [\n ...breadcrumbs,\n {\n labelKey: `breadcrumb.directory.city-ovm-pois`,\n labelArgs: [town],\n url: generateFullRoute(ROUTE_SEO_DIRECTORY_CITY_OVM_POIS, { zip: postcode, city: sluggedTown, pageIdx: 1 })\n }\n ]\n : breadcrumbs\n } else {\n const townPostCode = getPostCodeFromTown(town) ?? postcode\n const breadcrumbs = [\n ...links,\n {\n labelKey: town,\n url: generateFullRoute(ROUTE_SEO_ADDRESS, { location: `${townPostCode}-${sluggedTown}` })\n },\n {\n labelKey: `breadcrumb.directory.city-${translationSuffix}`,\n labelArgs: [town],\n url: generateFullRoute(route, { zip: townPostCode, city: sluggedTown, pageIdx: 1 })\n }\n ]\n return ovm\n ? [\n ...breadcrumbs,\n {\n labelKey: `breadcrumb.directory.city-ovm-pois`,\n labelArgs: [town],\n url: generateFullRoute(ROUTE_SEO_DIRECTORY_CITY_OVM_POIS, {\n zip: townPostCode,\n city: sluggedTown,\n pageIdx: 1\n })\n }\n ]\n : breadcrumbs\n }\n}\n"],"names":["_ref","searchInputRef","onChange","quickInputRef","useRef","handleChange","useCallback","event","current","focus","value","target","React","ref","className","autoFocus","iconId","mob_roundImage","useSelector","selectGeoentityIconDataForSearch","SVGIcon","icon","classnames","s","src","SearchInput","forwardRef","props","loading","onFocus","suggestFilterType","placeholder","idx","prefix","hasGreenPlaceholder","navigateToSuggestOnFocus","isFirstStepToFill","hasFocus","setFocus","useState","route","selectCurrentHistoryRoute","hasIcon","selectHasSearchIcon","prevRoute","useEffect","usePrevious","execSuggest","useAction","suggest","execSetCurrentSearch","setCurrentSearch","execNavigateTo","navigateTo","isReady","setIsReady","inputRef","debouncedValue","useDebounce","hasDebouncedValueChangeOnce","isBtnOkDisplayed","isGE","ROUTE_SUGGEST","isQuickSearch","inputId","showUI","useUIDisplay","UI_ELEMENTS","SUGGEST","isHomePage","selectIsHomePage","onSubmit","Promise","resolve","then","blur","useImperativeHandle","__BROWSER__","isPagelessRoute","doSuggest","val","terms","handleFocus","e","setTimeout","length","select","_inputRef$current","classNames","htmlFor","SearchInputIcon","type","id","disabled","autoComplete","Throbber","TagActionButton","tagInfo","tag","PUB_TAG","PUB_FOCUS_CHAMP_SAISI","TAG_PUBLISHER","shouldTagImpression","isSubmitButton","QuickSearchInput","displayName","getImageUrl","image","locale","logo","img","isAbsoluteUrl","startsWith","generateAbsoluteBaseUrl","_ref3","title","givenTitle","description","givenDescription","url","alternateLinkPath","canonical","shouldIgnoreEn","selectLocale","defaultTitle","defaultDescription","translations","typ","Helmet","name","content","property","toLowerCase","_ref2","SUBDOMAINS","map","subdomain","SUBDOMAIN_EN","key","rel","href","hreflang","getHrefLangBySubdomain","getAlternateLinks","COUNT_CITIES_FOOTER_OTHER","FRONT_SERVICES_LINK_HP","FRONT_SERVICES_LINK_ITINERARY_HP","getDepartments","departments","DepartmentService","findDepartmentByCode","departmentCode","find","department","code","toString","findBorderingDepartments","countryCode","isFranceCountryCode","this","borderingDepartments","nextTo","forEach","borderDepartmentCode","borderDepartment","push","findDepartmentsFromRegionCode","regionCode","filter","regionId","debug","cleanCities","cities","town","postcode","district","searchFirstCities","_ref4","offset","limit","dispatch","getState","CityService","findCitiesOrderedByPoi","SET_SEO_CITIES_FOR_FOOTER","payload","searchDepartmentCities","selectFirstAddress","findTopCitiesFromDepartmentWithCode","_ref5","searchRegionCities","departmentsFromRegionsList","departmentCodes","findTopCitiesFromDepartmentsWithCode","_ref6","searchCountryCities","isFranceOrBelgiumCountryCode","_ref7"],"sourceRoot":""}