{"version":3,"file":"product-landing-wDLW0gLF.js","sources":["../../../scripts/components/products/search/search-form-cruises.vue","../../../scripts/components/products/search/search-form-hotels.vue","../../../scripts/components/products/search/search-form-tours.vue","../../../scripts/components/shared/carousel-sponsored-products.vue","../../../scripts/components/pages/product-landing-page.vue","../../../scripts/entry-points/product-landing.ts"],"sourcesContent":["<template>\r\n <div class=\"mt-3\" data-testid=\"cruise-search\">\r\n <div class=\"row\">\r\n <div class=\"-query-container col-12 col-lg-4\">\r\n <label class=\"select--styled mb-0\">\r\n <select v-model=\"cruiseLines\" name=\"cruiseLines\" aria-label=\"Cruise Lines\">\r\n <option value=\"\">Any Cruise Line</option>\r\n <option v-for=\"(brand, brandIndex) in brands\" :key=\"brandIndex\" :value=\"brand.name\" v-html=\"brand.name\"></option>\r\n </select>\r\n </label>\r\n </div>\r\n <div class=\"col-12 col-lg-3 mt-1 mt-lg-0\">\r\n <label class=\"select--styled mb-0\">\r\n <select v-model=\"destination\" name=\"destination\" aria-label=\"destination\">\r\n <option value=\"\">Any Destination</option>\r\n <option value=\"Africa & Arabian Peninsula\">Africa & Arabian Peninsula</option>\r\n <option value=\"Alaska & Pacific Northwest\">Alaska & Pacific Northwest</option>\r\n <option value=\"Asia\">Asia</option>\r\n <option value=\"Canada & New England\">Canada & New England</option>\r\n <option value=\"Caribbean\">Caribbean</option>\r\n <option value=\"Hawaii\">Hawaii</option>\r\n <option value=\"Mediterranean & Southern Europe\">Mediterranean & Southern Europe</option>\r\n <option value=\"Mexico & Central America\">Mexico & Central America</option>\r\n <option value=\"Northern Europe & the British Isles\">Northern Europe & the British Isles</option>\r\n <option value=\"South America & Antarctica\">South America & Antarctica</option>\r\n <option value=\"South Pacific\">South Pacific</option>\r\n <option value=\"Western & Central Europe\">Western & Central Europe</option>\r\n </select>\r\n </label>\r\n </div>\r\n <div class=\"col-12 col-lg-3 mt-1 mt-lg-0\">\r\n <date-picker-component id=\"filter-dates\" placeholder-text=\"Travel Dates\"></date-picker-component>\r\n </div>\r\n <div class=\"col-2 mt-0 d-none d-lg-block\">\r\n <button class=\"btn btn-primary-emphasis btn-sm js-search-button w-100\" @click=\"doSearch\">Search</button>\r\n </div>\r\n </div>\r\n <div class=\"row mt-1\">\r\n <div class=\"col-12 col-lg-2\">\r\n <button class=\"btn btn-xs btn-tertiary\" @click=\"toggleMoreFilters\"><i :class=\"(isMoreFiltersOpen) ? 'icon-angle-down-ut' : 'icon-angle-right-ut'\"></i> More filters</button>\r\n </div>\r\n <div id=\"more-filters-panel\" class=\"col-12 col-lg-10 text--small\">\r\n <div class=\"row\">\r\n <div class=\"col-6 col-md-3 col-lg-2\">\r\n <span class=\"text-emphasis font-weight-bold\">Duration</span>\r\n <ul class=\"list-unstyled mt-1\">\r\n <li v-for=\"(facet, facetIndex) in durationFacets\" :key=\"facetIndex\">\r\n <label>\r\n <input :id=\"'lengths-' + facet\" :key=\"'lengths-' + facet\" v-model=\"selectedLengths\" type=\"checkbox\" :value=\"encodeURIComponent(facet)\"> {{ facet }}\r\n </label>\r\n </li>\r\n </ul>\r\n </div>\r\n <div class=\"col-6 col-md-3 col-lg-2\">\r\n <span class=\"text-emphasis font-weight-bold\">Style</span>\r\n <ul class=\"list-unstyled mt-1\">\r\n <li v-for=\"(facet, facetIndex) in styleFacets\" :key=\"facetIndex\">\r\n <label>\r\n <input :id=\"'cruiseTypes-' + facet\" :key=\"'cruiseTypes-' + facet\" v-model=\"selectedCruiseTypes\" type=\"checkbox\" :value=\"encodeURIComponent(facet)\"> {{ facet }}\r\n </label>\r\n </li>\r\n </ul>\r\n </div>\r\n <div class=\"col-12 col-md-6 col-lg-3\">\r\n <span class=\"text-emphasis font-weight-bold\">Virtuoso Exclusives</span>\r\n <ul class=\"list-unstyled mt-1\">\r\n <li v-for=\"(facet, facetIndex) in exclusivesFacets\" :key=\"facetIndex\">\r\n <label>\r\n <input :id=\"'exclusives-' + facet\" :key=\"'exclusives-' + facet\" v-model=\"selectedExclusives\" type=\"checkbox\" :value=\"encodeURIComponent(facet)\"> {{ facet }}\r\n </label>\r\n </li>\r\n </ul>\r\n </div>\r\n <div class=\"col-12 col-md-6 col-lg-5\">\r\n <span class=\"text-emphasis font-weight-bold\">Keyword</span>\r\n <AutocompleteInput v-model=\"query\" :show-icon=\"false\" :show-mobile-button=\"false\" :type=\"ProductType.CRUISES\" placeholder-text=\"Keyword\" @search=\"doSearch\" @select=\"selectCategory\" @clear=\"() => { query = '' }\" />\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"col-12 mt-2 d-lg-none\">\r\n <button class=\"btn btn-primary-emphasis btn-sm js-search-button w-100\" @click=\"doSearch\">Search</button>\r\n </div>\r\n </div>\r\n <div class=\"mt-2 text--small fw-bold d-none d-lg-block\">\r\n <a :href=\"b2bCatalogLink\" v-html=\"legacyLinkText\"></a>\r\n </div>\r\n </div>\r\n</template>\r\n\r\n\r\n<script setup lang=\"ts\">\r\n import AutocompleteInput from \"components/shared/autocomplete-input.vue\";\r\n import DatePickerComponent from \"components/shared/date-picker.vue\";\r\n import { facetsByProduct } from \"config/search-facet-data\";\r\n import { ProductType } from \"interfaces/enums\";\r\n import { BoxLink } from \"interfaces/link\";\r\n import { ProductSearchConfig } from \"interfaces/product\";\r\n import { isSupplier } from \"services/auth/user-info\";\r\n import { slideDownWithFade, slideUpWithFade } from \"services/helpers/html\";\r\n import { trackOmniboxSearch } from \"services/analytics\";\r\n import { cobrandLink } from \"virtuoso-shared-web-ui\";\r\n import { PropType, ref } from \"vue\";\r\n\r\n let omniboxCategorySearch = \"\";\r\n\r\n defineProps({\r\n brands: {\r\n type: Array as PropType<BoxLink[]>,\r\n default: undefined\r\n }\r\n });\r\n\r\n const b2bCatalogLink = cobrandLink(\"/cruises\");\r\n const cruiseLines = ref(\"\");\r\n const destination = ref(\"\");\r\n const durationFacets = ref(facetsByProduct[ProductType.CRUISES].find((category: ProductSearchConfig) => category.categoryName === \"lengths\")?.facets);\r\n const exclusivesFacets = ref(facetsByProduct[ProductType.CRUISES].find((category: ProductSearchConfig) => category.categoryName === \"virtuosoExclusives\")?.facets);\r\n const isMoreFiltersOpen = ref(false);\r\n const legacyLinkText = `For ${(isSupplier()) ? \"Partners\" : \"Advisors\"}: Advanced Search`;\r\n const query = ref(\"\");\r\n const selectedCruiseTypes = ref([]);\r\n const selectedExclusives = ref([]);\r\n const selectedLengths = ref([]);\r\n const styleFacets = ref(facetsByProduct[ProductType.CRUISES].find((category: ProductSearchConfig) => category.categoryName === \"cruiseTypes\")?.facets);\r\n\r\n function doSearch(): void {\r\n let queryHash = \"#\";\r\n // Omnibox Search\r\n if (omniboxCategorySearch !== \"\") {\r\n queryHash += `${encodeURIComponent(omniboxCategorySearch.trim())}=${encodeURIComponent(query.value.trim())}&`;\r\n }\r\n // Text query\r\n if (query.value.trim() !== \"\" && omniboxCategorySearch === \"\") {\r\n queryHash += `query=${encodeURIComponent(query.value.trim())}&sort=SearchRelevance&`;\r\n }\r\n // Destination\r\n if (destination.value !== \"\") {\r\n queryHash += `destinations=${encodeURIComponent(destination.value)}&`;\r\n }\r\n // Cruise Line\r\n if (cruiseLines.value !== \"\") {\r\n queryHash += `cruiseLines=${encodeURIComponent(cruiseLines.value)}&`;\r\n }\r\n // Travel dates (they'll either both be populated or neither)\r\n const startDate = (document.getElementById(\"dp-start-date\") as HTMLInputElement).value;\r\n const endDate = (document.getElementById(\"dp-end-date\") as HTMLInputElement).value;\r\n\r\n if (startDate !== \"\" && endDate !== \"\") {\r\n queryHash += `startDate=${startDate}&endDate=${endDate}&`;\r\n }\r\n // Cruise length\r\n if (selectedLengths.value.length > 0) {\r\n queryHash += `lengths=${selectedLengths.value.join(\"|\")}&`;\r\n }\r\n // Cruise Type\r\n if (selectedCruiseTypes.value.length > 0) {\r\n queryHash += `cruiseTypes=${selectedCruiseTypes.value.join(\"|\")}&`;\r\n }\r\n // Virtuoso Exclusives\r\n if (selectedExclusives.value.length > 0) {\r\n queryHash += `virtuosoExclusives=${selectedExclusives.value.join(\"|\")}&`;\r\n }\r\n // Trim trailing ampersand\r\n if (queryHash.slice(-1) === \"&\") {\r\n queryHash = queryHash.slice(0, -1); \r\n }\r\n\r\n window.location.href = cobrandLink(`/travel/luxury-cruises/search${queryHash}`);\r\n }\r\n\r\n function selectCategory(acCategory: string, acValue: string): void {\r\n query.value = acValue;\r\n\r\n switch (acCategory) {\r\n case \"city\":\r\n omniboxCategorySearch = \"citySearch\";\r\n break;\r\n case \"country\":\r\n omniboxCategorySearch = \"countrySearch\";\r\n break;\r\n case \"cruise line name\":\r\n omniboxCategorySearch = \"companySearch\";\r\n break;\r\n case \"all fields\":\r\n omniboxCategorySearch = \"\";\r\n break;\r\n }\r\n\r\n trackOmniboxSearch(ProductType.CRUISES, acCategory, acValue);\r\n\r\n doSearch();\r\n }\r\n\r\n function toggleMoreFilters(): void {\r\n if (isMoreFiltersOpen.value) {\r\n slideUpWithFade(document.getElementById(\"more-filters-panel\"));\r\n } else {\r\n slideDownWithFade(document.getElementById(\"more-filters-panel\"));\r\n }\r\n isMoreFiltersOpen.value = !isMoreFiltersOpen.value;\r\n } \r\n</script>\r\n","<template>\r\n <div class=\"mt-3\" data-testid=\"hotel-search\">\r\n <div class=\"row\">\r\n <div class=\"col-12 col-md-9 col-lg-6 mb-3 mb-md-0\"> \r\n <AutocompleteInput v-model=\"query\" :show-icon=\"false\" :show-mobile-button=\"false\" :type=\"ProductType.HOTELS\" placeholder-text=\"Where do you want to go?\" @search=\"doSearch\" @select=\"selectCategory\" @clear=\"() => { query = '' }\" />\r\n </div>\r\n <div class=\"col-12 col-md-3 col-lg-2\">\r\n <button class=\"btn btn-primary-emphasis btn-sm w-100\" @click=\"doSearch()\">Search</button>\r\n </div>\r\n </div>\r\n <div class=\"row mt-1\">\r\n <div class=\"col-12 col-lg-2\">\r\n <button class=\"btn btn-xs btn-tertiary\" @click=\"toggleMoreFilters\"><i :class=\"(isMoreFiltersOpen) ? 'icon-angle-down-ut' : 'icon-angle-right-ut'\"></i> More filters</button>\r\n </div>\r\n <div id=\"more-filters-panel\" class=\"col-12 col-lg-10 text--small\">\r\n <div class=\"row\">\r\n <div class=\"col-12 col-md-4 col-lg-3 \">\r\n <span class=\"text-emphasis font-weight-bold\">Hotel Type</span>\r\n <ul class=\"list-unstyled mt-1\">\r\n <li v-for=\"(facet, facetIndex) in hotelTypeFacets\" :key=\"facetIndex\">\r\n <label>\r\n <input :id=\"'hotelTypes-' + facet\" :key=\"'hotelTypes-' + facet\" v-model=\"selectedHotelTypes\" type=\"checkbox\" :value=\"encodeURIComponent(facet)\"> {{ facet }}\r\n </label>\r\n </li>\r\n </ul>\r\n </div>\r\n <div class=\"col-12 col-md-8 col-lg-6\">\r\n <span class=\"text-emphasis font-weight-bold\">Experiences</span>\r\n <ul id=\"experiences-container\" class=\"list-unstyled mt-1\">\r\n <li v-for=\"(facet, facetIndex) in experienceFacets\" :key=\"facetIndex\">\r\n <label>\r\n <input :id=\"'experiences-' + facet\" :key=\"'experiences-' + facet\" v-model=\"selectedExperiences\" type=\"checkbox\" :value=\"encodeURIComponent(facet)\"> {{ facet }}\r\n </label>\r\n </li>\r\n </ul>\r\n </div>\r\n <div class=\"col-12 col-md-6 col-lg-3\">\r\n <span class=\"text-emphasis font-weight-bold\">Virtuoso Exclusives</span>\r\n <ul class=\"list-unstyled mt-1\">\r\n <li v-for=\"(facet, facetIndex) in exclusivesFacets\" :key=\"facetIndex\">\r\n <label>\r\n <input :id=\"'exclusives-' + facet\" :key=\"'exclusives-' + facet\" v-model=\"selectedExclusives\" type=\"checkbox\" :value=\"encodeURIComponent(facet)\"> {{ facet }}\r\n </label>\r\n </li>\r\n </ul>\r\n\r\n <span class=\"text-emphasis font-weight-bold mt-lg-1\">Virtuoso Sustainability</span>\r\n <ul class=\"list-unstyled mt-1\">\r\n <li v-for=\"(facet, facetIndex) in sustainabilityFacets\" :key=\"facetIndex\">\r\n <label>\r\n <input :id=\"'sustainability-' + facet\" :key=\"'sustainability-' + facet\" v-model=\"selectedSustainability\" type=\"checkbox\" :value=\"true\"> {{ facet }}\r\n </label>\r\n </li>\r\n </ul>\r\n </div>\r\n </div>\r\n <div class=\"row\">\r\n <div class=\"col-12 mt-1 d-lg-none\">\r\n <button class=\"btn btn-primary-emphasis btn-sm js-search-button w-100\" @click=\"doSearch()\">Search</button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"mt-2 text--small fw-bold d-none d-lg-block\">\r\n <a :href=\"b2bCatalogLink\">Find rates and availability here.</a>\r\n </div>\r\n </div>\r\n</template>\r\n\r\n\r\n<script setup lang=\"ts\">\r\n import AutocompleteInput from \"components/shared/autocomplete-input.vue\";\r\n import { facetsByProduct } from \"config/search-facet-data\";\r\n import { ProductType } from \"interfaces/enums\";\r\n import { ProductSearchConfig } from \"interfaces/product\";\r\n import { slideDownWithFade, slideUpWithFade } from \"services/helpers/html\";\r\n import { trackOmniboxSearch } from \"services/analytics\";\r\n import { cobrandLink } from \"virtuoso-shared-web-ui\";\r\n import { ref } from \"vue\";\r\n\r\n let omniboxCategorySearch = \"\";\r\n const catalogType: ProductType = ProductType.HOTELS;\r\n\r\n const b2bCatalogLink = cobrandLink(\"/hotels\"); \r\n const exclusivesFacets = ref(facetsByProduct[catalogType].find((category: ProductSearchConfig) => category.categoryName === \"virtuosoExclusives\")?.facets);\r\n const experienceFacets = ref(facetsByProduct[catalogType].find((category: ProductSearchConfig) => category.categoryName === \"experiences\")?.facets); \r\n const hotelTypeFacets = ref(facetsByProduct[catalogType].find((category: ProductSearchConfig) => category.categoryName === \"hotelTypes\")?.facets); \r\n const isMoreFiltersOpen = ref(false);\r\n const query = ref(\"\");\r\n const selectedExclusives = ref([]);\r\n const selectedExperiences = ref([]);\r\n const selectedHotelTypes = ref([]);\r\n const selectedSustainability = ref(null);\r\n const sustainabilityFacets = ref(facetsByProduct[catalogType].find((category: ProductSearchConfig) => category.categoryName === \"sustainability\")?.facets);\r\n\r\n function doSearch(): void {\r\n let queryHash = \"#\";\r\n // Omnibox Search\r\n if (omniboxCategorySearch !== \"\") {\r\n queryHash += `${encodeURIComponent(omniboxCategorySearch.trim())}=${encodeURIComponent(query.value.trim())}&`;\r\n }\r\n // Text query\r\n if (query.value.trim() !== \"\" && omniboxCategorySearch === \"\") {\r\n queryHash += `query=${encodeURIComponent(query.value.trim())}&sort=SearchRelevance&`;\r\n }\r\n // Virtuoso Exclusives\r\n if (selectedExclusives.value.length > 0) {\r\n queryHash += `virtuosoExclusives=${selectedExclusives.value.join(\"|\")}&`;\r\n }\r\n // Virtuoso Sustainability\r\n if (selectedSustainability.value) {\r\n queryHash += \"sustainability=true&\";\r\n }\r\n // Experiences\r\n if (selectedExperiences.value.length > 0) {\r\n queryHash += `experiences=${selectedExperiences.value.join(\"|\")}&`;\r\n }\r\n // Hotel Type\r\n if (selectedHotelTypes.value.length > 0) {\r\n queryHash += `hotelTypes=${selectedHotelTypes.value.join(\"|\")}&`;\r\n }\r\n\r\n window.location.href = cobrandLink(`/travel/luxury-hotels/search${queryHash}`);\r\n }\r\n\r\n function selectCategory(acCategory: string, acValue: string): void {\r\n query.value = acValue;\r\n\r\n switch (acCategory) {\r\n case \"city\":\r\n omniboxCategorySearch = \"citySearch\";\r\n break;\r\n case \"country\":\r\n omniboxCategorySearch = \"countrySearch\";\r\n break;\r\n case \"hotel name\":\r\n omniboxCategorySearch = \"companySearch\";\r\n break;\r\n case \"all fields\":\r\n omniboxCategorySearch = \"\";\r\n break;\r\n }\r\n\r\n trackOmniboxSearch(ProductType.HOTELS, acCategory, acValue);\r\n\r\n doSearch();\r\n }\r\n\r\n function toggleMoreFilters(): void {\r\n if (isMoreFiltersOpen.value) {\r\n slideUpWithFade(document.getElementById(\"more-filters-panel\"));\r\n } else {\r\n slideDownWithFade(document.getElementById(\"more-filters-panel\"));\r\n }\r\n isMoreFiltersOpen.value = !isMoreFiltersOpen.value;\r\n } \r\n</script>\r\n","<template>\r\n <div class=\"mt-3\" data-testid=\"tour-search\">\r\n <div class=\"row\">\r\n <div class=\"-query-container col-12 col-lg-3\">\r\n <AutocompleteInput v-model=\"query\" :show-icon=\"false\" :show-mobile-button=\"false\" :type=\"ProductType.TOURS\" placeholder-text=\"Keyword\" @search=\"doSearch\" @select=\"selectCategory\" @clear=\"() => { query = '' }\" />\r\n </div>\r\n <div class=\"col-12 col-lg-3 mt-1 mt-lg-0\">\r\n <label class=\"select--styled mb-0\">\r\n <select v-model=\"destination\" name=\"destination\" aria-label=\"destination\">\r\n <option value=\"\">Any Destination</option>\r\n <option>Africa</option>\r\n <option>Antarctica</option>\r\n <option>Asia</option>\r\n <option>Caribbean</option>\r\n <option>Central America</option>\r\n <option>Europe</option>\r\n <option>Middle East</option>\r\n <option>North America</option>\r\n <option>South America</option>\r\n <option>South Pacific</option>\r\n </select>\r\n </label>\r\n </div>\r\n <div class=\"col-12 col-lg-4 mt-1 mt-lg-0\">\r\n <date-picker-component id=\"filter-dates\" placeholder-text=\"Travel Dates\"></date-picker-component>\r\n </div>\r\n <div class=\"col-12 col-lg-2 mt-0 d-none d-lg-block\">\r\n <button class=\"btn btn-primary-emphasis btn-sm js-search-button w-100\" @click=\"doSearch\">Search</button>\r\n </div>\r\n </div>\r\n <div class=\"row mt-1\">\r\n <div class=\"col-12 col-lg-2\">\r\n <button class=\"btn btn-xs btn-tertiary\" @click=\"toggleMoreFilters\"><i :class=\"(isMoreFiltersOpen) ? 'icon-angle-down-ut' : 'icon-angle-right-ut'\"></i> More filters</button>\r\n </div>\r\n <div id=\"more-filters-panel\" class=\"col-12 col-lg-10 text--small\">\r\n <div class=\"row\">\r\n <div class=\"col-12 col-md-4 col-lg-3 col-xl-2\">\r\n <span class=\"text-emphasis font-weight-bold\">Duration</span>\r\n <ul class=\"list-unstyled mt-1\">\r\n <li v-for=\"(facet, facetIndex) in durationFacets\" :key=\"facetIndex\">\r\n <label>\r\n <input :id=\"'lengths-' + facet\" :key=\"'lengths-' + facet\" v-model=\"selectedLengths\" type=\"checkbox\" :value=\"encodeURIComponent(facet)\"> {{ facet }}\r\n </label>\r\n </li>\r\n </ul>\r\n </div>\r\n <div class=\"col-12 col-md-8 col-lg-9\">\r\n <span class=\"text-emphasis font-weight-bold\">Experiences</span>\r\n <ul id=\"experiences-container\" class=\"list-unstyled mt-1\">\r\n <li v-for=\"(facet, facetIndex) in experienceFacets\" :key=\"facetIndex\">\r\n <label>\r\n <input :id=\"'experiences-' + facet\" :key=\"'experiences-' + facet\" v-model=\"selectedExperiences\" type=\"checkbox\" :value=\"encodeURIComponent(facet)\"> {{ facet }}\r\n </label>\r\n </li>\r\n </ul>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"col-12 mt-1 d-lg-none\">\r\n <button class=\"btn btn-primary-emphasis btn-sm js-search-button w-100\" @click=\"doSearch\">Search</button>\r\n </div>\r\n </div>\r\n <div class=\"mt-2 text--small fw-bold d-none d-lg-block\">\r\n <a :href=\"b2bCatalogLink\" v-html=\"legacyLinkText\"></a>\r\n </div>\r\n </div>\r\n</template>\r\n\r\n\r\n<script setup lang=\"ts\">\r\n import AutocompleteInput from \"components/shared/autocomplete-input.vue\";\r\n import DatePickerComponent from \"components/shared/date-picker.vue\";\r\n import { facetsByProduct } from \"config/search-facet-data\";\r\n import { ProductType } from \"interfaces/enums\";\r\n import { BoxLink } from \"interfaces/link\";\r\n import { ProductSearchConfig } from \"interfaces/product\";\r\n import { isSupplier } from \"services/auth/user-info\";\r\n import { slideDownWithFade, slideUpWithFade } from \"services/helpers/html\";\r\n import { trackOmniboxSearch } from \"services/analytics\";\r\n import { cobrandLink } from \"virtuoso-shared-web-ui\";\r\n import { PropType, ref } from \"vue\";\r\n\r\n let omniboxCategorySearch = \"\";\r\n\r\n defineProps({\r\n brands: {\r\n type: Array as PropType<BoxLink[]>,\r\n default: undefined\r\n }\r\n });\r\n\r\n const b2bCatalogLink = cobrandLink(\"/tours\");\r\n const durationFacets = ref(facetsByProduct[ProductType.TOURS].find((category: ProductSearchConfig) => category.categoryName === \"travelLengths\")?.facets);\r\n const destination = ref(\"\");\r\n const experienceFacets = ref(facetsByProduct[ProductType.TOURS].find((category: ProductSearchConfig) => category.categoryName === \"experiences\")?.facets);\r\n const isMoreFiltersOpen = ref(false);\r\n const legacyLinkText = `For ${(isSupplier()) ? \"Partners\" : \"Advisors\"}: Advanced Search`;\r\n const query = ref(\"\");\r\n const selectedLengths = ref([]);\r\n const selectedExperiences = ref([]);\r\n\r\n function doSearch(): void {\r\n let queryHash = \"#\";\r\n\r\n // Omnibox Search\r\n if (omniboxCategorySearch !== \"\") {\r\n queryHash += `${encodeURIComponent(omniboxCategorySearch.trim())}=${encodeURIComponent(query.value.trim())}&`;\r\n }\r\n\r\n // Text query\r\n if (query.value.trim() !== \"\" && omniboxCategorySearch === \"\") {\r\n queryHash += `query=${encodeURIComponent(query.value.trim())}&sort=SearchRelevance&`;\r\n }\r\n\r\n // Destination\r\n if (destination.value !== \"\") {\r\n queryHash += `destinations=${encodeURIComponent(destination.value)}&`;\r\n }\r\n\r\n // Travel dates (they'll either both be populated or neither)\r\n const startDate = (document.getElementById(\"dp-start-date\") as HTMLInputElement).value;\r\n const endDate = (document.getElementById(\"dp-end-date\") as HTMLInputElement).value;\r\n\r\n if (startDate !== \"\" && endDate !== \"\") {\r\n queryHash += `startDate=${startDate}&endDate=${endDate}&`;\r\n }\r\n\r\n // Tour length\r\n if (selectedLengths.value.length > 0) {\r\n queryHash += `travelLengths=${selectedLengths.value.join(\"|\")}&`;\r\n }\r\n\r\n // Experiences\r\n if (selectedExperiences.value.length > 0) {\r\n queryHash += `experiences=${selectedExperiences.value.join(\"|\")}&`;\r\n }\r\n if (queryHash.slice(-1) === \"&\") {\r\n queryHash = queryHash.slice(0, -1); // Trim trailing ampersand\r\n }\r\n\r\n window.location.href = cobrandLink(`/travel/luxury-tours/search${queryHash}`);\r\n }\r\n\r\n function selectCategory(acCategory: string, acValue: string): void {\r\n query.value = acValue;\r\n\r\n switch (acCategory) {\r\n case \"city\":\r\n omniboxCategorySearch = \"citySearch\";\r\n break;\r\n case \"country\":\r\n omniboxCategorySearch = \"countrySearch\";\r\n break;\r\n case \"company name\":\r\n omniboxCategorySearch = \"companySearch\";\r\n break;\r\n case \"all fields\":\r\n omniboxCategorySearch = \"\";\r\n break;\r\n }\r\n\r\n trackOmniboxSearch(ProductType.TOURS, acCategory, acValue);\r\n\r\n doSearch();\r\n }\r\n\r\n function toggleMoreFilters(): void {\r\n if (isMoreFiltersOpen.value) {\r\n slideUpWithFade(document.getElementById(\"more-filters-panel\"));\r\n } else {\r\n slideDownWithFade(document.getElementById(\"more-filters-panel\"));\r\n }\r\n isMoreFiltersOpen.value = !isMoreFiltersOpen.value;\r\n }\r\n</script>\r\n","<template>\r\n <CarouselSliderComponent\r\n carousel-class=\"extra-wide sponsored-product-carousel\"\r\n :carousel-config=\"carouselConfig\"\r\n :should-enable-hearts=\"true\"\r\n :slides=\"slides\"\r\n @ready=\"() => logAdView(0)\"\r\n @moved=\"(currentSlideIndex: number) => logAdView(currentSlideIndex)\">\r\n <template #slides=\"{index, slide, instance}\"> \r\n <div class=\"slide\">\r\n <button v-if=\"slide.identifier && slide.heartType\"\r\n title=\"Save to WanderList\"\r\n class=\"wl-heartable -top-right d-lg-none\"\r\n :data-wl-type=\"slide.heartType\"\r\n :data-wl-id=\"slide.identifier\"\r\n :data-wl-title=\"slide.title\"></button>\r\n <button v-if=\"slide.identifier && slide.heartType\"\r\n title=\"Save to WanderList\"\r\n class=\"wl-heartable -save-this -top-right d-none d-lg-block\"\r\n :data-wl-type=\"slide.heartType\"\r\n :data-wl-id=\"slide.identifier\"\r\n :data-wl-title=\"slide.title\"></button>\r\n <a :href=\"slide.url\">\r\n <div class=\"title-block\">\r\n <div v-if=\"slide.slideType === 'hotel'\"\r\n class=\"-bob\">\r\n <div class=\"-boblogo\">\r\n <img src=\"https://virtuoso-prod.dotcms.cloud/images/products/bob-logo-gray.svg\"\r\n alt=\"Virtuoso Best of the Best logo\"\r\n title=\"Virtuoso Best of the Best\"\r\n class=\"d-lg-none\" />\r\n <img src=\"https://virtuoso-prod.dotcms.cloud/images/products/bob-logo.svg\"\r\n alt=\"Virtuoso Best of the Best logo\"\r\n title=\"Virtuoso Best of the Best\"\r\n class=\"d-none d-lg-block\" />\r\n </div>\r\n <div :class=\"['-name', slide.title?.length > 30 ? '-long' : '']\">\r\n <div v-html=\"slide.title\"></div>\r\n </div>\r\n </div>\r\n <div v-else-if=\"isArticleDestinationSlideType(slide.slideType)\"\r\n class=\"-featured\">\r\n <div>\r\n <span v-if=\"slide.slideType === 'article' && slide.sponsoredText\"\r\n class=\"-sponsored-flag\"\r\n v-html=\"slide.sponsoredText\"></span>\r\n </div>\r\n <div class=\"d-none d-lg-block -type\"\r\n v-html=\"getSlideTabText(slide.slideType, slide.title)\"></div>\r\n <div :class=\"['-headline', slide.title?.length > 50 ? '-long' : '']\"\r\n v-html=\"slide.title\"></div>\r\n </div>\r\n <template v-else>\r\n <div v-if=\"slide.logoUrl\" class=\"-logo\">\r\n <img :src=\"slide.logoUrl\" alt=\"Logo\" />\r\n </div>\r\n </template>\r\n </div>\r\n <img :src=\"slide.imageUrl\" :class=\"['img-fit--cover', getImageCropFocusClass(slide.imageCropFocus)]\" :alt=\"slide.title\" width=\"100%\" />\r\n <div class=\"-nav context-dark weglot-exclude\">\r\n <div v-for=\"(allSlides, allIndex) in slides\"\r\n :key=\"allIndex\"\r\n :class=\"['-title d-none d-lg-block text-decoration-none', allIndex === index ? '-current' : '']\"\r\n @click.prevent.stop=\"instance.go(allIndex)\">\r\n <span v-html=\"getSlideTabText(allSlides.slideType, allSlides.title)\"></span>\r\n </div>\r\n <div v-if=\"isArticleDestinationSlideType(slide.slideType)\" class=\"-title d-lg-none\" v-html=\"getSlideTabText(slide.slideType, slide.title)\"></div>\r\n </div>\r\n </a>\r\n </div>\r\n </template>\r\n </CarouselSliderComponent>\r\n</template>\r\n\r\n<script setup lang=\"ts\">\r\n import { Options } from \"@splidejs/vue-splide\";\r\n import CarouselSliderComponent from \"components/shared/carousel-slider.vue\";\r\n import { CarouselSlideType } from \"interfaces/types/app-types\";\r\n import { CarouselSlide } from \"interfaces/carousel\";\r\n import { getImageCropFocusClass } from \"services/helpers/images\";\r\n import { shuffleInPlace } from \"services/helpers/sort-helpers\";\r\n import { PropType } from \"vue\";\r\n\r\n const props = defineProps({\r\n randomize: {\r\n type: Boolean,\r\n default: false\r\n },\r\n slides: {\r\n type: Array as PropType<CarouselSlide[]>,\r\n default: undefined\r\n }\r\n });\r\n\r\n const slideAdViewTracker = new Set<number>();\r\n const carouselConfig: Options = {\r\n arrows: false,\r\n autoplay: true,\r\n autoplaySpeed: 5000,\r\n pagination: false,\r\n type: \"fade\",\r\n rewind: true,\r\n breakpoints: \r\n {\r\n 992: {\r\n pagination: true\r\n }\r\n }\r\n };\r\n\r\n const isArticleDestinationSlideType = (slideType: CarouselSlideType): boolean => { return slideType === \"article\" || slideType === \"destination\"; };\r\n\r\n function getSlideTabText(slideType: CarouselSlideType, slideTitle: string): string {\r\n let featuredSlideTitle = slideTitle;\r\n\r\n if (slideType === \"article\") {\r\n featuredSlideTitle = \"Featured Article\";\r\n } else if (slideType === \"destination\") {\r\n featuredSlideTitle = \"Featured Destination\";\r\n }\r\n return featuredSlideTitle;\r\n };\r\n\r\n function logAdView(slideIndex: number): void {\r\n const slide = props.slides[slideIndex];\r\n\r\n if (slide.broadstreetAdId && !slideAdViewTracker.has(slideIndex)) {\r\n const campaignSuffix = slide.broadstreetCampaignId ? `/c${slide.broadstreetCampaignId}` : \"\";\r\n const bsaImg = document.createElement(\"img\");\r\n\r\n bsaImg.src = `https://ad.broadstreetads.com/display/${slide.broadstreetAdId}${campaignSuffix}?ts=${Date.now()}`;\r\n bsaImg.style.display = \"none\";\r\n document.body.appendChild(bsaImg);\r\n slideAdViewTracker.add(slideIndex); // Mark slide as seen\r\n }\r\n };\r\n\r\n if (props.randomize) {\r\n shuffleInPlace(props.slides);\r\n }\r\n</script>\r\n","<template>\r\n <div v-if=\"isReady\">\r\n <CarouselSponsoredProductsComponent v-if=\"sponsoredProductSlides && sponsoredProductSlides.length\" :slides=\"sponsoredProductSlides\" :randomize=\"content.sponsoredProductSlidesRandomize\"></CarouselSponsoredProductsComponent>\r\n\r\n <div class=\"extra-wide\">\r\n <div class=\"slab py-3 py-lg-6 mt-0 mb-6\">\r\n <div class=\"container px-lg-0 text-18\">\r\n <html-blob-component v-if=\"htmlBlobContent.length && htmlBlobContent[0].content && htmlBlobContent[0].content[0].content\" :html=\"htmlBlobContent[0].content[0].content\"></html-blob-component>\r\n <component :is=\"componentMap[searchComponent]\" v-if=\"componentMap[searchComponent]\" :brands=\"brands\"></component>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <section v-if=\"themedArticles.length\" class=\"container px-lg-0 pb-0 my-4\">\r\n <h2 class=\"text--serif mb-2\" v-html=\"themedArticlesHeader\"></h2>\r\n <content-tiles-component :content-tiles=\"themedArticles\" :layout-class=\"(themedArticles.length % 3 === 0) ? '-tall -featured -threecols' : '-tall -featured -twocols'\" :lazy-load=\"true\"></content-tiles-component>\r\n </section>\r\n\r\n <div class=\"slab py-6 mb-6\">\r\n <div v-if=\"htmlBlobContent.length && htmlBlobContent[1].content\" class=\"container px-lg-0\">\r\n <html-blob-component v-for=\"(blob, index) in htmlBlobContent[1].content\" :key=\"index\" :html=\"blob.content\"></html-blob-component>\r\n </div>\r\n </div>\r\n\r\n <section v-if=\"brandsWithExtras.length\" class=\"container px-lg-0 pb-0 my-4\" data-testid=\"brand-extra-links\">\r\n <h2 class=\"text--serif mb-2\" v-html=\"brandsHeader\"></h2>\r\n <box-links-component class=\"text-links-grid -compact weglot-exclude\" :content=\"brandsWithExtras\" link-class=\"-neutral\" @box-link-click=\"trackingBoxLinkBrowseClickHandler\"></box-links-component>\r\n </section>\r\n\r\n <div class=\"ad-zone\">\r\n <broadstreet-zone zone-id=\"82344\"></broadstreet-zone>\r\n </div>\r\n\r\n <section v-if=\"categoryCards.length || buttonLinks.length\" class=\"container px-lg-0 pb-0 my-4\">\r\n <h2 class=\"text--serif mb-2\" v-html=\"categoryCardsHeader\"></h2>\r\n <feature-cards-component v-if=\"categoryCards.length\" class=\"destination-catalogs\" :content=\"categoryCards\" :page-name=\"pageName\" @feature-card-click=\"trackFeatureCardBrowseClickHandler\"></feature-cards-component>\r\n <box-links-component v-if=\"buttonLinks.length\" :class=\"['text-links-grid', (buttonLinks.length < 3) ? '-two-cols' : '']\" :content=\"buttonLinks\" link-class=\"-neutral\" @box-link-click=\"trackingBoxLinkBrowseClickHandler\"></box-links-component>\r\n </section>\r\n\r\n <div class=\"ad-zone\">\r\n <broadstreet-zone zone-id=\"78463\"></broadstreet-zone>\r\n </div>\r\n\r\n <section class=\"my-4\">\r\n <div class=\"container px-lg-0\">\r\n <article-cards-component :articles-per-page=\"3\" :event-start-index=\"4\" :header-text=\"content.featuredArticlesHeader\" :initial-cards=\"content.featuredArticles\" :lazy-load=\"true\" :page-name=\"pageName\" :search-criteria=\"content.articleSearchCriteria\" :show-more=\"true\"></article-cards-component>\r\n </div>\r\n </section>\r\n\r\n <section v-if=\"content.realTravelerStoriesCarouselContent && content.realTravelerStoriesCarouselContent.slides && content.realTravelerStoriesCarouselContent.slides.length > 1\" :id=\"'rts-carousel-' + Date.now()\" :class=\"['py-0 my-3', content.realTravelerStoriesContainerClasses]\">\r\n <real-traveler-stories-carousel-component :content=\"content.realTravelerStoriesCarouselContent\"></real-traveler-stories-carousel-component>\r\n </section>\r\n <find-an-advisor-cta-component v-else></find-an-advisor-cta-component>\r\n\r\n <section v-if=\"content.featuredDestinations.length\" class=\"container px-lg-0 pb-0 my-4\">\r\n <h2 class=\"text--serif mb-2\" v-html=\"content.featuredDestinationsHeader\"></h2>\r\n <feature-cards-component class=\"featured-destinations\" :content=\"content.featuredDestinations\" @feature-card-clicked=\"trackFeatureCardDestination\"></feature-cards-component>\r\n </section>\r\n\r\n <product-cards-component v-if=\"content.productCardCollection.productCards.length\" id=\"featured-products\" :content=\"content.productCardCollection\" class=\"py-6\"></product-cards-component>\r\n </div>\r\n <LogoSplash v-else />\r\n</template>\r\n\r\n\r\n<script setup lang=\"ts\">\r\n import SearchFormCruisesComponent from \"components/products/search/search-form-cruises.vue\";\r\n import SearchFormHotelsComponent from \"components/products/search/search-form-hotels.vue\";\r\n import SearchFormToursComponent from \"components/products/search/search-form-tours.vue\";\r\n import FindAnAdvisorCtaComponent from \"components/advisor/find-an-advisor-cta.vue\";\r\n import ArticleCardsComponent from \"components/article/article-cards.vue\";\r\n import ProductCardsComponent from \"components/products/product-cards.vue\";\r\n import BoxLinksComponent from \"components/shared/box-links.vue\";\r\n import CarouselSponsoredProductsComponent from \"components/shared/carousel-sponsored-products.vue\";\r\n import ContentTilesComponent from \"components/shared/content-tiles.vue\";\r\n import FeatureCardsComponent from \"components/shared/feature-cards.vue\";\r\n import HtmlBlobComponent from \"components/shared/html-blob-allow-side-effects.vue\";\r\n import LogoSplash from \"components/shared/logo-splash.vue\";\r\n import RealTravelerStoriesCarouselComponent from \"components/shared/real-traveler-stories-carousel.vue\";\r\n import { tourBrandSupplierTypesRestricted } from \"config/collections\";\r\n import { DotCMSBasicArticleResponse, DotCMSDestinationsResponse, DotCMSProductLandingPageResponse, DotCMSRealTravelerStories } from \"interfaces/responses/dotcms-responses\";\r\n import { BrandsResponse } from \"interfaces/responses/product-detail-responses\";\r\n import { ContentTile, FeatureCard, ProductCardSearchResult } from \"interfaces/card\";\r\n import { CarouselSlide } from \"interfaces/carousel\";\r\n import { CmsPage, CmsPageContainer } from \"interfaces/cms\";\r\n import { ProductType } from \"interfaces/enums\";\r\n import { BoxLink } from \"interfaces/link\";\r\n import { ProductBrandsRequestPayload, ProductLandingPageContent } from \"interfaces/product\";\r\n import { getLandingPageJSON, getProductBrands, getProductLandingJSON } from \"services/api/products\";\r\n import { transformDotCMSPageContainers } from \"services/cms/cms\";\r\n import { buildDestinationPageURL } from \"services/helpers/destinations\";\r\n import { generateCmsImageUrl } from \"services/helpers/images\";\r\n import { toastError } from \"services/helpers/toasts\";\r\n import { transformCmsBasicArticleToArticleCard, transformCmsBasicArticleToContentTile } from \"services/transformers/article\";\r\n import { transformCmsFeatureCarouselSlideToCarouselSlide, transformRTSCarouselContent } from \"services/transformers/content-transformers\";\r\n import { trackEvent } from \"services/analytics\";\r\n import { getSponsoredAndRandomProducts, getViewAllLabel } from \"services/product-cards\";\r\n import * as virtuosoSharedHeader from \"virtuoso-shared-web-ui\";\r\n import type { Component } from \"vue\";\r\n import { nextTick, ref, watch } from \"vue\";\r\n\r\n const qsParams = virtuosoSharedHeader.parseURLParameters();\r\n const isReady = ref(false);\r\n\r\n const brands = ref<BoxLink[]>([] as BoxLink[]);\r\n const brandsWithExtras = ref<BoxLink[]>([] as BoxLink[]);\r\n const brandsHeader = ref(\"\");\r\n const category = window.VIRTUOSO.productType;\r\n const content = ref<ProductLandingPageContent>({} as ProductLandingPageContent);\r\n const pageName = ref(\"\");\r\n const searchComponent = ref(\"\");\r\n const sponsoredProductSlides = ref<CarouselSlide[]>([] as CarouselSlide[]);\r\n const htmlBlobContent = ref<CmsPageContainer<CmsPageContainer<string>[]>[]>([] as CmsPageContainer<CmsPageContainer<string>[]>[]);\r\n const customCompanies = ref<BoxLink[]>([] as BoxLink[]);\r\n const themedArticlesHeader = ref(\"\");\r\n const themedArticles = ref<ContentTile[]>([] as ContentTile[]);\r\n const categoryCardsHeader = ref(\"\");\r\n const categoryCards = ref<FeatureCard[]>([] as FeatureCard[]);\r\n const buttonLinks = ref<BoxLink[]>([] as BoxLink[]);\r\n const brandTrackMEIDs = ref<BrandsResponse[]>([] as BrandsResponse[]);\r\n // methods\r\n const populateBrands = (productType: ProductType, brandBaseUrl: string, postParams?: ProductBrandsRequestPayload): void => {\r\n getProductBrands(productType, postParams).then((result: BrandsResponse[]) => {\r\n if (result && result.length) {\r\n brandTrackMEIDs.value = result;\r\n result.forEach((obj: BrandsResponse) => {\r\n (brands.value as BoxLink[]).push({\r\n name: obj.supplierName,\r\n url: virtuosoSharedHeader.cobrandLink(`${brandBaseUrl}${obj.supplierId}/${virtuosoSharedHeader.slugify(obj.supplierName)}`)\r\n });\r\n });\r\n }\r\n\r\n (brands.value).sort((a, b) => a.name.toUpperCase().localeCompare(b.name.toUpperCase()));\r\n\r\n // Add extra brands from dotCMS, if present\r\n // Note that we don't want to display only the dotCMS ones if the main call failed,\r\n // which is why this lives in this block\r\n brandsWithExtras.value = [...brands.value];\r\n if (customCompanies.value) { // Any extras from dotCMS\r\n customCompanies.value.forEach((item: BoxLink) => {\r\n (brandsWithExtras.value as BoxLink[]).push({\r\n name: item.name,\r\n url: item.url\r\n });\r\n });\r\n\r\n (brandsWithExtras.value).sort((a, b) => a.name.toUpperCase().localeCompare(b.name.toUpperCase()));\r\n }\r\n\r\n }, () => {\r\n // If this dies, we don't need to do anything additional\r\n });\r\n };\r\n\r\n // Map of component names to actual components\r\n const componentMap: Record<string, Component> = {\r\n \"search-form-cruises-component\": SearchFormCruisesComponent,\r\n \"search-form-hotels-component\": SearchFormHotelsComponent,\r\n \"search-form-tours-component\": SearchFormToursComponent\r\n };\r\n\r\n const trackingBoxLinkBrowseClickHandler = (boxlink: BoxLink): void => {\r\n const shouldTrackMEID = (category === \"cruises\" || category === \"tours\");\r\n const brandMeid = brandTrackMEIDs.value.find((brand) => brand.supplierName === boxlink.name);\r\n const trackedMEID = (brandMeid && brandMeid.supplierId) ? brandMeid.supplierId : \"\";\r\n\r\n trackEvent(\"browse_click\", {\r\n item_name: boxlink.name,\r\n item_category: category,\r\n item_variant: \"text\",\r\n ...(shouldTrackMEID && { item_id: trackedMEID })\r\n });\r\n };\r\n const trackFeatureCardBrowseClickHandler = (featuredCard: FeatureCard): void => {\r\n trackEvent(\"browse_click\", {\r\n item_name: featuredCard.name,\r\n item_category: category,\r\n item_variant: \"image\",\r\n item_id: \"\"\r\n });\r\n };\r\n const trackFeatureCardDestination = (featuredCard: FeatureCard): void => {\r\n trackEvent(\"select_item\", {\r\n item_id: featuredCard.url,\r\n item_name: featuredCard.name,\r\n item_category: \"Destination\"\r\n });\r\n };\r\n // logic\r\n if (category) {\r\n // logic - entryPoint\r\n let cmsPage: CmsPage = {\r\n containers: [],\r\n title: \"\"\r\n };\r\n getLandingPageJSON(category).then(async (landingPageJSON) => {\r\n if (landingPageJSON.entity && landingPageJSON.entity.containers) {\r\n cmsPage = transformDotCMSPageContainers(landingPageJSON);\r\n } else {\r\n console.error(\"Error retrieving data, no containers found: \", landingPageJSON);\r\n }\r\n\r\n // ######### Render Mounted Logic\r\n pageName.value = `${category} Landing Page`;\r\n searchComponent.value = `search-form-${category}-component`;\r\n if (category === ProductType.CRUISES) {\r\n\r\n brandsHeader.value = \"Browse Cruise Lines\";\r\n populateBrands(category, \"/travel/luxury-cruises/cruise-lines/\");\r\n\r\n } else if (category === ProductType.TOURS) {\r\n\r\n brandsHeader.value = \"Browse Tour Operators\";\r\n populateBrands(category, \"/travel/luxury-tours/tour-operators/\", {\r\n supplierTypes: tourBrandSupplierTypesRestricted\r\n });\r\n\r\n }\r\n // Initialize and populate the content objects\r\n\r\n content.value.productType = category;\r\n htmlBlobContent.value = (cmsPage.containers).filter((container) => container.friendlyName === \"html-blob\") as CmsPageContainer<CmsPageContainer<string>[]>[];\r\n\r\n content.value.featuredArticlesHeader = \"More Stories\";\r\n content.value.featuredArticles = [];\r\n content.value.articleSearchCriteria = {\r\n contentTypes: [\"ConsumerArticleBasic\"],\r\n queryClauses: [\r\n `+(categories:${category})`\r\n ],\r\n sort: \"ConsumerArticleBasic.publish desc\"\r\n };\r\n\r\n content.value.productCardCollection = {\r\n productCards: [],\r\n productType: category\r\n };\r\n\r\n const realTravelerStoriesContainers: CmsPageContainer<DotCMSRealTravelerStories[]>[] = (cmsPage.containers).filter((container) => container.friendlyName === \"real-traveler-stories-carousel\") as CmsPageContainer<DotCMSRealTravelerStories[]>[];\r\n content.value.realTravelerStoriesContainerClasses = \"\";\r\n content.value.featuredDestinationsHeader = \"More Stories\";\r\n content.value.featuredDestinations = [];\r\n\r\n // Get the associated content for this product type -- has to be a separate call because of the related content\r\n const productLandingPageContent: CmsPageContainer<ProductLandingPageContent[]>[] = (cmsPage.containers).filter((container) => container.friendlyName === \"product-landing-page\") as CmsPageContainer<ProductLandingPageContent[]>[];\r\n\r\n if (productLandingPageContent.length && productLandingPageContent[0].content?.length && productLandingPageContent[0].content[0].identifier) {\r\n\r\n getProductLandingJSON(productLandingPageContent[0].content[0].identifier).then((productLandingJSON) => {\r\n if (productLandingJSON && productLandingJSON.contentlets?.length > 0) {\r\n\r\n const productLandingContent: DotCMSProductLandingPageResponse = productLandingJSON.contentlets[0];\r\n\r\n // Sponsored products carousel\r\n if (productLandingContent.sponsoredCarouselSlides?.length > 0) {\r\n productLandingContent.sponsoredCarouselSlides.forEach((slide) => {\r\n const transformedSlide = transformCmsFeatureCarouselSlideToCarouselSlide(slide);\r\n if (transformedSlide) {\r\n sponsoredProductSlides.value.push(transformedSlide);\r\n }\r\n });\r\n }\r\n\r\n content.value.sponsoredProductSlidesRandomize = (productLandingContent.slideOrder === \"random\") ? true : false;\r\n\r\n\r\n // Themed articles\r\n if (productLandingContent.themedArticles?.length > 0) {\r\n themedArticlesHeader.value = productLandingContent.themedArticlesHeader;\r\n\r\n (productLandingContent.themedArticles).forEach((article: DotCMSBasicArticleResponse) => {\r\n themedArticles.value.push(transformCmsBasicArticleToContentTile(article));\r\n });\r\n }\r\n\r\n\r\n // Category Cards\r\n categoryCardsHeader.value = productLandingContent.categoryCardsHeader;\r\n\r\n for (let i = 1; i < 5; i++) { \r\n const categoryCardImage = productLandingContent[`categoryCard${i}Image` as keyof DotCMSProductLandingPageResponse] as string;\r\n const categoryCardLink = productLandingContent[`categoryCard${i}Link` as keyof DotCMSProductLandingPageResponse] as string;\r\n const categoryCardText = productLandingContent[`categoryCard${i}Text` as keyof DotCMSProductLandingPageResponse] as string; \r\n\r\n if (categoryCardImage && categoryCardText && categoryCardLink) {\r\n categoryCards.value.push({\r\n imageUrl: generateCmsImageUrl(categoryCardImage),\r\n name: categoryCardText,\r\n url: virtuosoSharedHeader.cobrandLink(categoryCardLink)\r\n });\r\n }\r\n }\r\n\r\n\r\n // Content Button links\r\n for (let linkIndex = 1; linkIndex <= 4; linkIndex++) {\r\n const categoryButtonLink = productLandingContent[`categoryButton${linkIndex}Link` as keyof DotCMSProductLandingPageResponse] as string;\r\n const categoryButtonText = productLandingContent[`categoryButton${linkIndex}Text` as keyof DotCMSProductLandingPageResponse] as string;\r\n\r\n if (categoryButtonText && categoryButtonLink) {\r\n buttonLinks.value.push({\r\n name: categoryButtonText,\r\n url: virtuosoSharedHeader.cobrandLink(categoryButtonLink)\r\n });\r\n }\r\n }\r\n\r\n\r\n // Featured Articles\r\n if (productLandingContent.featuredArticlesHeader && productLandingContent.featuredArticlesHeader !== \"\") {\r\n content.value.featuredArticlesHeader = productLandingContent.featuredArticlesHeader;\r\n }\r\n\r\n if (productLandingContent.featuredArticles && productLandingContent.featuredArticles.length) {\r\n (productLandingContent.featuredArticles).forEach((article: DotCMSBasicArticleResponse) => {\r\n content.value.featuredArticles.push(transformCmsBasicArticleToArticleCard(article));\r\n });\r\n }\r\n\r\n\r\n // Real Traveler Stories Carousel\r\n if (realTravelerStoriesContainers.length && realTravelerStoriesContainers[0].content?.length) {\r\n content.value.realTravelerStoriesCarouselContent = transformRTSCarouselContent(realTravelerStoriesContainers[0].content[0]);\r\n content.value.realTravelerStoriesContainerClasses = realTravelerStoriesContainers[0].containerClasses;\r\n }\r\n\r\n\r\n // Featured Destinations\r\n // TODO: Only populate if there are exactly 5???\r\n if (productLandingContent.featuredDestinationsHeader && productLandingContent.featuredDestinationsHeader !== \"\") {\r\n content.value.featuredDestinationsHeader = productLandingContent.featuredDestinationsHeader;\r\n }\r\n\r\n (productLandingContent.featuredDestinations).forEach((featuredDest: DotCMSDestinationsResponse) => {\r\n content.value.featuredDestinations.push({\r\n imageUrl: generateCmsImageUrl(featuredDest.gridImage),\r\n url: buildDestinationPageURL(featuredDest.destinationTag, featuredDest.isArbitraryDestination),\r\n name: featuredDest.title\r\n });\r\n });\r\n\r\n\r\n // Custom companies (for brand link grid)\r\n if (productLandingContent.customCompanies) {\r\n const customCompany = productLandingContent.customCompanies.split(\"|\");\r\n customCompany.forEach((company) => {\r\n const companyFields = company.split(\"~\");\r\n if (companyFields.length === 2) {\r\n customCompanies.value.push({\r\n name: companyFields[0],\r\n url: virtuosoSharedHeader.cobrandLink((category === ProductType.CRUISES)\r\n ? \"/travel/luxury-cruises/cruise-lines/\"\r\n : \"/travel/luxury-tours/tour-operators/\")\r\n + `${companyFields[1]}/${virtuosoSharedHeader.slugify(companyFields[0])}`\r\n });\r\n }\r\n });\r\n }\r\n\r\n\r\n // Product cards -- sponsored + random\r\n if (category === ProductType.CRUISES) {\r\n content.value.productCardCollection.header = \"Set Sail: Virtuoso Cruises\";\r\n content.value.productCardCollection.viewAllLink = virtuosoSharedHeader.cobrandLink(\"/travel/luxury-cruises/search\");\r\n content.value.productCardCollection.viewAllText = \"See More Cruises\";\r\n } else if (category === ProductType.TOURS) {\r\n content.value.productCardCollection.header = \"Let’s Go: Virtuoso Tours & Experiences\";\r\n content.value.productCardCollection.viewAllLink = virtuosoSharedHeader.cobrandLink(\"/travel/luxury-tours/search\");\r\n content.value.productCardCollection.viewAllText = \"See More Tours & Experiences\";\r\n } else { // Hotels\r\n content.value.productCardCollection.header = \"Check In: Virtuoso Hotels\";\r\n content.value.productCardCollection.viewAllLink = virtuosoSharedHeader.cobrandLink(\"/travel/luxury-hotels/search\");\r\n content.value.productCardCollection.viewAllText = \"See More Hotels\";\r\n }\r\n\r\n // This is async and will return after the initial render happens\r\n getSponsoredAndRandomProducts(category, { rowsLimit: 6 }, productLandingContent.sponsoredProductIds).then(async (prods: ProductCardSearchResult) => {\r\n content.value.productCardCollection.productCards = await prods.productCards;\r\n if (category === ProductType.CRUISES) {\r\n content.value.productCardCollection.viewAllText = getViewAllLabel(category, prods.totalResults, 6);\r\n } else if (category === ProductType.TOURS) {\r\n content.value.productCardCollection.viewAllText = getViewAllLabel(category, prods.totalResults, 6);\r\n } else { // Hotels\r\n content.value.productCardCollection.viewAllText = getViewAllLabel(ProductType.HOTELS, prods.totalResults, 6);\r\n }\r\n\r\n });\r\n\r\n // watch\r\n const contentVal = content.value;\r\n const productCardCollection = ref(contentVal.productCardCollection);\r\n const productCardCollectionVal = productCardCollection.value;\r\n const productCards = ref(productCardCollectionVal.productCards.length);\r\n\r\n watch(productCards, (newVal: number): void => {\r\n if (qsParams[\"featured-products\"] === \"1\") {\r\n if (newVal > 0) {\r\n nextTick(() => {\r\n document.getElementById(\"featured-products\")?.scrollIntoView();\r\n });\r\n }\r\n }\r\n });\r\n }\r\n }, () => {\r\n toastError(\"Error retrieving data\");\r\n }).finally(() => {\r\n isReady.value = true;\r\n });\r\n }\r\n\r\n }, (e) => {\r\n toastError(\"Error retrieving data\");\r\n console.error(`Error retrieving data for /${category}-landing-page: `, e);\r\n });\r\n\r\n } else {\r\n console.error(\"Product type not provided\");\r\n }\r\n\r\n</script>\r\n","import ProductLandingPageComponent from \"components/pages/product-landing-page.vue\";\r\nimport { trackEvent } from \"services/analytics\";\r\nimport { capitalizeFirst } from \"virtuoso-shared-web-ui\";\r\nimport { createApp } from \"vue\";\r\nimport { mountApp } from \"vue-app\";\r\n\r\n\r\nif (window.VIRTUOSO.productType) {\r\n const app = createApp(ProductLandingPageComponent);\r\n mountApp(app, \"page-app\");\r\n\r\n const trackItemName = capitalizeFirst(window.VIRTUOSO.productType).slice(0, -1);\r\n trackEvent(\"entry_view\", { item_name: `${trackItemName}_Home`, item_category: trackItemName });\r\n} else {\r\n console.error(\"Product type not provided\");\r\n}\r\n"],"names":["omniboxCategorySearch","b2bCatalogLink","cobrandLink","cruiseLines","ref","destination","durationFacets","_a","facetsByProduct","ProductType","category","exclusivesFacets","_b","isMoreFiltersOpen","legacyLinkText","isSupplier","query","selectedCruiseTypes","selectedExclusives","selectedLengths","styleFacets","_c","doSearch","queryHash","startDate","endDate","selectCategory","acCategory","acValue","trackOmniboxSearch","toggleMoreFilters","slideUpWithFade","slideDownWithFade","catalogType","experienceFacets","hotelTypeFacets","selectedExperiences","selectedHotelTypes","selectedSustainability","sustainabilityFacets","_d","props","__props","slideAdViewTracker","carouselConfig","isArticleDestinationSlideType","slideType","getSlideTabText","slideTitle","featuredSlideTitle","logAdView","slideIndex","slide","campaignSuffix","bsaImg","shuffleInPlace","qsParams","virtuosoSharedHeader.parseURLParameters","isReady","brands","brandsWithExtras","brandsHeader","content","pageName","searchComponent","sponsoredProductSlides","htmlBlobContent","customCompanies","themedArticlesHeader","themedArticles","categoryCardsHeader","categoryCards","buttonLinks","brandTrackMEIDs","populateBrands","productType","brandBaseUrl","postParams","getProductBrands","result","obj","virtuosoSharedHeader.cobrandLink","virtuosoSharedHeader.slugify","a","b","item","componentMap","SearchFormCruisesComponent","SearchFormHotelsComponent","SearchFormToursComponent","trackingBoxLinkBrowseClickHandler","boxlink","shouldTrackMEID","brandMeid","brand","trackedMEID","trackEvent","trackFeatureCardBrowseClickHandler","featuredCard","trackFeatureCardDestination","cmsPage","getLandingPageJSON","landingPageJSON","transformDotCMSPageContainers","tourBrandSupplierTypesRestricted","container","realTravelerStoriesContainers","productLandingPageContent","getProductLandingJSON","productLandingJSON","productLandingContent","transformedSlide","transformCmsFeatureCarouselSlideToCarouselSlide","article","transformCmsBasicArticleToContentTile","i","categoryCardImage","categoryCardLink","categoryCardText","generateCmsImageUrl","linkIndex","categoryButtonLink","categoryButtonText","transformCmsBasicArticleToArticleCard","transformRTSCarouselContent","featuredDest","buildDestinationPageURL","company","companyFields","getSponsoredAndRandomProducts","prods","getViewAllLabel","contentVal","productCardCollectionVal","productCards","watch","newVal","nextTick","toastError","e","app","createApp","ProductLandingPageComponent","mountApp","trackItemName","capitalizeFirst"],"mappings":"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"}