{"version":3,"file":"static/js/890ad4898dd8eadab773.bundle.js","mappings":"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","sources":["webpack://bestseller.commerce.online/./src/modules/ext-product-collection/ext-product-collection.props.autogenerated.ts?ae75","webpack://bestseller.commerce.online/./src/modules/ext-product-collection/ext-product-collection.tsx?dacf","webpack://bestseller.commerce.online/./src/modules/ext-product-collection/ext-product-collection.view.tsx?2915","webpack://bestseller.commerce.online/./src/shared/functions/is-valid-image.ts?b7db","webpack://bestseller.commerce.online/./lib/ext-product-collection/module-registration.js?6d96","webpack://bestseller.commerce.online/external var \"React\"?0d3b","webpack://bestseller.commerce.online/external var \"ReactDOM\"?853b"],"sourcesContent":["/**\r\n * Copyright (c) Microsoft Corporation\r\n * All rights reserved. See License.txt in the project root for license information.\r\n * IExtProductCollection containerModule Interface Properties\r\n * THIS FILE IS AUTO-GENERATED - MANUAL MODIFICATIONS WILL BE LOST\r\n */\r\n\r\nimport * as Msdyn365 from '@msdyn365-commerce/core';\r\nimport * as React from 'react';\r\n\r\nexport const enum layout {\r\n carousel = 'carousel',\r\n grid = 'grid'\r\n}\r\n\r\nexport interface IExtProductCollectionConfig extends Msdyn365.IModuleConfig {\r\n productCollection: Msdyn365.IProductList;\r\n heading?: IHeadingData;\r\n layout?: layout;\r\n allowBackNavigation?: boolean;\r\n imageSettings?: Msdyn365.IImageSettings;\r\n clientRender?: boolean;\r\n enableAffiliationBasedPricing?: boolean;\r\n shouldDisplaySeeAllButton?: boolean;\r\n className?: string;\r\n}\r\n\r\nexport interface IExtProductCollectionResources {\r\n priceFree: string;\r\n priceRangeSeparator: string;\r\n ratingAriaLabel: string;\r\n flipperNext: string;\r\n flipperPrevious: string;\r\n originalPriceText: string;\r\n currentPriceText: string;\r\n ratingCountAriaLabel: string;\r\n ratingCountAriaLabelSingleUser: string;\r\n seeAllButtonText: string;\r\n memberPriceMessage: string;\r\n saleMessage: string;\r\n}\r\n\r\nexport const enum HeadingTag {\r\n h1 = 'h1',\r\n h2 = 'h2',\r\n h3 = 'h3',\r\n h4 = 'h4',\r\n h5 = 'h5',\r\n h6 = 'h6'\r\n}\r\n\r\nexport interface IHeadingData {\r\n text: string;\r\n tag?: HeadingTag;\r\n}\r\n\r\nexport interface IExtProductCollectionProps extends Msdyn365.IModule {\r\n resources: IExtProductCollectionResources;\r\n config: IExtProductCollectionConfig;\r\n slots: {\r\n quickview: React.ReactNode[];\r\n productComparisonButton: React.ReactNode[];\r\n };\r\n}\r\n","/*!\r\n * Copyright (c) Microsoft Corporation.\r\n * All rights reserved. See LICENSE in the project root for license information.\r\n */\r\n\r\n/* eslint-disable no-duplicate-imports */\r\nimport { IProductsDimensionsAvailabilities } from '@msdyn365-commerce/commerce-entities';\r\nimport * as Msdyn365 from '@msdyn365-commerce/core';\r\nimport { getCatalogId, getUrlSync, ICoreContext } from '@msdyn365-commerce/core';\r\nimport { ProductPrice, ProductSearchResult } from '@msdyn365-commerce/retail-proxy';\r\nimport {\r\n ArrayExtensions,\r\n DimensionAvailabilitiesForProductSearchResultInput,\r\n DimensionTypes,\r\n DimensionSwatchDisplayTypes,\r\n getDimensionAvailabilitiesForProductSearchResultAction,\r\n IDimensionsApp,\r\n ObjectExtensions,\r\n PriceForProductSearchResultInput,\r\n validateCatalogId\r\n} from '@msdyn365-commerce-modules/retail-actions';\r\nimport {\r\n Button,\r\n getTelemetryObject,\r\n IComponentNodeProps,\r\n IModuleProps,\r\n INodeProps,\r\n ISingleSlideCarouselProps,\r\n ITelemetryContent,\r\n NodeTag,\r\n SingleSlideCarousel\r\n} from '@msdyn365-commerce-modules/utilities';\r\nimport classnames from 'classnames';\r\nimport * as React from 'react';\r\n\r\nimport { IExtProductCollectionData } from './ext-product-collection.data';\r\nimport { IExtProductCollectionProps, layout } from './ext-product-collection.props.autogenerated';\r\n\r\nimport { ProductComponent } from '../../shared/components/product.component';\r\nimport { IPriceComponentResources } from '../../shared/components/price.component';\r\n\r\nexport interface IProductCollectionViewProps extends IExtProductCollectionProps {\r\n heading?: React.ReactNode;\r\n ProductCollectionContainer: IModuleProps;\r\n SingleSlideCarouselComponentProps: INodeProps;\r\n GridComponentProps: INodeProps;\r\n products: IProductComponentViewProps[];\r\n isCarousel: boolean;\r\n productPrices?: ProductPrice[];\r\n seeAllButton?: React.ReactNode;\r\n}\r\n\r\nexport interface IProductComponentViewProps {\r\n ProductContainer: INodeProps;\r\n productComponent: React.ReactNode;\r\n}\r\nexport interface IProductComponentState {\r\n products: ProductSearchResultExpanded[];\r\n productsDimensionAvailabilities?: IProductsDimensionsAvailabilities[][];\r\n productsFiltered: boolean;\r\n}\r\n\r\nimport { getCommercialName } from '../../shared/functions/get-commercial-name';\r\nimport { getPriceForProductSearchResultAction } from '../../actions/get-price-for-product-search-result';\r\nimport { ProductSearchResultExpanded } from '../../shared/classes/ProductSearchResultExpanded';\r\nimport { validateUrlAsync } from '../../shared/functions/is-valid-image';\r\n\r\n/**\r\n * ProductCollection component.\r\n */\r\nclass ProductCollection extends React.PureComponent, IProductComponentState> {\r\n private readonly telemetryContent: ITelemetryContent;\r\n\r\n private readonly productPrices: ProductPrice[];\r\n\r\n constructor(props: IExtProductCollectionProps) {\r\n super(props);\r\n this.productPrices = [];\r\n this.state = {\r\n products: this.props.config.productCollection.products || [],\r\n productsFiltered: false\r\n };\r\n this.telemetryContent = getTelemetryObject(\r\n this.props.context.request.telemetryPageName!,\r\n this.props.friendlyName,\r\n this.props.telemetry\r\n );\r\n }\r\n\r\n public async componentDidMount(): Promise {\r\n if (this.props.config.enableAffiliationBasedPricing) {\r\n await this._getActivePrice();\r\n }\r\n if (this.props.app.config.hideProductsWithoutImages) {\r\n var filteredProducts = [];\r\n for (const product of this.state.products) {\r\n var isValid = false;\r\n for (const attribute of product.AttributeValues ?? []) {\r\n if (attribute.Name?.toLowerCase() === 'color') {\r\n //Always just uses the first swatch\r\n if (attribute.Swatches && attribute.Swatches.length > 0 && attribute.Swatches[0].ProductImageUrls) {\r\n const productImage = attribute.Swatches[0].ProductImageUrls[0];\r\n isValid = await validateUrlAsync(productImage, this.props.context.actionContext.requestContext.apiSettings);\r\n }\r\n }\r\n }\r\n if (isValid) {\r\n filteredProducts.push(product);\r\n } else {\r\n this.props.telemetry.information('Product without image was filtered out', product.ItemId);\r\n }\r\n }\r\n this.setState({ products: filteredProducts, productsFiltered: true });\r\n }\r\n }\r\n\r\n public render(): JSX.Element | null {\r\n const { heading, className, shouldDisplaySeeAllButton } = this.props.config;\r\n const { resources } = this.props;\r\n const recommendation = this.props.config.productCollection.recommendationListId;\r\n\r\n // Initialize state in case if the products were not found during initial module render\r\n // eslint-disable-next-line @typescript-eslint/no-floating-promises -- Initialize data if not there.\r\n this.initProductState(this.props.config.productCollection);\r\n\r\n const products = this.state.products;\r\n if (this.props.app.config?.useCommercialStyleName) {\r\n for (var product of products) {\r\n product.Name = getCommercialName(\r\n product.AttributeValues,\r\n product.Name,\r\n this.props.app.config?.commercialStyleNameAttribute\r\n );\r\n }\r\n }\r\n const isCarousel = this.props.config.layout === layout.carousel;\r\n const headingLabel = heading ? heading.text : '';\r\n const headingComponent = heading && (\r\n \r\n );\r\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- product check for safety.\r\n const updatedProducts = products?.map((item: ProductSearchResult, index: number) => {\r\n const getProductData = this._getProduct(item, index);\r\n return !ObjectExtensions.isNullOrUndefined(getProductData) ? getProductData : undefined;\r\n });\r\n\r\n const productCollectionViewProps = {\r\n ...this.props,\r\n heading: headingComponent,\r\n SingleSlideCarouselComponentProps: {\r\n tag: SingleSlideCarousel,\r\n className: '',\r\n flipperPrevLabel: `${headingLabel} ${resources.flipperPrevious}`,\r\n flipperNextLabel: `${headingLabel} ${resources.flipperNext}`,\r\n parentId: this.props.id,\r\n telemetryContent: this.telemetryContent\r\n } as IComponentNodeProps,\r\n ProductCollectionContainer: {\r\n moduleProps: this.props,\r\n className: classnames('ms-product-collection', className)\r\n },\r\n GridComponentProps: {\r\n tag: 'ul' as NodeTag,\r\n className: 'ms-product-collection__items'\r\n },\r\n isCarousel,\r\n\r\n products:\r\n ArrayExtensions.hasElements(updatedProducts) &&\r\n updatedProducts.filter(item => {\r\n return item !== undefined;\r\n }),\r\n productPrices: this.productPrices,\r\n seeAllButton:\r\n recommendation && shouldDisplaySeeAllButton && ArrayExtensions.hasElements(updatedProducts)\r\n ? this._getSeeAllButton(recommendation, headingLabel)\r\n : undefined\r\n };\r\n return this.props.renderView(productCollectionViewProps) as React.ReactElement;\r\n }\r\n\r\n public handleHeadingChange = (event: Msdyn365.ContentEditableEvent) => (this.props.config.heading!.text = event.target.value);\r\n\r\n /**\r\n * Get products dimension availabilities.\r\n * @param products - Products.\r\n * @returns Promise.\r\n */\r\n private readonly _getProductsDimensionsAvailabilities = async (products: ProductSearchResult[]): Promise => {\r\n const context = this.props.context as ICoreContext;\r\n const dimensionsToDisplayOnProductCard = context.app.config.dimensionsInProductCard;\r\n const dimensionsToDisplayAsSwatch = context.app.config.dimensionsAsSwatchType;\r\n const validProducts = ArrayExtensions.validValues(products);\r\n if (\r\n ArrayExtensions.hasElements(validProducts) &&\r\n ArrayExtensions.hasElements(dimensionsToDisplayOnProductCard) &&\r\n !dimensionsToDisplayOnProductCard.includes(DimensionTypes.none) &&\r\n ArrayExtensions.hasElements(dimensionsToDisplayAsSwatch) &&\r\n !dimensionsToDisplayAsSwatch.includes(DimensionTypes.none)\r\n ) {\r\n const productsDimensionAvailabilities = await getDimensionAvailabilitiesForProductSearchResultAction(\r\n new DimensionAvailabilitiesForProductSearchResultInput(\r\n validProducts,\r\n this.props.context as ICoreContext,\r\n DimensionSwatchDisplayTypes.productCard\r\n ),\r\n this.props.context.actionContext\r\n );\r\n\r\n if (ArrayExtensions.hasElements(productsDimensionAvailabilities)) {\r\n this.setState({ productsDimensionAvailabilities });\r\n }\r\n }\r\n };\r\n\r\n /**\r\n * Helper method to initialize products state.\r\n * @param productCollection - List of products.\r\n */\r\n private readonly initProductState = async (productCollection: Msdyn365.IProductList) => {\r\n let products = this.state.products;\r\n const productCollectionProducts = productCollection.products;\r\n if (!ArrayExtensions.hasElements(products) && ArrayExtensions.hasElements(productCollectionProducts)) {\r\n products = productCollectionProducts;\r\n this.setState({ products });\r\n } else if (\r\n // If the products have been manually filtered, they are allowed to be different\r\n ArrayExtensions.hasElements(products) &&\r\n ArrayExtensions.hasElements(productCollectionProducts) &&\r\n !ArrayExtensions.equals(products, productCollectionProducts) &&\r\n !this.state.productsFiltered\r\n ) {\r\n products = productCollectionProducts;\r\n this.setState({ products });\r\n } else if (productCollectionProducts === undefined && ArrayExtensions.hasElements(this.state.products)) {\r\n products = [];\r\n this.setState({ products: products });\r\n }\r\n\r\n if (Msdyn365.msdyn365Commerce.isBrowser && !ArrayExtensions.hasElements(this.state.productsDimensionAvailabilities)) {\r\n await this._getProductsDimensionsAvailabilities(products);\r\n }\r\n };\r\n\r\n private readonly _getProduct = (product: ProductSearchResultExpanded, index: number): IProductComponentViewProps | null => {\r\n if (!product || !product.Name) {\r\n this.props.telemetry.trace('[product-collection] Product or product name is null');\r\n return null;\r\n }\r\n const telemetryContent = getTelemetryObject(\r\n this.props.context.request.telemetryPageName!,\r\n this.props.friendlyName,\r\n this.props.telemetry\r\n );\r\n const { imageSettings, allowBackNavigation } = this.props.config;\r\n const resources = this.props.resources;\r\n const breaCrumbType = this.props.context.app.config.breadcrumbType;\r\n const allowBack = allowBackNavigation && (breaCrumbType === 'back' || breaCrumbType === 'categoryAndBack');\r\n const quickviewSlot =\r\n this.props.slots && this.props.slots.quickview && this.props.slots.quickview.length > 0 ? this.props.slots.quickview[0] : null;\r\n const productComparisonButtonSlot = ArrayExtensions.hasElements(this.props.slots.productComparisonButton)\r\n ? this.props.slots.productComparisonButton[0]\r\n : null;\r\n\r\n const reviewCount = 1;\r\n const reviewTotalRatings = Number(product.TotalRatings);\r\n const reviewCountAriaLabelValue =\r\n reviewTotalRatings > reviewCount ? resources.ratingCountAriaLabel : resources.ratingCountAriaLabelSingleUser;\r\n const isPriceMinMaxEnabled = this.props.data.featureState.result?.find(\r\n featureState => featureState.Name === 'Dynamics.AX.Application.RetailSearchPriceRangeFeature'\r\n );\r\n const priceResources: IPriceComponentResources = {\r\n priceRangeSeparator: resources.priceRangeSeparator,\r\n memberPriceMessage: resources.memberPriceMessage,\r\n saleMessage: resources.saleMessage\r\n };\r\n return {\r\n ProductContainer: {\r\n tag: 'li' as NodeTag,\r\n className: 'ms-product-collection__item',\r\n role: 'listitem',\r\n key: index\r\n },\r\n productComponent: (\r\n \r\n ArrayExtensions.hasElements(dimensionAvailability) &&\r\n dimensionAvailability[0].masterProductId === (product.MasterProductId ?? product.RecordId)\r\n )}\r\n />\r\n )\r\n };\r\n };\r\n\r\n /**\r\n * Get the active price for products.\r\n */\r\n private readonly _getActivePrice = async (): Promise => {\r\n const productsList = this.state.products;\r\n //Uses custom action\r\n const products = await getPriceForProductSearchResultAction(\r\n new PriceForProductSearchResultInput(productsList),\r\n this.props.context.actionContext\r\n );\r\n if (Msdyn365.msdyn365Commerce.isBrowser) {\r\n await this._getProductsDimensionsAvailabilities(products);\r\n }\r\n\r\n this.setState({ products });\r\n };\r\n\r\n /**\r\n * Get the see all button.\r\n * @param recommendation - Recommendation.\r\n * @param headingLabel - Heading label.\r\n * @returns IProductComponentSeeAllViewProps - Product component see all view props.\r\n */\r\n private readonly _getSeeAllButton = (recommendation: string, headingLabel: string): React.ReactNode => {\r\n if (!Msdyn365.msdyn365Commerce.isBrowser) {\r\n return null;\r\n }\r\n\r\n const catalogId = getCatalogId(this.props.context.request);\r\n validateCatalogId(catalogId);\r\n const searchPageLink = getUrlSync('search', this.props.context.actionContext);\r\n if (!searchPageLink) {\r\n return null;\r\n }\r\n\r\n const url = new URL(searchPageLink, window.location.href);\r\n url.searchParams.set('recommendation', recommendation);\r\n url.searchParams.set('title', headingLabel);\r\n url.searchParams.set('catalogid', `${catalogId}`);\r\n\r\n return (\r\n \r\n {this.props.resources.seeAllButtonText}\r\n \r\n );\r\n };\r\n}\r\n\r\nexport default ProductCollection;\r\n","/*!\r\n * Copyright (c) Microsoft Corporation.\r\n * All rights reserved. See LICENSE in the project root for license information.\r\n */\r\n\r\n/* eslint-disable no-duplicate-imports */\r\nimport { INodeProps, Module, Node } from '@msdyn365-commerce-modules/utilities';\r\nimport * as React from 'react';\r\n\r\nimport { IProductCollectionViewProps, IProductComponentViewProps } from './ext-product-collection';\r\n\r\nconst ProductCollectionView: React.FC = props => {\r\n const {\r\n heading,\r\n ProductCollectionContainer,\r\n products,\r\n SingleSlideCarouselComponentProps,\r\n GridComponentProps,\r\n isCarousel,\r\n seeAllButton\r\n } = props;\r\n\r\n if (products) {\r\n return (\r\n \r\n {heading}\r\n {seeAllButton}\r\n {isCarousel ? _renderCarousel(SingleSlideCarouselComponentProps, products) : _renderGrid(GridComponentProps, products)}\r\n \r\n );\r\n }\r\n props.context.telemetry.error('Product collection content is empty, module wont render.');\r\n return null;\r\n};\r\n\r\nconst _renderCarousel = (carouselContainer: INodeProps, items: IProductComponentViewProps[]): JSX.Element => {\r\n return {items && items.map(_renderProduct)};\r\n};\r\n\r\nconst _renderGrid = (gridContainer: INodeProps, items: IProductComponentViewProps[]): JSX.Element => {\r\n return {items && items.map(_renderProduct)};\r\n};\r\n\r\nconst _renderProduct = (product: IProductComponentViewProps): JSX.Element => {\r\n const { ProductContainer, productComponent } = product;\r\n\r\n return {productComponent};\r\n};\r\n\r\nexport default ProductCollectionView;\r\n","import { generateImageUrl, ICommerceApiSettings, IImageData } from '@msdyn365-commerce/core';\r\n/**\r\n * Parses whether a URL is valid\r\n * @param url\r\n * @returns\r\n */\r\nexport const isValidImage = (url?: string): boolean => {\r\n if (url) {\r\n return url.startsWith('https') || url.startsWith('Products');\r\n } else {\r\n return false;\r\n }\r\n};\r\n\r\nexport async function validateUrlAsync(url: string, apiSettings: ICommerceApiSettings): Promise {\r\n const imageUrl = generateImageUrl(apiSettings, url);\r\n const imageData: IImageData = {\r\n src: imageUrl || ''\r\n };\r\n\r\n if (imageData.src === '') {\r\n return false;\r\n }\r\n\r\n return new Promise(resolve => {\r\n try {\r\n const http = new XMLHttpRequest();\r\n http.open('HEAD', imageData.src!, true);\r\n\r\n http.addEventListener('load', () => {\r\n resolve(http.status === 200 || http.status === 201);\r\n });\r\n\r\n http.addEventListener('error', () => {\r\n resolve(false);\r\n });\r\n\r\n http.send();\r\n } catch {\r\n resolve(false);\r\n }\r\n });\r\n}\r\n","const binding = { modules: {}, dataActions: {} };\n\n const registerActionId = (actionPath) => {\n if (binding.dataActions[actionPath] &&\n binding.dataActions[actionPath].default &&\n binding.dataActions[actionPath].default.prototype &&\n binding.dataActions[actionPath].default.prototype.id) {\n binding.dataActions[binding.dataActions[actionPath].default.prototype.id] = binding.dataActions[actionPath];\n } else {\n Object.keys(binding.dataActions[actionPath] || {}).forEach(exportName => {\n if (binding.dataActions[actionPath][exportName] &&\n binding.dataActions[actionPath][exportName].prototype &&\n binding.dataActions[actionPath][exportName].prototype.Action) {\n binding.dataActions[binding.dataActions[actionPath][exportName].prototype.id] = binding.dataActions[actionPath][exportName];\n }\n })\n }\n };\n\n const registerSanitizedActionPath = (sanitizedActionPath, dataAction) => {\n if (process.env.NODE_ENV === 'development') {\n if (!dataAction.default) {\n throw new Error('Data action path does not have a default export');\n }\n if (!(dataAction.default.prototype.id && binding.dataActions[dataAction.default.prototype.id]) || !binding.dataActions[sanitizedActionPath]) {\n binding.dataActions[sanitizedActionPath] = dataAction;\n }\n } else {\n binding.dataActions[sanitizedActionPath] = dataAction;\n if (!binding.dataActions[sanitizedActionPath].default) {\n throw new Error('Data action path ' + sanitizedActionPath + ' does not have a default export');\n }\n binding.dataActions[sanitizedActionPath].default.prototype.RegistrationId = sanitizedActionPath;\n if (binding.dataActions[sanitizedActionPath].default.prototype.id) {\n binding.dataActions[binding.dataActions[sanitizedActionPath].default.prototype.id] = sanitizedActionPath;\n }\n }\n };\n \n\n (binding.modules['ext-product-collection'] = {\n c: () => require('partner/modules/ext-product-collection/ext-product-collection.tsx'),\n $type: 'containerModule',\n da: [{name:'featureState', path:'@msdyn365-commerce-modules/retail-actions/dist/lib/get-feature-state', runOn: 0}],\n \n iNM: false,\n ns: '__local__',\n n: 'ext-product-collection',\n p: '__local__',\n \n pdp: '',\n \n \n md: 'src/modules/ext-product-collection'\n });\n \n\n {\n const sanitizedActionPath = '@msdyn365-commerce-modules/retail-actions/dist/lib/get-feature-state';\n let dataAction = require('@msdyn365-commerce-modules/retail-actions/dist/lib/get-feature-state');\n registerSanitizedActionPath(sanitizedActionPath, dataAction);\n }\n \n\n \n window.__bindings__ = window.__bindings__ || {};\n window.__bindings__.modules = {\n ...window.__bindings__.modules || {},\n ...binding.modules\n };\n \n window.__bindings__.dataActions = {\n ...window.__bindings__.dataActions || {},\n ...binding.dataActions\n };\n export const viewDictionary = {};\n viewDictionary['__local__|__local__|modules|ext-product-collection|ext-product-collection'] = {\n c: () => require('partner/modules/ext-product-collection/ext-product-collection.view.tsx'),\n cn: '__local__-__local__-ext-product-collection'\n };\nwindow.__bindings__ = window.__bindings__ || {};\nwindow.__bindings__.viewDictionary = {\n ...window.__bindings__.viewDictionary || {},\n ...viewDictionary\n };","module.exports = React;","module.exports = ReactDOM;"],"names":["layout","HeadingTag","ProductCollection","React","constructor","props","super","handleHeadingChange","event","this","config","heading","text","target","value","_getProductsDimensionsAvailabilities","async","context","dimensionsToDisplayOnProductCard","app","dimensionsInProductCard","dimensionsToDisplayAsSwatch","dimensionsAsSwatchType","validProducts","ArrayExtensions","validValues","products","hasElements","includes","DimensionTypes","none","productsDimensionAvailabilities","getDimensionAvailabilitiesForProductSearchResultAction","DimensionAvailabilitiesForProductSearchResultInput","DimensionSwatchDisplayTypes","productCard","actionContext","setState","initProductState","state","productCollectionProducts","productCollection","equals","productsFiltered","undefined","Msdyn365","isBrowser","_getProduct","product","index","_this$props$data$feat","_this$state$productsD","Name","telemetry","trace","telemetryContent","getTelemetryObject","request","telemetryPageName","friendlyName","imageSettings","allowBackNavigation","resources","breaCrumbType","breadcrumbType","allowBack","quickviewSlot","slots","quickview","length","productComparisonButtonSlot","productComparisonButton","reviewCountAriaLabelValue","Number","TotalRatings","ratingCountAriaLabel","ratingCountAriaLabelSingleUser","isPriceMinMaxEnabled","data","featureState","result","find","priceResources","priceRangeSeparator","memberPriceMessage","saleMessage","ProductContainer","tag","className","role","key","productComponent","ProductComponent","freePriceText","priceFree","originalPriceText","currentPriceText","ratingAriaLabel","id","typeName","quickViewButton","IsEnabled","dimensionAvailabilities","dimensionAvailability","_product$MasterProduc","masterProductId","MasterProductId","RecordId","_getActivePrice","productsList","getPriceForProductSearchResultAction","PriceForProductSearchResultInput","_getSeeAllButton","recommendation","headingLabel","catalogId","getCatalogId","validateCatalogId","searchPageLink","getUrlSync","url","URL","window","location","href","searchParams","set","Button","title","seeAllButtonText","productPrices","enableAffiliationBasedPricing","hideProductsWithoutImages","filteredProducts","isValid","attribute","_product$AttributeVal","AttributeValues","_attribute$Name","toLowerCase","Swatches","ProductImageUrls","productImage","validateUrlAsync","requestContext","apiSettings","push","information","ItemId","render","_this$props$app$confi","shouldDisplaySeeAllButton","recommendationListId","useCommercialStyleName","_this$props$app$confi2","getCommercialName","commercialStyleNameAttribute","isCarousel","carousel","headingComponent","editProps","onEdit","updatedProducts","map","item","getProductData","ObjectExtensions","isNullOrUndefined","productCollectionViewProps","_objectSpread","SingleSlideCarouselComponentProps","SingleSlideCarousel","flipperPrevLabel","flipperPrevious","flipperNextLabel","flipperNext","parentId","ProductCollectionContainer","moduleProps","classnames","GridComponentProps","filter","seeAllButton","renderView","_renderCarousel","carouselContainer","items","Node","Object","assign","_renderProduct","_renderGrid","gridContainer","Module","error","isValidImage","startsWith","imageData","src","generateImageUrl","Promise","resolve","http","XMLHttpRequest","open","addEventListener","status","send","_unused","binding","modules","dataActions","c","require","$type","da","name","path","runOn","iNM","ns","n","p","pdp","md","registerSanitizedActionPath","sanitizedActionPath","dataAction","default","Error","prototype","RegistrationId","__bindings__","viewDictionary","cn","module","exports","ReactDOM"],"sourceRoot":""}