@cludosearch/cludo-search-components 1.0.78 → 1.0.79
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/results/header/result-count.d.ts.map +1 -1
- package/dist/csr/main.csr.js +1 -1
- package/dist/csr/main.csr.js.map +1 -1
- package/dist/csr/service-worker.js +1 -1
- package/dist/csr/service-worker.js.map +1 -1
- package/dist/ssr/main.ssr.js +1 -1
- package/dist/ssr/main.ssr.js.map +1 -1
- package/dist/ssr/service-worker.js +1 -1
- package/dist/ssr/service-worker.js.map +1 -1
- package/package.json +1 -1
package/dist/ssr/main.ssr.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"main.ssr.js","mappings":"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","sources":["webpack://cludo-ssr/webpack/universalModuleDefinition","webpack://cludo-ssr/./node_modules/@cludosearch/cludo-api-client/dist/interfaces/api/public-settings.interface.js","webpack://cludo-ssr/webpack/bootstrap","webpack://cludo-ssr/webpack/runtime/compat get default export","webpack://cludo-ssr/webpack/runtime/define property getters","webpack://cludo-ssr/webpack/runtime/hasOwnProperty shorthand","webpack://cludo-ssr/webpack/runtime/make namespace object","webpack://cludo-ssr/external commonjs \"react\"","webpack://cludo-ssr/./src/context.tsx","webpack://cludo-ssr/./src/utils/result-utils.ts","webpack://cludo-ssr/./src/utils/context-utils.ts","webpack://cludo-ssr/./src/components/elements/result-link.tsx","webpack://cludo-ssr/./src/utils/theme-provider.tsx","webpack://cludo-ssr/./src/components/results/items/custom-result.tsx","webpack://cludo-ssr/./src/components/elements/cludo-highlighted-text.tsx","webpack://cludo-ssr/./src/components/elements/result-title.tsx","webpack://cludo-ssr/./src/components/elements/fragment-highlight/fragment-highlight.tsx","webpack://cludo-ssr/./src/components/elements/fragment-highlight-group/fragment-highlight-group.tsx","webpack://cludo-ssr/./src/components/elements/result-description.tsx","webpack://cludo-ssr/./src/components/elements/result-url.tsx","webpack://cludo-ssr/./src/components/elements/result-badge.tsx","webpack://cludo-ssr/./src/components/results/items/standard-result.tsx","webpack://cludo-ssr/./src/hooks/use-cludo-context.ts","webpack://cludo-ssr/./src/hooks/use-event-subscription.ts","webpack://cludo-ssr/./src/hooks/use-pagination.ts","webpack://cludo-ssr/./src/hooks/use-search-results.ts","webpack://cludo-ssr/./src/components/results/pagination/pagination.tsx","webpack://cludo-ssr/./src/components/elements/banner.tsx","webpack://cludo-ssr/./src/hooks/use-banners.ts","webpack://cludo-ssr/./src/components/elements/banner-group/banner-group.tsx","webpack://cludo-ssr/./src/components/results/header/did-you-mean.tsx","webpack://cludo-ssr/./src/components/results/header/result-count.tsx","webpack://cludo-ssr/./src/components/results/header/results-summary.tsx","webpack://cludo-ssr/./src/components/results/cludo-loader.tsx","webpack://cludo-ssr/./src/components/elements/loader/standard-loader.tsx","webpack://cludo-ssr/./src/components/results/list/results-list.tsx","webpack://cludo-ssr/./src/components/results/cludo-load-more.tsx","webpack://cludo-ssr/./src/components/results/load-more-results.tsx","webpack://cludo-ssr/./src/components/types/types.ts","webpack://cludo-ssr/./src/components/results/cludo-search-results.tsx","webpack://cludo-ssr/./src/components/sayt/items/sayt-result.tsx","webpack://cludo-ssr/./src/components/sayt/items/sayt-suggestion.tsx","webpack://cludo-ssr/./src/components/sayt/items/sayt-recent-search.tsx","webpack://cludo-ssr/./src/utils/render-utils.ts","webpack://cludo-ssr/./src/hooks/use-autocomplete.ts","webpack://cludo-ssr/./src/components/sayt/cludo-search-autocomplete.tsx","webpack://cludo-ssr/./src/utils/cludo-search-context.ts","webpack://cludo-ssr/external commonjs \"react-dom\"","webpack://cludo-ssr/./src/utils/components-controller.tsx","webpack://cludo-ssr/./src/utils/event-controller.ts","webpack://cludo-ssr/./src/utils/cludo-instance-controller.ts","webpack://cludo-ssr/./src/hooks/use-sort-by.ts","webpack://cludo-ssr/./src/components/controls/sort-picker/cludo-sort-picker.tsx","webpack://cludo-ssr/./src/components/utility/pseudo-link.tsx","webpack://cludo-ssr/./src/hooks/use-facet.ts","webpack://cludo-ssr/./src/components/controls/facets/items/standard-facet-item.tsx","webpack://cludo-ssr/./src/utils/facet-utils.ts","webpack://cludo-ssr/./src/components/controls/facets/elements/facet-header.tsx","webpack://cludo-ssr/./src/components/controls/facets/elements/facet-search.tsx","webpack://cludo-ssr/./src/components/controls/facets/elements/facet-items-list.tsx","webpack://cludo-ssr/./src/components/controls/facets/base-facet.tsx","webpack://cludo-ssr/./src/components/controls/facets/standard-facet.tsx","webpack://cludo-ssr/./src/hooks/use-facet-group.ts","webpack://cludo-ssr/./src/components/controls/cludo-search-controls.tsx","webpack://cludo-ssr/./src/utils/instantiator.ts","webpack://cludo-ssr/./src/components/controls/inputs/dropdown-input.tsx","webpack://cludo-ssr/./src/components/results/pagination/results-per-page.tsx","webpack://cludo-ssr/./src/components/sayt/items/sayt-categorized-result.tsx","webpack://cludo-ssr/./src/components/controls/facets/facet-group/facet-group.tsx","webpack://cludo-ssr/./src/components/controls/facets/items/checkbox-facet-item.tsx","webpack://cludo-ssr/./src/components/controls/facets/checkbox-facet.tsx","webpack://cludo-ssr/./src/components/controls/facets/items/radio-facet-item.tsx","webpack://cludo-ssr/./src/components/controls/facets/radio-facet.tsx","webpack://cludo-ssr/./src/components/icons/base-icon.tsx","webpack://cludo-ssr/./src/components/icons/close-icon.tsx","webpack://cludo-ssr/./src/components/controls/facets/elements/current-facets.tsx","webpack://cludo-ssr/./src/components/controls/facets/elements/clear-all-facets.tsx","webpack://cludo-ssr/./src/components/elements/result-image.tsx","webpack://cludo-ssr/./src/components/elements/result-breadcrumbs.tsx","webpack://cludo-ssr/./src/components/wrapper/cludo-wrapper.tsx","webpack://cludo-ssr/./src/components/forms/cludo-autocomplete-container.tsx","webpack://cludo-ssr/./src/components/forms/cludo-results-container.tsx","webpack://cludo-ssr/./src/components/forms/cludo-search-input.tsx","webpack://cludo-ssr/./src/components/forms/cludo-search-form.tsx","webpack://cludo-ssr/./src/hooks/use-search-input.ts","webpack://cludo-ssr/./src/components/icons/search-icon.tsx","webpack://cludo-ssr/./src/components/forms/search-input.tsx","webpack://cludo-ssr/./src/hooks/use-endless-scroll.ts"],"sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"CludoSearchComponents\"] = factory();\n\telse\n\t\troot[\"CludoSearchComponents\"] = factory();\n})(this, () => {\nreturn ","\"use strict\";\r\nObject.defineProperty(exports, \"__esModule\", { value: true });\r\nexports.CludoFeature = void 0;\r\n/** Feature values associated with subscription digest */\r\nvar CludoFeature;\r\n(function (CludoFeature) {\r\n CludoFeature[\"AdvancedIntents\"] = \"advanced insights\";\r\n CludoFeature[\"Intents\"] = \"basic insights\";\r\n CludoFeature[\"Sayt\"] = \"sayt\";\r\n CludoFeature[\"AnalyticsFilters\"] = \"analytics filters\";\r\n CludoFeature[\"VoiceSearches\"] = \"voice search\";\r\n CludoFeature[\"InstantSuggestions\"] = \"instant suggestions\";\r\n CludoFeature[\"Advanced404Analytics\"] = \"advanced 404 analytics\";\r\n CludoFeature[\"BannerStatistics\"] = \"banner statistics\";\r\n CludoFeature[\"RelatedSearches\"] = \"related searches\";\r\n CludoFeature[\"Basic404\"] = \"basic 404\";\r\n CludoFeature[\"IntelligentRanking\"] = \"intelligent rankings (ml)\";\r\n CludoFeature[\"GranularPermissions\"] = \"granular permissions\";\r\n CludoFeature[\"TimeScheduledBanner\"] = \"time-scheduled banners\";\r\n CludoFeature[\"GeoData\"] = \"geo analytics\";\r\n CludoFeature[\"DeviceData\"] = \"device analytics\";\r\n CludoFeature[\"AsyncCrawlingOneThousandPagesCrawledEveryDays\"] = \"async crawling 1000 pages crawled every day\";\r\n CludoFeature[\"AsyncCrawlingTwoThousandPagesCrawledEveryTwoDays\"] = \"async crawling 2000 pages crawled every 2 days\";\r\n CludoFeature[\"AsyncCrawlingThreeThousandPagesCrawledEveryThreeDays\"] = \"async crawling 3000 pages crawled every 3 days\";\r\n CludoFeature[\"AsyncCrawlingFourThousandPagesCrawledEveryFourDays\"] = \"async crawling 4000 pages crawled every 4 days\";\r\n CludoFeature[\"AsyncCrawlingFiveThousandPagesCrawledEveryFiveDays\"] = \"async crawling 5000 pages crawled every 5 days\";\r\n CludoFeature[\"AsyncCrawlingSixThousandPagesCrawledEverySixDays\"] = \"async crawling 6000 pages crawled every 6 days\";\r\n CludoFeature[\"AsyncCrawlingSevenThousandPagesCrawledEverySevenDays\"] = \"async crawling 7000 pages crawled every 7 days\";\r\n CludoFeature[\"WebContentHighlighter\"] = \"web content highlighter\";\r\n CludoFeature[\"Audiences\"] = \"audiences\";\r\n})(CludoFeature = exports.CludoFeature || (exports.CludoFeature = {}));\r\n//# sourceMappingURL=public-settings.interface.js.map","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId](module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n","// getDefaultExport function for compatibility with non-harmony modules\n__webpack_require__.n = (module) => {\n\tvar getter = module && module.__esModule ?\n\t\t() => (module['default']) :\n\t\t() => (module);\n\t__webpack_require__.d(getter, { a: getter });\n\treturn getter;\n};","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","const __WEBPACK_NAMESPACE_OBJECT__ = require(\"react\");","import React from \"react\";\n\nimport { EventController } from './utils/event-controller';\nimport { CludoSearchContext } from \"./utils/cludo-search-context\";\n\n// Provider and Consumer are connected through their \"parent\" context\nexport const CludoContext = React.createContext<CludoSearchContext>({} as any);\nexport const EventControllerContext = React.createContext<EventController>({} as any);\n","import { TypedDocument } from \"@cludosearch/cludo-api-client/dist/interfaces/api/search.interface\";\nimport { AutocompleteResult, AutocompleteTopHit } from \"../components/types/types\";\nimport { FacetMap, TopHit } from \"../types/core-script-types\";\n\nexport function getUrl(result: TypedDocument): string {\n return result.Fields['Url'].Value;\n}\n\nexport function hasField(result: TypedDocument, fieldName: string): boolean {\n return (result.FieldNames.indexOf(fieldName) !== -1);\n}\n\nexport function getFieldValue(result: TypedDocument, fieldName: string, maxWords?: number, wordDelim?: string): string | undefined {\n if (!hasField(result, fieldName)) {\n return undefined;\n }\n \n let splitDelim = wordDelim ?? /\\s+/;\n let joinDelim = wordDelim ?? ' ';\n let value = result.Fields[fieldName].Value;\n if (maxWords && maxWords > 0) {\n let words = value.split(splitDelim);\n if (words.length > maxWords) {\n value = words.slice(0, maxWords).join(joinDelim);\n }\n }\n\n return value;\n}\n\nexport function getFieldValues(result: TypedDocument, fieldName: string): string[] | undefined {\n if (!hasField(result, fieldName)) {\n return undefined;\n }\n return result.Fields[fieldName].Values;\n}\n\n/** Helper function similar to what is used in Razor templates */\nexport function getHighlightsOrValues(result: TypedDocument, fieldName: string, maxWords?: number, wordDelim = ' ', delim: string = '...'): string | undefined {\n if (!hasField(result, fieldName)) {\n return undefined;\n }\n return getHighlightsOrValuesArray(result, fieldName, maxWords, wordDelim).join(delim);\n}\n\n/** Helper function to get an array of description fragments for a result */\nexport function getHighlightsOrValuesArray(result: TypedDocument, fieldName: string, maxWords?: number, wordDelim = ' '): string[] {\n return (result.Fields[fieldName]?.Highlights?.length > 0) ?\n trimArrayToMaxWords(result.Fields[fieldName].Highlights, maxWords) :\n [getFieldValue(result, fieldName, maxWords, wordDelim) ?? ''];\n}\n\n/** Helper for getHighlightsOrValuesArray function to trim array of strings to max words */\nfunction trimArrayToMaxWords(values: string[], maxWords?: number) {\n let returnValues = [];\n if (maxWords) {\n let wordCount = 0;\n for (let i = 0; i < values.length; i++) {\n let stringArray = values[i].trim().split(/\\s+/);\n wordCount += stringArray.length;\n if (wordCount > maxWords) {\n stringArray.splice(-(wordCount - maxWords));\n returnValues.push(stringArray.join(' '));\n break;\n } else {\n returnValues.push(stringArray.join(' '));\n }\n }\n } else {\n returnValues = [...values];\n }\n return returnValues;\n}\n\n/** Returns an object that can be used for setting inner HTML */\nexport function getFormattedHTML(val: string) {\n return {__html: val};\n}\n\n/** Logs error message when result object missing from result widget components */\nexport function logMissingResultError(component: string): void {\n console.error(`No result provided to ${component} component. ${component} must receive a result through props or from a result context provider.`);\n}\n\n/** Checks if the selected element is an autocomplete item */\nexport function isAutocompleteItem(element: Element | null): boolean {\n if (!element) {\n return false;\n }\n return element.hasAttribute('data-cludo-autocomplete');\n}\n\n/** Extracts results from autocomplete top hit groups into a single array */\nexport function getAutocompleteResultsFromTopHits(categorizedResultGroups: AutocompleteTopHit[]): AutocompleteResult[] {\n let results: AutocompleteResult[] = [];\n categorizedResultGroups.forEach(resultGroup => {\n resultGroup.Values.forEach(resultValue => {\n results = results.concat(resultValue.Hits);\n })\n })\n return results;\n}\n\n/** Derive total number of results for individual categorized result categories from result counts in facet map */\nexport function getTopHitTotalCount<T extends TopHit | AutocompleteTopHit>(hit: T, facets: FacetMap) {\n return {\n Field: hit.Field,\n Values: hit.Values.map(hitValue => {\n const facetMatch = facets[hit.Field];\n const facetValueMatch = facetMatch?.Items?.find(value => value.Key === hitValue.Value);\n const count = facetValueMatch ? facetValueMatch.Count : 0;\n return {\n ...hitValue,\n AllCount: count\n }\n })\n } as T\n}","import { CludoFeature } from \"@cludosearch/cludo-api-client/dist/interfaces/api/public-settings.interface\";\nimport { CludoSearchContext } from \"./cludo-search-context\";\n\n/** If WCH is enabled, return the formatted link fragment part to be appended on a result URL */\nexport function getLinkFragmentUrlPart(fragment: string, context: CludoSearchContext): string {\n const enableFragmentHighlights: boolean = context.isFeatureEnabled(CludoFeature.WebContentHighlighter);\n\n if (enableFragmentHighlights) {\n const fragmentToken = '#:~:text=';\n const innerText = fragment.replace(/<[^>]+>/g, '');\n const encodedText = encodeURIComponent(innerText);\n return fragmentToken + encodedText;\n }\n\n return '';\n}","import React, { useContext, useEffect, useRef, useState} from \"react\";\nimport { CludoContext, EventControllerContext } from \"../../context\";\nimport { getFieldValue, logMissingResultError } from \"../../utils/result-utils\";\nimport { getLinkFragmentUrlPart } from \"../../utils/context-utils\";\nimport { EventController } from \"../../utils/event-controller\";\nimport { ResultContext } from \"../results/items/custom-result\";\nimport { BaseResultProps } from \"../types/types\";\n\ninterface ResultLinkProps extends BaseResultProps {\n className?: string,\n children?: React.ReactNode,\n openNewTab?: boolean,\n shouldBeFocused?: boolean,\n highlightQueryOnClickedPage?: boolean,\n linkField?: string\n}\n\ninterface LinkContext {\n onFragmentHover: (fragmentStr?: string) => void;\n onFragmentSelect: () => void; \n}\n\nexport const LinkContext = React.createContext<LinkContext>({} as any);\n\nexport function ResultLink(props: ResultLinkProps) {\n const context = useContext(CludoContext);\n const eventController = useContext(EventControllerContext);\n const resultContext = useContext(ResultContext);\n const initalFragment = props.highlightQueryOnClickedPage ? getLinkFragmentUrlPart(context.query, context) : '';\n\n const [fragmentUrlPart, setFragmentUrlPart] = useState(initalFragment);\n\n const result = props.result || resultContext;\n if (!result) {\n logMissingResultError('ResultLink');\n return null;\n }\n \n const model = result;\n const eleClass = props.className ? props.className : '';\n const titleField = getFieldValue(result, '_type') === \"PageContent\" ? 'Title' : 'fc_Title';\n\n // Set URL based on hovered fragment or first fragment\n // OnHover/OnSelect callbacks passed down to children that can \n // optionally use them if WCH is enabled.\n let url = props.linkField ? getFieldValue(result, props.linkField) : model.Fields[\"Url\"].Value;\n let urlWithFragments = url;\n if (fragmentUrlPart) {\n urlWithFragments += fragmentUrlPart\n }\n\n const anchorElem = useRef<HTMLAnchorElement>(null);\n\n const onFragmentHover = (fragment?: string) => {\n const urlFragmentPart = (fragment) ? getLinkFragmentUrlPart(fragment, context) : '';\n setFragmentUrlPart(urlFragmentPart);\n }\n\n const onFragmentSelect = () => {\n if (anchorElem.current) {\n anchorElem.current.click();\n }\n }\n\n const LinkContextInstance = { \n onFragmentHover: onFragmentHover,\n onFragmentSelect: onFragmentSelect\n };\n\n // Autofocus the first result\n useEffect(() => {\n if (props.shouldBeFocused && anchorElem.current) {\n anchorElem.current.focus();\n }\n }, []);\n\n \n return (\n <a \n ref={anchorElem}\n href={urlWithFragments}\n data-cludo-result=\"searchresult\"\n data-cludo-index={model.ResultIndex}\n data-cludo-url={url}\n data-cludo-title={getFieldValue(result, titleField)}\n data-cludo-page={context.currentPage}\n className={eleClass}\n target={props.openNewTab ? '_blank' : ''}\n {...props.attributes?.root}\n onKeyUp={(e) => onKeyUpHandler(e, eventController)}\n onClick={(e) => onClickHandler(e, eventController, anchorElem.current!)}\n >\n <LinkContext.Provider value={LinkContextInstance}>\n {props.children}\n </LinkContext.Provider>\n </a>\n )\n}\n\nfunction onKeyUpHandler(e: React.KeyboardEvent<HTMLAnchorElement>, eventController: EventController) {\n eventController.searchResultKeyUpEvent(e.nativeEvent);\n}\n\n/**\n * Handle click event on the anchor element -- sets web content highlighting properties and initiaties\n * click tracking\n * @param e \n * @param result \n * @param eventController \n * @param anchorElem \n */\nfunction onClickHandler(\n e: React.MouseEvent<HTMLAnchorElement, MouseEvent>,\n eventController: EventController,\n anchorElem: HTMLElement) {\n eventController.searchResultTrackClickEventHandler(e.nativeEvent, anchorElem);\n}\n","import React, { useContext } from \"react\";\n\ninterface ThemeContextProps {\n // FUTURE: For now, we're just accepting a class name under which consumers can define\n // scoped css variables to apply themes. We decided this is a good way to start theming\n // as it allows consumers to use their own css/sass variables to create themes. In the future,\n // we should also look into supporting themes created with a typed JSON object that we \n // put into scope for the consumer.\n theme: string | undefined;\n}\n\ninterface ThemeProviderProps extends ThemeContextProps {\n children: React.ReactNode;\n}\n\nexport const ThemeContext = React.createContext<ThemeProviderProps>({} as any);\n\nexport function ThemeProvider(props: ThemeProviderProps) {\n\n return (\n props.theme?.length ?\n <ThemeContext.Provider value={props}>\n <div className={props.theme}>\n { props.children }\n </div>\n </ThemeContext.Provider> :\n\n <>{ props.children }</>\n )\n}\n\n\n// This function can be used by components to enter any classes they need to apply themes\n// plus any additional classes from the component's className/s prop and generate a single \n// class string for the component to use.\nexport function generateThemeCss(themeCss: string, disableTheme?: boolean, ...classNameProps: (string | undefined)[]) {\n const themeContext = useContext(ThemeContext);\n\n // Remove undefined class props and join remaining into single string\n const classNamesString = classNameProps.filter(Boolean).join(' ');\n // Apply theme CSS only if theme applied and not manually disabled\n const themeCssString = themeContext && !disableTheme ? themeCss : '';\n\n const stylesToApply = [themeCssString, classNamesString].join(' ');\n return stylesToApply;\n}","import React, { useContext } from \"react\";\nimport { TypedDocument } from \"../../../types/core-script-types\";\nimport { ResultItemBaseProps, ThemeBaseProps } from \"../../types/types\";\nimport { ResultLink } from \"../../elements/result-link\";\nimport { CludoContext } from \"../../../context\";\nimport { generateThemeCss } from \"../../../utils/theme-provider\";\n\ntype CustomResultProps = ResultItemBaseProps & ThemeBaseProps & { \n children: React.ReactNode;\n wrapWithLink?: boolean;\n highlightQueryOnClickedPage?: boolean;\n openNewTab?: boolean;\n}\n\nexport const ResultContext = React.createContext<TypedDocument>({} as any);\n\nexport function CustomResult(props: CustomResultProps) {\n const context = useContext(CludoContext);\n const shouldBeFocused = props.shouldBeFocused ||\n (props.result.ResultIndex === 1\n && context.currentPage === 1\n && context.focusOnResultsAfterSearch);\n\n // Set theme css\n const themeCss = generateThemeCss('cludo-theme-result-link', props.disableTheme, props.className);\n\n return (\n <ResultContext.Provider value={{...props.result}}>\n { props.wrapWithLink || typeof props.wrapWithLink === 'undefined' ? \n <ResultLink\n openNewTab={props.openNewTab}\n highlightQueryOnClickedPage={props.highlightQueryOnClickedPage}\n result={props.result}\n shouldBeFocused={shouldBeFocused}\n className={themeCss}\n attributes={{root: props.attributes?.root}}\n >\n { props.children }\n </ResultLink> : \n <div className={props.className} {...props.attributes?.root}>\n { props.children }\n </div>\n }\n </ResultContext.Provider>\n )\n}\n\n","import React from \"react\";\nimport { FormattedTextChunk } from \"../types/types\";\n\ninterface HighlightedTextCommonProps {\n wrapDefaultText?: boolean;\n}\ninterface ChunkedTextProps extends HighlightedTextCommonProps {\n chunkedText: FormattedTextChunk[];\n splitByTag?: never;\n text?: never;\n}\n\ninterface UnchunkedTextProps extends HighlightedTextCommonProps {\n text: string;\n splitByTag?: 'b' | 'strong';\n chunkedText?: never;\n}\n\nexport type HighlightedTextProps = ChunkedTextProps | UnchunkedTextProps;\n\nexport function HighlightedText(props: HighlightedTextProps) {\n const chunkedText = props.chunkedText ?? splitByHighlightTags(props.text, props.splitByTag);\n const HighlightTag = props.splitByTag ?? 'b';\n\n return (\n <>\n {\n chunkedText.map((value: FormattedTextChunk, i: number) => {\n switch (value.displayType) {\n case 'highlight':\n return <HighlightTag role=\"presentation none\" key={i}>{value.text}</HighlightTag>;\n default:\n return props.wrapDefaultText ? \n <span role=\"presentation none\" key={i}>{value.text}</span> :\n <React.Fragment key={i}>{value.text}</React.Fragment>;\n }\n })\n }\n </>\n )\n}\n\n// Utility: Split string into highlighted and normal parts\nfunction splitByHighlightTags(input: string, hightlightTag?: 'b' | 'strong'): FormattedTextChunk[] {\n const result: { displayType: 'default' | 'highlight'; text: string }[] = [];\n const regex = hightlightTag === 'strong' ? /<strong>(.*?)<\\/strong>/gi : /<b>(.*?)<\\/b>/gi;\n let lastIndex = 0;\n let match: RegExpExecArray | null;\n\n while ((match = regex.exec(input)) !== null) {\n if (match.index > lastIndex) {\n result.push({\n displayType: 'default',\n text: input.slice(lastIndex, match.index),\n });\n }\n result.push({\n displayType: 'highlight',\n text: match[1],\n });\n lastIndex = regex.lastIndex;\n }\n\n if (lastIndex < input.length) {\n result.push({\n displayType: 'default',\n text: input.slice(lastIndex),\n });\n }\n\n return result;\n}","import React, { useContext } from \"react\";\nimport { getFieldValue, getFormattedHTML, getHighlightsOrValues, logMissingResultError } from \"../../utils/result-utils\";\nimport { generateThemeCss } from \"../../utils/theme-provider\";\nimport { ResultContext } from \"../results/items/custom-result\";\nimport { BaseResultProps, HeadingLevel } from \"../types/types\";\nimport { HighlightedText } from \"./cludo-highlighted-text\";\n\ninterface ResultTitleProps extends BaseResultProps {\n\tshowRawText?: boolean;\n\theadingElement?: HeadingLevel;\n\ttitleField?: string;\n}\n\nexport function ResultTitle(props: ResultTitleProps) {\n\tconst resultContext = useContext(ResultContext);\n\tconst result = props.result || resultContext;\n\tif (!result) {\n\t\tlogMissingResultError(\"ResultTitle\");\n\t\treturn null;\n\t}\n\n\t// Set theme css\n\tconst themeCss = generateThemeCss(`cludo-theme-result-title ${props.showRawText ? 'cludo-font-weight-bold' : 'cludo-font-weight-normal'}`, props.disableTheme, props.className);\n\n\tconst Heading = props.headingElement || \"h3\";\n\t// Need to check if result is a document or webpage to determine which title field to use\n\tconst fileType = getFieldValue(result, \"_type\");\n\tconst titleField = props.titleField || (fileType === \"PageContent\" ? \"Title\" : \"fc_Title\");\n\tconst title = props.showRawText ? getFieldValue(result, titleField) : getHighlightsOrValues(result, titleField);\n\n\treturn title ? <Heading className={themeCss} {...props.attributes?.root} ><HighlightedText text={title} /></Heading> : <></>;\n}\n","import React, { useContext } from \"react\";\nimport { CludoContext } from \"../../../context\";\nimport { getFormattedHTML } from \"../../../utils/result-utils\";\nimport { CludoFeature } from \"@cludosearch/cludo-api-client/dist/interfaces/api/public-settings.interface\";\nimport { LinkContext } from \"../result-link\";\nimport { HighlightedText } from \"../cludo-highlighted-text\";\n\n/** FragmentHighlight component */\nexport function FragmentHighlight(props: { fragment: string }) {\n const context = useContext(CludoContext);\n const linkContext = useContext(LinkContext);\n\n const enableWCH = context.isFeatureEnabled(CludoFeature.WebContentHighlighter);; // TODO: Check if enabled for the current engine instead\n const classStr = enableWCH ? 'cludo-theme-fragment-highlight' : 'cludo-ellipsis-after';\n\n return (\n <span\n tabIndex={0}\n role=\"link\"\n className={classStr}\n onKeyDown={\n (e) => {\n if (e.code === 'Enter') {\n linkContext.onFragmentSelect()\n }\n }\n }\n onFocus={() => linkContext.onFragmentHover(props.fragment)}\n onMouseEnter={() => linkContext.onFragmentHover(props.fragment)}\n onMouseLeave={() => linkContext.onFragmentHover()}\n >\n <HighlightedText text={props.fragment}/>\n </span>\n )\n}\n","import React from \"react\";\nimport { TypedDocument } from \"@cludosearch/cludo-api-client/dist/interfaces/api/search.interface\";\nimport { hasField, getHighlightsOrValuesArray } from \"../../../utils/result-utils\";\nimport { FragmentHighlight } from \"../fragment-highlight/fragment-highlight\";\nimport { ThemeBaseProps } from \"../../types/types\";\n\ninterface FragmentHighlightGroupProps extends ThemeBaseProps {\n result: TypedDocument;\n maxFragments?: number;\n maxWords?: number;\n fieldName?: string;\n}\n\nexport function FragmentHighlightGroup(props: FragmentHighlightGroupProps) {\n let fragments = getFragmentsFromResult(props.result, props.maxWords, props.fieldName);\n if (props.maxFragments && props.maxFragments > 0) {\n fragments = fragments.slice(0, props.maxFragments);\n }\n\n return (\n <p className={props.className} {...props.attributes?.root}>\n {fragments}\n </p>\n )\n}\n\n/** Get an array of FragmentHighlights */\nfunction getFragmentsFromResult(result: TypedDocument, maxWords?: number, field?: string): JSX.Element[] {\n const fieldName = field || (hasField(result, 'fc_Content') ? 'fc_Content' : 'Description');\n const fragments = getHighlightsOrValuesArray(result, fieldName, maxWords).map(\n (descriptionPart: string, i: number) => {\n return (\n <FragmentHighlight key={i} \n fragment={descriptionPart}\n />\n );\n }\n )\n\n return fragments;\n}\n","import React, { useContext } from \"react\";\nimport { ResultContext } from \"../results/items/custom-result\";\nimport { getFieldValue, getFormattedHTML, getHighlightsOrValues, hasField, logMissingResultError } from \"../../utils/result-utils\";\nimport { FragmentHighlightGroup } from \"./fragment-highlight-group/fragment-highlight-group\";\nimport { generateThemeCss } from \"../../utils/theme-provider\";\nimport { BaseResultProps } from \"../types/types\";\nimport { HighlightedText } from \"./cludo-highlighted-text\";\n\ninterface ResultDescriptionProps extends BaseResultProps {\n showRawText?: boolean;\n maxWordCount?: number;\n descriptionField?: string;\n highlightDelimiter?: string;\n makeHighlightsClickable?: boolean;\n}\n\nexport function ResultDescription(props: ResultDescriptionProps) {\n const resultContext = useContext(ResultContext);\n const result = props.result || resultContext;\n if (!result) {\n logMissingResultError('ResultDescription');\n return null;\n }\n\n // Set theme css\n const themeCss = generateThemeCss('cludo-theme-result-description', props.disableTheme, props.className); \n \n const descriptionField = props.descriptionField || (hasField(result, 'fc_Content') ? 'fc_Content' : 'Description');\n\n if (props.makeHighlightsClickable) {\n return <FragmentHighlightGroup className={themeCss} result={result} fieldName={descriptionField} maxWords={props.maxWordCount} />\n }\n\n const description = props.showRawText ? \n getFieldValue(result, descriptionField, props.maxWordCount) : \n getHighlightsOrValues(result, descriptionField, props.maxWordCount, undefined, props.highlightDelimiter);\n\n return description ? <p className={themeCss} {...props.attributes?.root} ><HighlightedText text={description} /></p> : <></>\n}","import React, { useContext } from \"react\";\nimport { ResultContext } from \"../results/items/custom-result\";\nimport { getFieldValue, logMissingResultError } from \"../../utils/result-utils\";\nimport { BaseResultProps } from \"../types/types\";\nimport { generateThemeCss } from \"../../utils/theme-provider\";\n\ninterface ResultUrlProps extends BaseResultProps {\n showRelativeUrl?: boolean;\n}\n\nexport function ResultUrl(props: ResultUrlProps) {\n const resultContext = useContext(ResultContext);\n const result = props.result || resultContext;\n if (!result) {\n logMissingResultError('ResultUrl');\n return null;\n }\n\n // Set theme css\n const themeCss = generateThemeCss('cludo-theme-result-url', props.disableTheme, props.className);\n\n let url = getFieldValue(result, 'Url');\n if (props.showRelativeUrl && url) {\n const urlObj = new URL(url);\n url = urlObj.toString().substring(urlObj.origin.length)\n }\n\n return url ? <div title={url} className={themeCss} {...props.attributes?.root}>{ url }</div> : <></>\n\n}","import React, { useContext } from \"react\";\nimport { ResultContext } from \"../results/items/custom-result\";\nimport { getFieldValue, logMissingResultError } from \"../../utils/result-utils\";\nimport { generateThemeCss } from \"../../utils/theme-provider\";\nimport { BaseResultProps } from \"../types/types\";\n\ninterface ResultBadgeProps extends BaseResultProps {\n field?: string;\n text?: string;\n}\n\nconst DEFAULT_BADGE_FIELD = 'Category';\n\nexport function ResultBadge(props: ResultBadgeProps) {\n const resultContext = useContext(ResultContext);\n const result = props.result || resultContext;\n if (!result && !props.text) {\n logMissingResultError('ResultBadge');\n return null;\n }\n \n // Set theme css\n const themeCss = generateThemeCss('cludo-theme-result-badge', props.disableTheme, props.className); \n\n const displayText = props.text || getFieldValue(result, props.field || DEFAULT_BADGE_FIELD);\n\n return displayText ? \n <span className={themeCss} {...props.attributes?.root}>{ displayText } </span> : null;\n}","import React, { useContext } from \"react\";\nimport { ResultItemBaseProps, StandardResultWidgetType, ThemeBaseProps } from \"../../types/types\";\nimport { CustomResult, ResultContext } from \"./custom-result\";\nimport { ResultTitle } from \"../../elements/result-title\";\nimport { ResultDescription } from \"../../elements/result-description\";\nimport { ResultUrl } from \"../../elements/result-url\";\nimport { ResultBadge } from \"../../elements/result-badge\";\n\nexport type StandardResultProps = \nResultItemBaseProps & \nThemeBaseProps<\n 'root' |\n 'title' |\n 'description' |\n 'url' |\n 'badge'\n> & {\n hideTitle?: boolean;\n hideDescription?: boolean;\n hideUrl?: boolean;\n hideBadge?: boolean;\n badgeField?: string;\n order?: StandardResultWidgetType[];\n makeHighlightsClickable?: boolean;\n highlightQueryOnClickedPage?: boolean\n descriptionMaxWordCount?: number;\n}\n\nconst defaultOrder: StandardResultWidgetType[] = ['title', 'description', 'url', 'badge'];\n\nfunction generateRenderOrder(propOrder: StandardResultWidgetType[]) {\n const generatedOrder = propOrder.concat(\n defaultOrder.filter(el => (propOrder.indexOf(el) === -1))\n );\n return generatedOrder;\n}\n\nexport function StandardResult(props: StandardResultProps) {\n const propOrder = props.order || [];\n\n let renderOrder = generateRenderOrder(propOrder);\n\n // Set final render order to props order and fill in any missing widgets from default\n // Filter out hidden widgets from order\n renderOrder = renderOrder.filter(el => {\n return !((el === 'title' && props.hideTitle) ||\n (el === 'description' && props.hideDescription) ||\n (el === 'url' && props.hideUrl) ||\n (el === 'badge' && props.hideBadge));\n });\n // Create lookup map for widget keys and JSX elements\n const widgetMap = new Map<StandardResultWidgetType, React.ReactNode>(\n [\n [\"title\", <ResultTitle className={props.classNames?.title} attributes={{root: props.attributes?.title}} disableTheme={props.disableTheme}/>],\n [\"description\", <ResultDescription className={props.classNames?.description}attributes={{root: props.attributes?.description}} disableTheme={props.disableTheme} maxWordCount={props.descriptionMaxWordCount || 90} makeHighlightsClickable={props.makeHighlightsClickable}/>],\n [\"url\", <ResultUrl className={props.classNames?.url} attributes={{root: props.attributes?.url}} disableTheme={props.disableTheme}/>],\n [\"badge\", <ResultBadge className={props.classNames?.badge} attributes={{root: props.attributes?.badge}} disableTheme={props.disableTheme} field={props.badgeField || 'Category'}/>]\n ]\n );\n\n return (\n <CustomResult \n highlightQueryOnClickedPage={props.highlightQueryOnClickedPage}\n disableTheme={props.disableTheme}\n className={`${props.className ?? ''}\n ${props.classNames?.root ?? ''}`}\n attributes={{root: props.attributes?.root}}\n result={props.result}\n shouldBeFocused={props.shouldBeFocused}\n >\n {\n renderOrder.map((el, i) => \n <React.Fragment key={i}>\n { widgetMap.get(el) }\n </React.Fragment>\n )\n }\n </CustomResult>\n )\n}","import { useContext } from \"react\";\nimport { CludoContext, EventControllerContext } from \"../context\";\n\n/** Helper for accessing both CludoContext and EventControllerContext */\nexport function useCludoContext() {\n const context = useContext(CludoContext);\n const eventController = useContext(EventControllerContext);\n\n return { context: context, eventController: eventController };\n}\n","import { useContext, useEffect } from \"react\";\nimport { EventType } from \"../utils/components-controller\";\nimport { EventControllerContext } from \"../context\";\n\n\n/** When the event controller receives any provided events, run a callback function\n * @param callback Function to call when events have been processed\n * @param events Array of events to subscribe to. If none provided, the callback will fire for\n * all events\n */\nexport function useEventSubscriptions(callback: Function, events?: EventType[]) {\n const eventController = useContext(EventControllerContext);\n\n useEffect(() => {\n let subscriptions: number[] = [];\n if (eventController && Object.keys(eventController).length > 0) {\n if (!events) {\n subscriptions = [eventController.subscribeToAllEvents(() => callback())];\n } else {\n events.forEach(eventType => {\n subscriptions.push(eventController.subscribe(eventType, callback));\n });\n }\n }\n return () => {\n if (eventController && eventController.unsubscribe) {\n subscriptions.forEach(subscriptionId => eventController.unsubscribe(subscriptionId));\n }\n }\n \n }, [eventController]);\n}","import { useState } from \"react\";\nimport { useCludoContext } from \"./use-cludo-context\";\nimport { useEventSubscriptions } from \"./use-event-subscription\";\n\nexport interface PaginationState {\n itemsPerPage: number;\n currentPage: number;\n maxPages: number;\n nextPageLabel: string;\n prevPageLabel: string;\n showPagination: boolean;\n showResultsPerPage: boolean;\n}\n\nexport interface PaginationDispatchers {\n goToPage: (pageNumber: number) => void;\n setPerPage: (perPage: number) => void;\n}\n\nexport function usePagination(): [PaginationState, PaginationDispatchers] {\n const { context, eventController } = useCludoContext();\n const searchResponse = context.storedSearchResponseData.cludoSearchResponse;\n\n // Derive state from CludoSearchContext\n const deriveState : () => PaginationState = () => {\n const resultsPerPage = context.resultsPerPage || 10;\n return {\n itemsPerPage: context.resultsPerPage || 10,\n currentPage: context.currentPage || 1,\n maxPages: Math.ceil(context.storedSearchResponseData?.cludoSearchResponse.ResultCount / resultsPerPage),\n nextPageLabel: context.translateProvider?.translate('next_page') || 'Next page',\n prevPageLabel: context.translateProvider?.translate('prev_page') || 'Previous page',\n showPagination: !(searchResponse.ResultCount < context.resultsPerPage || context.isEndlessScrollEnabled),\n showResultsPerPage: !(context.storedSearchResponseData.cludoSearchResponse.ResultCount <= 0 || context.isEndlessScrollEnabled)\n };\n }\n\n // Derive dispatchers from EventController\n // FUTURE: Investigate getting rid of bind here\n const deriveDispatchers : () => PaginationDispatchers = () => {\n return {\n goToPage: eventController?.goToPage?.bind(eventController) || (() => {}),\n setPerPage: eventController?.setPerPage?.bind(eventController) || (() => {})\n };\n }\n\n // When eventController changes, derive state and dispatchers again\n useEventSubscriptions(() => {\n setCludoState(deriveState());\n setCludoDispatchers(deriveDispatchers());\n });\n\n const [cludoState, setCludoState] = useState(deriveState());\n const [cludoDispatchers, setCludoDispatchers] = useState(deriveDispatchers());\n\n return [ cludoState, cludoDispatchers ];\n}","import { useState } from \"react\";\nimport { useCludoContext } from \"./use-cludo-context\";\nimport { BannerDefinition, RelatedSearchDocument, TopHit, TypedDocument } from \"../types/core-script-types\";\nimport { Facets } from \"@cludosearch/cludo-api-client/dist/interfaces/api/search.interface\";\nimport { EndlessScrollOptions } from \"../utils/models/instantiator-types\";\nimport { useEventSubscriptions } from \"./use-event-subscription\";\n\ninterface SearchResultEndlessScrollOptions extends EndlessScrollOptions {\n isEnabled: boolean;\n}\n\nexport interface SearchResultsState {\n suggestions: string[];\n results: TypedDocument[];\n categorizedResults: TopHit[];\n resultsSummary: {\n resultCount: number;\n resultCountMessage: string;\n fixedQuery: string;\n facets: Facets;\n didYouMean: string;\n };\n paginationOptions: {\n itemsPerPage: number;\n currentPage: number;\n maxPages: number;\n };\n currentPage: number;\n resultCount: number;\n endlessScrollOptions: SearchResultEndlessScrollOptions;\n banners: BannerDefinition[];\n relatedSearches: RelatedSearchDocument[];\n isLoading: boolean;\n}\n\nexport interface SearchResultsDispatchers {\n loadMore: () => void;\n searchResultKeyUp: (e: KeyboardEvent) => void;\n linkToSearchClickEvent: (anchor: HTMLAnchorElement) => void;\n handleDidYouMeanSelect: (text: string) => void;\n searchResultTrackClickEventHandler: (e: MouseEvent | KeyboardEvent, target: HTMLElement) => void;\n}\n\n/** Expose state and dispatchers for displaying search results\n * @returns cludoState (search result data, metadata, and config values) and cludoDispatchers (load more results event)\n */\nexport function useSearchResults(): [SearchResultsState, SearchResultsDispatchers] {\n const { context, eventController } = useCludoContext();\n\n // Derive state from CludoSearchContext\n const deriveState : () => SearchResultsState = () => {\n const currentPage = context.currentPage || 1;\n const resultsPerPage = context.resultsPerPage || 10;\n const resultsSummary = {\n resultCount: context.storedSearchResponseData?.cludoSearchResponse?.ResultCount || 0,\n resultCountMessage: context.storedSearchResponseData?.cludoSearchResponse?.ResultCountMessage || '',\n fixedQuery: context.storedSearchResponseData?.cludoSearchResponse?.FixedQuery || '',\n facets: context.storedSearchResponseData?.cludoSearchResponse?.Facets,\n didYouMean: context.storedSearchResponseData?.cludoSearchResponse?.Suggestions[0] || '',\n };\n return {\n suggestions: context.storedSearchResponseData?.cludoSearchResponse?.Suggestions || [],\n results: context.storedSearchResponseData?.cludoSearchResponse?.TypedDocuments || [],\n categorizedResults: context.storedSearchResponseData?.cludoSearchResponse?.TopHits || [],\n resultsSummary: resultsSummary,\n paginationOptions: {\n itemsPerPage: context.resultsPerPage,\n currentPage: context.currentPage,\n maxPages: Math.ceil(context.storedSearchResponseData?.cludoSearchResponse?.ResultCount / resultsPerPage),\n },\n endlessScrollOptions: {\n isEnabled: context.isEndlessScrollEnabled,\n ...context.endlessScroll as EndlessScrollOptions\n },\n currentPage: currentPage,\n banners: context.storedSearchResponseData?.cludoSearchResponse?.Banners || [],\n relatedSearches: context.storedSearchResponseData?.cludoSearchResponse?.RelatedSearchDocuments || [],\n resultCount: context.storedSearchResponseData?.cludoSearchResponse?.ResultCount || 0,\n isLoading: context.isLoadingResults\n }\n };\n\n // Derive dispatchers from EventController\n // FUTURE: Investigate getting rid of bind here\n const deriveDispatchers : () => SearchResultsDispatchers = () => {\n return {\n loadMore: eventController?.endlessScrollLoadMore?.bind(eventController) || (() => {}),\n searchResultKeyUp: eventController?.searchResultKeyUpEvent?.bind(eventController) || (() => {}),\n linkToSearchClickEvent: eventController?.linkToSearchClickEvent?.bind(eventController) || (() => {}),\n handleDidYouMeanSelect: eventController?.handleDidYouMeanSelect?.bind(eventController) || (() => {}),\n searchResultTrackClickEventHandler: eventController?.searchResultTrackClickEventHandler?.bind(eventController) || (() => {})\n }\n }\n\n // When eventController changes, derive state and dispatchers again\n useEventSubscriptions(() => {\n setCludoState(deriveState());\n setCludoDispatchers(deriveDispatchers());\n });\n\n const [cludoState, setCludoState] = useState(deriveState());\n const [cludoDispatchers, setCludoDispatchers] = useState(deriveDispatchers());\n\n return [ cludoState, cludoDispatchers ];\n}","import React, { useContext, useEffect, useState } from \"react\";\nimport { CludoContext } from \"../../../context\";\nimport { PaginationState, usePagination } from \"../../../hooks/use-pagination\";\nimport { generateThemeCss } from \"../../../utils/theme-provider\";\nimport { ThemeBaseProps } from \"../../types/types\";\nimport { useSearchResults } from \"../../../hooks/use-search-results\";\n\ninterface PaginationProps extends ThemeBaseProps<\n 'root' |\n 'list' |\n 'listItem' |\n 'firstButton' |\n 'lastButton' |\n 'previousButton' |\n 'nextButton' |\n 'pageNumberButton' |\n 'currentPageButton'\n> {\n hidePrevious?: boolean,\n hideNext?: boolean,\n hideFirst?: boolean,\n hideLast?: boolean,\n previousButtonIcon?: React.ReactNode;\n nextButtonIcon?: React.ReactNode;\n firstButtonIcon?: React.ReactNode;\n lastButtonIcon?: React.ReactNode;\n} \n\n\nexport function Pagination(props: PaginationProps) {\n const [ paginationState, paginationDispatchers ] = usePagination();\n const [ resultsState ] = useSearchResults();\n const [ localPaginationState, setLocalPaginationState ] = useState<PaginationState>(paginationState);\n const context = useContext(CludoContext);\n\n useEffect(() => {\n if (!context.isLoadingResults) {\n setLocalPaginationState(paginationState);\n }\n }, [paginationState])\n\n const previousButtonIcon = props.previousButtonIcon || '<';\n const nextButtonIcon = props.nextButtonIcon || '>';\n const firstButtonIcon = props.firstButtonIcon || '<<';\n const lastButtonIcon = props.lastButtonIcon || '>>';\n const startPage: number = (localPaginationState.currentPage <= 5) \n ? 1\n : (localPaginationState.currentPage >= localPaginationState.maxPages - 2\n ? localPaginationState.maxPages - 3\n : localPaginationState.currentPage - 2);\n\n const prevPageTranslation = localPaginationState.prevPageLabel;\n const nextPageTranslation = localPaginationState.nextPageLabel;\n \n // Set theme css\n const activeBtnCss = generateThemeCss('cludo-theme-btn-accent-secondary cludo-width-sm cludo-mr-2 cludo-my-1', props.disableTheme);\n const inactiveBtnCss = generateThemeCss('cludo-theme-btn-accent-secondary-inactive cludo-width-sm cludo-mr-2 cludo-my-1', props.disableTheme);\n const loadingCss = generateThemeCss(' cludo-theme-loading-disable', props.disableTheme || !resultsState.isLoading);\n\n function renderPageNumberButtons(startPage: number, maxPages: number) {\n \n const currentPageNum = localPaginationState.currentPage || 1;\n let pageNumberButtons: JSX.Element[] = [];\n \n const pageTranslation = context.translateProvider.translate('general_page');\n \n for (let i = startPage; i <= maxPages && i <= startPage + 4; i++) {\n if (i === currentPageNum) {\n pageNumberButtons.push(\n <li className={props.classNames?.listItem} {...props.attributes?.listItem} key={i}>\n <button \n aria-label={'Current, ' + pageTranslation + ' ' + i} \n aria-current=\"true\" \n aria-disabled=\"true\"\n className={`${props.classNames?.pageNumberButton ?? ''} ${props.classNames?.currentPageButton ?? ''} ${inactiveBtnCss}`}\n {...props.attributes?.pageNumberButton}\n {...props.attributes?.currentPageButton}\n >\n {i}\n </button>\n </li>\n );\n } else {\n pageNumberButtons.push(\n <li className={props.classNames?.listItem} {...props.attributes?.listItem} key={i}>\n <button aria-label={pageTranslation + ' ' + i}\n className={`${props.classNames?.pageNumberButton ?? ''} ${activeBtnCss}`}\n onClick={() => { paginationDispatchers.goToPage(i) }}\n {...props.attributes?.pageNumberButton}\n >\n {i}\n </button>\n </li>\n );\n }\n }\n return pageNumberButtons;\n }\n\n return (\n localPaginationState.showPagination ?\n <nav className={`${props.className ?? ''} ${props.classNames?.root ?? ''} ${loadingCss}`} {...props.attributes?.root}>\n <ul className={`${props.classNames?.list ?? ''} cludo-display-flex cludo-list-style-none cludo-p-0 cludo-m-0 cludo-mt-3 cludo-flex-wrap`} {...props.attributes?.list}>\n {/* First page button */}\n { (localPaginationState.currentPage !== 1) && !props.hideFirst ? \n <li className={props.classNames?.listItem} {...props.attributes?.listItem} key=\"first\">\n <button data-page=\"first\"\n className={`${props.classNames?.firstButton ?? ''} ${activeBtnCss}`}\n aria-label=\"First page\"\n onClick={() => { paginationDispatchers.goToPage(1)}}\n {...props.attributes?.firstButton}\n >\n { firstButtonIcon }\n </button>\n </li> : null\n }\n {/* Previous page button */}\n { (localPaginationState.currentPage !== 1) && !props.hidePrevious ? \n <li className={props.classNames?.listItem} {...props.attributes?.listItem} key=\"prev\">\n <button data-page=\"prev\"\n className={`${props.classNames?.previousButton ?? ''} ${activeBtnCss}`}\n aria-label={prevPageTranslation}\n onClick={() => { paginationDispatchers.goToPage(localPaginationState.currentPage - 1)}}\n {...props.attributes?.previousButton}\n >\n { previousButtonIcon }\n </button>\n </li> : null\n }\n\n { renderPageNumberButtons(startPage, localPaginationState.maxPages ) }\n\n {/* Next page button */}\n { (localPaginationState.currentPage < localPaginationState.maxPages) && !props.hideNext ? \n <li className={props.classNames?.listItem} {...props.attributes?.listItem} key=\"next\">\n <button data-page=\"next\"\n className={`${props.classNames?.nextButton ?? ''} ${activeBtnCss}`}\n aria-label={nextPageTranslation}\n onClick={() => { paginationDispatchers.goToPage(localPaginationState.currentPage + 1) }}\n {...props.attributes?.nextButton}\n >\n { nextButtonIcon }\n </button>\n </li> : null\n }\n {/* Last page button */}\n { (localPaginationState.currentPage < localPaginationState.maxPages) && !props.hideLast ? \n <li className={props.classNames?.listItem} {...props.attributes?.listItem} key=\"last\">\n <button data-page=\"last\"\n className={`${props.classNames?.lastButton ?? ''} ${activeBtnCss}`}\n aria-label=\"Last page\"\n onClick={() => { paginationDispatchers.goToPage(localPaginationState.maxPages) }}\n {...props.attributes?.lastButton}\n >\n { lastButtonIcon }\n </button>\n </li> : null\n }\n </ul>\n </nav> : null\n )\n}","import React, { useContext, useEffect, useRef, useState } from \"react\";\nimport { getFormattedHTML } from \"../../utils/result-utils\";\nimport { CludoContext, EventControllerContext } from \"../../context\";\nimport { CludoSearchContext } from \"../../utils/cludo-search-context\";\nimport { EventController } from \"../../utils/event-controller\";\nimport { BannerDefinition } from \"../../types/core-script-types\";\nimport { generateThemeCss } from \"../../utils/theme-provider\";\nimport { ThemeBaseProps } from \"../types/types\";\n\nexport interface BannerProps extends ThemeBaseProps { banner: BannerDefinition }\n\nexport function Banner(props: BannerProps) {\n const context = useContext(CludoContext);\n const eventController = useContext(EventControllerContext);\n const bannerRef = useRef(null);\n\n useEffect(() => {\n if (bannerRef.current) {\n onBannerLoad(bannerRef.current, props.banner, context, eventController);\n }\n }, []);\n \n const bannerCss = \n generateThemeCss('cludo-mb-4 cludo-overflow-auto cludo-border-radius-card cludo-p-4 cludo-bg-color-accent-primary-light', props.disableTheme, props.className);\n \n const loadingCss = \n generateThemeCss('cludo-theme-loading-disable-children', props.disableTheme || !context.isLoadingResults);\n\n return (\n <div\n ref={bannerRef}\n data-cludo-result=\"banner\"\n data-cludo-id={props.banner.Id}\n data-cludo-title={props.banner.Name}\n className={`cludo-banner ${bannerCss} ${loadingCss}`}\n role=\"banner\"\n dangerouslySetInnerHTML={\n getFormattedHTML(props.banner.Banner)\n }\n {...props.attributes?.root}\n ></div>\n )\n}\n\nfunction onBannerLoad(\n target: HTMLElement,\n banner: BannerDefinition,\n context: CludoSearchContext,\n eventController: EventController) {\n const bannerLinks = target.querySelectorAll('a');\n const paramsPrefix = context.paramsPrefix;\n\n bannerLinks.forEach( link => {\n addBannerAttributesToAnchor(link, banner);\n if (decodeURIComponent(link.href).indexOf('#?' + paramsPrefix) !== -1) {\n link.addEventListener('click', (e) => {\n e.preventDefault();\n eventController.linkToSearchClickEvent(link);\n })\n } else {\n link.addEventListener('click', (e) => {\n eventController.searchResultTrackClickEventHandler(e, link);\n })\n }\n })\n}\n\nfunction addBannerAttributesToAnchor(anchor: HTMLAnchorElement, banner: BannerDefinition) {\n const bannerId = String(banner.Id);\n const bannerTitle = banner.Name;\n\n anchor.setAttribute(\"data-cludo-result\", \"banner\");\n anchor.setAttribute(\"data-cludo-index\", \"1\");\n anchor.setAttribute(\"data-cludo-object-id\", bannerId);\n anchor.setAttribute(\"data-cludo-title\", bannerTitle);\n}","import { useState } from \"react\";\nimport { useCludoContext } from \"./use-cludo-context\";\nimport { BannerDefinition } from \"../types/core-script-types\";\nimport { useEventSubscriptions } from \"./use-event-subscription\";\n\nexport interface BannersState {\n banners: BannerDefinition[];\n}\n\n/** Expose state for displaying banners\n * @returns cludoState object containing an array of currently active banners\n */\nexport function useBanners(): [BannersState] {\n const { context } = useCludoContext();\n\n // Derive state from CludoSearchContext\n const deriveState : () => BannersState = () => {\n return {\n banners: context.storedSearchResponseData?.cludoSearchResponse.Banners || [],\n }\n }\n\n // When eventController changes, derive state and dispatchers again\n useEventSubscriptions(() => setCludoState(deriveState()))\n\n const [cludoState, setCludoState] = useState(deriveState());\n\n return [ cludoState ];\n}","import React from \"react\";\nimport { Banner } from \"../banner\";\nimport { useBanners } from \"../../../hooks/use-banners\";\nimport { BannerDefinition } from \"../../../types/core-script-types\";\n\nexport function BannerGroup(props: {banners?: BannerDefinition[], className?: string}) {\n const [bannersState] = useBanners();\n const banners = props.banners || bannersState.banners;\n const bannerComponents = banners.map( (banner) => <Banner key={banner.Id} banner={banner} className={props.className} />);\n return (\n bannerComponents.length ?\n <div className=\"cludo-banner-group\">\n { bannerComponents }\n </div> : <></>\n )\n}","import React, { useContext } from 'react';\nimport { CludoContext, EventControllerContext } from '../../../context';\nimport { EventController } from '../../../utils/event-controller';\nimport { getFormattedHTML } from '../../../utils/result-utils';\nimport { useSearchResults } from '../../../hooks/use-search-results';\nimport { ThemeBaseProps } from '../../types/types';\nimport { generateThemeCss } from '../../../utils/theme-provider';\n\nexport interface DidYouMeanProps extends ThemeBaseProps {\n suggestedQuery?: string;\n}\n\nexport function DidYouMean(props: DidYouMeanProps) {\n const [ resultsState, resultsDispatchers ] = useSearchResults();\n const context = useContext(CludoContext);\n const eventController = useContext(EventControllerContext);\n\n const suggestionFromContext = resultsState.resultCount && resultsState.resultCount < 10 ? resultsState.resultsSummary.didYouMean : '';\n const suggestedQuery = props.suggestedQuery || suggestionFromContext;\n const didYouMeanInnerHTML = context.translateProvider.translate('did_you_mean', suggestedQuery);\n \n // Set theme css\n const themeCss = generateThemeCss('cludo-font-family-default cludo-font-size-md cludo-mb-2', props.disableTheme, props.className);\n const loadingCss = generateThemeCss(' cludo-theme-loading-disable', props.disableTheme || !resultsState.isLoading);\n\n return (\n <div className={themeCss + loadingCss + ' cludo-did-you-mean'}\n {...props.attributes?.root}\n onClick={(e) => onDidYouMeanClick(e, suggestedQuery, eventController)}\n dangerouslySetInnerHTML={ suggestedQuery ? getFormattedHTML(didYouMeanInnerHTML) : { __html: '' } }\n />\n )\n}\n\nfunction onDidYouMeanClick(event: React.MouseEvent, suggestion: string, eventController: EventController) {\n const target = event.target;\n if (target instanceof HTMLElement) {\n\n // If we clicked on the anchor tag or its child, handle setting Did You Mean properties\n const anchorElem = target.closest('.cludo-did-you-mean > a');\n if (anchorElem) {\n // Prevent navigation\n event.preventDefault();\n \n // Call utility function which restores autocomplete and searches for the suggestion\n eventController.handleDidYouMeanSelect(suggestion);\n }\n }\n}","import React, { useContext, useEffect, useState } from \"react\";\nimport { CludoContext } from \"../../../context\";\nimport { useSearchResults } from \"../../../hooks/use-search-results\";\nimport { ThemeBaseProps } from \"../../types/types\";\nimport { generateThemeCss } from \"../../../utils/theme-provider\";\nimport { HighlightedText } from \"../../elements/cludo-highlighted-text\";\n\nexport interface ResultCountProps extends ThemeBaseProps {\n resultCount?: number;\n}\n\nexport function ResultCount(props: ResultCountProps) {\n const [ resultsState, resultsDispatchers ] = useSearchResults();\n const [ resultTextState, setResultTextState] = useState('');\n const context = useContext(CludoContext);\n const resultCount = props.resultCount || resultsState.resultCount;\n const query = context.storedSearchResponseData.cludoSearchResponse.Query;\n \n useEffect(() => {\n if (!context.isLoadingResults && query) {\n // Set result count message from combination of your search and total results translations\n const yourSearchMsg = \n context.translateProvider.translate('your_search_on', query);\n const totalMsg = \n resultCount === 1 ? \n context.translateProvider.translate('total_result', resultCount.toString()) :\n context.translateProvider.translate('total_results', resultCount.toString());\n const resultMsg = \n yourSearchMsg + \n (yourSearchMsg.length && totalMsg.length ? ' ' : '') + \n totalMsg;\n setResultTextState(resultMsg);\n }\n }, [resultsState]);\n \n // Set theme css\n const themeCss = generateThemeCss('cludo-font-family-default cludo-font-size-md cludo-mb-2', props.disableTheme, props.className);\n const loadingCss = generateThemeCss(' cludo-theme-loading-disable', props.disableTheme || !context.isLoadingResults)\n\n return (\n resultTextState.length ? \n <span className={themeCss + loadingCss} role=\"status\" {...props.attributes?.root}><HighlightedText text={resultTextState}/></span> : null\n )\n}","import React from \"react\";\n\nimport { DidYouMean, DidYouMeanProps } from \"./did-you-mean\";\nimport { ResultCount, ResultCountProps } from \"./result-count\";\n\ntype ResultsSummaryProps = ResultCountProps & DidYouMeanProps;\n\nexport function ResultsSummary(props: ResultsSummaryProps) {\n return (\n <>\n <ResultCount {...(props)} />\n\n <DidYouMean suggestedQuery={props.suggestedQuery} />\n </>\n )\n}","import React, { useContext } from \"react\";\nimport { CludoContext } from \"../../context\";\nimport { LoaderProps } from \"../types/types\";\n\n/** Default Search Results template */\nexport function CludoLoader(props: LoaderProps) {\n const context = useContext(CludoContext);\n const loadingAltText = context.translateProvider.translate('loading_results');\n return (\n <>\n {\n props.isLoading\n ? <img src=\"https://customer.cludo.com/img/loading.gif\" className=\"loading\" tabIndex={-1} alt={loadingAltText} />\n : <></>\n }\n </>\n )\n}","import React from \"react\";\nimport { ThemeBaseProps } from \"../../types/types\";\n\nexport function StandardLoader(props: ThemeBaseProps) {\n return(\n <div className={`cludo-loader ${props.className}`} {...props.attributes?.root}>\n <div></div>\n <div></div>\n <div></div>\n <div></div>\n </div>\n )\n}","import React, { useContext, useEffect, useState } from \"react\";\nimport { BannerDefinition, TypedDocument } from \"../../../types/core-script-types\";\nimport { useSearchResults } from \"../../../hooks/use-search-results\";\nimport { StandardResult } from \"../items/standard-result\";\nimport { CssUnit, LayoutColumnOptions, ThemeBaseProps } from \"../../types/types\";\nimport { generateThemeCss } from \"../../../utils/theme-provider\";\nimport { StandardLoader } from \"../../elements/loader/standard-loader\";\nimport { useBanners } from \"../../../hooks/use-banners\";\nimport { Banner } from \"../../elements/banner\";\nimport { CludoContext } from \"../../../context\";\n\nexport type ResultsListProps = ThemeBaseProps<\n 'root' |\n 'banner' |\n 'resultsListContainer' |\n 'resultsListItem' |\n 'loaderContainer'\n> & {\n results?: TypedDocument[];\n columns?: LayoutColumnOptions;\n columnsBreakpoint?: number;\n resultSpacing?: number;\n cssUnit?: CssUnit;\n hideBanners?: boolean;\n template?: (result: TypedDocument, shouldBeFocused?: boolean) => React.ReactNode;\n customLoader?: React.ReactNode;\n focusIndex?: number;\n}\n\nexport function ResultsList(props: ResultsListProps) {\n const [resultsState, resultsdispatchers] = useSearchResults();\n const [bannersState] = useBanners();\n const context = useContext(CludoContext);\n // Resolve props with defaults\n const templateFn = props.template ?? ((result: TypedDocument, shouldBeFocused?: boolean) => <StandardResult shouldBeFocused={shouldBeFocused} disableTheme={props.disableTheme} result={result} />)\n const results = props.results ?? resultsState.results;\n const columns = props.columns ?? 1;\n const loader = props.customLoader ?? <StandardLoader></StandardLoader>;\n const resultSpacing = props.resultSpacing ?? 0;\n const cssUnit = props.cssUnit ?? 'px';\n const focusIndex = props.focusIndex ?? context.focusIndex;\n const [resultsToRender, setResultsToRender] = useState<TypedDocument[]>([]);\n const [bannersToRender, setBannersToRender] = useState<BannerDefinition[]>([]);\n\n useEffect(() => {\n if (!context.isLoadingResults) {\n setResultsToRender(results);\n }\n }, [resultsState]);\n\n useEffect(() => {\n if (!context.isLoadingResults) {\n setBannersToRender(bannersState.banners);\n }\n }, [bannersState]);\n\n // Set theme css\n // FUTURE: we apply structural css here no matter what - need to rethink how we handle structural css\n const containerCss = \n generateThemeCss('cludo-position-relative', props.disableTheme, props.className, props.classNames?.root);\n const bannerCss = \n generateThemeCss('', props.disableTheme, props.classNames?.banner);\n const listCss = \n generateThemeCss('cludo-theme-results-list', props.disableTheme, props.classNames?.resultsListContainer) +\n \" cludo_results-list cludo-box-sizing cludo-display-flex cludo-flex-wrap cludo-list-style-none cludo-p-0\";\n const listItemCss =\n generateThemeCss('', props.disableTheme, props?.classNames?.resultsListItem) +\n \" cludo_result cludo-border-box cludo-col-in-grid-\" + columns\n const loadingCss = \n generateThemeCss(' cludo-theme-loading-disable', props.disableTheme || !context.isLoadingResults);\n const loaderCss =\n generateThemeCss('cludo-my-5 cludo-position-absolute cludo-top-0 cludo-absolute-center', props.disableTheme, props.classNames?.loaderContainer)\n\n const generateStyleOverrides = () => {\n let cssString = ``;\n // FUTURE: Offer discrete breakpoints (i.e. breakpoint-sm) possibly using a library like Tailwinds\n if (props.columnsBreakpoint) {\n cssString += `\n @media (max-width: ${props.columnsBreakpoint}${cssUnit}) {\n .cludo_result { width: 100% !important }\n }\n `\n }\n \n cssString += `\n .cludo_results-list { margin: -${resultSpacing/2}${cssUnit} }\n .cludo_result { padding: ${resultSpacing/2}${cssUnit} }\n `\n return cssString;\n }\n\n return (\n <> \n { !props.hideBanners ?\n bannersToRender.map((banner, i) =>\n <Banner key={'banner-' + i} className={bannerCss} attributes={{root: props.attributes?.banner}} banner={banner}></Banner>\n ) : <></>\n }\n <div className={containerCss} {...props.attributes?.root}>\n { resultsToRender.length > 0 &&\n <>\n <style>\n { generateStyleOverrides() }\n </style>\n <ul className={listCss} {...props.attributes?.resultsListContainer}>\n { resultsToRender.map((result, i) => \n <li className={listItemCss + loadingCss} {...props.attributes?.resultsListItem} key={'result-' + i}>\n { templateFn(result, i === focusIndex) }\n </li>\n )}\n </ul>\n </>\n }\n {\n !props.disableTheme && resultsState.isLoading ?\n <div className={loaderCss} {...props.attributes?.loaderContainer}>\n { loader }\n </div> : <></>\n }\n </div>\n </>\n )\n}","import React, { useContext } from \"react\";\nimport { CludoContext } from \"../../context\";\nimport { ThemeBaseProps } from \"../types/types\";\n\ninterface LoadMoreProps extends ThemeBaseProps<\n 'root' |\n 'loadMoreButton'\n> {\n onClick: (wasKeyboardClick?: boolean) => void;\n label?: string;\n}\n\nexport function LoadMore(props: LoadMoreProps) {\n const context = useContext(CludoContext);\n\n const loadMoreStr: string = props.label || context.translateProvider.translate('load_more');\n\n function handleClick(e: React.MouseEvent) {\n const wasKeyboardClick = e.detail === 0 ? true : false;\n props.onClick(wasKeyboardClick);\n }\n\n return (\n <div className={`${props.classNames?.root ?? ''} ${props.className ?? ''}`} id=\"cludo-load-more\" {...props.attributes?.root}>\n <button className={props.classNames?.loadMoreButton ?? ''} type=\"button\" onClick={handleClick} {...props.attributes?.loadMoreButton}>\n { loadMoreStr }\n </button>\n </div>\n )\n}","import React, { useContext } from \"react\";\nimport { CludoContext } from \"../../context\";\nimport { useSearchResults } from \"../../hooks/use-search-results\";\nimport { usePagination } from \"../../hooks/use-pagination\";\nimport { LoadMore } from \"./cludo-load-more\";\nimport { generateThemeCss } from \"../../utils/theme-provider\";\nimport { ThemeBaseProps } from \"../types/types\";\n\ninterface LoadMoreResultsProps extends ThemeBaseProps<\n // Child component custom class names definition\n 'root' |\n 'loadMoreButton'\n> { \n label?: string;\n onLoadMore?: (wasKeyboardClick?: boolean) => void;\n disableKeyboardFocusHandling?: boolean;\n}\n\nexport function LoadMoreResults(props: LoadMoreResultsProps) {\n const [searchResultsState, searchResultsDispatchers] = useSearchResults();\n const [paginationState, paginationDispatchers] = usePagination();\n const context = useContext(CludoContext);\n\n const loadMoreStr: string = props.label || context.translateProvider.translate('load_more');\n const showLoadMore = searchResultsState.endlessScrollOptions.isEnabled\n && searchResultsState.resultCount > 0\n && searchResultsState.endlessScrollOptions?.stopAfterPage\n && searchResultsState.endlessScrollOptions?.stopAfterPage <= paginationState.currentPage\n && paginationState.currentPage !== paginationState.maxPages\n && !searchResultsState.isLoading;\n \n // Set theme css\n const rootCss = generateThemeCss('', props.disableTheme, props.className, props.classNames?.root)\n const buttonCss = generateThemeCss('cludo-theme-btn-accent-secondary cludo-font-size-sm cludo-font-weight-bold cludo-width-100 cludo-mt-3', props.disableTheme, props.classNames?.loadMoreButton);\n const classNamesObj = {\n root: rootCss,\n loadMoreButton: buttonCss\n }\n const attrsObj = {\n root: props.attributes?.root,\n loadMoreButton: props.attributes?.loadMoreButton\n }\n\n function handleLoadMore(wasKeyboardClick?: boolean) {\n if (wasKeyboardClick && !props.disableKeyboardFocusHandling) {\n context.focusIndex = searchResultsState.results.length;\n } else {\n context.focusIndex = undefined;\n }\n props.onLoadMore && props.onLoadMore(wasKeyboardClick);\n searchResultsDispatchers.loadMore();\n }\n\n return (\n showLoadMore ?\n <LoadMore classNames={classNamesObj} attributes={attrsObj} label={loadMoreStr} onClick={handleLoadMore}/> : null\n )\n}","import { TypedDocument } from \"@cludosearch/cludo-api-client/dist/interfaces/api/search.interface\";\nimport { ExternalFacet } from \"../../utils/cludo-search-context\";\nimport { SortOption } from \"../../utils/models/instantiator-types\";\nimport { CludoSearchResponseState, TopHit } from \"../../types/core-script-types\";\nimport { FacetMap } from \"../../types/core-script-types\";\n\ntype FormattedTextDisplayType = 'default' | 'highlight';\n\nexport type CssUnit = 'px'|'pt'|'pc'|'in'|'Q'|'mm'|'cm'|'em'|'rem'|'ex'|'ch'|'lh'|'rlh'|'vw'|'vh'|'vmin'|'vmax'|'vb'|'vi'|'svw'|'svh'|'lvh'|'lvw'|'dvw'|'dvh';\nexport type HeadingLevel = 'h1'|'h2'|'h3'|'h4'|'h5'|'h6';\nexport type LayoutColumnOptions = 1|2|3|4|5|6|7|8|9|10|11|12;\nexport type StandardResultWidgetType = 'title' | 'description' | 'url' | 'badge';\n\nexport enum AutocompleteItemType {\n Result = 'result',\n CategorizedResult = 'categorized-result',\n Suggestion = 'suggestion',\n RecentSearch = 'recent-search'\n}\n\nexport interface FormattedTextChunk {\n text: string;\n displayType: FormattedTextDisplayType;\n}\n\ninterface AutocompleteBaseItem {\n title: string;\n chunkedTitle: FormattedTextChunk[];\n}\n\nexport interface AutocompleteResult extends AutocompleteBaseItem {\n document: TypedDocument;\n}\n\nexport interface AutocompleteSuggestion extends AutocompleteBaseItem {}\n\nexport interface AutocompleteRecentSearch extends AutocompleteBaseItem {}\n\nexport interface AutocompleteTopHit {\n Field: string;\n Values: AutocompleteTopHitValue[];\n}\n\nexport interface AutocompleteTopHitValue {\n Value: string;\n Hits: AutocompleteResult[];\n AllCount?: number;\n}\n\nexport interface FormattedCludoAutocompleteResponse {\n query: string;\n facets?: FacetMap;\n totalResults?: number;\n totalSuggestions?: number;\n totalRecentSearches?: number;\n results?: AutocompleteResult[];\n suggestions?: AutocompleteSuggestion[];\n instantSuggestions?: AutocompleteSuggestion[];\n recentSearches?: AutocompleteRecentSearch[];\n categorizedResults?: AutocompleteTopHit[];\n}\n\nexport type CludoAutocompleteBaseProps = { \n data: FormattedCludoAutocompleteResponse,\n isLoading: boolean;\n};\n\nexport type ThemeBaseProps<T extends string = never> = {\n disableTheme?: boolean;\n className?: string;\n classNames?: Partial<Record<T, string>>;\n attributes?: Partial<Record<'root' | T, React.HTMLAttributes<HTMLElement> & Record<string, string>>>;\n};\nexport type CludoFacetBaseProps = { facet: ExternalFacet };\nexport type CludoControlsBaseProps = { facets: ExternalFacet[]; sortItems: SortOption[]; };\nexport type ResultItemBaseProps = { result: TypedDocument, shouldBeFocused?: boolean }\nexport type BaseResultProps = ThemeBaseProps & { result?: TypedDocument }\n\nexport type LoaderProps = { isLoading: boolean }\n\nexport type CludoSearchResultsBaseProps = { cludoSearchResponse: CludoSearchResponseState };\nexport type CludoLoaderBaseProps = { isLoading: boolean };","import React from \"react\";\nimport { StandardResult } from \"./items/standard-result\";\nimport { Pagination } from \"./pagination/pagination\";\nimport { LoaderProps, ResultItemBaseProps } from \"../types/types\";\nimport { BannerGroup } from \"../elements/banner-group/banner-group\";\nimport { ResultsSummary } from \"./header/results-summary\";\nimport { SearchResultsCompositionOptions } from \"../../utils/models/instantiator-types\";\nimport { CludoLoader } from \"./cludo-loader\";\nimport { useSearchResults } from \"../../hooks/use-search-results\";\nimport { ResultsList, ResultsListProps } from \"./list/results-list\";\nimport { LoadMoreResults } from \"./load-more-results\";\n\n\n// Default search results template\nexport const CludoSearchResults = composeResults({});\n\nexport function composeResults(options: SearchResultsCompositionOptions): () => JSX.Element {\n const ResultComponent: React.ComponentType<ResultItemBaseProps> = options.result || StandardResult;\n const ListComponent: React.ComponentType<ResultsListProps> = options.list || ResultsList;\n const LoaderComponent: React.ComponentType<LoaderProps> = options.loader || CludoLoader;\n const PaginationComponent = options.pagination || Pagination;\n\n return () => {\n // Use custom hook to derive state and access relevant events\n const [ searchResultsState, searchResultsDispatchers ] = useSearchResults();\n\n const suggestion: string = searchResultsState.suggestions[0] ? searchResultsState.suggestions[0] : '';\n\n return (\n <>\n {/* Render header elements */}\n <ResultsSummary {...searchResultsState.resultsSummary} suggestedQuery={suggestion} />\n\n {/* Render banners */}\n <BannerGroup />\n \n <ListComponent template={(result) => <ResultComponent result={result} />} />\n\n <LoaderComponent isLoading={searchResultsState.isLoading} />\n\n <PaginationComponent />\n\n <LoadMoreResults />\n </>\n );\n }\n}","import React, { useContext, useEffect } from \"react\";\nimport { ResultLink } from \"../../elements/result-link\";\nimport { AutocompleteItemType, AutocompleteResult, ThemeBaseProps } from \"../../types/types\";\nimport { HighlightedText } from \"../../elements/cludo-highlighted-text\";\nimport { EventControllerContext } from \"../../../context\";\nimport { generateThemeCss } from \"../../../utils/theme-provider\";\n\nexport interface SaytResultProps extends ThemeBaseProps {\n result: AutocompleteResult;\n isSelected: boolean;\n resultIndex: number;\n resultType?: AutocompleteItemType.Result | AutocompleteItemType.CategorizedResult;\n children?: React.ReactNode;\n}\n\nexport function SaytResult(props: SaytResultProps) {\n const eventController = useContext(EventControllerContext);\n const id = `cludo-result-item-${props.resultIndex}`;\n const suggestionCSS = generateThemeCss(`cludo-p-2 cludo-font-family-default cludo-border-b-1-neutral cludo-border-b-solid cludo-border-radius-button cludo-cursor-pointer cludo-bg-hover-gray-light ${props.isSelected ? 'cludo-bg-color-gray-light' : 'cludo-bg-color-white'}`,\n props.disableTheme, props.className) + (props.isSelected ? ' active' : '');\n const resultChildren = props.children ?? <HighlightedText chunkedText={props.result.chunkedTitle} wrapDefaultText></HighlightedText>;\n const itemType = props.resultType || AutocompleteItemType.Result\n\n useEffect(()=> {\n if (props.isSelected) {\n eventController.setActiveDescendantToSuggestions(id);\n }\n }, [props.isSelected])\n\n return (\n <li\n id={id}\n tabIndex={0}\n aria-selected={props.isSelected ? 'true' : undefined}\n role=\"option\"\n className={suggestionCSS}\n data-cludo-autocomplete={itemType}\n data-cludo-autocomplete-index={props.resultIndex}\n {...props.attributes?.root}\n onClick={() => eventController.selectResult(props.result.document)}\n >\n <ResultLink result={props.result.document}>\n { resultChildren }\n </ResultLink>\n </li>\n )\n}","import React, { useContext, useEffect } from \"react\";\nimport { HighlightedText } from \"../../elements/cludo-highlighted-text\";\nimport { AutocompleteItemType, AutocompleteSuggestion, ThemeBaseProps } from \"../../types/types\";\nimport { EventControllerContext } from \"../../../context\";\nimport { generateThemeCss } from \"../../../utils/theme-provider\";\n\nexport interface SaytSuggestionProps extends ThemeBaseProps {\n suggestion: AutocompleteSuggestion;\n isSelected: boolean;\n suggestionIndex: number;\n}\n\nexport function SaytSuggestion(props: SaytSuggestionProps) {\n const eventController = useContext(EventControllerContext);\n const id = `cludo-suggestion-item-${props.suggestionIndex}`;\n const suggestionCSS = generateThemeCss(`cludo-p-2 cludo-font-family-default cludo-border-b-1-neutral cludo-border-b-solid cludo-border-radius-button cludo-cursor-pointer cludo-bg-hover-gray-light ${props.isSelected ? 'cludo-bg-color-gray-light' : 'cludo-bg-color-white'}`,\n props.disableTheme, props.className) + (props.isSelected ? ' active' : '')\n \n useEffect(() => {\n if (props.isSelected) {\n eventController.setActiveDescendantToSuggestions(id)\n }\n }, [props.isSelected])\n\n return (\n <li\n id={id}\n tabIndex={0}\n aria-selected={props.isSelected ? 'true' : undefined}\n role=\"option\"\n className={suggestionCSS}\n data-cludo-autocomplete={AutocompleteItemType.Suggestion}\n data-cludo-autocomplete-index={props.suggestionIndex}\n {...props.attributes?.root}\n onClick={() =>eventController.selectSuggestion(props.suggestion.title, props.suggestionIndex)}\n >\n <HighlightedText chunkedText={props.suggestion.chunkedTitle} wrapDefaultText></HighlightedText>\n </li>\n )\n}","import React, { useContext, useEffect } from \"react\";\nimport { HighlightedText } from \"../../elements/cludo-highlighted-text\";\nimport { AutocompleteItemType, AutocompleteSuggestion, ThemeBaseProps } from \"../../types/types\";\nimport { EventControllerContext } from \"../../../context\";\nimport { generateThemeCss } from \"../../../utils/theme-provider\";\n\nexport interface SaytRecentSearchProps extends ThemeBaseProps {\n recentSearch: AutocompleteSuggestion;\n isSelected: boolean;\n recentSearchIndex: number;\n}\n\nexport function SaytRecentSearch(props: SaytRecentSearchProps) {\n const eventController = useContext(EventControllerContext);\n const id = `cludo-recent-search-item-${props.recentSearchIndex}`;\n const suggestionCSS = generateThemeCss(`cludo-p-2 cludo-font-family-default cludo-border-b-1-neutral cludo-border-b-solid cludo-border-radius-button cludo-cursor-pointer cludo-bg-hover-gray-light ${props.isSelected ? 'cludo-bg-color-gray-light' : 'cludo-bg-color-white'}`,\n props.disableTheme, props.className) + (props.isSelected ? ' active' : '')\n\n useEffect(() => {\n if (props.isSelected) {\n eventController.setActiveDescendantToSuggestions(id);\n }\n }, [props.isSelected])\n\n return (\n <li\n id={id}\n tabIndex={0}\n aria-selected={props.isSelected ? 'true' : undefined}\n role=\"option\"\n className={suggestionCSS}\n data-cludo-autocomplete={AutocompleteItemType.RecentSearch}\n data-cludo-autocomplete-index={props.recentSearchIndex}\n {...props.attributes?.root}\n onClick={() =>eventController.selectSuggestion(props.recentSearch.title, props.recentSearchIndex)}\n >\n <HighlightedText chunkedText={props.recentSearch.chunkedTitle} wrapDefaultText></HighlightedText>\n </li>\n )\n}","// Utility function to check if code is being executed on the client\n// Used to guard against accessing window or document when using SSR.\nexport function isOnClient(): boolean {\n return !(typeof window === 'undefined' || typeof document === 'undefined');\n}","import { useRef, useState, useEffect } from \"react\";\nimport { useCludoContext } from \"./use-cludo-context\";\nimport { AutocompleteResult, AutocompleteSuggestion, AutocompleteTopHit } from \"../components/types/types\";\nimport { getAutocompleteResultsFromTopHits, isAutocompleteItem } from \"../utils/result-utils\";\nimport { TopHit } from \"../types/core-script-types\";\nimport { isOnClient } from \"../utils/render-utils\";\n\nexport interface AutocompleteState {\n suggestions: AutocompleteSuggestion[];\n instantSuggestions: AutocompleteSuggestion[];\n results: AutocompleteResult[];\n recentSearches: AutocompleteSuggestion[];\n categorizedResults: AutocompleteTopHit[];\n selectedSuggestion: number;\n selectedResult: number;\n selectedRecentSearch: number;\n suggestionsTitle: string;\n resultsTitle: string;\n recentSearchesTitle: string;\n}\n\nexport interface AutocompleteDispatchers {\n /** Performs a request to retrieve autocomplete results for the given query */\n initiateAutocompleteRequest: (query: string) => void;\n /** Takes a keyboard input event and selects the next available autocomplete item */\n autocompleteSelectionNext: () => void;\n /** Takes a keyboard input event and selects the previous available autocomplete item */\n autocompleteSelectionPrev: () => void;\n /** Takes the currently active autocomplete item and performs a search (or clicks, if the item is a search result) */\n autocompleteSelect: (e?: React.KeyboardEvent<HTMLInputElement>) => void;\n /** Clears out stored autocomplete data */\n clear: () => void;\n}\n\n/** Expose state and handle mouse/keyboard input listening for an autocomplete component \n * @returns cludoState (all relevant autocomplete state properties) and cludoDispatchers (ability to kick off autocomplete requests by query)\n*/\nexport function useAutocomplete(): [AutocompleteState, AutocompleteDispatchers] {\n const { context, eventController } = useCludoContext();\n\n // Keep track of list index\n const selectedIndex = useRef(-1);\n\n // Autocomplete keyboard event handling -- get all autocomplete elements using data attributes\n const keydownListener = (key: string) => {\n if (!isOnClient()) return;\n const suggestions = context.storedAutocompleteResponse?.data.suggestions || [];\n const instantSuggestions = context.storedAutocompleteResponse?.data.instantSuggestions || [];\n const results = context.storedAutocompleteResponse?.data.results || [];\n const recentSearches = context.storedAutocompleteResponse?.data.recentSearches || [];\n const categorizedResults = getAutocompleteResultsFromTopHits(context.storedAutocompleteResponse?.data.categorizedResults || []);\n const listItems = document.querySelectorAll<HTMLLIElement>('[data-cludo-autocomplete]');\n let tempSelectedSuggestion, tempSelectedResult, tempSelectedRecentSearch;\n tempSelectedSuggestion = tempSelectedResult = tempSelectedRecentSearch = -1;\n let tempIndex = selectedIndex.current;\n const numSuggestions = listItems.length;\n // Handle search via enter key\n if (key === 'Enter' && tempIndex === -1) {\n eventController.search();\n } else if (listItems && listItems.length > 0) {\n if (key === 'ArrowKeyUp') {\n tempIndex = (tempIndex === -1) ? 0 : tempIndex;\n tempIndex = ((((tempIndex - 1) % numSuggestions) + numSuggestions) % numSuggestions);\n }\n if (key === 'ArrowKeyDown') {\n tempIndex = ((((tempIndex + 1) % numSuggestions) + numSuggestions) % numSuggestions);\n }\n // Update selectedIndex for sublists\n if (listItems[tempIndex]) {\n switch (listItems[tempIndex].getAttribute('data-cludo-autocomplete')) {\n case 'suggestion':\n tempSelectedSuggestion = parseInt(listItems[tempIndex].getAttribute('data-cludo-autocomplete-index') as string);\n const suggestion = suggestions[tempSelectedSuggestion] ?? instantSuggestions[tempSelectedSuggestion];\n if (key === 'Enter') {\n eventController.selectSuggestion(suggestion.title, tempSelectedSuggestion);\n }\n break;\n case 'result':\n tempSelectedResult = parseInt(listItems[tempIndex].getAttribute('data-cludo-autocomplete-index') as string);\n const result = results[tempSelectedResult];\n if (key === 'Enter') {\n eventController.selectResult(result.document);\n }\n break;\n case 'categorized-result':\n tempSelectedResult = parseInt(listItems[tempIndex].getAttribute('data-cludo-autocomplete-index') as string);\n const categorizedResult = categorizedResults[tempSelectedResult];\n if (key === 'Enter') {\n eventController.selectResult(categorizedResult.document);\n }\n break;\n case 'recent-search':\n tempSelectedRecentSearch = parseInt(listItems[tempIndex].getAttribute('data-cludo-autocomplete-index') as string);\n const recentSearch = recentSearches[tempSelectedRecentSearch];\n if (key === 'Enter') {\n eventController.selectRecentSearch(recentSearch.title, tempSelectedRecentSearch);\n }\n break;\n }\n }\n }\n selectedIndex.current = tempIndex;\n const newState: AutocompleteState = {\n ...deriveAutocompleteState(),\n selectedSuggestion: tempSelectedSuggestion,\n selectedResult: tempSelectedResult,\n selectedRecentSearch: tempSelectedRecentSearch\n }\n setAutocompleteState(newState)\n }\n\n const clearSelectedIndices = () => {\n selectedIndex.current = -1;\n const newState: AutocompleteState = {\n ...deriveAutocompleteState(),\n suggestions: context.storedAutocompleteResponse?.data.suggestions || [],\n results: context.storedAutocompleteResponse?.data.results || [],\n selectedSuggestion: -1,\n selectedResult: -1,\n selectedRecentSearch: -1\n }\n setAutocompleteState(newState)\n }\n\n // Attach keyboard event handlers \n useEffect(() => {\n const eventControllerIsDefined = Object.keys(eventController).length > 0;\n const keyboardNextSubscription = eventControllerIsDefined ? eventController.subscribe('autocompleteSelectionNext', () => { keydownListener('ArrowKeyDown')}) : -1;\n const keyboardPrevSubscription = eventControllerIsDefined ? eventController.subscribe('autocompleteSelectionPrev', () => { keydownListener('ArrowKeyUp')}) : -1;\n const keyboardEnterSubscription = eventControllerIsDefined ? eventController.subscribe('autocompleteSetSelection', () => { keydownListener('Enter')}) : -1;\n const autocompleteCompleteSubscription = eventControllerIsDefined ? eventController.subscribe('afterautocomplete', () => { clearSelectedIndices() }) : -1;\n\n return () => {\n if (eventControllerIsDefined) {\n eventController.unsubscribe(keyboardNextSubscription);\n eventController.unsubscribe(keyboardPrevSubscription);\n eventController.unsubscribe(keyboardEnterSubscription);\n eventController.unsubscribe(autocompleteCompleteSubscription);\n }\n }\n });\n\n // Initial autocomplete state\n const [autocompleteState, setAutocompleteState] = useState<AutocompleteState>({\n suggestions: [],\n instantSuggestions: context.storedAutocompleteResponse?.data.instantSuggestions || [],\n results: [],\n recentSearches: context.storedAutocompleteResponse?.data.recentSearches || [],\n categorizedResults: [],\n selectedSuggestion: -1,\n selectedResult: -1,\n selectedRecentSearch: -1,\n suggestionsTitle: context.translateProvider?.translate('template_suggestions') || '' || '',\n resultsTitle: context.translateProvider?.translate('template_search_results') || '',\n recentSearchesTitle: context.translateProvider?.translate('recent_searches_title') || ''\n });\n\n const initiateAutocompleteRequest = (query: string) => {\n return eventController.initiateAutocompleteRequest(query);\n }\n\n const autocompleteSelectionNext = () => {\n eventController.emitEvent('autocompleteSelectionNext', {});\n }\n\n const autocompleteSelectionPrev = () => {\n eventController.emitEvent('autocompleteSelectionPrev', {});\n }\n\n const clear = () => {\n eventController.clearAutocomplete();\n }\n\n const autocompleteSelect = (e?: React.KeyboardEvent<HTMLInputElement>) => {\n if (autocompleteState.selectedSuggestion !== -1) {\n e && e.preventDefault();\n const suggestion = autocompleteState.suggestions[autocompleteState.selectedSuggestion] ?? autocompleteState.instantSuggestions[autocompleteState.selectedSuggestion];\n if (suggestion) {\n eventController.selectSuggestion(suggestion.title, autocompleteState.selectedSuggestion);\n }\n }\n if (autocompleteState.selectedResult !== -1) {\n e && e.preventDefault();\n const result = autocompleteState.results[autocompleteState.selectedResult];\n if (result) {\n eventController.selectResult(result.document);\n }\n }\n if (autocompleteState.selectedRecentSearch !== -1) {\n e && e.preventDefault();\n const recentSearch = autocompleteState.recentSearches[autocompleteState.selectedRecentSearch];\n if (recentSearch) {\n eventController.selectRecentSearch(recentSearch.title, autocompleteState.selectedRecentSearch);\n }\n }\n }\n \n\n const autocompleteDispatchers: AutocompleteDispatchers = {\n initiateAutocompleteRequest,\n autocompleteSelectionNext,\n autocompleteSelectionPrev,\n autocompleteSelect,\n clear\n }\n\n const deriveAutocompleteState: () => AutocompleteState = () => {\n const newState: AutocompleteState = {\n ...autocompleteState,\n suggestions: context.storedAutocompleteResponse?.data.suggestions || [],\n instantSuggestions: context.storedAutocompleteResponse?.data.instantSuggestions || [],\n results: context.storedAutocompleteResponse?.data.results || [],\n recentSearches: context.storedAutocompleteResponse?.data.recentSearches || [],\n categorizedResults: context.storedAutocompleteResponse?.data.categorizedResults || [],\n suggestionsTitle: context.translateProvider?.translate('template_suggestions') || '' || '',\n resultsTitle: context.translateProvider?.translate('template_search_results') || '',\n recentSearchesTitle: context.translateProvider?.translate('recent_searches_title') || ''\n }\n\n return newState;\n }\n\n return [ autocompleteState, autocompleteDispatchers ];\n}\n\n/** Handle navigating and selecting autocomplete suggestions from a search input */\nexport const autocompleteHandleInputKeyDown = (e: React.KeyboardEvent<HTMLInputElement>, autocompleteDispatchers: AutocompleteDispatchers) => {\n switch (e.key) {\n case 'ArrowDown':\n e.preventDefault();\n autocompleteDispatchers.autocompleteSelectionNext();\n break;\n case 'ArrowUp':\n e.preventDefault();\n autocompleteDispatchers.autocompleteSelectionPrev();\n break;\n case 'Enter':\n autocompleteDispatchers.autocompleteSelect(e);\n break;\n }\n}\n\n/** Handle clearing autocomplete state when the input loses focus */\nexport const autocompleteHandleInputBlur = (e: React.FocusEvent<HTMLInputElement>, autocompleteDispatchers: AutocompleteDispatchers) => {\n if (!isAutocompleteItem(e.relatedTarget)) {\n autocompleteDispatchers.clear();\n }\n}\n\n/** Handle initiating an autocomplete request when the input changes */\nexport const autocompleteHandleInputChange = (e: React.ChangeEvent<HTMLInputElement>, autocompleteDispatchers: AutocompleteDispatchers) => {\n autocompleteDispatchers.initiateAutocompleteRequest(e.target.value);\n}","import React from \"react\";\nimport { AutocompleteResult, AutocompleteSuggestion } from \"../types/types\";\nimport { SaytResult } from \"./items/sayt-result\";\nimport { SaytSuggestion } from \"./items/sayt-suggestion\";\nimport { SaytRecentSearch } from \"./items/sayt-recent-search\";\nimport { useAutocomplete } from \"../../hooks/use-autocomplete\";\n\n\nexport function CludoSearchAutocomplete() {\n const [autocompleteState] = useAutocomplete();\n const {\n suggestions,\n results,\n recentSearches,\n selectedSuggestion,\n selectedResult,\n selectedRecentSearch,\n suggestionsTitle,\n resultsTitle,\n recentSearchesTitle\n } = autocompleteState;\n\n return (\n <>\n { suggestions.length ? \n <>\n <h3>{ suggestionsTitle }</h3>\n <div className=\"section-divider\"></div>\n <ul className=\"cludo-search-autocomplete-suggestions\">\n {suggestions.map((suggestion: AutocompleteSuggestion, i: number) => {\n const isSelected = (i === selectedSuggestion);\n return <SaytSuggestion key={i} suggestion={suggestion} isSelected={isSelected} suggestionIndex={i} />\n })}\n </ul>\n </> :\n null\n }\n { results.length ?\n <>\n <h3>{ resultsTitle }</h3>\n <ul className=\"cludo-search-autocomplete-results\">\n {results.map((result: AutocompleteResult, i: number) => {\n const isSelected = (i === selectedResult);\n return <SaytResult key={i} result={result} isSelected={isSelected} resultIndex={i} />\n })}\n </ul>\n </> :\n null\n }\n { recentSearches.length ? \n <>\n <h3>{ recentSearchesTitle }</h3>\n <div className=\"section-divider\"></div>\n <ul className=\"cludo-search-autocomplete-recent-searches\">\n {recentSearches.map((recentSearch: AutocompleteSuggestion, i: number) => {\n const isSelected = (i === selectedRecentSearch);\n return <SaytRecentSearch key={i} recentSearch={recentSearch} isSelected={isSelected} recentSearchIndex={i}/>\n })}\n </ul>\n </> :\n null\n }\n </>\n );\n\n}","import { CludoFeature, InstantSuggestionsConfiguration } from \"@cludosearch/cludo-api-client/dist/interfaces/api/public-settings.interface\";\nimport { Facets, Facet, FacetValue, TypedDocument } from \"@cludosearch/cludo-api-client/dist/interfaces/api/search.interface\";\nimport { AutocompleteResult, AutocompleteSuggestion, AutocompleteTopHit, CludoAutocompleteBaseProps, CludoSearchResultsBaseProps, FormattedTextChunk } from \"../components/types/types\";\nimport { EndlessScrollOptions, SortOption } from \"./models/instantiator-types\";\nimport { getFieldValue, getTopHitTotalCount } from \"./result-utils\";\nimport { CludoSearch, SearchRequestParams, SortOrder, FacetMapRequest, CludoErrorState, CludoAutocompleteState, FilterMap, TopHit, TopHitValue } from \"../types/core-script-types\";\nimport { TranslateProvider } from \"../types/translation-types\";\n\n// just an idea for now -- potentially useful for simplifying access to features\n // TO-DO -- better name for ExternalFacet?\nexport interface ExternalFacet {\n allCount: number;\n hasSelection: boolean;\n key: string;\n missingCount?: number;\n values: FacetItem[];\n selectedValues: string[];\n}\n\nexport interface FacetItem {\n facetName: string;\n value: string;\n isSelected: boolean;\n count?: number;\n}\n\nexport interface TemplateState {\n focusIndex?: number;\n}\n\n/**\n * This object is meant to provide access to the CludoSearch object properties, but modified such that:\n * - Only the properties that we intend to be public are accessible\n * - Properties that are poorly named have been renamed for clarity\n * - Properties that are not well-organized or well-structured have been transformed for ease of use\n */\nexport class CludoSearchContext {\n private _cludoSearch: CludoSearch;\n private _templateState: TemplateState;\n\n constructor(cludoSearch: CludoSearch) {\n this._cludoSearch = cludoSearch;\n this._templateState = {};\n }\n\n // Internal template state\n\n public get focusIndex(): number | undefined {\n return this._templateState.focusIndex;\n }\n\n public set focusIndex(index: number | undefined) {\n this._templateState.focusIndex = index;\n }\n\n // Cludo instance state\n\n private get params(): SearchRequestParams {\n return this._cludoSearch.params;\n }\n\n public get customerId(): number {\n return this._cludoSearch.customerId;\n }\n\n public get engineId(): number {\n return this._cludoSearch.engineId;\n }\n\n public get query(): string {\n return this._cludoSearch.params.query;\n }\n\n public set query(query: string) {\n this._cludoSearch.params.query = query;\n }\n\n public get currentPage(): number {\n return this._cludoSearch.params.page;\n }\n\n public get resultsPerPage(): number {\n return this._cludoSearch.params.perPage;\n }\n\n public get sort(): SortOrder {\n return this._cludoSearch.params.sort;\n }\n\n public get sortItems(): SortOption[] {\n // default to empty array if not found\n return this._cludoSearch.clientTemplateSortOptions || [];\n }\n\n // FUTURE -- consider defining experience keys here (or potentially leave them up to the experience scripts)\n public get experienceConfigs(): { [key: string]: any } {\n return this._cludoSearch.websiteSettings.configurations;\n }\n\n public get translateProvider(): TranslateProvider {\n return this._cludoSearch.translateProvider;\n }\n\n public isFacetSelected(key: string, value: string): boolean {\n return (this.params.facets[key] && this.params.facets[key].indexOf(value) !== -1);\n }\n\n public isFilterSelected(key: string, value: string): boolean {\n return (this.params.filters[key] && this.params.filters[key].indexOf(value) !== -1);\n }\n\n private getSelectedMapItem<T extends FilterMap | FacetMapRequest>(arrayToCheck: T): T {\n const selected: T = {} as T;\n\n for(var item in arrayToCheck) {\n if (arrayToCheck[item].length) {\n selected[item] = arrayToCheck[item];\n }\n }\n \n return selected;\n }\n\n public get selectedFacets(){ return this.getSelectedMapItem(this.params.facets) };\n\n public get selectedFilters(){ return this.getSelectedMapItem(this.params.filters) };\n\n public get facets(): ExternalFacet[] {\n let facetsInResponse: Facets = this.storedSearchResponseData.cludoSearchResponse.Facets;\n let facetsToRender = Object.keys(this._cludoSearch.facets);\n\n return Object.entries(facetsInResponse)\n .filter(([key, _]) => facetsToRender.includes(key)) \n .map(\n (facetMapItem: [string, Facet]) => {\n const facetKey: string = facetMapItem[0];\n const facetObj: Facet = facetMapItem[1];\n\n const facet: ExternalFacet = {\n key: facetKey,\n hasSelection: this.params.facets[facetKey] ? this.params.facets[facetKey].length > 0 : false,\n values: facetObj.Items.map((facetValue: FacetValue) => {\n return {\n facetName: facetKey,\n count: facetValue.Count,\n value: facetValue.Key,\n isSelected: this.isFacetSelected(facetKey, facetValue.Key)\n }\n }),\n selectedValues: this.params.facets[facetKey] ?? [],\n allCount: facetObj.AllCount,\n missingCount: facetObj.MissingCount\n };\n\n // Here we address an edge case where a facet is selected, then a search is made that\n // returns 0 results. We need to add the selected facet as an option to indicate in the\n // UI that it is selected.\n const facetValues = new Set(facet.values.map(item => item.value));\n const selectedValuesNotInResponse = facet.selectedValues.filter(str => !facetValues.has(str));\n selectedValuesNotInResponse.forEach(value => {\n const newValue: FacetItem = {\n facetName: facetKey,\n count: 0,\n value: value,\n isSelected: true\n }\n facet.values.push(newValue);\n });\n\n return facet;\n }\n )\n }\n\n public get isLoadingResults(): boolean {\n return this._cludoSearch.isLoadingResults;\n }\n\n public get enabledFeatures(): CludoFeature[] {\n return this._cludoSearch.enabledFeatures;\n }\n\n public isFeatureEnabled(featureKey: CludoFeature): boolean {\n return this._cludoSearch.enabledFeatures.includes(featureKey);\n }\n\n public get endlessScroll(): EndlessScrollOptions | null {\n return this._cludoSearch.endlessScroll || null;\n }\n\n public set endlessScroll(options: EndlessScrollOptions) {\n this._cludoSearch.endlessScroll = options;\n }\n\n public get isEndlessScrollEnabled(): boolean {\n return this._cludoSearch.endlessScroll\n ? true\n : false;\n }\n\n public get isAutocompleteEnabled(): boolean {\n return this._cludoSearch.richAutocomplete;\n }\n\n public get paramsPrefix(): string {\n return this._cludoSearch.paramsPrefix;\n }\n\n public set linkFragment(fragmentText: string) {\n this._cludoSearch.linkFragment = fragmentText;\n }\n\n public get storedSearchResponseData(): CludoSearchResultsBaseProps {\n return { \n cludoSearchResponse: {\n ...this._cludoSearch.storedSearchResponseData,\n TopHits: this._cludoSearch.storedSearchResponseData.TopHits.map(hit => {\n return getTopHitTotalCount(hit, this._cludoSearch.storedSearchResponseData.Facets);\n }\n )\n }\n };\n }\n\n public get focusOnResultsAfterSearch(): boolean {\n return this._cludoSearch.focusOnResultsAfterSearch;\n }\n\n public get customEngineSettings(): {\n [featureConfigKey: string]: object,\n } {\n let customEngineSettings: {\n [featureConfigKey: string]: object\n } = {};\n\n try {\n customEngineSettings = JSON.parse(this._cludoSearch.websiteSettings.customEngineSettings) ?? customEngineSettings; \n } catch (error) {\n // TODO consider logging this error\n }\n\n if (!this._cludoSearch.websiteSettings.configurations) {\n return customEngineSettings;\n }\n\n // add feature keys from configuration\n const featureConfigKeys = Object.keys(this._cludoSearch.websiteSettings.configurations);\n\n featureConfigKeys.forEach((featureConfigKey: string) => {\n customEngineSettings[featureConfigKey] = this._cludoSearch.websiteSettings.configurations[featureConfigKey];\n });\n\n return customEngineSettings;\n }\n\n public get instantSuggestionsConfiguration(): InstantSuggestionsConfiguration | undefined {\n return this._cludoSearch.websiteSettings.instantSuggestionsConfiguration;\n }\n\n public get recentSearches(): string[] {\n return this._cludoSearch.recentSearches;\n }\n\n public get storedError(): CludoErrorState {\n return this._cludoSearch.storedError;\n }\n /**\n * Given a source string, and a search string, returns an array of\n * FormattedTextChunk objects marked as either \"default\" (no special handling\n * should be applied), or \"highlight\" (the first segment of the source string that matches\n * the search string, which can be formatted in a way to bring attention to the match)\n * @param input \n * @param needle \n * @returns \n */\n private chunkString(input: string, needle: string): FormattedTextChunk[] {\n const needleIndex: number = input.toLowerCase().indexOf(needle.toLowerCase());\n\n if (needleIndex === -1) {\n return [{\n text: input,\n displayType: 'default'\n }]\n }\n\n return [\n {\n text: input.substring(0, needleIndex),\n displayType: 'default'\n },\n {\n text: input.substring(needleIndex, needleIndex + needle.length),\n displayType: 'highlight'\n },\n {\n text: input.substring(needleIndex + needle.length),\n displayType: 'default'\n }\n ];\n }\n\n private mapTypedDocumentToResult(document: TypedDocument, query: string): AutocompleteResult {\n const title: string = getFieldValue(document, 'Title') ?? '';\n\n return {\n title: title,\n chunkedTitle: this.chunkString(title, query),\n document: document\n };\n }\n \n private mapTypedDocumentToSuggestion(document: TypedDocument, query: string): AutocompleteSuggestion {\n const title: string = getFieldValue(document, 'Title') ?? '';\n\n return {\n title: title,\n chunkedTitle: this.chunkString(title, query)\n };\n }\n\n private mapStringToSuggestion(str: string): AutocompleteSuggestion {\n return {\n title: str,\n chunkedTitle: this.chunkString(str, '')\n }\n }\n\n private mapTopHitsToCategorizedResults(hit: TopHit, query: string): AutocompleteTopHit {\n return {\n Field: hit.Field,\n Values: hit.Values.map(value => this.mapHitValuesToResults(value, query))\n }\n }\n\n private mapHitValuesToResults(value: TopHitValue, query: string) {\n return {\n Value: value.Value,\n Hits: value.Hits.map(document => {\n return this.mapTypedDocumentToResult(document, query);\n })\n }\n }\n\n public get storedAutocompleteResponse(): CludoAutocompleteBaseProps {\n const coreAutocompleteData: CludoAutocompleteState = this._cludoSearch.storedAutocompleteResponse;\n\n return {\n data: {\n query: coreAutocompleteData.cludoAutocompleteResponse.query,\n facets: coreAutocompleteData.cludoAutocompleteResponse.facets,\n totalResults: coreAutocompleteData.cludoAutocompleteResponse.totalResults,\n totalSuggestions: coreAutocompleteData.cludoAutocompleteResponse.totalSuggestions,\n totalRecentSearches: coreAutocompleteData.cludoAutocompleteResponse.totalRecentSearches,\n results: coreAutocompleteData.cludoAutocompleteResponse.results\n ?.map((document: TypedDocument) => this.mapTypedDocumentToResult(document, coreAutocompleteData.cludoAutocompleteResponse.query)),\n suggestions: coreAutocompleteData.cludoAutocompleteResponse.suggestions\n ?.map((document: TypedDocument) => this.mapTypedDocumentToSuggestion(document, coreAutocompleteData.cludoAutocompleteResponse.query)),\n instantSuggestions: coreAutocompleteData.cludoAutocompleteResponse.instantSuggestions\n ?.map((document: TypedDocument) => this.mapTypedDocumentToSuggestion(document, coreAutocompleteData.cludoAutocompleteResponse.query)),\n recentSearches: coreAutocompleteData.cludoAutocompleteResponse.recentSearches\n ?.map((search: string) => this.mapStringToSuggestion(search)),\n categorizedResults: coreAutocompleteData.cludoAutocompleteResponse.topHits\n ?.map((hit: TopHit) => {\n const mappedHit = this.mapTopHitsToCategorizedResults(hit, coreAutocompleteData.cludoAutocompleteResponse.query);\n const hitWithCount = getTopHitTotalCount(mappedHit, coreAutocompleteData.cludoAutocompleteResponse.facets);\n return hitWithCount;\n })\n },\n isLoading: coreAutocompleteData.isLoading\n }\n }\n\n public get isTrackedSession(): boolean {\n return this._cludoSearch.isTrackedSession !== 0;\n }\n\n public set canUserBeTracked(canUserBeTracked: () => boolean) {\n this._cludoSearch.canUserBeTracked = canUserBeTracked;\n }\n\n public get queryId(): string {\n return this._cludoSearch.queryId;\n }\n\n public get sessionId(): string {\n return this._cludoSearch.getSessionId();\n }\n\n public get querySessionId(): string {\n return this._cludoSearch.querySessionId;\n }\n\n public get deviceType(): string {\n return this._cludoSearch.deviceType;\n }\n\n public get traits(): string[] {\n const traits = this._cludoSearch.getTraitsFromStorage();\n return traits ? traits : [];\n }\n}","const __WEBPACK_NAMESPACE_OBJECT__ = require(\"react-dom\");","import React from \"react\";\nimport ReactDOM from \"react-dom\";\nimport { CludoSearchContext } from \"./cludo-search-context\";\nimport { CludoContext, EventControllerContext } from \"../context\";\nimport { EventController } from \"./event-controller\";\nimport { CludoSearch } from \"../types/core-script-types\";\nimport { ThemeProvider } from \"./theme-provider\";\nimport { isOnClient } from \"./render-utils\";\n\ninterface ManagedComponent {\n component: React.ComponentType;\n elem: HTMLElement | null;\n elemSelector?: string;\n observedEventTypes: EventType[];\n hasRendered: boolean;\n}\n\nexport type EventType = 'beforesearch'\n| 'aftersearch'\n| 'beforeredirect'\n| 'afterautocomplete'\n| 'autocompleteSelectionNext'\n| 'autocompleteSelectionPrev'\n| 'autocompleteSetSelection'\n| 'afterinputfocus'\n| 'afterpageload'\n| 'error';\n\nexport enum TemplateType {\n Results = 'results',\n Autocomplete = 'autocomplete',\n Controls = 'controls',\n Loader = 'loader',\n Custom = 'custom'\n}\n\n/**\n * This object provides a way to manage tracked components; it exposes\n * - methods for registering standard components (registerSearchResultsTemplate, registerFacetsTemplate, etc.)\n * - a method for registering generic components (registerTemplate)\n * - an interface to notify the components that an event has occurred in the core script, and allow them to handle events\n */\nexport class ComponentsController {\n private managedComponents: ManagedComponent[] = [];\n private _searchContext: CludoSearchContext;\n private _cssTheme: string | undefined;\n public events: EventController;\n\n constructor(\n cludoSearch: CludoSearch,\n searchContext: CludoSearchContext,\n cssTheme?: string\n ) {\n this._searchContext = searchContext;\n this.events = new EventController(cludoSearch, searchContext);\n this._cssTheme = cssTheme;\n }\n\n /**\n * Register a search results component; will be updated on search events\n * @param component\n * @param element HTMLElement reference or CSS selector\n */\n public registerSearchResultsComponent(\n component: React.ComponentType,\n element: HTMLElement | string): void {\n this.addManagedComponent(\n component,\n element,\n ['beforesearch', 'aftersearch']\n );\n }\n\n /**\n * Register a controls template; will be updated on search events\n * \n * Controls, by default, contains facets and sort-picker components\n * @param component\n * @param element HTMLElement reference or CSS selector\n */\n public registerControlsComponent(\n component: React.ComponentType,\n element: HTMLElement | string): void {\n this.addManagedComponent(\n component,\n element,\n ['beforesearch', 'aftersearch']\n );\n }\n\n /**\n * Register an autocomplete template; will be updated on afterautocomplete events\n * @param component\n * @param element HTMLElement reference or CSS selector\n */\n public registerAutocompleteComponent(\n component: React.ComponentType,\n element: HTMLElement | string): void {\n this.addManagedComponent(\n component,\n element,\n ['afterautocomplete', 'afterinputfocus']\n );\n }\n\n /**\n * \n * @param component\n * @param element HTMLElement reference or CSS selector\n * @param observedEventTypes The list of event types that trigger an update of props; if not specified, \n * all events are treated as relevant\n */\n public registerComponent(\n component: React.ComponentType,\n element: HTMLElement | string,\n observedEventTypes: EventType[] = [],\n renderImmediately = true\n ): void {\n this.addManagedComponent(\n component,\n element,\n observedEventTypes,\n renderImmediately\n );\n }\n\n /**\n * Adds a managed component to the array stored in the managedComponents property\n * @param component\n * @param element\n * @param elemSelector\n * @param observedEventTypes \n */\n private addManagedComponent(\n component: React.ComponentType,\n element: HTMLElement | string,\n observedEventTypes: EventType[] = [],\n renderImmediately: boolean = false\n ): void {\n if (!isOnClient()) return;\n const resolvedElement: HTMLElement | null =\n (typeof element === 'string')\n ? document.querySelector(element)\n : element;\n\n const resolvedSelector: string | undefined =\n (typeof element === 'string')\n ? element\n : undefined;\n\n const managedComponent: ManagedComponent = {\n component: component,\n elem: resolvedElement,\n elemSelector: resolvedSelector,\n observedEventTypes: observedEventTypes,\n hasRendered: false\n } \n\n this.managedComponents.push(managedComponent);\n\n if (renderImmediately) {\n this.renderComponent(managedComponent);\n }\n }\n\n /**\n * Processes an event from the core script\n * \n * - Emits the event to any subscribing components\n * \n * @param type\n * @param data \n * @param callbackFnc \n */\n public processEvent(type: EventType, data?: any, callbackFnc?: () => void): void {\n this.events.emitEvent(type, data);\n\n this.managedComponents\n .filter((component: ManagedComponent) => component.observedEventTypes.length === 0 || component.observedEventTypes.includes(type))\n .forEach((component: ManagedComponent) => this.renderComponent(component));\n\n if (callbackFnc) {\n callbackFnc();\n }\n }\n\n /**\n * Renders a managed component\n * @param component\n */\n private renderComponent(component: ManagedComponent): void {\n const RenderedComponent = component.component;\n\n // Removing this for now - investigate bug it creates for addWidget() components\n // if (component.hasRendered) {\n // return;\n // }\n\n // try to grab a reference to the element if it wasn't found on mount\n if (!component.elem && isOnClient()) {\n component.elem = document.querySelector(component.elemSelector!);\n }\n\n // if element still found, skip -- React would throw an error\n if (!component.elem) { return; }\n\n component.hasRendered = true;\n \n ReactDOM.render(\n <React.StrictMode>\n <CludoContext.Provider value={this._searchContext}>\n <EventControllerContext.Provider value={this.events}>\n <ThemeProvider theme={this._cssTheme}>\n <RenderedComponent />\n </ThemeProvider>\n </EventControllerContext.Provider>\n </CludoContext.Provider>\n </React.StrictMode>,\n component.elem,\n () => {}\n );\n }\n}","import { ChatRequestBody, ChatResponse, ChatFeedbackData } from \"../types/conversation-types\";\nimport { ClientSearchResponse, CludoSearch, FilterMap, RelatedPagesRequestParams, TypedDocument } from \"../types/core-script-types\";\nimport { FeedbackData } from \"../types/feedback-module-types\";\nimport { QueryLogObject, ClickLogObject, ChatClickLog } from \"../types/tracking-types\";\nimport { TrendingPagesResponse } from \"../types/trending-pages-types\";\nimport { CludoSearchContext } from \"./cludo-search-context\";\nimport { EventType } from \"./components-controller\";\n\ninterface CallbackMeta {\n id: number;\n type: EventType;\n fnc: Function;\n}\n\nexport class EventController {\n private _cludoSearch: CludoSearch;\n private _searchContext: CludoSearchContext;\n\n private keyedSubscriptions: CallbackMeta[] = [];\n\n private _curSubscriptionIndex: number = 1;\n\n constructor(\n cludoSearch: CludoSearch,\n searchContext: CludoSearchContext) {\n this._cludoSearch = cludoSearch;\n this._searchContext = searchContext;\n }\n\n /**\n * Registers a callback function to be called whenever a\n * trigger of a certain type (beforesearch, aftersearch, etc) occurs\n * @param key \n * @param callback \n * @returns Subscription id -- necessary for unsubscribing\n */\n public subscribe(type: EventType, callback: Function): number {\n const subscriptionId: number = this._curSubscriptionIndex++;\n\n this.keyedSubscriptions.push({\n id: subscriptionId,\n type: type,\n fnc: callback,\n });\n\n return subscriptionId;\n }\n\n /**\n * Registers a callback function to be called whenever any trigger occurs\n * @param callback \n * @returns Subscription id -- necessary for unsubscribing\n */\n public subscribeToAllEvents(callback: Function): number {\n const subscriptionId: number = this._curSubscriptionIndex++;\n const allEventTypes: EventType[] = [\n 'afterautocomplete',\n 'aftersearch',\n 'autocompleteSelectionNext',\n 'autocompleteSelectionPrev',\n 'autocompleteSetSelection',\n 'beforeredirect',\n 'beforesearch',\n 'error'\n ]\n\n // Subscribe to all with the same subscription ID\n allEventTypes.forEach((type: EventType) => {\n this.keyedSubscriptions.push({\n id: subscriptionId,\n type: type,\n fnc: callback\n });\n });\n\n return subscriptionId;\n }\n\n /**\n * Unregisters a previously defined callback\n * @param subscriptionId\n */\n public unsubscribe(subscriptionId: number): void {\n this.keyedSubscriptions =\n this.keyedSubscriptions.filter(\n // keep all subscriptions that don't match the passed sub id\n (sub: CallbackMeta) => sub.id !== subscriptionId);\n }\n\n /**\n * Emits an event that will then be transmitted via the callbacks to all subscribers for the specific type\n * @param key \n * @param data \n */\n public emitEvent(key: EventType, data: any): void {\n this.executeCallbacksForType(key, data);\n }\n\n // FUTURE -- might be possible to better type the payload object\n private executeCallbacksForType(eventType: EventType, payload: any): void {\n this.subscribersForType(eventType)\n .forEach((callback: CallbackMeta) => {\n // call the provided function and pass the payload object as a param\n callback.fnc(payload);\n });\n }\n\n private subscribersForType(eventType: EventType): CallbackMeta[] {\n return this.keyedSubscriptions.filter(\n (callback: CallbackMeta) => callback.type === eventType\n );\n }\n\n public search(query?: string): void {\n if (query) {\n this._cludoSearch.params.query = query;\n }\n if (this._cludoSearch._handleQuickLinks()) {\n return;\n }\n this._cludoSearch.search();\n }\n\n public clearResults(): void {\n this._cludoSearch.clearStoredSearchResponseData();\n }\n\n //#region results\n public get searchResultKeyUpEvent(): (e: KeyboardEvent) => void {\n return this._cludoSearch.searchResultKeyUpEvent;\n }\n\n public get searchResultTrackClickEventHandler(): (e: MouseEvent | KeyboardEvent, target?: HTMLElement) => void {\n return this._cludoSearch.searchResultTrackClickEventHandler;\n }\n\n public get linkToSearchClickEvent(): (anchor: HTMLAnchorElement) => void {\n return this._cludoSearch.linkToSearchClickEvent;\n }\n //#endregion\n\n //#region facets\n public selectFacet(field: string, value: string, multi: boolean = false, shouldSearch = true): void {\n this._cludoSearch.facet(field, value, multi, shouldSearch);\n }\n\n public deselectFacet(field: string, value: string, shouldSearch = true): void {\n this._cludoSearch.clearFacet(field, value, shouldSearch);\n }\n\n public clearFacet(field: string, shouldSearch = true): void {\n this._cludoSearch.clearFacetByName(field, shouldSearch);\n }\n\n public clearAllFacets(shouldSearch = true): void {\n this._cludoSearch.clearAllFacetsAndSearch(shouldSearch);\n }\n\n // Deprecated - use clearAllFacets(false) going forward\n public softClearAllFacets(): void {\n this._cludoSearch.clearAllFacets();\n }\n\n public setDateRangeFacet = (field: string, from: string, to: string, shouldSearch = true) => {\n this._cludoSearch.setDateRangeFacet(field, from, to, shouldSearch);\n }\n\n public setNumberRangeFacet = (field: string, from: number, to: number, shouldSearch = true) => {\n this._cludoSearch.setNumberRangeFacet(field, from, to, shouldSearch);\n }\n\n public clearDateRangeFacet = (shouldSearch = true) => { \n this._cludoSearch.clearFacetByName('date', shouldSearch)\n };\n\n public clearNumberRangeFacet = (shouldSearch = true) => {\n this._cludoSearch.clearFacetByName('range', shouldSearch)\n };\n\n // #region filters\n\n public setFilter(facetKey: string, value: string[], shouldSearch = true): void {\n this._cludoSearch.filter(facetKey, value, shouldSearch);\n }\n\n public setFilters(filters: FilterMap): void {\n this._cludoSearch.params.filters = filters;\n }\n\n public clearAllFilters(shouldSearch = true): void {\n this._cludoSearch.clearAllFilters(shouldSearch);\n }\n\n // #endregion\n\n // replacement for handleFacetValueClick, onFacetValueClick\n public toggleFacetValue(facetField: string, facetValue: string, shouldSearch = true): void {\n if (!this._searchContext.isFacetSelected(facetField, facetValue)) {\n this.selectFacet(facetField, facetValue, undefined, shouldSearch);\n } else {\n this.deselectFacet(facetField, facetValue, shouldSearch);\n }\n }\n //#endregion\n\n //#region did you mean\n private set didYouMean(didYouMeanText: string) {\n this._cludoSearch.didYouMean = didYouMeanText;\n }\n\n public handleDidYouMeanSelect(didYouMeanText: string): void {\n this.didYouMean = didYouMeanText;\n\n this._cludoSearch.setDidYouMean();\n }\n //#endregion\n\n //#region pagination\n public goToPage(pageNumber: number): void {\n this._cludoSearch.page(pageNumber, true);\n }\n public setPerPage(perPage: number): void {\n this._cludoSearch.params.perPage = perPage;\n this._cludoSearch.page(1);\n }\n //#endregion\n\n //#region sort\n /** Clears sorting parameters and performs a search */\n public clearSortOrder(shouldSearch = true): void {\n this._cludoSearch.clearSortOrder(shouldSearch);\n }\n\n /** Clears sorting parameters */\n public clearSortParams(): void {\n this._cludoSearch.clearSortParams();\n }\n\n /** Augments current sort order with passed arguments and performs a search */\n public addToSortOrder(field: string, dir: string, shouldSearch = true): void {\n this._cludoSearch.setSortOrder(field, dir, shouldSearch);\n }\n\n /** Sets the sort order according to passed arguments and performs a search */\n public setSortOrder(field: string, dir: string, shouldSearch = true): void {\n this.clearSortParams();\n this.addToSortOrder(field, dir, shouldSearch);\n }\n //#endregion\n\n // #region autocomplete\n /** Performs an autocomplete request which, when complete, updates the list of autocomplete items */\n public initiateAutocompleteRequest(query: string): void {\n // FUTURE: Debouncing is handled within CoreJS in this function. Consider optionally ignoring it in the core script and handling debouncing in the component\n this._cludoSearch.autocompleteByQuery(query);\n }\n\n public selectSuggestion(suggestion: string, suggestionIndex: number) {\n this._cludoSearch.autocompleteSetSelectedSuggestion(suggestion, suggestionIndex);\n }\n\n public selectResult(result: TypedDocument) {\n this._cludoSearch.autocompleteSetSelectedResult(result);\n }\n\n public selectRecentSearch(recentSearch: string, recentSearchIndex: number) {\n this._cludoSearch.autocompleteSetSelectedRecentSearch(recentSearch, recentSearchIndex);\n }\n\n public clearRecentSearches() {\n this._cludoSearch.clearRecentSearches();\n }\n\n public clearAutocomplete() {\n this._cludoSearch.autocompleteRestoreClient();\n }\n\n public setActiveDescendantToSuggestions(id: string) {\n this._cludoSearch.setActiveDescendantToSuggestions(id);\n }\n // #endregion\n\n // #region endless scroll\n public endlessScrollLoadMore(): void {\n this._cludoSearch.endlessScrollLoadMoreClickEvent();\n }\n // #endregion\n\n // #region tracking\n /** Refer to https://docs.cludo.com/#tracking_queries for Query Log properties */\n public trackQuery(queryLog: QueryLogObject) {\n return this._cludoSearch.trackQuery(queryLog);\n }\n\n /** Refer to https://docs.cludo.com/#tracking_clicks for Click Log properties */\n public trackClick(clickLog: ClickLogObject) {\n return this._cludoSearch.trackClick(clickLog);\n }\n\n /** Sends a click log associated with a chat result */\n public trackChatClick(clickLog: ChatClickLog) {\n return this._cludoSearch.trackChatClick(clickLog);\n }\n // #endregion\n\n // #region Conversations\n\n /** Get conversations from storage */\n public getConversations(): any[] {\n return this._cludoSearch.conversationService.getConversationsFromStorage();\n }\n\n /** Store conversations */\n public storeConversations(conversations: any): void {\n this._cludoSearch.conversationService.storeConversations(conversations);\n }\n\n /** Send a question to our QA service */\n public sendQuestion(customerId: number, engineId: number, requestBody: ChatRequestBody, controller: AbortController): Promise<ChatResponse> {\n return this._cludoSearch.conversationService.sendQuestion(customerId, engineId, requestBody, controller);\n }\n\n /** Send feedback data regarding an exchange */\n public sendChatFeedbackData(customerId: number, engineId: number, feedbackData: ChatFeedbackData): Promise<void> {\n return this._cludoSearch.conversationService.sendFeedbackData(customerId, engineId, feedbackData);\n }\n\n /** Send feedback data from the feedback module experience */\n public sendFeedbackData(customerId: number, engineId: number, feedbackData: FeedbackData): Promise<void> {\n return this._cludoSearch.feedbackService.sendFeedback(customerId, engineId, feedbackData);\n }\n\n // #endregion\n\n // #region Trending pages\n\n /** Get trending pages for the current customer/engine */\n public getTrendingPages(daysBack: number, limit?: number, timezone?: string): Promise<TrendingPagesResponse> {\n return this._cludoSearch.getTrendingPages(daysBack, limit, timezone);\n }\n\n /** Get popular pages for the current customer/engine */\n public getPopularPages(daysBack: number, limit?: number, timezone?: string): Promise<TrendingPagesResponse> {\n return this._cludoSearch.getPopularPages(daysBack, limit, timezone);\n }\n\n /** Get related pages for the current customer/engine */\n public getRelatedPages(url: string, overrideParams?: RelatedPagesRequestParams): Promise<ClientSearchResponse> {\n return this._cludoSearch.getRelatedPages(url, overrideParams);\n }\n\n // #endregion\n}","import { CludoSearch, FilterMap } from \"../types/core-script-types\";\nimport { StringOverrideKeys, SupportedLanguage } from \"../types/translation-types\";\nimport { CludoSearchContext } from \"./cludo-search-context\";\nimport { ComponentsController, TemplateType } from \"./components-controller\";\nimport { CoreScriptStringOverrides } from \"./models/instantiator-types\";\n\n/**\n * Abstraction layer for interacting with the core Cludo script\n * \n * Provides public functions that are available to consumers and seals away internal functions that should not be callable\n */\nexport class CludoInstanceController {\n \n private _cludoSearch: CludoSearch;\n\n // TO-DO -- maybe there is a better name for this property?\n public instance: CludoSearchContext;\n\n public components: ComponentsController;\n\n constructor(cludoSearch: CludoSearch, cssTheme?: string) {\n this._cludoSearch = cludoSearch;\n\n this.instance = new CludoSearchContext(this._cludoSearch);\n this.components = new ComponentsController(this._cludoSearch, this.instance, cssTheme);\n }\n\n // FUTURE -- provide \"on init\" callback\n \n /**\n * Trigger a new search, which includes\n * - ensuring that the observed input values reflect the query value\n * - resets the page number\n * - resets the facets\n * - restores autocomplete\n * - restores endless scroll\n * - resets sort\n * \n * FUTURE -- provide a one-time callback specific to this search call\n */\n public search(): void {\n this._cludoSearch.search();\n }\n\n // Below methods intentionally all return an instance of the CludoSearchController class\n // so that the method calls can be chained\n\n /**\n * Registers a component for a specific type of widget\n * @param widgetType \n * @param widgetComponent \n * @returns Instance of CludoInstanceController (to allow chaining of calls)\n */\n public addWidget(\n widgetType: TemplateType,\n widgetComponent: React.ComponentType,\n element: HTMLElement | string\n ): CludoInstanceController {\n switch(widgetType) {\n case TemplateType.Results:\n this.components.registerSearchResultsComponent(\n widgetComponent,\n element);\n case TemplateType.Controls:\n this.components.registerControlsComponent(\n widgetComponent,\n element);\n case TemplateType.Autocomplete:\n this.components.registerAutocompleteComponent(\n widgetComponent,\n element);\n }\n\n return this;\n }\n\n /**\n * Override the translation for a given token and language\n * @param key The translation token to assign\n * @param value The value of the translation\n * @param language The language the translation should override\n * @returns Instance of CludoInstanceController (to allow chaining of calls)\n */\n public setOverrideString(key: StringOverrideKeys, value: string, language: SupportedLanguage): CludoInstanceController {\n const languageSpecificTranslationSet = this._cludoSearch.translateProvider.translations[language];\n\n if (languageSpecificTranslationSet) {\n languageSpecificTranslationSet[key] = value;\n }\n \n return this;\n }\n \n /**\n * Assign a collection of override strings for the current language\n * @param overrides The collection of override strings for the current language\n * @returns Instance of CludoInstanceController (to allow chaining of calls)\n */\n public setOverrideStrings(overrides: CoreScriptStringOverrides): CludoInstanceController {\n const language = this.instance.translateProvider.language;\n Object.keys(overrides).map( (key) => {\n const value = overrides[key];\n if (key && value) {\n this.setOverrideString(key as StringOverrideKeys, value, language)\n }\n });\n\n return this;\n }\n\n /**\n * Assigns the current language for the Cludo instance\n * @param language The language to set as the current language\n */\n public setLanguage(language: SupportedLanguage): CludoInstanceController {\n this.instance.translateProvider.language = language;\n\n return this;\n }\n\n // FUTURE -- consider adding chainable utility functions for updating the CludoSearch options\n // Potential options:\n // setAutocompleteOptions(options: AutocompleteInitializationOptions): CludoInstanceController\n // addCallback(type: CallbackType, callback: Function): CludoInstanceController\n}","import { useState } from \"react\";\nimport { useCludoContext } from \"./use-cludo-context\";\nimport { SortOrder } from \"../types/core-script-types\";\nimport { SortOption } from \"../utils/models/instantiator-types\";\nimport { useEventSubscriptions } from \"./use-event-subscription\";\n\nexport interface SortByState {\n sortOrder: SortOrder;\n sortItems: SortOption[];\n}\n\nexport interface SortByDispatchers {\n setSortOrder: (field: string, direction: string, shouldSearch?: boolean) => void;\n addToSortOrder: (field: string, direction: string, shouldSearch?: boolean) => void;\n clearSortOrder: (shouldSearch?: boolean) => void;\n}\n\n/** Expose state and dispatchers for controlling sorting \n * @returns cludoState (sortOrder, sortItems) and cludoDispatchers (events for setting/clearing sort order)\n*/\nexport function useSortBy(): [SortByState, SortByDispatchers] {\n const { context, eventController } = useCludoContext();\n\n // Derive state from CludoSearchContext\n const deriveState : () => SortByState = () => {\n return {\n sortOrder: context.sort || {},\n sortItems: context.sortItems || [],\n }\n };\n\n // Derive dispatchers from EventController\n // FUTURE: Investigate getting rid of bind here\n const deriveDispatchers : () => SortByDispatchers = () => {\n return {\n setSortOrder: eventController?.setSortOrder?.bind(eventController) || (() => {}),\n addToSortOrder: eventController?.addToSortOrder?.bind(eventController) || (() => {}),\n clearSortOrder: eventController?.clearSortOrder?.bind(eventController) || (() => {}),\n\n }\n }\n\n // When eventController changes, derive state and dispatchers again\n useEventSubscriptions(() => {\n setCludoState(deriveState());\n setCludoDispatchers(deriveDispatchers());\n });\n\n const [cludoState, setCludoState] = useState(deriveState());\n const [cludoDispatchers, setCludoDispatchers] = useState(deriveDispatchers());\n\n return [ cludoState, cludoDispatchers ];\n}","import React from 'react';\nimport { useSortBy } from '../../../hooks/use-sort-by';\n\n/** Props interface */\nexport type CludoSortBaseProps = {\n relevanceLabel?: string;\n}\n\nexport function CludoSortPicker(props: CludoSortBaseProps) {\n\n const [sortByState, sortByDispatchers] = useSortBy();\n\n // If set to nothing, keep translation to be Relevance\n const relTranslation = (props.relevanceLabel) ? props.relevanceLabel : 'Relevance';\n\n // Length of sort object\n let sortObject = Object.keys(sortByState.sortOrder);\n // If sort is active\n let sortActive = sortObject.length > 0;\n // Active class for relevance field\n let relActive = (sortActive) ? undefined : 'active';\n\n return (\n <div className='cludo-sort-picker'>\n <ul className=\"cludo-sort-picker-list\">\n <li className={`cludo-sort-picker-item ${relActive}`}>\n <a onClick={() => sortByDispatchers.clearSortOrder() }>{relTranslation}</a>\n </li>\n\n {sortByState.sortItems.map(sortItem => {\n const isActive =\n (sortActive && (sortObject[0] == sortItem.key) && sortByState.sortOrder[sortItem.key] == sortItem.direction)\n ? 'active'\n : undefined;\n\n return (\n <li className={`cludo-sort-picker-item ${isActive}`}\n key={sortItem.key + sortItem.direction}>\n <a onClick={() => sortByDispatchers.setSortOrder(sortItem.key, sortItem.direction) }>\n {sortItem.displayText}\n </a>\n </li>\n );\n })}\n </ul>\n </div>\n )\n}\n\n","import React, { PropsWithChildren } from \"react\";\n\ninterface PseudoLinkProps {\n className: string;\n onClick: () => void;\n}\n\nexport function PseudoLink(props: PropsWithChildren<PseudoLinkProps>) {\n const interceptClick: (event: React.MouseEvent) => void =\n (event: React.MouseEvent) => {\n event.preventDefault();\n props.onClick();\n }\n\n return (\n <a className={props.className} href=\"#\"\n onClick={(e) => interceptClick(e) }>\n { props.children}\n </a>\n )\n}","import { useState } from \"react\";\nimport { ExternalFacet } from \"../utils/cludo-search-context\";\nimport { useCludoContext } from \"./use-cludo-context\";\nimport { useEventSubscriptions } from \"./use-event-subscription\";\n\nexport interface FacetState {\n facet: ExternalFacet | null;\n}\n\nexport interface FacetDispatchers {\n selectFacet: (value: string, multi?: boolean, shouldSearch?: boolean) => void;\n deselectFacet: (value: string, shouldSearch?: boolean) => void;\n toggleFacetValue: (value: string) => void;\n clearFacet: (shouldSearch?: boolean) => void;\n setDateRangeFacet: (from: string, to: string, shouldSearch?: boolean) => void;\n setNumberRangeFacet: (from: number, to: number, shouldSearch?: boolean) => void;\n}\n\n/** Expose data and dispatchers for a facet component \n * @returns cludoState (data of facet for inputted facet field) and cludoDispatchers (select, deselect, and toggle facet events)\n*/\nexport function useFacet(facetField: string) : [FacetState, FacetDispatchers] {\n const { context, eventController } = useCludoContext();\n\n // Derive state from CludoSearchContext\n const deriveState : () => FacetState = () => {\n const facet = context?.facets?.find(facet => facet.key === facetField) || null;\n return {\n facet\n }\n }\n\n // Derive dispatchers from EventController\n // FUTURE: Investigate getting rid of bind here\n const deriveDispatchers : () => FacetDispatchers = () => {\n return {\n selectFacet: eventController?.selectFacet?.bind(eventController, facetField) || (() => {}),\n deselectFacet: eventController?.deselectFacet?.bind(eventController, facetField) || (() => {}),\n toggleFacetValue: eventController?.toggleFacetValue?.bind(eventController, facetField) || (() => {}),\n clearFacet: eventController?.clearFacet?.bind(eventController, facetField) || (() => {}),\n setDateRangeFacet: eventController?.setDateRangeFacet?.bind(eventController, facetField) || (() => {}),\n setNumberRangeFacet: eventController?.setNumberRangeFacet?.bind(eventController, facetField) || (() => {})\n }\n }\n\n // When eventController changes, derive state and dispatchers again\n useEventSubscriptions(() => {\n setCludoState(deriveState());\n setCludoDispatchers(deriveDispatchers());\n });\n\n const [cludoState, setCludoState] = useState(deriveState());\n const [cludoDispatchers, setCludoDispatchers] = useState(deriveDispatchers());\n\n return [ cludoState, cludoDispatchers ];\n}","import React from \"react\";\nimport { PseudoLink } from \"../../../utility/pseudo-link\";\nimport { FacetItemProps } from \"../base-facet\";\nimport { useFacet } from \"../../../../hooks/use-facet\";\nimport { generateThemeCss } from \"../../../../utils/theme-provider\";\n\n/** Renders a single facet item */\nexport function StandardFacetItem(props: FacetItemProps) {\n const [facetState, facetDispatchers] = useFacet(props.facetItem.facetName);\n\n // Set theme css\n const optionThemeCss = generateThemeCss('cludo-theme-facet-option', props.disableTheme, props.className);\n const activeThemeCss = generateThemeCss('cludo-theme-facet-option cludo-font-weight-bold', props.disableTheme, props.className) + ' cludo-active';\n const countThemeCss = generateThemeCss('cludo-theme-facet-count', props.disableTheme, props.className);\n\n const valueClass = props.facetItem.isSelected ?\n activeThemeCss :\n optionThemeCss;\n\n const handleFacetClick = () => {\n // Override used mostly for \"All results\" option to clear any set facet values\n if (props.overrideOnChange) {\n props.overrideOnChange();\n return;\n }\n facetDispatchers.toggleFacetValue(props.facetItem.value);\n if (props.onChange) props.onChange();\n }\n\n return (\n <PseudoLink className={valueClass}\n onClick={handleFacetClick}>\n { props.facetItem.value }\n {\n (!props.hideCount && props.facetItem.count !== undefined) ? \n <> <span className={countThemeCss}>{props.facetItem.count}</span></>\n : null\n }\n </PseudoLink>\n )\n}","import React, { ReactNode } from \"react\";\nimport { StandardFacet } from \"../components/controls/facets/standard-facet\";\n\n\n/** Takes in unordered facet field/option array and order reference array and returns ordered facet field/option array */\nexport function setOrderBasedOnReference(unordered: string[], reference: string[]): string[] {\n let unorderedArr = [...unordered];\n let referenceArr = [...reference];\n\n const wildcards = referenceArr.filter(x => x === \"*\").length;\n if (wildcards > 1) {\n throw new Error('Only one wildcard (*) allowed in a reference order');\n }\n\n // Sorting is done by first removing any elements from reference array that don't exist in original array\n // Remaining reference elements are removed from original unordered array\n referenceArr = referenceArr.filter(x => unorderedArr.includes(x) || x === \"*\");\n unorderedArr = unorderedArr.filter(x => !referenceArr.includes(x));\n\n // Remaining unordered elements (unorderedArr) are either inserted into wildcard (*) position\n // or simply added to end of ordered reference array and returned\n const wildcardIndex = referenceArr.indexOf(\"*\");\n if (wildcardIndex > -1) {\n referenceArr.splice(wildcardIndex, 1, ...unorderedArr);\n return referenceArr;\n } \n else {\n return referenceArr.concat(unorderedArr);\n }\n}\n\n\n/** Takes in facet field array and collection of child components that should override default component */\n/** Returns map with key set to facet field string and value set to facet component that should be rendered for field */\nexport function populateFacetGroupMap(facetFields: string[], facetOverrides: React.ReactNode): Map<string, React.ReactNode> {\n let DefaultComponent: React.ReactElement;\n const facetMap = new Map<string, React.ReactNode>(facetFields.map(field => [field, null]));\n\n if (facetOverrides) {\n React.Children.forEach(facetOverrides, override => {\n\n // Make sure any overrides are valid React elements and have a \"field\" prop\n if (!React.isValidElement(override)) return;\n const { field } = override.props;\n const { type, props } = override;\n if (!field) {\n throw new Error(\n `Could not find \"field\" prop for facet group override ${type || 'unknown'}.`\n );\n }\n\n // If default (*) override set, make sure it is the first default override\n // Set default component to instance of override type with any pre-set props (will add field prop later)\n if (override.props.field === \"*\") {\n if (DefaultComponent) {\n throw new Error('Only one override component with wildcard (*) field allowed in a facet group');\n } else {\n DefaultComponent = React.createElement(type, {...props});\n }\n }\n // Otherwise, set instance of specific override with field prop in map\n else {\n facetMap.set(field, \n React.createElement(type, {field: field, ...props})\n );\n } \n });\n }\n\n // Check map for any facet fields that still have null component value\n // Set component instance to either the default component override, if it was set, or standand facet\n facetMap.forEach((value, key, map) => {\n if(value === null) {\n const fallback = DefaultComponent ? \n React.cloneElement(DefaultComponent, {field: key}) : \n React.createElement(StandardFacet, {field: key});\n map.set(key, fallback);\n }\n })\n \n return facetMap;\n}\n\n","import React from \"react\"\nimport { ExternalFacet } from \"../../../../utils/cludo-search-context\"\nimport { generateThemeCss } from \"../../../../utils/theme-provider\";\nimport { ThemeBaseProps } from \"../../../types/types\";\n\nexport function FacetHeader(props: ThemeBaseProps<\n // Child component custom class names definition\n 'root' |\n 'header' |\n 'clearButton'\n> & {\n facet: ExternalFacet | null,\n label: string,\n hideClear?: boolean,\n clearLabel?: string,\n onClear?: (e?: React.SyntheticEvent) => void\n}) {\n \n // Set theme css\n const rootCss = generateThemeCss('cludo-display-flex cludo-align-items-center cludo-mb-2', props.disableTheme, props.className, props.classNames?.root)\n const headerThemeCss = generateThemeCss('cludo-font-size-lg cludo-m-0 cludo-mr-3 cludo-line-height-2', props.disableTheme, props.classNames?.header);\n const clearThemeCss = generateThemeCss('cludo-theme-btn-gray', props.disableTheme, props.classNames?.clearButton);\n\n return ( \n props.facet ?\n <div className={rootCss} {...props.attributes?.root}>\n <h3 className={headerThemeCss} {...props.attributes?.header}>{ props.label }</h3>\n {!props.hideClear && props.facet.hasSelection ?\n // TODO: future task will add translation/override support for 'clear'\n <button \n className={clearThemeCss}\n onClick={props.onClear}\n {...props.attributes?.clearButton}>\n { props.clearLabel || 'Clear' }\n </button> : null\n }\n </div> :\n null\n )\n}","import React from \"react\"\nimport { FacetItem } from \"../../../../utils/cludo-search-context\";\nimport { generateThemeCss } from \"../../../../utils/theme-provider\";\nimport { ThemeBaseProps } from \"../../../types/types\";\n\nexport function FacetSearch(props: ThemeBaseProps & {\n facetItems: FacetItem[],\n onChange: (filteredList: FacetItem[]) => void,\n placeholder?: string,\n hideSelected?: boolean\n}) {\n const unfilteredList = props.facetItems;\n const placeholderOption = props.placeholder || 'Search options'\n const hideSelectedOption = props.hideSelected || false\n\n // Set theme css\n const themeCss = generateThemeCss('cludo-theme-searchbar', props.disableTheme, props.className);\n\n function filterBySearch(event: React.ChangeEvent<HTMLInputElement>) {\n const query = event.currentTarget?.value;\n const filteredList = unfilteredList?.filter((item) => {\n return (\n item.value.toLowerCase().includes(query.toLowerCase()) ||\n (item.isSelected && !hideSelectedOption)\n )\n });\n props.onChange(filteredList);\n };\n\n return (\n <input placeholder={placeholderOption} className={themeCss} onChange={filterBySearch} {...props.attributes?.root} />\n )\n}","import React, { useEffect, useState } from \"react\";\nimport { FacetItem } from \"../../../../utils/cludo-search-context\";\nimport { FacetItemProps } from \"../base-facet\";\nimport { LoadMore } from \"../../../results/cludo-load-more\";\nimport { generateThemeCss } from \"../../../../utils/theme-provider\";\nimport { ThemeBaseProps } from \"../../../types/types\";\nimport { useCludoContext } from \"../../../../hooks/use-cludo-context\";\n\nexport function FacetItemsList(props: ThemeBaseProps<\n // Child component custom class names definition\n 'root' |\n 'listItem' |\n 'allResultsListItem' |\n 'loadMoreButton'\n> & {\n facetItems: FacetItem[],\n itemComponent: React.ComponentType<FacetItemProps>,\n limit?: number,\n showMoreLabel?: string,\n hideShowMore?: boolean,\n hideCount?: boolean,\n includeAllResultsOption?: boolean,\n allResultsOptionLabel?: string,\n allCount?: number\n}) {\n\n const facetLimitOption = props.limit || Infinity;\n const facetHideShowMoreOption = props.hideShowMore || false;\n const facetHideCountOption = props.hideCount || false;\n\n const {context, eventController} = useCludoContext();\n const [visibleFacets, setVisibleFacets] = useState(facetLimitOption);\n\n const allResultsOption: FacetItem = {\n facetName: props.facetItems[0]?.facetName ?? '',\n value: props.allResultsOptionLabel ?? context.translateProvider.translate('template_all_results'),\n isSelected: !props.facetItems.some(item => item.isSelected),\n count: props.allCount\n }\n\n function handleAllResultsClick() {\n if (!allResultsOption.isSelected && allResultsOption.facetName) {\n eventController.clearFacet(allResultsOption.facetName);\n }\n }\n\n // FUTURE: we apply structural css here no matter what - need to rethink how we handle structural css\n const listCss =\n (props.className ? props.className + ' ' : '') +\n (props.classNames?.root ? props.classNames.root + ' ' : '') +\n 'cludo-list-style-none cludo-p-0 cludo-mt-0 cludo-mb-3';\n const listItemCss =\n (props.classNames?.listItem ? props.classNames.listItem + ' ' : '')\n const loadMoreThemeCss =\n generateThemeCss('cludo-theme-btn-accent-secondary cludo-font-weight-bold', props.disableTheme, props.classNames?.loadMoreButton);\n\n function shouldBeHidden(item: FacetItem, i: number) {\n return (\n !item.isSelected &&\n (i > (visibleFacets - 1))\n )\n }\n\n useEffect(() => {\n setVisibleFacets(facetLimitOption);\n }, [props.limit]);\n\n return (\n <>\n <ul className={listCss} {...props.attributes?.root}>\n {props.includeAllResultsOption ?\n <li\n className={props.classNames?.allResultsListItem ?? listItemCss}\n {...props.attributes?.listItem}\n {...props.attributes?.allResultsListItem}\n key={`facet-value-all-results`}>\n <props.itemComponent\n key={`facet-value-all-results`}\n facetItem={allResultsOption}\n hideCount={facetHideCountOption}\n disableTheme={props.disableTheme}\n overrideOnChange={handleAllResultsClick}\n />\n </li> : <></>\n\n }\n {props.facetItems.map((facetItem, i) => {\n return (\n <li\n className={listItemCss}\n {...props.attributes?.listItem}\n style={shouldBeHidden(facetItem, i) ? {display: 'none'} : undefined}\n key={`facet-value-${facetItem.value}`}>\n <props.itemComponent\n key={`facet-value-${facetItem.value}`}\n facetItem={facetItem}\n hideCount={facetHideCountOption}\n disableTheme={props.disableTheme}\n />\n </li>\n );\n })}\n </ul>\n {\n !facetHideShowMoreOption && (visibleFacets < props.facetItems.length) ?\n <LoadMore label={props.showMoreLabel} classNames={{ loadMoreButton: loadMoreThemeCss }} attributes={{loadMoreButton: props.attributes?.loadMoreButton}} onClick={() => setVisibleFacets(Infinity)} /> :\n null\n }\n </>\n )\n}","import React, { useContext, useEffect, useState } from \"react\";\nimport { useFacet } from \"../../../hooks/use-facet\";\nimport { ExternalFacet, FacetItem } from \"../../../utils/cludo-search-context\";\nimport { setOrderBasedOnReference } from \"../../../utils/facet-utils\";\nimport { FacetHeader } from \"./elements/facet-header\";\nimport { FacetSearch } from \"./elements/facet-search\";\nimport { FacetItemsList } from \"./elements/facet-items-list\";\nimport { ThemeBaseProps } from \"../../types/types\";\nimport { generateThemeCss } from \"../../../utils/theme-provider\";\nimport { CludoContext } from \"../../../context\";\n\nexport type FacetProps = ThemeBaseProps<\n // Child component custom class names definition\n 'root' |\n 'header' |\n 'clearButton' |\n 'search' |\n 'facetListContainer' |\n 'facetListItem' |\n 'facetAllResultsListItem' |\n 'loadMoreButton'\n> & {\n field: string;\n facet?: ExternalFacet;\n label?: string;\n clearLabel?: string;\n showMoreLabel?: string;\n searchPlaceholder?: string;\n includeAllResultsOption?: boolean,\n allResultsOptionLabel?: string,\n sortBy?: \"count\" | \"alphabetical\";\n order?: string [];\n exclude?: string [];\n hideCount?: boolean;\n hideClear?: boolean;\n hideSearchBar?: boolean;\n limit?: number;\n hideShowMore?: boolean;\n onChange?: () => {}; \n}\n\nexport type FacetItemProps = ThemeBaseProps & { \n facetItem: FacetItem,\n hideCount?: boolean,\n onChange?: Function,\n overrideOnChange?: Function\n}\n\nexport function BaseFacet(props: FacetProps & {itemComponent: React.ComponentType<FacetItemProps>}) {\n const [facetState, facetDispatchers ] = useFacet(props.field);\n const context = useContext(CludoContext);\n\n // Set options from props or use defaults\n const facetSortByOption = props.sortBy || \"count\";\n const facetOrderOption = props.order || [];\n const facetExcludeOption = props.exclude || [];\n \n // Set theme css\n const containerThemeCss = generateThemeCss('cludo-box-shadow-card cludo-border-radius-card cludo-p-4 cludo-mb-5 cludo-font-family-default cludo-bg-color-white', props.disableTheme, props.className, props.classNames?.root);\n const loadingCss = generateThemeCss(' cludo-theme-loading-disable-children', props.disableTheme || !context.isLoadingResults);\n\n // Consuming component can pass in facet data directly\n // or just pass in field prop and facet data will be retrieved from facet hook\n const facet = props.facet || facetState.facet;\n const [localFacetState, setLocalFacetState] = useState<ExternalFacet | null>(null);\n const [facetItemsSavedCopy, setFacetItemsSavedCopy] = useState<FacetItem[]>([]);\n const [facetItemsToRender, setFacetItemsToRender] = useState<FacetItem[]>([]);\n\n const handleClearFacet = () => {\n facetDispatchers.clearFacet();\n }\n\n useEffect(() => {\n if (!context.isLoadingResults) {\n setLocalFacetState(facet);\n }\n }, [facetState]);\n\n useEffect(() => {\n if (localFacetState?.values?.length) {\n let facetItemValues = localFacetState.values.map(x => x.value);\n // Set sort\n if (facetSortByOption) {\n switch(facetSortByOption) {\n case 'count':\n facetItemValues = localFacetState.values.sort((a, b) => (b.count || -1) - (a.count || -1)).map(facet => facet.value)\n break;\n case 'alphabetical':\n facetItemValues = localFacetState.values.sort((a, b) => a.value.localeCompare(b.value)).map(facet => facet.value)\n break;\n default:\n break;\n }\n }\n // Set exclusions\n if (facetExcludeOption.length) {\n facetItemValues = facetItemValues.filter(x => !facetExcludeOption.includes(x));\n }\n // Set custom order\n if (facetOrderOption.length) {\n facetItemValues = setOrderBasedOnReference(facetItemValues, facetOrderOption);\n }\n // Take filtered/sorted/etc array of facet items values (strings) and push corresponding\n // facet items into an array of facet items that should be rendered\n const facetItemsMap = new Map<string, FacetItem>(localFacetState.values?.map(option => [option.value, option]));\n const filteredFacetItemsList = [] as FacetItem[];\n facetItemValues.forEach(item => {\n const mappedItem = facetItemsMap.get(item);\n if (mappedItem) filteredFacetItemsList.push(mappedItem);\n })\n setFacetItemsSavedCopy(filteredFacetItemsList);\n setFacetItemsToRender(filteredFacetItemsList);\n }\n }, [localFacetState]);\n\n\n return (\n localFacetState?.values.length ?\n <div className={containerThemeCss + loadingCss} {...props.attributes?.root}>\n <FacetHeader\n classNames={{\n header: props.classNames?.header,\n clearButton: props.classNames?.clearButton\n }}\n attributes={{\n header: props.attributes?.header,\n clearButton: props.attributes?.clearButton\n }}\n facet={localFacetState}\n label={props.label ? props.label : localFacetState?.key || ''}\n clearLabel={props.clearLabel}\n hideClear={props.hideClear}\n onClear={handleClearFacet}\n disableTheme={props.disableTheme} />\n {\n !props.hideSearchBar ?\n <FacetSearch\n className={props.classNames?.search}\n attributes={{\n root: props.attributes?.search\n }}\n facetItems={facetItemsSavedCopy}\n placeholder={props.searchPlaceholder}\n onChange={(filteredList) => {setFacetItemsToRender(filteredList)}}\n disableTheme={props.disableTheme} />\n : null\n }\n <FacetItemsList\n classNames={{\n root: props.classNames?.facetListContainer,\n listItem: props.classNames?.facetListItem,\n allResultsListItem: props.classNames?.facetAllResultsListItem,\n loadMoreButton: props.classNames?.loadMoreButton\n }}\n attributes={{\n root: props.attributes?.facetListContainer,\n listItem: props.attributes?.facetListItem,\n allResultsListItem: props.attributes?.facetAllResultsListItem,\n loadMoreButton: props.attributes?.loadMoreButton\n }}\n facetItems={facetItemsToRender}\n itemComponent={props.itemComponent}\n showMoreLabel={props.showMoreLabel}\n limit={props.limit}\n hideShowMore={props.hideShowMore}\n hideCount={props.hideCount}\n disableTheme={props.disableTheme}\n includeAllResultsOption={props.includeAllResultsOption}\n allResultsOptionLabel={props.allResultsOptionLabel}\n allCount={facet?.allCount} />\n\n </div> : null\n )\n}","import React from \"react\";\nimport { StandardFacetItem } from \"./items/standard-facet-item\";\nimport { BaseFacet, FacetProps } from \"./base-facet\";\n\nexport function StandardFacet(props: FacetProps) { \n\n return (\n <BaseFacet itemComponent={StandardFacetItem} {...props} />\n )\n}","import { useState } from \"react\";\nimport { ExternalFacet } from \"../utils/cludo-search-context\";\nimport { useCludoContext } from \"./use-cludo-context\";\nimport { useEventSubscriptions } from \"./use-event-subscription\";\nimport { FacetMapRequest, RangeFacetMap } from \"../types/core-script-types\";\n\nexport interface FacetGroupState {\n facets: ExternalFacet[];\n selectedFacets: FacetMapRequest;\n}\n\nexport interface FacetGroupDispatchers {\n clearAllFacets: (shouldSearch?: boolean) => void;\n softClearAllFacets: () => void;\n deselectFacet: (field: string, value: string, shouldSearch?: boolean) => void;\n}\n\n/** Expose data and dispatchers for a facet group component (collection of all Cludo search facets) \n * @returns cludoState (list of all available facets) and cludoDispatchers (the \"Clear all facets\" event)\n*/\nexport function useFacetGroup() : [FacetGroupState, FacetGroupDispatchers] {\n const { context, eventController } = useCludoContext();\n\n // Derive state from CludoSearchContext\n const deriveState : () => FacetGroupState = () => {\n return {\n facets: context?.facets || [],\n selectedFacets: context?.selectedFacets\n }\n }\n\n // Derive dispatchers from EventController\n // FUTURE: Investigate getting rid of bind here\n const deriveDispatchers : () => FacetGroupDispatchers = () => {\n return {\n clearAllFacets: eventController?.clearAllFacets?.bind(eventController) || (() => {}),\n softClearAllFacets: eventController?.softClearAllFacets?.bind(eventController) || (() => {}),\n deselectFacet: eventController?.deselectFacet?.bind(eventController) || (() => {})\n }\n }\n\n // When eventController changes, derive state and dispatchers again\n useEventSubscriptions(() => {\n setCludoState(deriveState());\n setCludoDispatchers(deriveDispatchers());\n });\n\n const [cludoState, setCludoState] = useState(deriveState());\n const [cludoDispatchers, setCludoDispatchers] = useState(deriveDispatchers());\n\n return [ cludoState, cludoDispatchers ];\n}","import React from \"react\";\nimport { CludoSortPicker } from \"./sort-picker/cludo-sort-picker\";\nimport { ControlsCompositionOptions } from \"../../utils/models/instantiator-types\";\nimport { StandardFacet } from \"./facets/standard-facet\";\nimport { useSortBy } from \"../../hooks/use-sort-by\";\nimport { useFacetGroup } from \"../../hooks/use-facet-group\";\n\nexport const CludoSearchControls = composeControls({});\n\nexport function composeControls(options: ControlsCompositionOptions): () => JSX.Element {\n const SortPickerComponent = options.sortPicker || CludoSortPicker;\n const FacetComponent = options.facet || StandardFacet;\n\n return () => {\n const [ sortByState ] = useSortBy();\n const [ facetsState ] = useFacetGroup();\n const shouldShowSortPicker: boolean = sortByState.sortItems.length > 0;\n const facets = facetsState.facets;\n\n return (\n <>\n {\n shouldShowSortPicker\n ? <SortPickerComponent />\n : <></>\n }\n\n {/* Render facet components */}\n {\n facets.map((facet) => {\n return <FacetComponent key={facet.key} field={facet.key} />\n })\n }\n </>\n \n );\n }\n}\n","import { CludoSearchResults } from '../components/results/cludo-search-results';\nimport { CludoSearchAutocomplete } from '../components/sayt/cludo-search-autocomplete';\nimport { CludoInstanceController } from './cludo-instance-controller';\nimport { CustomComponentConfig, CustomComponentMap, ExternalCludoSearchOptions, PublicSettingsRequestOptions } from './models/instantiator-types';\nimport { CludoSearchControls } from '../components/controls/cludo-search-controls';\nimport { PublicSettings } from '@cludosearch/cludo-api-client/dist/interfaces/api/public-settings.interface';\nimport { SupportedLanguage } from '../types/translation-types';\nimport { CludoSearchOptions, PublicSettingsLocal } from '../types/core-script-types';\nimport { isOnClient } from './render-utils';\nimport styles from \"../styles/all.scss?lazy\";\n\nconst defaultLanguage: SupportedLanguage = 'da';\nconst coreScriptUrl = 'https://customer.cludo.com/scripts/bundles/search-script.min.js';\n\nexport async function getPublicSettings(options: PublicSettingsRequestOptions): Promise<PublicSettings> {\n try {\n let publicSettingsDataStr: string = '';\n publicSettingsDataStr = await window.Cludo.getPublicSettingsByOptions({\n customerId: options.customerId,\n engineId: options.engineId,\n experienceId: options.experienceId,\n apiUrl: undefined,\n authKey: undefined,\n searchSiteKey: undefined,\n isIntranet: options.isIntranet\n } as PublicSettingsRequestOptions);\n\n // Parse public settings from the response (instantSuggestionsConfiguration is double encoded for some reason)\n const publicSettings: PublicSettingsLocal = JSON.parse(publicSettingsDataStr);\n publicSettings.instantSuggestionsConfiguration = JSON.parse(publicSettings.instantSuggestionsConfiguration as any);\n\n return publicSettings;\n\n } catch {\n throw('Unable to resolve public settings via web service');\n }\n}\n\n// FUTURE: This may be replaced by a CoreJS package in the future\nexport async function injectCoreScript(overrideCoreScriptUrl?: string): Promise<void> {\n if (!isOnClient()) return;\n return new Promise(function(resolve, reject) {\n \n const scriptUrl = overrideCoreScriptUrl ?? coreScriptUrl;\n\n if (!isOnClient()) resolve();\n if (document.querySelector(`script[src=\"${scriptUrl}\"]`)){\n resolve();\n } else {\n let script = document.createElement('script');\n script.onload = () => resolve();\n script.onerror = () => reject();\n script.src = scriptUrl;\n document.body.appendChild(script);\n }\n });\n}\n\nexport async function initCludo(options: ExternalCludoSearchOptions): Promise<CludoInstanceController> {\n \n if (!isOnClient()) return {} as CludoInstanceController;\n\n const publicSettingsOptions: PublicSettingsRequestOptions = {\n customerId: options.customerId,\n engineId: options.engineId,\n experienceId: options.experienceId,\n isIntranet: options.secureSearch?.enable\n };\n\n // Get core script (headless only)\n if (options.headless) {\n await injectCoreScript(options.overrideCoreScriptUrl);\n }\n\n // If theme set, inject css\n if (options.cssTheme && styles) {\n styles.use();\n }\n\n // Get public settings\n const publicSettings = await getPublicSettings(publicSettingsOptions);\n\n // Init and return instance controller\n const controller = initCludoWithPublicSettings(options, publicSettings);\n return controller;\n}\n\nexport function initCludoWithPublicSettings(options: ExternalCludoSearchOptions, publicSettings: PublicSettings): CludoInstanceController {\n let cludoSettings: CludoSearchOptions = {\n customerId: options.customerId,\n engineId: options.engineId,\n language: options.language,\n searchUrl: options.searchUrl,\n paramsPrefix: options.instanceId,\n clientTemplates: true, // always true\n publicSettings: publicSettings,\n searchInputs: options.searchInputSelectors,\n headlessSearch: options.headless,\n searchResultsWrapper: options.searchResultsWrapperSelector,\n intranetSearch: options.secureSearch?.enable,\n searchApiUrl: options.secureSearch?.proxyApiUrl,\n customHttpHeaders: options.secureSearch?.customHttpHeaders,\n disableAutocomplete: options.autocomplete?.disable,\n facets: options.facets?.keys,\n initFacets: options.facets?.defaultValues,\n filters: options.filters,\n perPage: options.theme?.resultsPerPage,\n hideResultsCount: options.theme?.hideResultsCount,\n hideSearchFilters: options.theme?.hideSearchFilters,\n hideSearchDidYouMean: options.theme?.hideSearchDidYouMean,\n type: options.theme?.type,\n sortOrder: options.sort?.defaultOrder,\n sortOptions: options.sort?.options,\n logPageVisits: !options.tracking?.skipLoggingPageVisits,\n richAutocomplete: options.autocomplete?.useSearchAsYouType,\n autocompleteForceUseTemplate: options.autocomplete?.renderTemplateWhenNoResults,\n autocompleteMinimumQueryLength: options.autocomplete?.minimumQueryLength,\n applyMultiLevelFacets: options.facets?.applyMultiLevel,\n rangeFacets: options.facets?.rangeValues,\n pierceShadowDom: options.behavior?.pierceShadowDom,\n enableRelatedSearches: options.behavior?.enableRelatedSearches,\n customNoResultsMessage: options.overrideStrings?.noResultsMessage,\n enableVoiceSearch: options.voiceSearch?.enable,\n disableVoiceSearchActiveAnimation: options.voiceSearch?.disableActiveAnimation,\n useFixedQueryInResultsCount: options.theme?.showFixedQueryInResultsCount,\n allowSearchWithoutSearchword: options.behavior?.allowSearchWithoutSearchword,\n jumpToTopOnFacetClick: options.behavior?.jumpToTopOnFacetClick,\n endlessScroll: options.behavior?.endlessScroll,\n enableExtendedTracking: !options.tracking?.disableExtendedTracking,\n customCallbackAfterSearch: options.callbacks?.afterSearch,\n customCallbackBeforeSearch: options.callbacks?.beforeSearch,\n customCallbackBeforeRedirect: options.callbacks?.beforeRedirect,\n customCallbackAfterAutocomplete: options.callbacks?.afterAutocomplete,\n customCallbackBeforeQuicklink: options.callbacks?.beforeQuicklink,\n canUserBeTracked: options.tracking?.canUserBeTracked,\n ovarlayResultsWrapperOpenClass: options.theme?.overlayResultsWrapperOpenClass,\n theme: {\n searchBoxPosition: options.theme?.searchBoxPosition,\n themeColor: options.theme?.themeColor,\n elementFocusColor: options.theme?.elementFocusColor,\n themeBannerColor: options.theme?.themeBannerColor,\n textColor: options.theme?.textColor,\n borderRadius: options.theme?.borderRadius,\n borderRadiusInput: options.theme?.borderRadius\n },\n showInstantSuggestions: options.autocomplete?.showInstantSuggestions,\n suggestedSearchesHeader: options.overrideStrings?.suggestedSearchesHeader,\n recentSearchesHeader: options.overrideStrings?.recentSearchesHeader,\n googleAnalyticsTrackingId: options.tracking?.googleAnalyticsId,\n focusOnResultsAfterSearch: options.behavior?.focusOnResultsAfterSearch,\n translateSearchTemplates: true, // FUTURE -- resolve; theoretically, this shouldn't be necessary\n changeWindowLocation: options.behavior?.updateUrlOnSearch !== undefined ? options.behavior?.updateUrlOnSearch : true,\n urlListDelimiter: options.behavior?.urlListDelimiter\n };\n\n const cludoInstance = new window.Cludo(cludoSettings);\n\n // Get a reference to the current translation object to use for overrides\n let translationRef = cludoInstance.translateProvider\n .translations[options.language || options.filters?.Language[0] || defaultLanguage];\n\n\n // Copy the custom strings into the translateProvider object\n if (translationRef) {\n translationRef = Object.assign(translationRef, options.overrideStrings);\n } else {\n console.warn('Cludo: Translations not found for language ' + options.language);\n }\n\n // Apply any categorize by field settings\n if (options.categorizeResultsByField) {\n cludoInstance.params.topHitsFields = [{\n // Set required field\n field: options.categorizeResultsByField.field,\n // Conditionally set max results and categories\n ...(options.categorizeResultsByField.maxResultsPerCategory &&\n {size: options.categorizeResultsByField.maxResultsPerCategory}),\n ...(options.categorizeResultsByField.maxCategories &&\n {MaxFieldValues: options.categorizeResultsByField.maxCategories})\n }];\n }\n\n const controller: CludoInstanceController = new CludoInstanceController(cludoInstance, options.cssTheme);\n\n // FUTURE -- remove if / once supported in corejs\n if (cludoInstance.setClientTemplateComponentsController) {\n cludoInstance.setClientTemplateComponentsController(controller.components);\n }\n\n cludoInstance.configureFeaturesFromPublicSettings(publicSettings);\n cludoInstance.init();\n\n // render any custom components, or their defaults if not defined\n if (options.headless !== true) {\n const searchComponentMap = {\n results: {} as CustomComponentConfig,\n controls: {} as CustomComponentConfig,\n autocomplete: {} as CustomComponentConfig,\n };\n\n // Since v1.1, we accept components as either a plain component type or a CustomComponentConfig \n // to accommodate custom render events and container selectors. Here, we check which type each\n // component is, and map them all to a CustomcomponentConfig before registering them\n if (isComponentConfigObject(options.components?.results)) {\n searchComponentMap.results = options.components?.results as CustomComponentConfig;\n } else {\n searchComponentMap.results = {\n component: options.components?.results ?? CludoSearchResults,\n containerSelector: cludoSettings.searchResultsWrapper ?? '.search-results .search-results-container',\n renderEvents: ['beforesearch', 'aftersearch']\n } as CustomComponentConfig\n }\n\n if (isComponentConfigObject(options.components?.controls)) {\n searchComponentMap.controls = options.components?.controls as CustomComponentConfig;\n } else {\n searchComponentMap.controls = {\n component: options.components?.controls ?? CludoSearchControls,\n containerSelector: options.controlsWrapperSelector ?? '.search-filters',\n renderEvents: ['beforesearch', 'aftersearch']\n } as CustomComponentConfig\n }\n\n if (isComponentConfigObject(options.components?.autocomplete)) {\n searchComponentMap.autocomplete = options.components?.autocomplete as CustomComponentConfig;\n } else {\n searchComponentMap.autocomplete = {\n component: options.components?.autocomplete ?? CludoSearchAutocomplete,\n containerSelector: '#cludo-search-input #search_autocomplete',\n renderEvents: ['afterautocomplete', 'afterinputfocus']\n } as CustomComponentConfig\n }\n\n // Register components\n\n registerComponent(searchComponentMap.results);\n\n !cludoSettings.hideSearchFilters && registerComponent(searchComponentMap.controls);\n\n if (options.autocomplete?.disable !== true) {\n // register autocomplete for each configured search input or fall back to default input selector\n if (options.searchInputSelectors?.length) {\n options.searchInputSelectors.forEach(selector => {\n registerComponent(searchComponentMap.autocomplete, selector + ' #search_autocomplete');\n })\n } else {\n registerComponent(searchComponentMap.autocomplete);\n }\n }\n\n options.components?.custom?.forEach(component => registerComponent(component));\n }\n\n // Helpers\n function registerComponent(config: CustomComponentConfig, overrideSelector?: string) {\n controller.components.registerComponent(\n config.component,\n overrideSelector ?? config.containerSelector,\n config.renderEvents,\n config.renderEvents.includes('afterpageload')\n );\n }\n\n function isComponentConfigObject(component: any): boolean {\n return component !== null &&\n component !== undefined &&\n typeof component === 'object' &&\n typeof component.containerSelector === 'string' &&\n Array.isArray(component.renderEvents);\n }\n\n return controller;\n}\n\n\n// DROPPED PROPERTIES\n // The below properties are supported in the Cludo constructor but have been dropped from this\n // implementation for the sake of clarity and simplicity\n\n // siteId: number -- dropping siteId as it seems to be a legacy property; only a couple uses found in the customers repo\n // clientTemplates: any -- dropping as we should be able to default this to true\n // searchApiUrlPublic?: string -- dropping as it doesn't appear to be used\n // statisticsApiUrl?: dropping as it's used extremely rarely\n // searchSiteKey?: string; // dropping, custom value doesn't appear to be used and has default\n // customerTemplate?: string; // dropping, not used with the client template approach\n // loading?: string; // dropping, should be overridden as a component instead\n // paramsPrefix?: string // dropping, appears to be unused and has a default ('cludo')\n // showSearchPage?: boolean; // dropping, appeard to be unused and has a default (true)\n // bannerIsInSearchTemplate?: boolean; // dropping for now, not compatible with client-side templates (needs to default to true)\n // xhrRequestHeader?: string; // dropping, not used and has a default ('application/json')\n // hideSearchFiltersIfNoResult?: boolean; // drop, for now at least. I believe the decision \n // on whether to show the filters when there are no\n // results should be delegated to the React components\n // resetFiltersBeforeSearch?: boolean; // dropping as it's used extremely rarely\n // resetSortBeforeSearch?: boolean; // dropping as it's used extremely rarely\n // voiceGrammar?: string[]; // drop for now, as it's not currently supported\n // template?: CludoSearchTemplate; // dropping as it can be recreated with other properties\n // updateInputOnBlur?: boolean; // dropping as it's used rarely and has a default (true) in corejs\n // useStandardSearchTemplate?: boolean; // dropping as it's not currently supported for client side templating\n // translateSearchTemplates?: boolean; dropping as it's not currently supported for client-side templating\n // suggestedSearchesHeader?: boolean; // duplicative with the translateProvider key suggested_searches_title\n // recentSearchesHeader?: string; // duplicative with the translateProvider key recent_searches_title","import React from \"react\";\nimport { SelectorTypeProps } from \"../../../types/control-types\";\nimport { generateThemeCss } from \"../../../utils/theme-provider\";\nimport { ThemeBaseProps } from \"../../types/types\";\n\ntype DropdownInputProps = SelectorTypeProps & ThemeBaseProps<\n 'root' |\n 'label' |\n 'dropdown' |\n 'dropdownOption'\n>\n\nexport function DropdownInput(props: DropdownInputProps) {\n\n const labelThemeCss = generateThemeCss('cludo-font-family-default cludo-font-size-md cludo-font-weight-bold cludo-mr-2', props.disableTheme, props.className, props.classNames?.label)\n const selectThemeCss = generateThemeCss('cludo-p-1 cludo-border-radius-button cludo-height-sm', props.disableTheme, props.className, props.classNames?.dropdown);\n\n return (\n <div className={props.classNames?.root ?? ''} {...props.attributes?.root}>\n { props.label ?\n <label htmlFor={props.id} className={labelThemeCss} {...props.attributes?.label}>\n {props.label}\n </label> : null\n }\n <select \n id={props.id}\n className={selectThemeCss}\n {...props.attributes?.dropdown}\n value={props.currentValue}\n defaultValue={props.default}\n onChange={(event) => props.onChange(event.target.value)}>\n {\n props.options.map((option, i) =>\n <option className={props.classNames?.dropdownOption ?? ''} {...props.attributes?.dropdownOption} key={i} value={option.value}>\n {option.label}\n </option> \n )\n }\n </select>\n </div>\n )\n}","import React, { useContext, useEffect, useState } from \"react\";\nimport { PaginationState, usePagination } from \"../../../hooks/use-pagination\";\nimport { DropdownInput } from \"../../controls/inputs/dropdown-input\";\nimport { ThemeBaseProps } from \"../../types/types\";\nimport { generateThemeCss } from \"../../../utils/theme-provider\";\nimport { useSearchResults } from \"../../../hooks/use-search-results\";\nimport { CludoContext } from \"../../../context\";\n\ninterface ResultsPerPageProps extends ThemeBaseProps<\n 'root' |\n 'label' |\n 'selector' |\n 'selectorOption'\n> {\n options?: number[];\n label?: string;\n // FUTURE: Support more selector types like button list\n // selectorType?: SelectorType;\n}\n\nexport function ResultsPerPage(props: ResultsPerPageProps) {\n const [paginationState, paginationDispatchers] = usePagination();\n const [resultsState] = useSearchResults();\n const [ localPaginationState, setLocalPaginationState ] = useState<PaginationState>(paginationState);\n const context = useContext(CludoContext);\n\n useEffect(() => {\n if (!context.isLoadingResults) {\n setLocalPaginationState(paginationState);\n }\n }, [paginationState])\n\n const options = props.options || [10, 20, 50];\n const optionsMap = options.map(option => { return {label: option.toString(), value: option} });\n const label = props.label || 'Results per page: ';\n const currentPerPage = localPaginationState.itemsPerPage;\n \n const themeCss = generateThemeCss('cludo-mt-3', props.disableTheme, props.className);\n const loadingCss = generateThemeCss(' cludo-theme-loading-disable', props.disableTheme || !resultsState.isLoading);\n \n // FUTURE: Support more selector types like button list\n const SelectorComponent = DropdownInput;\n\n return (\n localPaginationState.showResultsPerPage ?\n <>\n <SelectorComponent\n options={optionsMap} \n id=\"perpage\"\n label={label}\n disableTheme={props.disableTheme}\n className={loadingCss}\n classNames={{\n root: props.classNames?.root,\n label: props.classNames?.label,\n dropdown: `${themeCss} ${props.classNames?.selector ?? ''}`,\n dropdownOption: props.classNames?.selectorOption\n }}\n attributes={{\n root: props.attributes?.root,\n label: props.attributes?.label,\n dropdown: props.attributes?.selector,\n dropdownOption: props.attributes?.selectorOption\n }}\n currentValue={currentPerPage} \n onChange={(value) => paginationDispatchers.setPerPage(Number(value))} />\n </> : null\n )\n}","import React from \"react\";\nimport { SaytResult, SaytResultProps } from \"./sayt-result\";\nimport { AutocompleteItemType } from \"../../types/types\";\n\nexport function SaytCategorizedResult(props: SaytResultProps) {\n return (\n <SaytResult {...props} resultType={AutocompleteItemType.CategorizedResult} />\n )\n}","import React, {Fragment, useMemo, useRef} from \"react\";\nimport {useFacetGroup} from \"../../../../hooks/use-facet-group\";\nimport { populateFacetGroupMap, setOrderBasedOnReference } from \"../../../../utils/facet-utils\";\n\n\nexport function FacetGroup(props : {\n order? : string[],\n exclude? : string[],\n children? : React.ReactNode\n}) {\n const [facetsState] = useFacetGroup();\n const facetOrder = props.order || [];\n const facetExclude = props.exclude || [];\n const facetOverrides = (props.children as React.ReactElement)?.type === Fragment\n ? (props.children as React.ReactElement).props.children\n : props.children;\n\n let facetFields = facetsState.facets.map(x => x.key);\n const facetFieldsRef = useRef<string[]>([]);\n const facetMap = useRef(new Map<string, React.ReactNode>());\n\n useMemo(() => {\n if (facetFields.length) {\n facetFieldsRef.current = facetFields;\n // Set exclusions\n if (facetExclude.length) {\n facetFieldsRef.current = facetFields.filter(x => !facetExclude.includes(x));\n }\n // Set custom order\n if (facetOrder.length) {\n facetFieldsRef.current = setOrderBasedOnReference(facetFields, facetOrder);\n }\n // Populate facet map\n facetMap.current = populateFacetGroupMap(facetFields, facetOverrides);\n }\n }, [facetsState]);\n\n return (\n <>\n { facetFieldsRef.current.map((field) => {\n return <Fragment key={field}>\n {facetMap.current.get(field)}\n </Fragment>\n })\n }\n </>\n )\n}\n","import React from \"react\";\nimport { FacetItemProps } from \"../base-facet\";\nimport { useFacet } from \"../../../../hooks/use-facet\";\nimport { generateThemeCss } from \"../../../../utils/theme-provider\";\n\n\nexport function CheckboxFacetItem(props: FacetItemProps) {\n const [facetState, facetDispatchers] = useFacet(props.facetItem.facetName)\n \n const optionThemeCss = generateThemeCss('cludo-theme-facet-option', props.disableTheme);\n const activeThemeCss = generateThemeCss('cludo-theme-facet-option cludo-font-weight-bold', props.disableTheme) + ' cludo-active';\n const countThemeCss = generateThemeCss('cludo-theme-facet-count', props.disableTheme);\n const inputThemeCss = generateThemeCss('cludo-m-0 cludo-mr-2', props.disableTheme);\n\n const handleFacetChange = (event: React.ChangeEvent<HTMLInputElement>, facetValue: string) => {\n // Override used mostly for \"All results\" option to clear any set facet values\n if (props.overrideOnChange) {\n props.overrideOnChange();\n return;\n }\n const target = event.target;\n const value: boolean = target.checked;\n\n if (value) {\n facetDispatchers.selectFacet(facetValue, true);\n } else {\n facetDispatchers.deselectFacet(facetValue);\n }\n if (props.onChange) props.onChange();\n }\n\n return (\n <label className={ (props.className ? props.className + ' ': '') + (props.facetItem.isSelected ? activeThemeCss : optionThemeCss )}>\n <input\n name={ props.facetItem.facetName }\n type=\"checkbox\"\n checked={ props.facetItem.isSelected }\n className={inputThemeCss} \n onChange={(event) => handleFacetChange(event, props.facetItem.value)} />\n { props.facetItem.value }\n {\n (!props.hideCount && props.facetItem.count !== undefined) ? \n <> <span className={countThemeCss}>{props.facetItem.count}</span></>\n : null\n }\n </label>\n )\n}","import React from \"react\";\nimport { BaseFacet, FacetProps } from \"./base-facet\";\nimport { CheckboxFacetItem } from \"./items/checkbox-facet-item\";\n\nexport function CheckboxFacet(props: FacetProps) { \n\n return (\n <BaseFacet itemComponent={CheckboxFacetItem} {...props} />\n )\n}","import React from \"react\";\nimport { FacetItemProps } from \"../base-facet\";\nimport { useFacet } from \"../../../../hooks/use-facet\";\nimport { generateThemeCss } from \"../../../../utils/theme-provider\";\n\nexport function RadioFacetItem(props: FacetItemProps) {\n const [facetState, facetDispatchers] = useFacet(props.facetItem.facetName);\n \n // Set theme css\n const optionThemeCss = generateThemeCss('cludo-theme-facet-option', props.disableTheme, props.className);\n const activeThemeCss = generateThemeCss('cludo-theme-facet-option cludo-font-weight-bold', props.disableTheme, props.className) + ' cludo-active';\n const countThemeCss = generateThemeCss('cludo-theme-facet-count', props.disableTheme, props.className);\n const inputThemeCss = generateThemeCss('cludo-m-0 cludo-mr-2', props.disableTheme, props.className);\n\n const handleFacetChange = (event: React.ChangeEvent<HTMLInputElement>, facetValue: string) => {\n // Override used mostly for \"All results\" option to clear any set facet values\n if (props.overrideOnChange) {\n props.overrideOnChange();\n return;\n }\n const target = event.target;\n const value: boolean = target.checked;\n\n if (value) {\n facetDispatchers.selectFacet(facetValue);\n }\n if (props.onChange) props.onChange();\n }\n\n return (\n <label className={ props.facetItem.isSelected ? activeThemeCss : optionThemeCss }>\n <input\n name={ props.facetItem.facetName }\n type=\"radio\"\n checked={ props.facetItem.isSelected }\n className={inputThemeCss} \n onChange={(event) => handleFacetChange(event, props.facetItem.value)} />\n { props.facetItem.value }\n {\n (!props.hideCount && props.facetItem.count !== undefined) ? \n <> <span className={countThemeCss}>{props.facetItem.count}</span></>\n : null\n }\n </label>\n )\n}","import React from \"react\";\nimport { BaseFacet, FacetProps } from \"./base-facet\";\nimport { RadioFacetItem } from \"./items/radio-facet-item\";\n\nexport function RadioFacet(props: FacetProps) { \n\n return (\n <BaseFacet itemComponent={RadioFacetItem} {...props} />\n )\n}","import React from \"react\";\n\nconst DEFAULT_HEIGHT = '200';\nconst DEFAULT_WIDTH = '200';\nconst DEFAULT_COLOR = '#000';\nconst DEFAULT_VIEWBOX = '0 0 200 200';\n\nexport interface IconProps {\n height?: string;\n width?: string;\n viewbox?: string;\n color?: string;\n className?: string;\n}\n\nexport interface IconChildProps {\n color?: string;\n}\n\ninterface BaseIconProps extends IconProps {\n children: React.ReactElement<IconChildProps>;\n}\n\nexport const BaseIcon = (props: BaseIconProps) => {\n const width = props.width || DEFAULT_WIDTH;\n const height = props.height || DEFAULT_HEIGHT;\n const viewbox = props.viewbox || DEFAULT_VIEWBOX;\n const color = props.color || DEFAULT_COLOR;\n\n return (\n <svg className={props.className} aria-hidden=\"true\" focusable=\"false\" width={width} height={height} viewBox={viewbox} fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n { React.cloneElement(props.children, { color: color }, null) }\n </svg>\n );\n};\n\n\n","import React from \"react\";\nimport { BaseIcon, IconProps } from \"./base-icon\";\n\nexport function CloseIcon(props: IconProps) {\n return (\n <BaseIcon {...props} >\n <path \n d=\"M4.62154 23.33C-0.245279 28.1934 -0.245271 36.0785 4.62155 40.9419L59.6556 95.9373L4.5986 150.956C-0.268218 155.819 -0.268218 163.704 4.5986 168.567L23.3455 187.301C28.2123 192.165 36.103 192.165 40.9698 187.301L96.0267 132.283L150.927 187.145C155.794 192.008 163.685 192.008 168.551 187.145L187.298 168.411C192.165 163.548 192.165 155.663 187.298 150.799L132.398 95.9373L187.275 41.0983C192.142 36.2349 192.142 28.3498 187.275 23.4864L168.529 4.75271C163.662 -0.11069 155.771 -0.110682 150.904 4.75272L96.0267 59.5916L40.9927 4.59628C36.1259 -0.267119 28.2352 -0.267119 23.3684 4.59628L4.62154 23.33Z\"\n fill={props.color}/>\n </BaseIcon>\n )\n}","import React from \"react\";\nimport { useFacetGroup } from \"../../../../hooks/use-facet-group\";\nimport { generateThemeCss } from \"../../../../utils/theme-provider\";\nimport { ThemeBaseProps } from \"../../../types/types\";\nimport { CloseIcon } from \"../../../icons/close-icon\";\nimport { useSearchResults } from \"../../../../hooks/use-search-results\";\n\ninterface CurrentFacetsProps extends ThemeBaseProps<\n 'root' |\n 'facetContainer' |\n 'facetLabel' |\n 'facetValue' |\n 'facetRemoveButton'\n> {\n exclude?: string[];\n labelsMap?: {[key: string]: string};\n}\n\n// FUTURE: share these values in variables that SCSS and JS can access\nconst ICON_DIMENSION = \"10\";\nconst ICON_FILL_COLOR = \"#344054\";\n\nexport function CurrentFacets(props: CurrentFacetsProps) {\n const [facetGroupState, facetGroupDispatchers] = useFacetGroup();\n const [resultsState] = useSearchResults();\n const selected = facetGroupState.selectedFacets;\n \n // Set theme css\n const rootThemeCss = generateThemeCss('cludo-display-flex cludo-align-items-start cludo-flex-wrap', props.disableTheme, props.className, props.classNames?.root);\n const containerThemeCss = generateThemeCss('cludo-theme-current-facets', props.disableTheme, props.classNames?.facetContainer); \n const labelThemeCss = generateThemeCss('cludo-font-weight-bold', props.disableTheme, props.classNames?.facetLabel); \n const valueThemeCss = generateThemeCss('cludo-ml-2 cludo-display-inline-block', props.disableTheme, props.classNames?.facetValue); \n const buttonThemeCss = generateThemeCss('cludo-theme-current-facets-btn cludo-height-xs', props.disableTheme, props.classNames?.facetRemoveButton); \n const loadingCss = generateThemeCss(' cludo-theme-loading-disable', props.disableTheme || !resultsState.isLoading);\n\n return(\n <div className={rootThemeCss} {...props.attributes?.root}>\n { Object.keys(selected).map((key, i) => {\n if (props.exclude?.includes(key)) {\n return null;\n } else {\n return (\n <div className={containerThemeCss + loadingCss} {...props.attributes?.facetContainer} key={i}>\n <label className={labelThemeCss} {...props.attributes?.facetLabel}>\n { props.labelsMap ? props.labelsMap[key] || key : key }: \n </label>\n <div>\n {\n selected[key].map((value, i) => \n <span key={i} className={valueThemeCss} {...props.attributes?.facetValue}>\n { value } \n <button className={buttonThemeCss} {...props.attributes?.facetRemoveButton} onClick={ () => facetGroupDispatchers.deselectFacet(key, value) }>\n <CloseIcon height={ICON_DIMENSION} width={ICON_DIMENSION} color={ICON_FILL_COLOR} />\n </button>\n </span> \n )\n }\n </div>\n </div>\n )\n }\n })}\n </div>\n )\n}","import React from \"react\";\nimport { useFacetGroup } from \"../../../../hooks/use-facet-group\";\nimport { ThemeBaseProps } from \"../../../types/types\";\nimport { generateThemeCss } from \"../../../../utils/theme-provider\";\n\ninterface ClearAllFacetsProps extends ThemeBaseProps {\n label?: string;\n}\n\nexport function ClearAllFacets(props: ClearAllFacetsProps) {\n const [facetGroupState, facetGroupDispatchers] = useFacetGroup();\n \n // Set theme css\n const themeCss = generateThemeCss('cludo-theme-btn-accent-secondary cludo-font-weight-bold cludo-mb-2', props.disableTheme, props.className);\n\n return ( \n <>\n { facetGroupState.facets.some(facet => facet.hasSelection) ?\n <button className={themeCss} {...props.attributes?.root} onClick={() => facetGroupDispatchers.clearAllFacets()}>\n { props.label || 'Clear all' }\n </button> : <></>\n }\n </>\n )\n}","import React, { useContext } from \"react\";\nimport { ResultContext } from \"../results/items/custom-result\";\nimport { getFieldValue, logMissingResultError } from \"../../utils/result-utils\";\nimport { BaseResultProps } from \"../types/types\";\n\ninterface ResultImageProps extends BaseResultProps {\n altText?: string;\n imageField?: string;\n}\n\nexport function ResultImage(props: ResultImageProps) {\n const resultContext = useContext(ResultContext);\n const result = props.result || resultContext;\n if (!result) {\n logMissingResultError('ResultImage');\n return null;\n }\n\n const imageField = props.imageField || 'Image';\n const imageSrc = getFieldValue(result, imageField);\n const imageAltText = props.altText || getFieldValue(result, 'Title');\n\n return (\n imageSrc ?\n <img src={imageSrc} alt={imageAltText} className={props.className} {...props.attributes?.root} /> :\n null\n )\n}","import React, { useContext, useMemo, useRef } from \"react\";\nimport { ResultContext } from \"../results/items/custom-result\";\nimport { getFieldValue, getFieldValues, logMissingResultError } from \"../../utils/result-utils\";\nimport { ThemeBaseProps } from \"../types/types\";\nimport { generateThemeCss } from \"../../utils/theme-provider\";\nimport { TypedDocument } from \"@cludosearch/cludo-api-client/dist/interfaces/api/search.interface\";\n\ninterface ResultBreadcrumbsProps extends ThemeBaseProps<\n 'root' |\n 'list' |\n 'listItem' |\n 'listItemLink' |\n 'separator'\n> {\n result?: TypedDocument;\n textField: string | string[];\n textFieldDelimiter?: string;\n linkField?: string | string[];\n linkFieldDelimiter?: string;\n separator?: string | React.ReactNode;\n template?: (text: string) => React.ReactNode;\n}\n\nexport function ResultBreadcrumbs(props: ResultBreadcrumbsProps) {\n const resultContext = useContext(ResultContext);\n const result = props.result || resultContext;\n if (!result) {\n logMissingResultError('ResultBreadcrumbs');\n return null;\n }\n\n const templateFn = props.template || ((text: string) => <span>{ text }</span>);\n const separator = props.separator || <span className=\"cludo-px-1\">/</span>;\n const textArray = useRef<(string|undefined)[]>([]);\n const linkArray = useRef<(string|undefined)[]>([]);\n\n const navCss = generateThemeCss('cludo-font-family-default cludo-font-size-sm cludo-mb-2 cludo-font-color-gray', props.disableTheme, props.className, props.classNames?.root);\n const listCss = generateThemeCss('cludo-list-style-none cludo-p-0 cludo-display-flex', props.disableTheme, props.classNames?.list);\n const listItemCss = generateThemeCss('', props.disableTheme, props.classNames?.listItem);\n const listItemLinkCss = generateThemeCss('cludo-font-color-gray', props.disableTheme, props.classNames?.listItemLink);\n const separatorCss = generateThemeCss('', props.disableTheme, props.classNames?.separator);\n\n /**\n * populateBreadcrumbArr function populates an array of breadcrumb data one of two ways:\n * - If array of fields entered through props, loop through array to get field values to add to our array\n * - If single field entered, get value from this field and attempt to split it by an optionally added delimiter before adding to our array\n */\n function populateBreadcrumbArr(field: string | string[], arr: React.MutableRefObject<(string|undefined)[]>, delim?: string) {\n arr.current = [];\n // If array of fields entered, loop through and add values to array\n if (Array.isArray(field)) {\n field.forEach(field => {\n const text = getFieldValue(result, field);\n arr.current.push(text ?? undefined);\n })\n // Otherwise get single field value as an array and split by delimiter if it exists\n } else {\n const text = getFieldValues(result, field);\n if (text && text[0]) {\n const textSubarr = (delim ? text[0].split(delim) : text);\n arr.current.push(...textSubarr);\n } else {\n arr.current.push(undefined);\n }\n }\n }\n\n useMemo(() => {\n populateBreadcrumbArr(props.textField, textArray, props.textFieldDelimiter);\n if (props.linkField) {\n populateBreadcrumbArr(props.linkField, linkArray, props.linkFieldDelimiter);\n }\n }, [result])\n\n return (\n textArray.current.length && !textArray.current.every(x => x === undefined) ?\n <nav className={navCss} aria-label=\"breadcrumb\" {...props.attributes?.root}>\n <ol className={listCss} {...props.attributes?.list}>\n { textArray.current.map((text, i) => {\n \n if (text !== undefined) {\n // If link array populated, wrap breadcrumbs with links\n if (linkArray.current[i] !== undefined) {\n return <React.Fragment key={i}>\n <li className={listItemCss} {...props.attributes?.listItem}>\n <a className={listItemLinkCss} {...props.attributes?.listItemLink} href={linkArray.current[i]}>\n { templateFn(text) }\n </a>\n </li>\n { i !== textArray.current.length - 1 ?\n <li className={separatorCss} aria-hidden=\"true\" {...props.attributes?.separator}>\n { separator }\n </li> : null\n }\n </React.Fragment>\n // Otherwise, render read-only breadcrumbs\n } else {\n return <React.Fragment key={i}>\n <li className={listItemCss} {...props.attributes?.listItem}>\n <>\n { templateFn(text) }\n </>\n </li>\n \n { i !== textArray.current.length - 1 ?\n <li className={separatorCss} aria-hidden=\"true\" {...props.attributes?.separator}>\n { separator }\n </li> : null\n }\n </React.Fragment>\n }\n } else {\n return null;\n }\n }) }\n </ol>\n </nav> : <></>\n )\n}","import React, { ReactNode, useEffect, useState } from \"react\";\nimport { ExternalCludoSearchOptions } from \"../../utils/models/instantiator-types\";\nimport { initCludo, initCludoWithPublicSettings } from \"../../utils/instantiator\";\nimport { CludoContext, EventControllerContext } from \"../../context\";\nimport { CludoSearchContext } from \"../../utils/cludo-search-context\";\nimport { CludoInstanceController } from \"../../utils/cludo-instance-controller\";\nimport { EventController } from \"../../utils/event-controller\";\nimport { CludoSearch } from \"../../types/core-script-types\";\nimport { ThemeProvider } from \"../../utils/theme-provider\";\nimport { PublicSettings } from \"@cludosearch/cludo-api-client/dist/interfaces/api/public-settings.interface\";\n\ninterface CludoWrapperProps {\n config: ExternalCludoSearchOptions,\n publicSettings?: PublicSettings,\n onInit?: (controller: CludoInstanceController) => void,\n children?: ReactNode\n}\n\n/** This component wraps React components with a Cludo Search Context, and should be used to wrap input elements and search containers */\nexport function CludoWrapper(props: CludoWrapperProps) {\n const [searchContext, setSearchContext] = useState({} as CludoSearchContext);\n const [eventContext, setEventContext] = useState({} as EventController);\n const [hasInitialized, setHasInitialized] = useState(false);\n\n // Once we get the instance controller, save the context to state so we can provide it \n useEffect(() => {\n if(props.publicSettings) {\n // if the publicSettings property is set, we can skip the initCludo call and just use the public settings\n // to create the search context via initCludoFromPublicSettings (which resolves synchronously)\n const controller = initCludoWithPublicSettings(props.config, props.publicSettings);\n\n if (props.onInit) {\n props.onInit(controller);\n }\n setSearchContext(controller.instance);\n setEventContext(controller.components.events);\n setHasInitialized(true);\n } else {\n // Set headless to true by default (overwritten by passed config)\n const config: ExternalCludoSearchOptions = {\n headless: true,\n ...props.config\n }\n\n // If the public settings are not provided, we need to use the config to create the search context\n // via initCludo (which resolves asynchronously via a Promise)\n initCludo(config).then( (controller: CludoInstanceController) => {\n if (props.onInit) {\n props.onInit(controller);\n }\n setSearchContext(controller.instance);\n setEventContext(controller.components.events);\n setHasInitialized(true);\n });\n }\n\n return () => {\n // Remove the instance from the global array of instances\n const windowObject = window as any;\n if (windowObject?.CludoSearchInstances?.length) {\n windowObject.CludoSearchInstances = windowObject.CludoSearchInstances.filter((instance: CludoSearch) => instance.engineId !== props.config.engineId);\n }\n }\n }, []);\n\n return(\n !hasInitialized ? null :\n <CludoContext.Provider value={searchContext}>\n <EventControllerContext.Provider value={eventContext}>\n <ThemeProvider theme={props.config.cssTheme}>\n {/* FUTURE -- consider deferred rendering of the children until the public settings have been retrieved */}\n { props.children }\n </ThemeProvider>\n </EventControllerContext.Provider>\n </CludoContext.Provider>\n )\n\n}","import React, { useContext } from \"react\";\nimport { CludoContext } from \"../../context\";\n\nexport function CludoAutocompleteContainer() {\n const context = useContext(CludoContext);\n const autocompleteHintText = context.translateProvider?.translate('template_autocomplete_hint');\n\n return (\n <>\n {/* Container */}\n <div className=\"search_autocomplete\" id=\"search_autocomplete\" tabIndex={0}></div>\n\n {/* Hint element */}\n <span id=\"autocomplete_hint\" aria-hidden=\"false\" aria-atomic=\"true\" role=\"status\" aria-live=\"polite\">\n { autocompleteHintText }\n </span>\n </>\n )\n}","import React from \"react\";\n\n/** We mount the Search Results Component here */\nexport function CludoResultsContainer(props: {id?: string}) {\n const resultsWrapperId = props.id ? props.id : \"cludo-search-results\";\n return (\n <div id={resultsWrapperId}></div>\n )\n}","import React, { useContext } from \"react\";\nimport { CludoContext } from \"../../context\";\n\nexport function CludoSearchInput() {\n const context = useContext(CludoContext);\n const placeholder = context.translateProvider?.translate('search_input_label');\n const ariaLabel = context.translateProvider?.translate('search_input_label');\n\n const autocompleteEnabled = context.isAutocompleteEnabled;\n\n if (autocompleteEnabled) {\n return (\n <input \n type=\"search\" \n className=\"cludo-search-input\" \n aria-label={ariaLabel} \n placeholder={placeholder}\n aria-describedby=\"autocomplete_hint\"\n aria-autocomplete=\"list\"\n aria-controls=\"search_autocomplete\"\n />\n );\n } else {\n return (\n <input \n type=\"search\" \n className=\"cludo-search-input\" \n aria-label={ariaLabel} \n placeholder={placeholder}\n />\n );\n }\n\n}","import React, { useContext } from \"react\";\nimport { CludoContext } from \"../../context\";\nimport { CludoSearchInput } from \"./cludo-search-input\";\nimport { CludoAutocompleteContainer } from \"./cludo-autocomplete-container\";\n\nexport function CludoSearchForm(props: {uniqueFormId?: string}) {\n const context = useContext(CludoContext);\n const ariaLabel = context.translateProvider?.translate('search_input_label');\n const autocompleteEnabled = context.isAutocompleteEnabled;\n \n const formId = props.uniqueFormId ? props.uniqueFormId : 'cludo-search-input';\n\n return(\n <form id={formId} role=\"search\">\n <CludoSearchInput />\n <button type=\"submit\" \n className=\"cludo-search-button\"\n aria-label={ariaLabel} />\n { autocompleteEnabled ? <CludoAutocompleteContainer /> : <></> }\n </form>\n )\n}","import { useEffect, useState } from \"react\";\nimport { useCludoContext } from \"./use-cludo-context\";\n\nexport interface SearchInputState {\n query: string;\n}\nexport interface SearchInputDispatchers {\n search: (updatedQuery: string) => void;\n setQuery: (updatedQuery: string) => void;\n}\n\n/** Expose state and dispatchers necessary to create a functional search input\n * @returns cludoState (current query) and cludoDispatchers (search event)\n */\nexport function useSearchInput(): [SearchInputState, SearchInputDispatchers] {\n const { context, eventController } = useCludoContext();\n\n const [searchInputState, setSearchInputState] = useState({\n query: context.query || ''\n });\n\n // Derive dispatchers from CludoSearchContext\n const searchInputDispatchers: SearchInputDispatchers = {\n search: (updatedQuery: string) => {\n eventController.search(updatedQuery);\n },\n setQuery: (updatedQuery: string) => {\n setSearchInputState({query: updatedQuery})\n }\n };\n\n // Update search input state whenever the context's query changes\n useEffect(() => {\n setSearchInputState({query: context.query || ''})\n }, [context.query]);\n\n return [searchInputState, searchInputDispatchers];\n}","import React from \"react\";\nimport { BaseIcon, IconProps } from \"./base-icon\";\n\nexport function SearchIcon(props: IconProps) {\n return (\n <BaseIcon {...props} >\n <path \n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M112.092 140.376C101.162 146.595 88.5179 150.147 75.0446 150.147C33.5986 150.147 0 116.535 0 75.0733C0 33.6115 33.5986 0 75.0446 0C116.491 0 150.089 33.6115 150.089 75.0733C150.089 88.5145 146.558 101.131 140.374 112.044L186.485 158.173C191.17 162.86 191.17 170.46 186.485 175.147L175.151 186.485C170.466 191.172 162.869 191.172 158.184 186.485L112.092 140.376ZM120.071 75.0733C120.071 99.9504 99.9122 120.117 75.0446 120.117C50.177 120.117 30.0179 99.9504 30.0179 75.0733C30.0179 50.1962 50.177 30.0293 75.0446 30.0293C99.9122 30.0293 120.071 50.1962 120.071 75.0733Z\"\n fill={props.color}/>\n </BaseIcon>\n )\n}","import React, { useContext } from \"react\";\nimport { useSearchInput } from \"../../hooks/use-search-input\";\nimport { generateThemeCss } from \"../../utils/theme-provider\";\nimport { ThemeBaseProps } from \"../types/types\";\nimport { SearchIcon } from \"../icons/search-icon\";\nimport { CludoContext } from \"../../context\";\n\nexport interface SearchInputProps extends ThemeBaseProps<\n 'root' |\n 'input' |\n 'submitButton'\n> {\n placeholder?: string;\n className?: string;\n formId?: string;\n submitIcon?: React.ReactNode;\n onChange?: (event: React.ChangeEvent<HTMLInputElement>) => void;\n onSubmit?: (event: React.FormEvent<HTMLFormElement>) => void;\n onFocus?: (event: React.FocusEvent<HTMLInputElement>) => void;\n onBlur?: (event: React.FocusEvent<HTMLInputElement>) => void;\n onKeyDown?: (event: React.KeyboardEvent<HTMLInputElement>) => void;\n}\n\n/** Search input component that can perform search requests */\nexport function SearchInput(props: SearchInputProps) {\n const [ cludoState, cludoDispatchers ] = useSearchInput(); \n const context = useContext(CludoContext);\n const placeholder = props.placeholder || 'Enter a search term';\n const buttonAriaLabel = context.translateProvider?.translate('search_button_text');\n const inputAriaLabel = context.translateProvider?.translate('search_input_label');\n\n const handleSubmit = (event: React.FormEvent<HTMLFormElement>) => {\n event.preventDefault();\n cludoDispatchers.search(cludoState.query);\n if (props.onSubmit) {\n props.onSubmit(event);\n }\n }\n\n const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {\n cludoDispatchers.setQuery(event.target.value);\n if (props.onChange) {\n props.onChange(event);\n }\n }\n \n // Set theme css\n const formCss = generateThemeCss('cludo-display-flex cludo-box-shadow-card cludo-border-radius-card cludo-p-4 cludo-mb-3 cludo-align-items-center cludo-bg-color-white', props.disableTheme, props.className, props.classNames?.root);\n const inputCss = generateThemeCss('cludo-font-size-md cludo-py-1 cludo-px-2 cludo-font-family-default cludo-border-radius-button cludo-border-1-neutral cludo-height-sm cludo-flex-grow-1 cludo-bg-color-gray-light', props.disableTheme, props.classNames?.input);\n const buttonCss = generateThemeCss('cludo-theme-icon-btn-secondary cludo-ml-1', props.disableTheme, props.classNames?.submitButton);\n\n const submitButtonContent: React.ReactNode = props.submitIcon ? props.submitIcon : <SearchIcon width=\"100%\" height=\"100%\" color=\"#fff\" />; \n\n return (\n <form id={props.formId} onSubmit={handleSubmit} className={formCss} {...props.attributes?.root}>\n <input \n type=\"search\" \n aria-label={inputAriaLabel}\n className={inputCss}\n placeholder={placeholder}\n onChange={handleChange}\n onBlur={props.onBlur}\n onFocus={props.onFocus}\n onKeyDown={props.onKeyDown}\n value={cludoState.query}\n {...props.attributes?.input}\n />\n <button\n aria-label={buttonAriaLabel}\n className={buttonCss}\n type=\"submit\"\n {...props.attributes?.submitButton}\n >\n {submitButtonContent}\n </button>\n </form>\n );\n}","import { useState, useEffect } from \"react\";\nimport { SearchResultsState, useSearchResults } from \"./use-search-results\";\nimport { EndlessScrollOptions } from \"../utils/models/instantiator-types\";\nimport { useCludoContext } from \"./use-cludo-context\";\nimport { isOnClient } from \"../utils/render-utils\";\n\nexport interface EndlessScrollState {\n showLoadMore: boolean;\n isLoading: boolean;\n};\n\nexport function useEndlessScroll(options: EndlessScrollOptions): EndlessScrollState {\n const { context } = useCludoContext();\n const [searchResultsState, searchResultsDispatchers] = useSearchResults();\n\n // Needed so that the results add to themselves, instead of replacing them\n context.endlessScroll = options;\n\n // This use effect handles the endless scroll\n useEffect(() => {\n if (!isOnClient()) return;\n\n const handleScroll = () => {\n if (searchResultsState.isLoading) { return; }\n if (scrolledElement instanceof Element) {\n handleElementScroll(scrolledElement);\n } else {\n handleWindowScroll();\n }\n }\n \n const handleElementScroll = (element: Element) => {\n if (element.scrollTop + element.clientHeight >= element.scrollHeight - options.bottomOffset) {\n if (\n (searchResultsState.currentPage < options.stopAfterPage) &&\n (searchResultsState.resultCount > options.resultsPerPage) &&\n (searchResultsState.currentPage < Math.ceil(searchResultsState.resultCount / options.resultsPerPage))\n ){\n // Load more results\n searchResultsDispatchers.loadMore();\n }\n }\n }\n \n const handleWindowScroll = () => {\n if (!isOnClient()) return;\n if (window.scrollY + window.innerHeight >= document.body.scrollHeight - options.bottomOffset) {\n if (\n (searchResultsState.currentPage < options.stopAfterPage) &&\n (searchResultsState.resultCount > options.resultsPerPage) &&\n (searchResultsState.currentPage < Math.ceil(searchResultsState.resultCount / options.resultsPerPage))\n ){\n // Load more results\n searchResultsDispatchers.loadMore();\n }\n }\n }\n\n const scrolledElement = (options.scrolledElementSelector ? document.querySelector(options.scrolledElementSelector) : window) || window;\n scrolledElement.addEventListener('scroll', handleScroll);\n return () => {\n scrolledElement.removeEventListener('scroll', handleScroll);\n }\n }, [options]);\n\n\n // Derive state when search results change\n const deriveState = (state: SearchResultsState) => {\n return {\n showLoadMore: (state.currentPage >= options.stopAfterPage) && (state.resultCount > options.resultsPerPage) && (state.currentPage < Math.ceil(state.resultCount / options.resultsPerPage)),\n isLoading: state.isLoading\n }\n }\n\n // Update state based on search results\n useEffect(() => {\n setEndlessScrollState(deriveState(searchResultsState));\n }, [searchResultsState]);\n\n // State\n const [endlessScrollState, setEndlessScrollState] = useState({showLoadMore: false, isLoading: false});\n\n return endlessScrollState;\n}"],"names":["root","factory","exports","module","define","amd","this","CludoFeature","__webpack_module_cache__","__webpack_require__","moduleId","cachedModule","undefined","__webpack_modules__","n","getter","__esModule","d","a","definition","key","o","Object","defineProperty","enumerable","get","obj","prop","prototype","hasOwnProperty","call","r","Symbol","toStringTag","value","require","CludoContext","EventControllerContext","getUrl","result","Fields","Value","hasField","fieldName","FieldNames","indexOf","getFieldValue","maxWords","wordDelim","splitDelim","joinDelim","words","split","length","slice","join","getFieldValues","Values","getHighlightsOrValues","delim","getHighlightsOrValuesArray","Highlights","values","returnValues","wordCount","i","stringArray","trim","splice","push","trimArrayToMaxWords","getFormattedHTML","val","__html","logMissingResultError","component","console","error","isAutocompleteItem","element","hasAttribute","getTopHitTotalCount","hit","facets","Field","map","hitValue","facetMatch","facetValueMatch","Items","find","Key","count","Count","AllCount","getLinkFragmentUrlPart","fragment","context","isFeatureEnabled","WebContentHighlighter","innerText","replace","encodeURIComponent","LinkContext","ResultLink","props","useContext","eventController","resultContext","ResultContext","initalFragment","highlightQueryOnClickedPage","query","useState","fragmentUrlPart","setFragmentUrlPart","model","eleClass","className","titleField","url","linkField","urlWithFragments","anchorElem","useRef","LinkContextInstance","onFragmentHover","urlFragmentPart","onFragmentSelect","current","click","useEffect","shouldBeFocused","focus","ref","href","ResultIndex","currentPage","target","openNewTab","attributes","onKeyUp","e","searchResultKeyUpEvent","nativeEvent","onKeyUpHandler","onClick","searchResultTrackClickEventHandler","onClickHandler","Provider","children","ThemeContext","ThemeProvider","theme","generateThemeCss","themeCss","disableTheme","classNameProps","filter","Boolean","CustomResult","focusOnResultsAfterSearch","wrapWithLink","HighlightedText","chunkedText","input","hightlightTag","match","regex","lastIndex","exec","index","displayType","text","splitByHighlightTags","splitByTag","HighlightTag","role","wrapDefaultText","ResultTitle","showRawText","Heading","headingElement","fileType","title","FragmentHighlight","linkContext","classStr","tabIndex","onKeyDown","code","onFocus","onMouseEnter","onMouseLeave","FragmentHighlightGroup","field","fragments","descriptionPart","maxFragments","ResultDescription","descriptionField","makeHighlightsClickable","maxWordCount","description","highlightDelimiter","ResultUrl","showRelativeUrl","urlObj","URL","toString","substring","origin","DEFAULT_BADGE_FIELD","ResultBadge","displayText","defaultOrder","StandardResult","propOrder","renderOrder","order","concat","el","hideTitle","hideDescription","hideUrl","hideBadge","widgetMap","Map","classNames","descriptionMaxWordCount","badge","badgeField","useCludoContext","useEventSubscriptions","callback","events","subscriptions","keys","forEach","eventType","subscribe","subscribeToAllEvents","unsubscribe","subscriptionId","usePagination","searchResponse","storedSearchResponseData","cludoSearchResponse","deriveState","resultsPerPage","itemsPerPage","maxPages","Math","ceil","ResultCount","nextPageLabel","translateProvider","translate","prevPageLabel","showPagination","isEndlessScrollEnabled","showResultsPerPage","deriveDispatchers","goToPage","bind","setPerPage","setCludoState","setCludoDispatchers","cludoState","cludoDispatchers","useSearchResults","resultsSummary","resultCount","resultCountMessage","ResultCountMessage","fixedQuery","FixedQuery","Facets","didYouMean","Suggestions","suggestions","results","TypedDocuments","categorizedResults","TopHits","paginationOptions","endlessScrollOptions","isEnabled","endlessScroll","banners","Banners","relatedSearches","RelatedSearchDocuments","isLoading","isLoadingResults","loadMore","endlessScrollLoadMore","searchResultKeyUp","linkToSearchClickEvent","handleDidYouMeanSelect","Pagination","paginationState","paginationDispatchers","resultsState","localPaginationState","setLocalPaginationState","previousButtonIcon","nextButtonIcon","firstButtonIcon","lastButtonIcon","startPage","prevPageTranslation","nextPageTranslation","activeBtnCss","inactiveBtnCss","loadingCss","list","hideFirst","listItem","firstButton","hidePrevious","previousButton","currentPageNum","pageNumberButtons","pageTranslation","pageNumberButton","currentPageButton","renderPageNumberButtons","hideNext","nextButton","hideLast","lastButton","Banner","bannerRef","banner","bannerLinks","querySelectorAll","paramsPrefix","link","anchor","bannerId","String","Id","bannerTitle","Name","setAttribute","addBannerAttributesToAnchor","decodeURIComponent","addEventListener","preventDefault","onBannerLoad","bannerCss","dangerouslySetInnerHTML","useBanners","BannerGroup","bannersState","bannerComponents","DidYouMean","suggestionFromContext","suggestedQuery","didYouMeanInnerHTML","event","suggestion","HTMLElement","closest","onDidYouMeanClick","resultTextState","setResultTextState","Query","yourSearchMsg","totalMsg","resultMsg","ResultsSummary","CludoLoader","loadingAltText","src","alt","StandardLoader","ResultsList","templateFn","template","columns","loader","customLoader","resultSpacing","cssUnit","focusIndex","resultsToRender","setResultsToRender","bannersToRender","setBannersToRender","cssString","containerCss","listCss","resultsListContainer","listItemCss","resultsListItem","loaderCss","loaderContainer","hideBanners","columnsBreakpoint","LoadMore","loadMoreStr","label","id","loadMoreButton","type","wasKeyboardClick","detail","LoadMoreResults","searchResultsState","searchResultsDispatchers","showLoadMore","stopAfterPage","classNamesObj","attrsObj","disableKeyboardFocusHandling","onLoadMore","AutocompleteItemType","CludoSearchResults","composeResults","options","ResultComponent","ListComponent","LoaderComponent","PaginationComponent","pagination","SaytResult","resultIndex","suggestionCSS","isSelected","resultChildren","chunkedTitle","itemType","resultType","Result","setActiveDescendantToSuggestions","selectResult","document","SaytSuggestion","suggestionIndex","Suggestion","selectSuggestion","SaytRecentSearch","recentSearchIndex","RecentSearch","recentSearch","isOnClient","window","useAutocomplete","selectedIndex","keydownListener","tempSelectedSuggestion","tempSelectedResult","tempSelectedRecentSearch","storedAutocompleteResponse","data","instantSuggestions","recentSearches","categorizedResultGroups","resultGroup","resultValue","Hits","getAutocompleteResultsFromTopHits","listItems","tempIndex","numSuggestions","search","getAttribute","parseInt","categorizedResult","selectRecentSearch","newState","deriveAutocompleteState","selectedSuggestion","selectedResult","selectedRecentSearch","setAutocompleteState","eventControllerIsDefined","keyboardNextSubscription","keyboardPrevSubscription","keyboardEnterSubscription","autocompleteCompleteSubscription","clearSelectedIndices","suggestionsTitle","resultsTitle","recentSearchesTitle","autocompleteState","autocompleteDispatchers","initiateAutocompleteRequest","autocompleteSelectionNext","emitEvent","autocompleteSelectionPrev","autocompleteSelect","clear","clearAutocomplete","autocompleteHandleInputKeyDown","autocompleteHandleInputBlur","relatedTarget","autocompleteHandleInputChange","CludoSearchAutocomplete","cludoSearch","_cludoSearch","_templateState","params","customerId","engineId","page","perPage","sort","clientTemplateSortOptions","websiteSettings","configurations","isFacetSelected","isFilterSelected","filters","getSelectedMapItem","arrayToCheck","selected","item","facetsInResponse","facetsToRender","entries","includes","facetMapItem","facetKey","facetObj","facet","hasSelection","facetValue","facetName","selectedValues","allCount","missingCount","MissingCount","facetValues","Set","str","has","newValue","enabledFeatures","featureKey","richAutocomplete","fragmentText","linkFragment","customEngineSettings","JSON","parse","featureConfigKey","instantSuggestionsConfiguration","storedError","chunkString","needle","needleIndex","toLowerCase","mapTypedDocumentToResult","mapTypedDocumentToSuggestion","mapStringToSuggestion","mapTopHitsToCategorizedResults","mapHitValuesToResults","coreAutocompleteData","cludoAutocompleteResponse","totalResults","totalSuggestions","totalRecentSearches","topHits","isTrackedSession","canUserBeTracked","queryId","getSessionId","querySessionId","deviceType","getTraitsFromStorage","TemplateType","searchContext","keyedSubscriptions","_curSubscriptionIndex","setDateRangeFacet","from","to","shouldSearch","setNumberRangeFacet","clearDateRangeFacet","clearFacetByName","clearNumberRangeFacet","_searchContext","fnc","sub","executeCallbacksForType","payload","subscribersForType","_handleQuickLinks","clearResults","clearStoredSearchResponseData","selectFacet","multi","deselectFacet","clearFacet","clearAllFacets","clearAllFacetsAndSearch","softClearAllFacets","setFilter","setFilters","clearAllFilters","toggleFacetValue","facetField","didYouMeanText","setDidYouMean","pageNumber","clearSortOrder","clearSortParams","addToSortOrder","dir","setSortOrder","autocompleteByQuery","autocompleteSetSelectedSuggestion","autocompleteSetSelectedResult","autocompleteSetSelectedRecentSearch","clearRecentSearches","autocompleteRestoreClient","endlessScrollLoadMoreClickEvent","trackQuery","queryLog","trackClick","clickLog","trackChatClick","getConversations","conversationService","getConversationsFromStorage","storeConversations","conversations","sendQuestion","requestBody","controller","sendChatFeedbackData","feedbackData","sendFeedbackData","feedbackService","sendFeedback","getTrendingPages","daysBack","limit","timezone","getPopularPages","getRelatedPages","overrideParams","cssTheme","managedComponents","EventController","_cssTheme","registerSearchResultsComponent","addManagedComponent","registerControlsComponent","registerAutocompleteComponent","registerComponent","observedEventTypes","renderImmediately","managedComponent","elem","querySelector","elemSelector","hasRendered","renderComponent","processEvent","callbackFnc","RenderedComponent","instance","CludoSearchContext","components","ComponentsController","addWidget","widgetType","widgetComponent","Results","Controls","Autocomplete","setOverrideString","language","languageSpecificTranslationSet","translations","setOverrideStrings","overrides","setLanguage","useSortBy","sortOrder","sortItems","CludoSortPicker","sortByState","sortByDispatchers","relTranslation","relevanceLabel","sortObject","sortActive","relActive","sortItem","isActive","direction","PseudoLink","useFacet","StandardFacetItem","facetItem","facetDispatchers","optionThemeCss","activeThemeCss","countThemeCss","valueClass","overrideOnChange","onChange","hideCount","setOrderBasedOnReference","unordered","reference","unorderedArr","referenceArr","x","Error","wildcardIndex","FacetHeader","rootCss","headerThemeCss","header","clearThemeCss","clearButton","hideClear","onClear","clearLabel","FacetSearch","unfilteredList","facetItems","placeholderOption","placeholder","hideSelectedOption","hideSelected","currentTarget","filteredList","FacetItemsList","facetLimitOption","Infinity","facetHideShowMoreOption","hideShowMore","facetHideCountOption","visibleFacets","setVisibleFacets","allResultsOption","allResultsOptionLabel","some","loadMoreThemeCss","shouldBeHidden","includeAllResultsOption","allResultsListItem","itemComponent","style","display","showMoreLabel","BaseFacet","facetState","facetSortByOption","sortBy","facetOrderOption","facetExcludeOption","exclude","containerThemeCss","localFacetState","setLocalFacetState","facetItemsSavedCopy","setFacetItemsSavedCopy","facetItemsToRender","setFacetItemsToRender","facetItemValues","b","localeCompare","option","mappedItem","hideSearchBar","searchPlaceholder","facetListContainer","facetListItem","facetAllResultsListItem","StandardFacet","useFacetGroup","selectedFacets","CludoSearchControls","composeControls","SortPickerComponent","sortPicker","FacetComponent","facetsState","shouldShowSortPicker","defaultLanguage","coreScriptUrl","getPublicSettings","publicSettingsDataStr","Cludo","getPublicSettingsByOptions","experienceId","apiUrl","authKey","searchSiteKey","isIntranet","publicSettings","injectCoreScript","overrideCoreScriptUrl","Promise","resolve","reject","scriptUrl","script","createElement","onload","onerror","body","appendChild","initCludo","publicSettingsOptions","secureSearch","enable","headless","use","initCludoWithPublicSettings","cludoSettings","searchUrl","instanceId","clientTemplates","searchInputs","searchInputSelectors","headlessSearch","searchResultsWrapper","searchResultsWrapperSelector","intranetSearch","searchApiUrl","proxyApiUrl","customHttpHeaders","disableAutocomplete","autocomplete","disable","initFacets","defaultValues","hideResultsCount","hideSearchFilters","hideSearchDidYouMean","sortOptions","logPageVisits","tracking","skipLoggingPageVisits","useSearchAsYouType","autocompleteForceUseTemplate","renderTemplateWhenNoResults","autocompleteMinimumQueryLength","minimumQueryLength","applyMultiLevelFacets","applyMultiLevel","rangeFacets","rangeValues","pierceShadowDom","behavior","enableRelatedSearches","customNoResultsMessage","overrideStrings","noResultsMessage","enableVoiceSearch","voiceSearch","disableVoiceSearchActiveAnimation","disableActiveAnimation","useFixedQueryInResultsCount","showFixedQueryInResultsCount","allowSearchWithoutSearchword","jumpToTopOnFacetClick","enableExtendedTracking","disableExtendedTracking","customCallbackAfterSearch","callbacks","afterSearch","customCallbackBeforeSearch","beforeSearch","customCallbackBeforeRedirect","beforeRedirect","customCallbackAfterAutocomplete","afterAutocomplete","customCallbackBeforeQuicklink","beforeQuicklink","ovarlayResultsWrapperOpenClass","overlayResultsWrapperOpenClass","searchBoxPosition","themeColor","elementFocusColor","themeBannerColor","textColor","borderRadius","borderRadiusInput","showInstantSuggestions","suggestedSearchesHeader","recentSearchesHeader","googleAnalyticsTrackingId","googleAnalyticsId","translateSearchTemplates","changeWindowLocation","updateUrlOnSearch","urlListDelimiter","cludoInstance","translationRef","Language","assign","warn","categorizeResultsByField","topHitsFields","maxResultsPerCategory","size","maxCategories","MaxFieldValues","CludoInstanceController","setClientTemplateComponentsController","configureFeaturesFromPublicSettings","init","controls","isComponentConfigObject","containerSelector","renderEvents","controlsWrapperSelector","selector","custom","config","overrideSelector","Array","isArray","DropdownInput","labelThemeCss","selectThemeCss","dropdown","htmlFor","currentValue","defaultValue","default","dropdownOption","ResultsPerPage","optionsMap","currentPerPage","SelectorComponent","selectorOption","Number","SaytCategorizedResult","CategorizedResult","FacetGroup","facetOrder","facetExclude","facetOverrides","Fragment","facetFields","facetFieldsRef","facetMap","useMemo","DefaultComponent","override","set","fallback","populateFacetGroupMap","CheckboxFacetItem","inputThemeCss","name","checked","handleFacetChange","CheckboxFacet","RadioFacetItem","RadioFacet","BaseIcon","width","height","viewbox","color","focusable","viewBox","fill","xmlns","CloseIcon","ICON_DIMENSION","ICON_FILL_COLOR","CurrentFacets","facetGroupState","facetGroupDispatchers","rootThemeCss","facetContainer","facetLabel","valueThemeCss","buttonThemeCss","facetRemoveButton","labelsMap","ClearAllFacets","ResultImage","imageSrc","imageField","imageAltText","altText","ResultBreadcrumbs","separator","textArray","linkArray","navCss","listItemLinkCss","listItemLink","separatorCss","populateBreadcrumbArr","arr","textSubarr","textField","textFieldDelimiter","linkFieldDelimiter","every","CludoWrapper","setSearchContext","eventContext","setEventContext","hasInitialized","setHasInitialized","onInit","then","windowObject","CludoSearchInstances","CludoAutocompleteContainer","autocompleteHintText","CludoResultsContainer","resultsWrapperId","CludoSearchInput","ariaLabel","isAutocompleteEnabled","CludoSearchForm","autocompleteEnabled","formId","uniqueFormId","useSearchInput","searchInputState","setSearchInputState","searchInputDispatchers","updatedQuery","setQuery","SearchIcon","fillRule","clipRule","SearchInput","buttonAriaLabel","inputAriaLabel","formCss","inputCss","buttonCss","submitButton","submitButtonContent","submitIcon","onSubmit","onBlur","useEndlessScroll","handleScroll","scrolledElement","Element","handleElementScroll","handleWindowScroll","scrollTop","clientHeight","scrollHeight","bottomOffset","scrollY","innerHeight","scrolledElementSelector","removeEventListener","state","setEndlessScrollState","endlessScrollState"],"sourceRoot":""}
|
|
1
|
+
{"version":3,"file":"main.ssr.js","mappings":"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","sources":["webpack://cludo-ssr/webpack/universalModuleDefinition","webpack://cludo-ssr/./node_modules/@cludosearch/cludo-api-client/dist/interfaces/api/public-settings.interface.js","webpack://cludo-ssr/webpack/bootstrap","webpack://cludo-ssr/webpack/runtime/compat get default export","webpack://cludo-ssr/webpack/runtime/define property getters","webpack://cludo-ssr/webpack/runtime/hasOwnProperty shorthand","webpack://cludo-ssr/webpack/runtime/make namespace object","webpack://cludo-ssr/external commonjs \"react\"","webpack://cludo-ssr/./src/context.tsx","webpack://cludo-ssr/./src/utils/result-utils.ts","webpack://cludo-ssr/./src/utils/context-utils.ts","webpack://cludo-ssr/./src/components/elements/result-link.tsx","webpack://cludo-ssr/./src/utils/theme-provider.tsx","webpack://cludo-ssr/./src/components/results/items/custom-result.tsx","webpack://cludo-ssr/./src/components/elements/cludo-highlighted-text.tsx","webpack://cludo-ssr/./src/components/elements/result-title.tsx","webpack://cludo-ssr/./src/components/elements/fragment-highlight/fragment-highlight.tsx","webpack://cludo-ssr/./src/components/elements/fragment-highlight-group/fragment-highlight-group.tsx","webpack://cludo-ssr/./src/components/elements/result-description.tsx","webpack://cludo-ssr/./src/components/elements/result-url.tsx","webpack://cludo-ssr/./src/components/elements/result-badge.tsx","webpack://cludo-ssr/./src/components/results/items/standard-result.tsx","webpack://cludo-ssr/./src/hooks/use-cludo-context.ts","webpack://cludo-ssr/./src/hooks/use-event-subscription.ts","webpack://cludo-ssr/./src/hooks/use-pagination.ts","webpack://cludo-ssr/./src/hooks/use-search-results.ts","webpack://cludo-ssr/./src/components/results/pagination/pagination.tsx","webpack://cludo-ssr/./src/components/elements/banner.tsx","webpack://cludo-ssr/./src/hooks/use-banners.ts","webpack://cludo-ssr/./src/components/elements/banner-group/banner-group.tsx","webpack://cludo-ssr/./src/components/results/header/did-you-mean.tsx","webpack://cludo-ssr/./src/hooks/use-facet-group.ts","webpack://cludo-ssr/./src/components/results/header/result-count.tsx","webpack://cludo-ssr/./src/components/results/header/results-summary.tsx","webpack://cludo-ssr/./src/components/results/cludo-loader.tsx","webpack://cludo-ssr/./src/components/elements/loader/standard-loader.tsx","webpack://cludo-ssr/./src/components/results/list/results-list.tsx","webpack://cludo-ssr/./src/components/results/cludo-load-more.tsx","webpack://cludo-ssr/./src/components/results/load-more-results.tsx","webpack://cludo-ssr/./src/components/types/types.ts","webpack://cludo-ssr/./src/components/results/cludo-search-results.tsx","webpack://cludo-ssr/./src/components/sayt/items/sayt-result.tsx","webpack://cludo-ssr/./src/components/sayt/items/sayt-suggestion.tsx","webpack://cludo-ssr/./src/components/sayt/items/sayt-recent-search.tsx","webpack://cludo-ssr/./src/utils/render-utils.ts","webpack://cludo-ssr/./src/hooks/use-autocomplete.ts","webpack://cludo-ssr/./src/components/sayt/cludo-search-autocomplete.tsx","webpack://cludo-ssr/./src/utils/cludo-search-context.ts","webpack://cludo-ssr/external commonjs \"react-dom\"","webpack://cludo-ssr/./src/utils/components-controller.tsx","webpack://cludo-ssr/./src/utils/event-controller.ts","webpack://cludo-ssr/./src/utils/cludo-instance-controller.ts","webpack://cludo-ssr/./src/hooks/use-sort-by.ts","webpack://cludo-ssr/./src/components/controls/sort-picker/cludo-sort-picker.tsx","webpack://cludo-ssr/./src/components/utility/pseudo-link.tsx","webpack://cludo-ssr/./src/hooks/use-facet.ts","webpack://cludo-ssr/./src/components/controls/facets/items/standard-facet-item.tsx","webpack://cludo-ssr/./src/utils/facet-utils.ts","webpack://cludo-ssr/./src/components/controls/facets/elements/facet-header.tsx","webpack://cludo-ssr/./src/components/controls/facets/elements/facet-search.tsx","webpack://cludo-ssr/./src/components/controls/facets/elements/facet-items-list.tsx","webpack://cludo-ssr/./src/components/controls/facets/base-facet.tsx","webpack://cludo-ssr/./src/components/controls/facets/standard-facet.tsx","webpack://cludo-ssr/./src/components/controls/cludo-search-controls.tsx","webpack://cludo-ssr/./src/utils/instantiator.ts","webpack://cludo-ssr/./src/components/controls/inputs/dropdown-input.tsx","webpack://cludo-ssr/./src/components/results/pagination/results-per-page.tsx","webpack://cludo-ssr/./src/components/sayt/items/sayt-categorized-result.tsx","webpack://cludo-ssr/./src/components/controls/facets/facet-group/facet-group.tsx","webpack://cludo-ssr/./src/components/controls/facets/items/checkbox-facet-item.tsx","webpack://cludo-ssr/./src/components/controls/facets/checkbox-facet.tsx","webpack://cludo-ssr/./src/components/controls/facets/items/radio-facet-item.tsx","webpack://cludo-ssr/./src/components/controls/facets/radio-facet.tsx","webpack://cludo-ssr/./src/components/icons/base-icon.tsx","webpack://cludo-ssr/./src/components/icons/close-icon.tsx","webpack://cludo-ssr/./src/components/controls/facets/elements/current-facets.tsx","webpack://cludo-ssr/./src/components/controls/facets/elements/clear-all-facets.tsx","webpack://cludo-ssr/./src/components/elements/result-image.tsx","webpack://cludo-ssr/./src/components/elements/result-breadcrumbs.tsx","webpack://cludo-ssr/./src/components/wrapper/cludo-wrapper.tsx","webpack://cludo-ssr/./src/components/forms/cludo-autocomplete-container.tsx","webpack://cludo-ssr/./src/components/forms/cludo-results-container.tsx","webpack://cludo-ssr/./src/components/forms/cludo-search-input.tsx","webpack://cludo-ssr/./src/components/forms/cludo-search-form.tsx","webpack://cludo-ssr/./src/hooks/use-search-input.ts","webpack://cludo-ssr/./src/components/icons/search-icon.tsx","webpack://cludo-ssr/./src/components/forms/search-input.tsx","webpack://cludo-ssr/./src/hooks/use-endless-scroll.ts"],"sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"CludoSearchComponents\"] = factory();\n\telse\n\t\troot[\"CludoSearchComponents\"] = factory();\n})(this, () => {\nreturn ","\"use strict\";\r\nObject.defineProperty(exports, \"__esModule\", { value: true });\r\nexports.CludoFeature = void 0;\r\n/** Feature values associated with subscription digest */\r\nvar CludoFeature;\r\n(function (CludoFeature) {\r\n CludoFeature[\"AdvancedIntents\"] = \"advanced insights\";\r\n CludoFeature[\"Intents\"] = \"basic insights\";\r\n CludoFeature[\"Sayt\"] = \"sayt\";\r\n CludoFeature[\"AnalyticsFilters\"] = \"analytics filters\";\r\n CludoFeature[\"VoiceSearches\"] = \"voice search\";\r\n CludoFeature[\"InstantSuggestions\"] = \"instant suggestions\";\r\n CludoFeature[\"Advanced404Analytics\"] = \"advanced 404 analytics\";\r\n CludoFeature[\"BannerStatistics\"] = \"banner statistics\";\r\n CludoFeature[\"RelatedSearches\"] = \"related searches\";\r\n CludoFeature[\"Basic404\"] = \"basic 404\";\r\n CludoFeature[\"IntelligentRanking\"] = \"intelligent rankings (ml)\";\r\n CludoFeature[\"GranularPermissions\"] = \"granular permissions\";\r\n CludoFeature[\"TimeScheduledBanner\"] = \"time-scheduled banners\";\r\n CludoFeature[\"GeoData\"] = \"geo analytics\";\r\n CludoFeature[\"DeviceData\"] = \"device analytics\";\r\n CludoFeature[\"AsyncCrawlingOneThousandPagesCrawledEveryDays\"] = \"async crawling 1000 pages crawled every day\";\r\n CludoFeature[\"AsyncCrawlingTwoThousandPagesCrawledEveryTwoDays\"] = \"async crawling 2000 pages crawled every 2 days\";\r\n CludoFeature[\"AsyncCrawlingThreeThousandPagesCrawledEveryThreeDays\"] = \"async crawling 3000 pages crawled every 3 days\";\r\n CludoFeature[\"AsyncCrawlingFourThousandPagesCrawledEveryFourDays\"] = \"async crawling 4000 pages crawled every 4 days\";\r\n CludoFeature[\"AsyncCrawlingFiveThousandPagesCrawledEveryFiveDays\"] = \"async crawling 5000 pages crawled every 5 days\";\r\n CludoFeature[\"AsyncCrawlingSixThousandPagesCrawledEverySixDays\"] = \"async crawling 6000 pages crawled every 6 days\";\r\n CludoFeature[\"AsyncCrawlingSevenThousandPagesCrawledEverySevenDays\"] = \"async crawling 7000 pages crawled every 7 days\";\r\n CludoFeature[\"WebContentHighlighter\"] = \"web content highlighter\";\r\n CludoFeature[\"Audiences\"] = \"audiences\";\r\n})(CludoFeature = exports.CludoFeature || (exports.CludoFeature = {}));\r\n//# sourceMappingURL=public-settings.interface.js.map","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId](module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n","// getDefaultExport function for compatibility with non-harmony modules\n__webpack_require__.n = (module) => {\n\tvar getter = module && module.__esModule ?\n\t\t() => (module['default']) :\n\t\t() => (module);\n\t__webpack_require__.d(getter, { a: getter });\n\treturn getter;\n};","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","const __WEBPACK_NAMESPACE_OBJECT__ = require(\"react\");","import React from \"react\";\n\nimport { EventController } from './utils/event-controller';\nimport { CludoSearchContext } from \"./utils/cludo-search-context\";\n\n// Provider and Consumer are connected through their \"parent\" context\nexport const CludoContext = React.createContext<CludoSearchContext>({} as any);\nexport const EventControllerContext = React.createContext<EventController>({} as any);\n","import { TypedDocument } from \"@cludosearch/cludo-api-client/dist/interfaces/api/search.interface\";\nimport { AutocompleteResult, AutocompleteTopHit } from \"../components/types/types\";\nimport { FacetMap, TopHit } from \"../types/core-script-types\";\n\nexport function getUrl(result: TypedDocument): string {\n return result.Fields['Url'].Value;\n}\n\nexport function hasField(result: TypedDocument, fieldName: string): boolean {\n return (result.FieldNames.indexOf(fieldName) !== -1);\n}\n\nexport function getFieldValue(result: TypedDocument, fieldName: string, maxWords?: number, wordDelim?: string): string | undefined {\n if (!hasField(result, fieldName)) {\n return undefined;\n }\n \n let splitDelim = wordDelim ?? /\\s+/;\n let joinDelim = wordDelim ?? ' ';\n let value = result.Fields[fieldName].Value;\n if (maxWords && maxWords > 0) {\n let words = value.split(splitDelim);\n if (words.length > maxWords) {\n value = words.slice(0, maxWords).join(joinDelim);\n }\n }\n\n return value;\n}\n\nexport function getFieldValues(result: TypedDocument, fieldName: string): string[] | undefined {\n if (!hasField(result, fieldName)) {\n return undefined;\n }\n return result.Fields[fieldName].Values;\n}\n\n/** Helper function similar to what is used in Razor templates */\nexport function getHighlightsOrValues(result: TypedDocument, fieldName: string, maxWords?: number, wordDelim = ' ', delim: string = '...'): string | undefined {\n if (!hasField(result, fieldName)) {\n return undefined;\n }\n return getHighlightsOrValuesArray(result, fieldName, maxWords, wordDelim).join(delim);\n}\n\n/** Helper function to get an array of description fragments for a result */\nexport function getHighlightsOrValuesArray(result: TypedDocument, fieldName: string, maxWords?: number, wordDelim = ' '): string[] {\n return (result.Fields[fieldName]?.Highlights?.length > 0) ?\n trimArrayToMaxWords(result.Fields[fieldName].Highlights, maxWords) :\n [getFieldValue(result, fieldName, maxWords, wordDelim) ?? ''];\n}\n\n/** Helper for getHighlightsOrValuesArray function to trim array of strings to max words */\nfunction trimArrayToMaxWords(values: string[], maxWords?: number) {\n let returnValues = [];\n if (maxWords) {\n let wordCount = 0;\n for (let i = 0; i < values.length; i++) {\n let stringArray = values[i].trim().split(/\\s+/);\n wordCount += stringArray.length;\n if (wordCount > maxWords) {\n stringArray.splice(-(wordCount - maxWords));\n returnValues.push(stringArray.join(' '));\n break;\n } else {\n returnValues.push(stringArray.join(' '));\n }\n }\n } else {\n returnValues = [...values];\n }\n return returnValues;\n}\n\n/** Returns an object that can be used for setting inner HTML */\nexport function getFormattedHTML(val: string) {\n return {__html: val};\n}\n\n/** Logs error message when result object missing from result widget components */\nexport function logMissingResultError(component: string): void {\n console.error(`No result provided to ${component} component. ${component} must receive a result through props or from a result context provider.`);\n}\n\n/** Checks if the selected element is an autocomplete item */\nexport function isAutocompleteItem(element: Element | null): boolean {\n if (!element) {\n return false;\n }\n return element.hasAttribute('data-cludo-autocomplete');\n}\n\n/** Extracts results from autocomplete top hit groups into a single array */\nexport function getAutocompleteResultsFromTopHits(categorizedResultGroups: AutocompleteTopHit[]): AutocompleteResult[] {\n let results: AutocompleteResult[] = [];\n categorizedResultGroups.forEach(resultGroup => {\n resultGroup.Values.forEach(resultValue => {\n results = results.concat(resultValue.Hits);\n })\n })\n return results;\n}\n\n/** Derive total number of results for individual categorized result categories from result counts in facet map */\nexport function getTopHitTotalCount<T extends TopHit | AutocompleteTopHit>(hit: T, facets: FacetMap) {\n return {\n Field: hit.Field,\n Values: hit.Values.map(hitValue => {\n const facetMatch = facets[hit.Field];\n const facetValueMatch = facetMatch?.Items?.find(value => value.Key === hitValue.Value);\n const count = facetValueMatch ? facetValueMatch.Count : 0;\n return {\n ...hitValue,\n AllCount: count\n }\n })\n } as T\n}","import { CludoFeature } from \"@cludosearch/cludo-api-client/dist/interfaces/api/public-settings.interface\";\nimport { CludoSearchContext } from \"./cludo-search-context\";\n\n/** If WCH is enabled, return the formatted link fragment part to be appended on a result URL */\nexport function getLinkFragmentUrlPart(fragment: string, context: CludoSearchContext): string {\n const enableFragmentHighlights: boolean = context.isFeatureEnabled(CludoFeature.WebContentHighlighter);\n\n if (enableFragmentHighlights) {\n const fragmentToken = '#:~:text=';\n const innerText = fragment.replace(/<[^>]+>/g, '');\n const encodedText = encodeURIComponent(innerText);\n return fragmentToken + encodedText;\n }\n\n return '';\n}","import React, { useContext, useEffect, useRef, useState} from \"react\";\nimport { CludoContext, EventControllerContext } from \"../../context\";\nimport { getFieldValue, logMissingResultError } from \"../../utils/result-utils\";\nimport { getLinkFragmentUrlPart } from \"../../utils/context-utils\";\nimport { EventController } from \"../../utils/event-controller\";\nimport { ResultContext } from \"../results/items/custom-result\";\nimport { BaseResultProps } from \"../types/types\";\n\ninterface ResultLinkProps extends BaseResultProps {\n className?: string,\n children?: React.ReactNode,\n openNewTab?: boolean,\n shouldBeFocused?: boolean,\n highlightQueryOnClickedPage?: boolean,\n linkField?: string\n}\n\ninterface LinkContext {\n onFragmentHover: (fragmentStr?: string) => void;\n onFragmentSelect: () => void; \n}\n\nexport const LinkContext = React.createContext<LinkContext>({} as any);\n\nexport function ResultLink(props: ResultLinkProps) {\n const context = useContext(CludoContext);\n const eventController = useContext(EventControllerContext);\n const resultContext = useContext(ResultContext);\n const initalFragment = props.highlightQueryOnClickedPage ? getLinkFragmentUrlPart(context.query, context) : '';\n\n const [fragmentUrlPart, setFragmentUrlPart] = useState(initalFragment);\n\n const result = props.result || resultContext;\n if (!result) {\n logMissingResultError('ResultLink');\n return null;\n }\n \n const model = result;\n const eleClass = props.className ? props.className : '';\n const titleField = getFieldValue(result, '_type') === \"PageContent\" ? 'Title' : 'fc_Title';\n\n // Set URL based on hovered fragment or first fragment\n // OnHover/OnSelect callbacks passed down to children that can \n // optionally use them if WCH is enabled.\n let url = props.linkField ? getFieldValue(result, props.linkField) : model.Fields[\"Url\"].Value;\n let urlWithFragments = url;\n if (fragmentUrlPart) {\n urlWithFragments += fragmentUrlPart\n }\n\n const anchorElem = useRef<HTMLAnchorElement>(null);\n\n const onFragmentHover = (fragment?: string) => {\n const urlFragmentPart = (fragment) ? getLinkFragmentUrlPart(fragment, context) : '';\n setFragmentUrlPart(urlFragmentPart);\n }\n\n const onFragmentSelect = () => {\n if (anchorElem.current) {\n anchorElem.current.click();\n }\n }\n\n const LinkContextInstance = { \n onFragmentHover: onFragmentHover,\n onFragmentSelect: onFragmentSelect\n };\n\n // Autofocus the first result\n useEffect(() => {\n if (props.shouldBeFocused && anchorElem.current) {\n anchorElem.current.focus();\n }\n }, []);\n\n \n return (\n <a \n ref={anchorElem}\n href={urlWithFragments}\n data-cludo-result=\"searchresult\"\n data-cludo-index={model.ResultIndex}\n data-cludo-url={url}\n data-cludo-title={getFieldValue(result, titleField)}\n data-cludo-page={context.currentPage}\n className={eleClass}\n target={props.openNewTab ? '_blank' : ''}\n {...props.attributes?.root}\n onKeyUp={(e) => onKeyUpHandler(e, eventController)}\n onClick={(e) => onClickHandler(e, eventController, anchorElem.current!)}\n >\n <LinkContext.Provider value={LinkContextInstance}>\n {props.children}\n </LinkContext.Provider>\n </a>\n )\n}\n\nfunction onKeyUpHandler(e: React.KeyboardEvent<HTMLAnchorElement>, eventController: EventController) {\n eventController.searchResultKeyUpEvent(e.nativeEvent);\n}\n\n/**\n * Handle click event on the anchor element -- sets web content highlighting properties and initiaties\n * click tracking\n * @param e \n * @param result \n * @param eventController \n * @param anchorElem \n */\nfunction onClickHandler(\n e: React.MouseEvent<HTMLAnchorElement, MouseEvent>,\n eventController: EventController,\n anchorElem: HTMLElement) {\n eventController.searchResultTrackClickEventHandler(e.nativeEvent, anchorElem);\n}\n","import React, { useContext } from \"react\";\n\ninterface ThemeContextProps {\n // FUTURE: For now, we're just accepting a class name under which consumers can define\n // scoped css variables to apply themes. We decided this is a good way to start theming\n // as it allows consumers to use their own css/sass variables to create themes. In the future,\n // we should also look into supporting themes created with a typed JSON object that we \n // put into scope for the consumer.\n theme: string | undefined;\n}\n\ninterface ThemeProviderProps extends ThemeContextProps {\n children: React.ReactNode;\n}\n\nexport const ThemeContext = React.createContext<ThemeProviderProps>({} as any);\n\nexport function ThemeProvider(props: ThemeProviderProps) {\n\n return (\n props.theme?.length ?\n <ThemeContext.Provider value={props}>\n <div className={props.theme}>\n { props.children }\n </div>\n </ThemeContext.Provider> :\n\n <>{ props.children }</>\n )\n}\n\n\n// This function can be used by components to enter any classes they need to apply themes\n// plus any additional classes from the component's className/s prop and generate a single \n// class string for the component to use.\nexport function generateThemeCss(themeCss: string, disableTheme?: boolean, ...classNameProps: (string | undefined)[]) {\n const themeContext = useContext(ThemeContext);\n\n // Remove undefined class props and join remaining into single string\n const classNamesString = classNameProps.filter(Boolean).join(' ');\n // Apply theme CSS only if theme applied and not manually disabled\n const themeCssString = themeContext && !disableTheme ? themeCss : '';\n\n const stylesToApply = [themeCssString, classNamesString].join(' ');\n return stylesToApply;\n}","import React, { useContext } from \"react\";\nimport { TypedDocument } from \"../../../types/core-script-types\";\nimport { ResultItemBaseProps, ThemeBaseProps } from \"../../types/types\";\nimport { ResultLink } from \"../../elements/result-link\";\nimport { CludoContext } from \"../../../context\";\nimport { generateThemeCss } from \"../../../utils/theme-provider\";\n\ntype CustomResultProps = ResultItemBaseProps & ThemeBaseProps & { \n children: React.ReactNode;\n wrapWithLink?: boolean;\n highlightQueryOnClickedPage?: boolean;\n openNewTab?: boolean;\n}\n\nexport const ResultContext = React.createContext<TypedDocument>({} as any);\n\nexport function CustomResult(props: CustomResultProps) {\n const context = useContext(CludoContext);\n const shouldBeFocused = props.shouldBeFocused ||\n (props.result.ResultIndex === 1\n && context.currentPage === 1\n && context.focusOnResultsAfterSearch);\n\n // Set theme css\n const themeCss = generateThemeCss('cludo-theme-result-link', props.disableTheme, props.className);\n\n return (\n <ResultContext.Provider value={{...props.result}}>\n { props.wrapWithLink || typeof props.wrapWithLink === 'undefined' ? \n <ResultLink\n openNewTab={props.openNewTab}\n highlightQueryOnClickedPage={props.highlightQueryOnClickedPage}\n result={props.result}\n shouldBeFocused={shouldBeFocused}\n className={themeCss}\n attributes={{root: props.attributes?.root}}\n >\n { props.children }\n </ResultLink> : \n <div className={props.className} {...props.attributes?.root}>\n { props.children }\n </div>\n }\n </ResultContext.Provider>\n )\n}\n\n","import React from \"react\";\nimport { FormattedTextChunk } from \"../types/types\";\n\ninterface HighlightedTextCommonProps {\n wrapDefaultText?: boolean;\n}\ninterface ChunkedTextProps extends HighlightedTextCommonProps {\n chunkedText: FormattedTextChunk[];\n splitByTag?: never;\n text?: never;\n}\n\ninterface UnchunkedTextProps extends HighlightedTextCommonProps {\n text: string;\n splitByTag?: 'b' | 'strong';\n chunkedText?: never;\n}\n\nexport type HighlightedTextProps = ChunkedTextProps | UnchunkedTextProps;\n\nexport function HighlightedText(props: HighlightedTextProps) {\n const chunkedText = props.chunkedText ?? splitByHighlightTags(props.text, props.splitByTag);\n const HighlightTag = props.splitByTag ?? 'b';\n\n return (\n <>\n {\n chunkedText.map((value: FormattedTextChunk, i: number) => {\n switch (value.displayType) {\n case 'highlight':\n return <HighlightTag role=\"presentation none\" key={i}>{value.text}</HighlightTag>;\n default:\n return props.wrapDefaultText ? \n <span role=\"presentation none\" key={i}>{value.text}</span> :\n <React.Fragment key={i}>{value.text}</React.Fragment>;\n }\n })\n }\n </>\n )\n}\n\n// Utility: Split string into highlighted and normal parts\nfunction splitByHighlightTags(input: string, hightlightTag?: 'b' | 'strong'): FormattedTextChunk[] {\n const result: { displayType: 'default' | 'highlight'; text: string }[] = [];\n const regex = hightlightTag === 'strong' ? /<strong>(.*?)<\\/strong>/gi : /<b>(.*?)<\\/b>/gi;\n let lastIndex = 0;\n let match: RegExpExecArray | null;\n\n while ((match = regex.exec(input)) !== null) {\n if (match.index > lastIndex) {\n result.push({\n displayType: 'default',\n text: input.slice(lastIndex, match.index),\n });\n }\n result.push({\n displayType: 'highlight',\n text: match[1],\n });\n lastIndex = regex.lastIndex;\n }\n\n if (lastIndex < input.length) {\n result.push({\n displayType: 'default',\n text: input.slice(lastIndex),\n });\n }\n\n return result;\n}","import React, { useContext } from \"react\";\nimport { getFieldValue, getFormattedHTML, getHighlightsOrValues, logMissingResultError } from \"../../utils/result-utils\";\nimport { generateThemeCss } from \"../../utils/theme-provider\";\nimport { ResultContext } from \"../results/items/custom-result\";\nimport { BaseResultProps, HeadingLevel } from \"../types/types\";\nimport { HighlightedText } from \"./cludo-highlighted-text\";\n\ninterface ResultTitleProps extends BaseResultProps {\n\tshowRawText?: boolean;\n\theadingElement?: HeadingLevel;\n\ttitleField?: string;\n}\n\nexport function ResultTitle(props: ResultTitleProps) {\n\tconst resultContext = useContext(ResultContext);\n\tconst result = props.result || resultContext;\n\tif (!result) {\n\t\tlogMissingResultError(\"ResultTitle\");\n\t\treturn null;\n\t}\n\n\t// Set theme css\n\tconst themeCss = generateThemeCss(`cludo-theme-result-title ${props.showRawText ? 'cludo-font-weight-bold' : 'cludo-font-weight-normal'}`, props.disableTheme, props.className);\n\n\tconst Heading = props.headingElement || \"h3\";\n\t// Need to check if result is a document or webpage to determine which title field to use\n\tconst fileType = getFieldValue(result, \"_type\");\n\tconst titleField = props.titleField || (fileType === \"PageContent\" ? \"Title\" : \"fc_Title\");\n\tconst title = props.showRawText ? getFieldValue(result, titleField) : getHighlightsOrValues(result, titleField);\n\n\treturn title ? <Heading className={themeCss} {...props.attributes?.root} ><HighlightedText text={title} /></Heading> : <></>;\n}\n","import React, { useContext } from \"react\";\nimport { CludoContext } from \"../../../context\";\nimport { getFormattedHTML } from \"../../../utils/result-utils\";\nimport { CludoFeature } from \"@cludosearch/cludo-api-client/dist/interfaces/api/public-settings.interface\";\nimport { LinkContext } from \"../result-link\";\nimport { HighlightedText } from \"../cludo-highlighted-text\";\n\n/** FragmentHighlight component */\nexport function FragmentHighlight(props: { fragment: string }) {\n const context = useContext(CludoContext);\n const linkContext = useContext(LinkContext);\n\n const enableWCH = context.isFeatureEnabled(CludoFeature.WebContentHighlighter);; // TODO: Check if enabled for the current engine instead\n const classStr = enableWCH ? 'cludo-theme-fragment-highlight' : 'cludo-ellipsis-after';\n\n return (\n <span\n tabIndex={0}\n role=\"link\"\n className={classStr}\n onKeyDown={\n (e) => {\n if (e.code === 'Enter') {\n linkContext.onFragmentSelect()\n }\n }\n }\n onFocus={() => linkContext.onFragmentHover(props.fragment)}\n onMouseEnter={() => linkContext.onFragmentHover(props.fragment)}\n onMouseLeave={() => linkContext.onFragmentHover()}\n >\n <HighlightedText text={props.fragment}/>\n </span>\n )\n}\n","import React from \"react\";\nimport { TypedDocument } from \"@cludosearch/cludo-api-client/dist/interfaces/api/search.interface\";\nimport { hasField, getHighlightsOrValuesArray } from \"../../../utils/result-utils\";\nimport { FragmentHighlight } from \"../fragment-highlight/fragment-highlight\";\nimport { ThemeBaseProps } from \"../../types/types\";\n\ninterface FragmentHighlightGroupProps extends ThemeBaseProps {\n result: TypedDocument;\n maxFragments?: number;\n maxWords?: number;\n fieldName?: string;\n}\n\nexport function FragmentHighlightGroup(props: FragmentHighlightGroupProps) {\n let fragments = getFragmentsFromResult(props.result, props.maxWords, props.fieldName);\n if (props.maxFragments && props.maxFragments > 0) {\n fragments = fragments.slice(0, props.maxFragments);\n }\n\n return (\n <p className={props.className} {...props.attributes?.root}>\n {fragments}\n </p>\n )\n}\n\n/** Get an array of FragmentHighlights */\nfunction getFragmentsFromResult(result: TypedDocument, maxWords?: number, field?: string): JSX.Element[] {\n const fieldName = field || (hasField(result, 'fc_Content') ? 'fc_Content' : 'Description');\n const fragments = getHighlightsOrValuesArray(result, fieldName, maxWords).map(\n (descriptionPart: string, i: number) => {\n return (\n <FragmentHighlight key={i} \n fragment={descriptionPart}\n />\n );\n }\n )\n\n return fragments;\n}\n","import React, { useContext } from \"react\";\nimport { ResultContext } from \"../results/items/custom-result\";\nimport { getFieldValue, getFormattedHTML, getHighlightsOrValues, hasField, logMissingResultError } from \"../../utils/result-utils\";\nimport { FragmentHighlightGroup } from \"./fragment-highlight-group/fragment-highlight-group\";\nimport { generateThemeCss } from \"../../utils/theme-provider\";\nimport { BaseResultProps } from \"../types/types\";\nimport { HighlightedText } from \"./cludo-highlighted-text\";\n\ninterface ResultDescriptionProps extends BaseResultProps {\n showRawText?: boolean;\n maxWordCount?: number;\n descriptionField?: string;\n highlightDelimiter?: string;\n makeHighlightsClickable?: boolean;\n}\n\nexport function ResultDescription(props: ResultDescriptionProps) {\n const resultContext = useContext(ResultContext);\n const result = props.result || resultContext;\n if (!result) {\n logMissingResultError('ResultDescription');\n return null;\n }\n\n // Set theme css\n const themeCss = generateThemeCss('cludo-theme-result-description', props.disableTheme, props.className); \n \n const descriptionField = props.descriptionField || (hasField(result, 'fc_Content') ? 'fc_Content' : 'Description');\n\n if (props.makeHighlightsClickable) {\n return <FragmentHighlightGroup className={themeCss} result={result} fieldName={descriptionField} maxWords={props.maxWordCount} />\n }\n\n const description = props.showRawText ? \n getFieldValue(result, descriptionField, props.maxWordCount) : \n getHighlightsOrValues(result, descriptionField, props.maxWordCount, undefined, props.highlightDelimiter);\n\n return description ? <p className={themeCss} {...props.attributes?.root} ><HighlightedText text={description} /></p> : <></>\n}","import React, { useContext } from \"react\";\nimport { ResultContext } from \"../results/items/custom-result\";\nimport { getFieldValue, logMissingResultError } from \"../../utils/result-utils\";\nimport { BaseResultProps } from \"../types/types\";\nimport { generateThemeCss } from \"../../utils/theme-provider\";\n\ninterface ResultUrlProps extends BaseResultProps {\n showRelativeUrl?: boolean;\n}\n\nexport function ResultUrl(props: ResultUrlProps) {\n const resultContext = useContext(ResultContext);\n const result = props.result || resultContext;\n if (!result) {\n logMissingResultError('ResultUrl');\n return null;\n }\n\n // Set theme css\n const themeCss = generateThemeCss('cludo-theme-result-url', props.disableTheme, props.className);\n\n let url = getFieldValue(result, 'Url');\n if (props.showRelativeUrl && url) {\n const urlObj = new URL(url);\n url = urlObj.toString().substring(urlObj.origin.length)\n }\n\n return url ? <div title={url} className={themeCss} {...props.attributes?.root}>{ url }</div> : <></>\n\n}","import React, { useContext } from \"react\";\nimport { ResultContext } from \"../results/items/custom-result\";\nimport { getFieldValue, logMissingResultError } from \"../../utils/result-utils\";\nimport { generateThemeCss } from \"../../utils/theme-provider\";\nimport { BaseResultProps } from \"../types/types\";\n\ninterface ResultBadgeProps extends BaseResultProps {\n field?: string;\n text?: string;\n}\n\nconst DEFAULT_BADGE_FIELD = 'Category';\n\nexport function ResultBadge(props: ResultBadgeProps) {\n const resultContext = useContext(ResultContext);\n const result = props.result || resultContext;\n if (!result && !props.text) {\n logMissingResultError('ResultBadge');\n return null;\n }\n \n // Set theme css\n const themeCss = generateThemeCss('cludo-theme-result-badge', props.disableTheme, props.className); \n\n const displayText = props.text || getFieldValue(result, props.field || DEFAULT_BADGE_FIELD);\n\n return displayText ? \n <span className={themeCss} {...props.attributes?.root}>{ displayText } </span> : null;\n}","import React, { useContext } from \"react\";\nimport { ResultItemBaseProps, StandardResultWidgetType, ThemeBaseProps } from \"../../types/types\";\nimport { CustomResult, ResultContext } from \"./custom-result\";\nimport { ResultTitle } from \"../../elements/result-title\";\nimport { ResultDescription } from \"../../elements/result-description\";\nimport { ResultUrl } from \"../../elements/result-url\";\nimport { ResultBadge } from \"../../elements/result-badge\";\n\nexport type StandardResultProps = \nResultItemBaseProps & \nThemeBaseProps<\n 'root' |\n 'title' |\n 'description' |\n 'url' |\n 'badge'\n> & {\n hideTitle?: boolean;\n hideDescription?: boolean;\n hideUrl?: boolean;\n hideBadge?: boolean;\n badgeField?: string;\n order?: StandardResultWidgetType[];\n makeHighlightsClickable?: boolean;\n highlightQueryOnClickedPage?: boolean\n descriptionMaxWordCount?: number;\n}\n\nconst defaultOrder: StandardResultWidgetType[] = ['title', 'description', 'url', 'badge'];\n\nfunction generateRenderOrder(propOrder: StandardResultWidgetType[]) {\n const generatedOrder = propOrder.concat(\n defaultOrder.filter(el => (propOrder.indexOf(el) === -1))\n );\n return generatedOrder;\n}\n\nexport function StandardResult(props: StandardResultProps) {\n const propOrder = props.order || [];\n\n let renderOrder = generateRenderOrder(propOrder);\n\n // Set final render order to props order and fill in any missing widgets from default\n // Filter out hidden widgets from order\n renderOrder = renderOrder.filter(el => {\n return !((el === 'title' && props.hideTitle) ||\n (el === 'description' && props.hideDescription) ||\n (el === 'url' && props.hideUrl) ||\n (el === 'badge' && props.hideBadge));\n });\n // Create lookup map for widget keys and JSX elements\n const widgetMap = new Map<StandardResultWidgetType, React.ReactNode>(\n [\n [\"title\", <ResultTitle className={props.classNames?.title} attributes={{root: props.attributes?.title}} disableTheme={props.disableTheme}/>],\n [\"description\", <ResultDescription className={props.classNames?.description}attributes={{root: props.attributes?.description}} disableTheme={props.disableTheme} maxWordCount={props.descriptionMaxWordCount || 90} makeHighlightsClickable={props.makeHighlightsClickable}/>],\n [\"url\", <ResultUrl className={props.classNames?.url} attributes={{root: props.attributes?.url}} disableTheme={props.disableTheme}/>],\n [\"badge\", <ResultBadge className={props.classNames?.badge} attributes={{root: props.attributes?.badge}} disableTheme={props.disableTheme} field={props.badgeField || 'Category'}/>]\n ]\n );\n\n return (\n <CustomResult \n highlightQueryOnClickedPage={props.highlightQueryOnClickedPage}\n disableTheme={props.disableTheme}\n className={`${props.className ?? ''}\n ${props.classNames?.root ?? ''}`}\n attributes={{root: props.attributes?.root}}\n result={props.result}\n shouldBeFocused={props.shouldBeFocused}\n >\n {\n renderOrder.map((el, i) => \n <React.Fragment key={i}>\n { widgetMap.get(el) }\n </React.Fragment>\n )\n }\n </CustomResult>\n )\n}","import { useContext } from \"react\";\nimport { CludoContext, EventControllerContext } from \"../context\";\n\n/** Helper for accessing both CludoContext and EventControllerContext */\nexport function useCludoContext() {\n const context = useContext(CludoContext);\n const eventController = useContext(EventControllerContext);\n\n return { context: context, eventController: eventController };\n}\n","import { useContext, useEffect } from \"react\";\nimport { EventType } from \"../utils/components-controller\";\nimport { EventControllerContext } from \"../context\";\n\n\n/** When the event controller receives any provided events, run a callback function\n * @param callback Function to call when events have been processed\n * @param events Array of events to subscribe to. If none provided, the callback will fire for\n * all events\n */\nexport function useEventSubscriptions(callback: Function, events?: EventType[]) {\n const eventController = useContext(EventControllerContext);\n\n useEffect(() => {\n let subscriptions: number[] = [];\n if (eventController && Object.keys(eventController).length > 0) {\n if (!events) {\n subscriptions = [eventController.subscribeToAllEvents(() => callback())];\n } else {\n events.forEach(eventType => {\n subscriptions.push(eventController.subscribe(eventType, callback));\n });\n }\n }\n return () => {\n if (eventController && eventController.unsubscribe) {\n subscriptions.forEach(subscriptionId => eventController.unsubscribe(subscriptionId));\n }\n }\n \n }, [eventController]);\n}","import { useState } from \"react\";\nimport { useCludoContext } from \"./use-cludo-context\";\nimport { useEventSubscriptions } from \"./use-event-subscription\";\n\nexport interface PaginationState {\n itemsPerPage: number;\n currentPage: number;\n maxPages: number;\n nextPageLabel: string;\n prevPageLabel: string;\n showPagination: boolean;\n showResultsPerPage: boolean;\n}\n\nexport interface PaginationDispatchers {\n goToPage: (pageNumber: number) => void;\n setPerPage: (perPage: number) => void;\n}\n\nexport function usePagination(): [PaginationState, PaginationDispatchers] {\n const { context, eventController } = useCludoContext();\n const searchResponse = context.storedSearchResponseData.cludoSearchResponse;\n\n // Derive state from CludoSearchContext\n const deriveState : () => PaginationState = () => {\n const resultsPerPage = context.resultsPerPage || 10;\n return {\n itemsPerPage: context.resultsPerPage || 10,\n currentPage: context.currentPage || 1,\n maxPages: Math.ceil(context.storedSearchResponseData?.cludoSearchResponse.ResultCount / resultsPerPage),\n nextPageLabel: context.translateProvider?.translate('next_page') || 'Next page',\n prevPageLabel: context.translateProvider?.translate('prev_page') || 'Previous page',\n showPagination: !(searchResponse.ResultCount < context.resultsPerPage || context.isEndlessScrollEnabled),\n showResultsPerPage: !(context.storedSearchResponseData.cludoSearchResponse.ResultCount <= 0 || context.isEndlessScrollEnabled)\n };\n }\n\n // Derive dispatchers from EventController\n // FUTURE: Investigate getting rid of bind here\n const deriveDispatchers : () => PaginationDispatchers = () => {\n return {\n goToPage: eventController?.goToPage?.bind(eventController) || (() => {}),\n setPerPage: eventController?.setPerPage?.bind(eventController) || (() => {})\n };\n }\n\n // When eventController changes, derive state and dispatchers again\n useEventSubscriptions(() => {\n setCludoState(deriveState());\n setCludoDispatchers(deriveDispatchers());\n });\n\n const [cludoState, setCludoState] = useState(deriveState());\n const [cludoDispatchers, setCludoDispatchers] = useState(deriveDispatchers());\n\n return [ cludoState, cludoDispatchers ];\n}","import { useState } from \"react\";\nimport { useCludoContext } from \"./use-cludo-context\";\nimport { BannerDefinition, RelatedSearchDocument, TopHit, TypedDocument } from \"../types/core-script-types\";\nimport { Facets } from \"@cludosearch/cludo-api-client/dist/interfaces/api/search.interface\";\nimport { EndlessScrollOptions } from \"../utils/models/instantiator-types\";\nimport { useEventSubscriptions } from \"./use-event-subscription\";\n\ninterface SearchResultEndlessScrollOptions extends EndlessScrollOptions {\n isEnabled: boolean;\n}\n\nexport interface SearchResultsState {\n suggestions: string[];\n results: TypedDocument[];\n categorizedResults: TopHit[];\n resultsSummary: {\n resultCount: number;\n resultCountMessage: string;\n fixedQuery: string;\n facets: Facets;\n didYouMean: string;\n };\n paginationOptions: {\n itemsPerPage: number;\n currentPage: number;\n maxPages: number;\n };\n currentPage: number;\n resultCount: number;\n endlessScrollOptions: SearchResultEndlessScrollOptions;\n banners: BannerDefinition[];\n relatedSearches: RelatedSearchDocument[];\n isLoading: boolean;\n}\n\nexport interface SearchResultsDispatchers {\n loadMore: () => void;\n searchResultKeyUp: (e: KeyboardEvent) => void;\n linkToSearchClickEvent: (anchor: HTMLAnchorElement) => void;\n handleDidYouMeanSelect: (text: string) => void;\n searchResultTrackClickEventHandler: (e: MouseEvent | KeyboardEvent, target: HTMLElement) => void;\n}\n\n/** Expose state and dispatchers for displaying search results\n * @returns cludoState (search result data, metadata, and config values) and cludoDispatchers (load more results event)\n */\nexport function useSearchResults(): [SearchResultsState, SearchResultsDispatchers] {\n const { context, eventController } = useCludoContext();\n\n // Derive state from CludoSearchContext\n const deriveState : () => SearchResultsState = () => {\n const currentPage = context.currentPage || 1;\n const resultsPerPage = context.resultsPerPage || 10;\n const resultsSummary = {\n resultCount: context.storedSearchResponseData?.cludoSearchResponse?.ResultCount || 0,\n resultCountMessage: context.storedSearchResponseData?.cludoSearchResponse?.ResultCountMessage || '',\n fixedQuery: context.storedSearchResponseData?.cludoSearchResponse?.FixedQuery || '',\n facets: context.storedSearchResponseData?.cludoSearchResponse?.Facets,\n didYouMean: context.storedSearchResponseData?.cludoSearchResponse?.Suggestions[0] || '',\n };\n return {\n suggestions: context.storedSearchResponseData?.cludoSearchResponse?.Suggestions || [],\n results: context.storedSearchResponseData?.cludoSearchResponse?.TypedDocuments || [],\n categorizedResults: context.storedSearchResponseData?.cludoSearchResponse?.TopHits || [],\n resultsSummary: resultsSummary,\n paginationOptions: {\n itemsPerPage: context.resultsPerPage,\n currentPage: context.currentPage,\n maxPages: Math.ceil(context.storedSearchResponseData?.cludoSearchResponse?.ResultCount / resultsPerPage),\n },\n endlessScrollOptions: {\n isEnabled: context.isEndlessScrollEnabled,\n ...context.endlessScroll as EndlessScrollOptions\n },\n currentPage: currentPage,\n banners: context.storedSearchResponseData?.cludoSearchResponse?.Banners || [],\n relatedSearches: context.storedSearchResponseData?.cludoSearchResponse?.RelatedSearchDocuments || [],\n resultCount: context.storedSearchResponseData?.cludoSearchResponse?.ResultCount || 0,\n isLoading: context.isLoadingResults\n }\n };\n\n // Derive dispatchers from EventController\n // FUTURE: Investigate getting rid of bind here\n const deriveDispatchers : () => SearchResultsDispatchers = () => {\n return {\n loadMore: eventController?.endlessScrollLoadMore?.bind(eventController) || (() => {}),\n searchResultKeyUp: eventController?.searchResultKeyUpEvent?.bind(eventController) || (() => {}),\n linkToSearchClickEvent: eventController?.linkToSearchClickEvent?.bind(eventController) || (() => {}),\n handleDidYouMeanSelect: eventController?.handleDidYouMeanSelect?.bind(eventController) || (() => {}),\n searchResultTrackClickEventHandler: eventController?.searchResultTrackClickEventHandler?.bind(eventController) || (() => {})\n }\n }\n\n // When eventController changes, derive state and dispatchers again\n useEventSubscriptions(() => {\n setCludoState(deriveState());\n setCludoDispatchers(deriveDispatchers());\n });\n\n const [cludoState, setCludoState] = useState(deriveState());\n const [cludoDispatchers, setCludoDispatchers] = useState(deriveDispatchers());\n\n return [ cludoState, cludoDispatchers ];\n}","import React, { useContext, useEffect, useState } from \"react\";\nimport { CludoContext } from \"../../../context\";\nimport { PaginationState, usePagination } from \"../../../hooks/use-pagination\";\nimport { generateThemeCss } from \"../../../utils/theme-provider\";\nimport { ThemeBaseProps } from \"../../types/types\";\nimport { useSearchResults } from \"../../../hooks/use-search-results\";\n\ninterface PaginationProps extends ThemeBaseProps<\n 'root' |\n 'list' |\n 'listItem' |\n 'firstButton' |\n 'lastButton' |\n 'previousButton' |\n 'nextButton' |\n 'pageNumberButton' |\n 'currentPageButton'\n> {\n hidePrevious?: boolean,\n hideNext?: boolean,\n hideFirst?: boolean,\n hideLast?: boolean,\n previousButtonIcon?: React.ReactNode;\n nextButtonIcon?: React.ReactNode;\n firstButtonIcon?: React.ReactNode;\n lastButtonIcon?: React.ReactNode;\n} \n\n\nexport function Pagination(props: PaginationProps) {\n const [ paginationState, paginationDispatchers ] = usePagination();\n const [ resultsState ] = useSearchResults();\n const [ localPaginationState, setLocalPaginationState ] = useState<PaginationState>(paginationState);\n const context = useContext(CludoContext);\n\n useEffect(() => {\n if (!context.isLoadingResults) {\n setLocalPaginationState(paginationState);\n }\n }, [paginationState])\n\n const previousButtonIcon = props.previousButtonIcon || '<';\n const nextButtonIcon = props.nextButtonIcon || '>';\n const firstButtonIcon = props.firstButtonIcon || '<<';\n const lastButtonIcon = props.lastButtonIcon || '>>';\n const startPage: number = (localPaginationState.currentPage <= 5) \n ? 1\n : (localPaginationState.currentPage >= localPaginationState.maxPages - 2\n ? localPaginationState.maxPages - 3\n : localPaginationState.currentPage - 2);\n\n const prevPageTranslation = localPaginationState.prevPageLabel;\n const nextPageTranslation = localPaginationState.nextPageLabel;\n \n // Set theme css\n const activeBtnCss = generateThemeCss('cludo-theme-btn-accent-secondary cludo-width-sm cludo-mr-2 cludo-my-1', props.disableTheme);\n const inactiveBtnCss = generateThemeCss('cludo-theme-btn-accent-secondary-inactive cludo-width-sm cludo-mr-2 cludo-my-1', props.disableTheme);\n const loadingCss = generateThemeCss(' cludo-theme-loading-disable', props.disableTheme || !resultsState.isLoading);\n\n function renderPageNumberButtons(startPage: number, maxPages: number) {\n \n const currentPageNum = localPaginationState.currentPage || 1;\n let pageNumberButtons: JSX.Element[] = [];\n \n const pageTranslation = context.translateProvider.translate('general_page');\n \n for (let i = startPage; i <= maxPages && i <= startPage + 4; i++) {\n if (i === currentPageNum) {\n pageNumberButtons.push(\n <li className={props.classNames?.listItem} {...props.attributes?.listItem} key={i}>\n <button \n aria-label={'Current, ' + pageTranslation + ' ' + i} \n aria-current=\"true\" \n aria-disabled=\"true\"\n className={`${props.classNames?.pageNumberButton ?? ''} ${props.classNames?.currentPageButton ?? ''} ${inactiveBtnCss}`}\n {...props.attributes?.pageNumberButton}\n {...props.attributes?.currentPageButton}\n >\n {i}\n </button>\n </li>\n );\n } else {\n pageNumberButtons.push(\n <li className={props.classNames?.listItem} {...props.attributes?.listItem} key={i}>\n <button aria-label={pageTranslation + ' ' + i}\n className={`${props.classNames?.pageNumberButton ?? ''} ${activeBtnCss}`}\n onClick={() => { paginationDispatchers.goToPage(i) }}\n {...props.attributes?.pageNumberButton}\n >\n {i}\n </button>\n </li>\n );\n }\n }\n return pageNumberButtons;\n }\n\n return (\n localPaginationState.showPagination ?\n <nav className={`${props.className ?? ''} ${props.classNames?.root ?? ''} ${loadingCss}`} {...props.attributes?.root}>\n <ul className={`${props.classNames?.list ?? ''} cludo-display-flex cludo-list-style-none cludo-p-0 cludo-m-0 cludo-mt-3 cludo-flex-wrap`} {...props.attributes?.list}>\n {/* First page button */}\n { (localPaginationState.currentPage !== 1) && !props.hideFirst ? \n <li className={props.classNames?.listItem} {...props.attributes?.listItem} key=\"first\">\n <button data-page=\"first\"\n className={`${props.classNames?.firstButton ?? ''} ${activeBtnCss}`}\n aria-label=\"First page\"\n onClick={() => { paginationDispatchers.goToPage(1)}}\n {...props.attributes?.firstButton}\n >\n { firstButtonIcon }\n </button>\n </li> : null\n }\n {/* Previous page button */}\n { (localPaginationState.currentPage !== 1) && !props.hidePrevious ? \n <li className={props.classNames?.listItem} {...props.attributes?.listItem} key=\"prev\">\n <button data-page=\"prev\"\n className={`${props.classNames?.previousButton ?? ''} ${activeBtnCss}`}\n aria-label={prevPageTranslation}\n onClick={() => { paginationDispatchers.goToPage(localPaginationState.currentPage - 1)}}\n {...props.attributes?.previousButton}\n >\n { previousButtonIcon }\n </button>\n </li> : null\n }\n\n { renderPageNumberButtons(startPage, localPaginationState.maxPages ) }\n\n {/* Next page button */}\n { (localPaginationState.currentPage < localPaginationState.maxPages) && !props.hideNext ? \n <li className={props.classNames?.listItem} {...props.attributes?.listItem} key=\"next\">\n <button data-page=\"next\"\n className={`${props.classNames?.nextButton ?? ''} ${activeBtnCss}`}\n aria-label={nextPageTranslation}\n onClick={() => { paginationDispatchers.goToPage(localPaginationState.currentPage + 1) }}\n {...props.attributes?.nextButton}\n >\n { nextButtonIcon }\n </button>\n </li> : null\n }\n {/* Last page button */}\n { (localPaginationState.currentPage < localPaginationState.maxPages) && !props.hideLast ? \n <li className={props.classNames?.listItem} {...props.attributes?.listItem} key=\"last\">\n <button data-page=\"last\"\n className={`${props.classNames?.lastButton ?? ''} ${activeBtnCss}`}\n aria-label=\"Last page\"\n onClick={() => { paginationDispatchers.goToPage(localPaginationState.maxPages) }}\n {...props.attributes?.lastButton}\n >\n { lastButtonIcon }\n </button>\n </li> : null\n }\n </ul>\n </nav> : null\n )\n}","import React, { useContext, useEffect, useRef, useState } from \"react\";\nimport { getFormattedHTML } from \"../../utils/result-utils\";\nimport { CludoContext, EventControllerContext } from \"../../context\";\nimport { CludoSearchContext } from \"../../utils/cludo-search-context\";\nimport { EventController } from \"../../utils/event-controller\";\nimport { BannerDefinition } from \"../../types/core-script-types\";\nimport { generateThemeCss } from \"../../utils/theme-provider\";\nimport { ThemeBaseProps } from \"../types/types\";\n\nexport interface BannerProps extends ThemeBaseProps { banner: BannerDefinition }\n\nexport function Banner(props: BannerProps) {\n const context = useContext(CludoContext);\n const eventController = useContext(EventControllerContext);\n const bannerRef = useRef(null);\n\n useEffect(() => {\n if (bannerRef.current) {\n onBannerLoad(bannerRef.current, props.banner, context, eventController);\n }\n }, []);\n \n const bannerCss = \n generateThemeCss('cludo-mb-4 cludo-overflow-auto cludo-border-radius-card cludo-p-4 cludo-bg-color-accent-primary-light', props.disableTheme, props.className);\n \n const loadingCss = \n generateThemeCss('cludo-theme-loading-disable-children', props.disableTheme || !context.isLoadingResults);\n\n return (\n <div\n ref={bannerRef}\n data-cludo-result=\"banner\"\n data-cludo-id={props.banner.Id}\n data-cludo-title={props.banner.Name}\n className={`cludo-banner ${bannerCss} ${loadingCss}`}\n role=\"banner\"\n dangerouslySetInnerHTML={\n getFormattedHTML(props.banner.Banner)\n }\n {...props.attributes?.root}\n ></div>\n )\n}\n\nfunction onBannerLoad(\n target: HTMLElement,\n banner: BannerDefinition,\n context: CludoSearchContext,\n eventController: EventController) {\n const bannerLinks = target.querySelectorAll('a');\n const paramsPrefix = context.paramsPrefix;\n\n bannerLinks.forEach( link => {\n addBannerAttributesToAnchor(link, banner);\n if (decodeURIComponent(link.href).indexOf('#?' + paramsPrefix) !== -1) {\n link.addEventListener('click', (e) => {\n e.preventDefault();\n eventController.linkToSearchClickEvent(link);\n })\n } else {\n link.addEventListener('click', (e) => {\n eventController.searchResultTrackClickEventHandler(e, link);\n })\n }\n })\n}\n\nfunction addBannerAttributesToAnchor(anchor: HTMLAnchorElement, banner: BannerDefinition) {\n const bannerId = String(banner.Id);\n const bannerTitle = banner.Name;\n\n anchor.setAttribute(\"data-cludo-result\", \"banner\");\n anchor.setAttribute(\"data-cludo-index\", \"1\");\n anchor.setAttribute(\"data-cludo-object-id\", bannerId);\n anchor.setAttribute(\"data-cludo-title\", bannerTitle);\n}","import { useState } from \"react\";\nimport { useCludoContext } from \"./use-cludo-context\";\nimport { BannerDefinition } from \"../types/core-script-types\";\nimport { useEventSubscriptions } from \"./use-event-subscription\";\n\nexport interface BannersState {\n banners: BannerDefinition[];\n}\n\n/** Expose state for displaying banners\n * @returns cludoState object containing an array of currently active banners\n */\nexport function useBanners(): [BannersState] {\n const { context } = useCludoContext();\n\n // Derive state from CludoSearchContext\n const deriveState : () => BannersState = () => {\n return {\n banners: context.storedSearchResponseData?.cludoSearchResponse.Banners || [],\n }\n }\n\n // When eventController changes, derive state and dispatchers again\n useEventSubscriptions(() => setCludoState(deriveState()))\n\n const [cludoState, setCludoState] = useState(deriveState());\n\n return [ cludoState ];\n}","import React from \"react\";\nimport { Banner } from \"../banner\";\nimport { useBanners } from \"../../../hooks/use-banners\";\nimport { BannerDefinition } from \"../../../types/core-script-types\";\n\nexport function BannerGroup(props: {banners?: BannerDefinition[], className?: string}) {\n const [bannersState] = useBanners();\n const banners = props.banners || bannersState.banners;\n const bannerComponents = banners.map( (banner) => <Banner key={banner.Id} banner={banner} className={props.className} />);\n return (\n bannerComponents.length ?\n <div className=\"cludo-banner-group\">\n { bannerComponents }\n </div> : <></>\n )\n}","import React, { useContext } from 'react';\nimport { CludoContext, EventControllerContext } from '../../../context';\nimport { EventController } from '../../../utils/event-controller';\nimport { getFormattedHTML } from '../../../utils/result-utils';\nimport { useSearchResults } from '../../../hooks/use-search-results';\nimport { ThemeBaseProps } from '../../types/types';\nimport { generateThemeCss } from '../../../utils/theme-provider';\n\nexport interface DidYouMeanProps extends ThemeBaseProps {\n suggestedQuery?: string;\n}\n\nexport function DidYouMean(props: DidYouMeanProps) {\n const [ resultsState, resultsDispatchers ] = useSearchResults();\n const context = useContext(CludoContext);\n const eventController = useContext(EventControllerContext);\n\n const suggestionFromContext = resultsState.resultCount && resultsState.resultCount < 10 ? resultsState.resultsSummary.didYouMean : '';\n const suggestedQuery = props.suggestedQuery || suggestionFromContext;\n const didYouMeanInnerHTML = context.translateProvider.translate('did_you_mean', suggestedQuery);\n \n // Set theme css\n const themeCss = generateThemeCss('cludo-font-family-default cludo-font-size-md cludo-mb-2', props.disableTheme, props.className);\n const loadingCss = generateThemeCss(' cludo-theme-loading-disable', props.disableTheme || !resultsState.isLoading);\n\n return (\n <div className={themeCss + loadingCss + ' cludo-did-you-mean'}\n {...props.attributes?.root}\n onClick={(e) => onDidYouMeanClick(e, suggestedQuery, eventController)}\n dangerouslySetInnerHTML={ suggestedQuery ? getFormattedHTML(didYouMeanInnerHTML) : { __html: '' } }\n />\n )\n}\n\nfunction onDidYouMeanClick(event: React.MouseEvent, suggestion: string, eventController: EventController) {\n const target = event.target;\n if (target instanceof HTMLElement) {\n\n // If we clicked on the anchor tag or its child, handle setting Did You Mean properties\n const anchorElem = target.closest('.cludo-did-you-mean > a');\n if (anchorElem) {\n // Prevent navigation\n event.preventDefault();\n \n // Call utility function which restores autocomplete and searches for the suggestion\n eventController.handleDidYouMeanSelect(suggestion);\n }\n }\n}","import { useState } from \"react\";\nimport { ExternalFacet } from \"../utils/cludo-search-context\";\nimport { useCludoContext } from \"./use-cludo-context\";\nimport { useEventSubscriptions } from \"./use-event-subscription\";\nimport { FacetMapRequest, RangeFacetMap } from \"../types/core-script-types\";\n\nexport interface FacetGroupState {\n facets: ExternalFacet[];\n selectedFacets: FacetMapRequest;\n}\n\nexport interface FacetGroupDispatchers {\n clearAllFacets: (shouldSearch?: boolean) => void;\n softClearAllFacets: () => void;\n deselectFacet: (field: string, value: string, shouldSearch?: boolean) => void;\n}\n\n/** Expose data and dispatchers for a facet group component (collection of all Cludo search facets) \n * @returns cludoState (list of all available facets) and cludoDispatchers (the \"Clear all facets\" event)\n*/\nexport function useFacetGroup() : [FacetGroupState, FacetGroupDispatchers] {\n const { context, eventController } = useCludoContext();\n\n // Derive state from CludoSearchContext\n const deriveState : () => FacetGroupState = () => {\n return {\n facets: context?.facets || [],\n selectedFacets: context?.selectedFacets\n }\n }\n\n // Derive dispatchers from EventController\n // FUTURE: Investigate getting rid of bind here\n const deriveDispatchers : () => FacetGroupDispatchers = () => {\n return {\n clearAllFacets: eventController?.clearAllFacets?.bind(eventController) || (() => {}),\n softClearAllFacets: eventController?.softClearAllFacets?.bind(eventController) || (() => {}),\n deselectFacet: eventController?.deselectFacet?.bind(eventController) || (() => {})\n }\n }\n\n // When eventController changes, derive state and dispatchers again\n useEventSubscriptions(() => {\n setCludoState(deriveState());\n setCludoDispatchers(deriveDispatchers());\n });\n\n const [cludoState, setCludoState] = useState(deriveState());\n const [cludoDispatchers, setCludoDispatchers] = useState(deriveDispatchers());\n\n return [ cludoState, cludoDispatchers ];\n}","import React, { useContext, useEffect, useState } from \"react\";\nimport { CludoContext } from \"../../../context\";\nimport { useFacetGroup } from \"../../../hooks/use-facet-group\";\nimport { useSearchResults } from \"../../../hooks/use-search-results\";\nimport { generateThemeCss } from \"../../../utils/theme-provider\";\nimport { ThemeBaseProps } from \"../../types/types\";\n\nexport interface ResultCountProps extends ThemeBaseProps {\n\tresultCount?: number;\n}\n\nexport function ResultCount(props: ResultCountProps) {\n\tconst [resultsState, resultsDispatchers] = useSearchResults();\n\tconst [facetsState, facetsDispatchers] = useFacetGroup();\n\tconst [resultTextState, setResultTextState] = useState(\"\");\n\tconst context = useContext(CludoContext);\n\tconst resultCount = props.resultCount || resultsState.resultCount;\n\tconst query = context.storedSearchResponseData.cludoSearchResponse.Query;\n\n\tuseEffect(() => {\n\t\tif (!context.isLoadingResults && query) {\n\t\t\t// Set result count message from combination of your search, total results, in category and searched instead translations\n\t\t\tconst yourSearchMsg = context.translateProvider.translate(\"your_search_on\", query);\n\n\t\t\tlet totalMsg = resultCount === 1 ? context.translateProvider.translate(\"total_result\", resultCount.toString()) : context.translateProvider.translate(\"total_results\", resultCount.toString());\n\n\t\t\tlet inCategoryMsg = \"\";\n\t\t\tif (facetsState.selectedFacets) {\n\t\t\t\tconst selectedValues = Object.entries(facetsState.selectedFacets)\n\t\t\t\t\t.map(([facetName, values]) => (Array.isArray(values) ? values.join(\", \") : String(values)))\n\t\t\t\t\t.join(\", \");\n\t\t\t\tif (selectedValues.length) {\n\t\t\t\t\tinCategoryMsg = context.translateProvider.translate(\"in_category\", selectedValues);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tlet searchedInsteadMsg = \"\";\n\t\t\tif (resultsState.resultsSummary.fixedQuery) {\n\t\t\t\t// If there is a fixed query, set totalMsg to 0 and construct searchedInsteadMsg\n\t\t\t\ttotalMsg = resultCount === 1 ? context.translateProvider.translate(\"total_result\", \"0\") : context.translateProvider.translate(\"total_results\", \"0\");\n\n\t\t\t\tsearchedInsteadMsg = context.translateProvider.translate(\"searched_instead\").replace(\"{{number}}\", resultCount.toString()).replace(\"{{term}}\", resultsState.resultsSummary.fixedQuery);\n\t\t\t}\n\n\t\t\tconst resultMsg =\n\t\t\t\tyourSearchMsg +\n\t\t\t\t(yourSearchMsg.length && totalMsg.length ? \" \" : \"\") +\n\t\t\t\ttotalMsg +\n\t\t\t\t(inCategoryMsg && inCategoryMsg.length ? \" \" + inCategoryMsg : \"\") +\n\t\t\t\t(searchedInsteadMsg && searchedInsteadMsg.length ? \" \" + searchedInsteadMsg : \"\");\n\n\t\t\tsetResultTextState(resultMsg.replace(/,([^,]*)$/, \"</b>\" + context.translateProvider.translate(\"and\") + \"<b>\" + \"$1\").replace(/<b>/g, '<b role=\"presentation none\">'));\n\t\t}\n\t}, [resultsState]);\n\n\t// Set theme css\n\tconst themeCss = generateThemeCss(\"cludo-font-family-default cludo-font-size-md cludo-mb-2\", props.disableTheme, props.className);\n\tconst loadingCss = generateThemeCss(\" cludo-theme-loading-disable\", props.disableTheme || !context.isLoadingResults);\n\n\treturn resultTextState.length ? <span className={themeCss + loadingCss} role=\"status\" {...props.attributes?.root} dangerouslySetInnerHTML={{ __html: resultTextState }}></span> : null;\n}\n","import React from \"react\";\n\nimport { DidYouMean, DidYouMeanProps } from \"./did-you-mean\";\nimport { ResultCount, ResultCountProps } from \"./result-count\";\n\ntype ResultsSummaryProps = ResultCountProps & DidYouMeanProps;\n\nexport function ResultsSummary(props: ResultsSummaryProps) {\n return (\n <>\n <ResultCount {...(props)} />\n\n <DidYouMean suggestedQuery={props.suggestedQuery} />\n </>\n )\n}","import React, { useContext } from \"react\";\nimport { CludoContext } from \"../../context\";\nimport { LoaderProps } from \"../types/types\";\n\n/** Default Search Results template */\nexport function CludoLoader(props: LoaderProps) {\n const context = useContext(CludoContext);\n const loadingAltText = context.translateProvider.translate('loading_results');\n return (\n <>\n {\n props.isLoading\n ? <img src=\"https://customer.cludo.com/img/loading.gif\" className=\"loading\" tabIndex={-1} alt={loadingAltText} />\n : <></>\n }\n </>\n )\n}","import React from \"react\";\nimport { ThemeBaseProps } from \"../../types/types\";\n\nexport function StandardLoader(props: ThemeBaseProps) {\n return(\n <div className={`cludo-loader ${props.className}`} {...props.attributes?.root}>\n <div></div>\n <div></div>\n <div></div>\n <div></div>\n </div>\n )\n}","import React, { useContext, useEffect, useState } from \"react\";\nimport { BannerDefinition, TypedDocument } from \"../../../types/core-script-types\";\nimport { useSearchResults } from \"../../../hooks/use-search-results\";\nimport { StandardResult } from \"../items/standard-result\";\nimport { CssUnit, LayoutColumnOptions, ThemeBaseProps } from \"../../types/types\";\nimport { generateThemeCss } from \"../../../utils/theme-provider\";\nimport { StandardLoader } from \"../../elements/loader/standard-loader\";\nimport { useBanners } from \"../../../hooks/use-banners\";\nimport { Banner } from \"../../elements/banner\";\nimport { CludoContext } from \"../../../context\";\n\nexport type ResultsListProps = ThemeBaseProps<\n 'root' |\n 'banner' |\n 'resultsListContainer' |\n 'resultsListItem' |\n 'loaderContainer'\n> & {\n results?: TypedDocument[];\n columns?: LayoutColumnOptions;\n columnsBreakpoint?: number;\n resultSpacing?: number;\n cssUnit?: CssUnit;\n hideBanners?: boolean;\n template?: (result: TypedDocument, shouldBeFocused?: boolean) => React.ReactNode;\n customLoader?: React.ReactNode;\n focusIndex?: number;\n}\n\nexport function ResultsList(props: ResultsListProps) {\n const [resultsState, resultsdispatchers] = useSearchResults();\n const [bannersState] = useBanners();\n const context = useContext(CludoContext);\n // Resolve props with defaults\n const templateFn = props.template ?? ((result: TypedDocument, shouldBeFocused?: boolean) => <StandardResult shouldBeFocused={shouldBeFocused} disableTheme={props.disableTheme} result={result} />)\n const results = props.results ?? resultsState.results;\n const columns = props.columns ?? 1;\n const loader = props.customLoader ?? <StandardLoader></StandardLoader>;\n const resultSpacing = props.resultSpacing ?? 0;\n const cssUnit = props.cssUnit ?? 'px';\n const focusIndex = props.focusIndex ?? context.focusIndex;\n const [resultsToRender, setResultsToRender] = useState<TypedDocument[]>([]);\n const [bannersToRender, setBannersToRender] = useState<BannerDefinition[]>([]);\n\n useEffect(() => {\n if (!context.isLoadingResults) {\n setResultsToRender(results);\n }\n }, [resultsState]);\n\n useEffect(() => {\n if (!context.isLoadingResults) {\n setBannersToRender(bannersState.banners);\n }\n }, [bannersState]);\n\n // Set theme css\n // FUTURE: we apply structural css here no matter what - need to rethink how we handle structural css\n const containerCss = \n generateThemeCss('cludo-position-relative', props.disableTheme, props.className, props.classNames?.root);\n const bannerCss = \n generateThemeCss('', props.disableTheme, props.classNames?.banner);\n const listCss = \n generateThemeCss('cludo-theme-results-list', props.disableTheme, props.classNames?.resultsListContainer) +\n \" cludo_results-list cludo-box-sizing cludo-display-flex cludo-flex-wrap cludo-list-style-none cludo-p-0\";\n const listItemCss =\n generateThemeCss('', props.disableTheme, props?.classNames?.resultsListItem) +\n \" cludo_result cludo-border-box cludo-col-in-grid-\" + columns\n const loadingCss = \n generateThemeCss(' cludo-theme-loading-disable', props.disableTheme || !context.isLoadingResults);\n const loaderCss =\n generateThemeCss('cludo-my-5 cludo-position-absolute cludo-top-0 cludo-absolute-center', props.disableTheme, props.classNames?.loaderContainer)\n\n const generateStyleOverrides = () => {\n let cssString = ``;\n // FUTURE: Offer discrete breakpoints (i.e. breakpoint-sm) possibly using a library like Tailwinds\n if (props.columnsBreakpoint) {\n cssString += `\n @media (max-width: ${props.columnsBreakpoint}${cssUnit}) {\n .cludo_result { width: 100% !important }\n }\n `\n }\n \n cssString += `\n .cludo_results-list { margin: -${resultSpacing/2}${cssUnit} }\n .cludo_result { padding: ${resultSpacing/2}${cssUnit} }\n `\n return cssString;\n }\n\n return (\n <> \n { !props.hideBanners ?\n bannersToRender.map((banner, i) =>\n <Banner key={'banner-' + i} className={bannerCss} attributes={{root: props.attributes?.banner}} banner={banner}></Banner>\n ) : <></>\n }\n <div className={containerCss} {...props.attributes?.root}>\n { resultsToRender.length > 0 &&\n <>\n <style>\n { generateStyleOverrides() }\n </style>\n <ul className={listCss} {...props.attributes?.resultsListContainer}>\n { resultsToRender.map((result, i) => \n <li className={listItemCss + loadingCss} {...props.attributes?.resultsListItem} key={'result-' + i}>\n { templateFn(result, i === focusIndex) }\n </li>\n )}\n </ul>\n </>\n }\n {\n !props.disableTheme && resultsState.isLoading ?\n <div className={loaderCss} {...props.attributes?.loaderContainer}>\n { loader }\n </div> : <></>\n }\n </div>\n </>\n )\n}","import React, { useContext } from \"react\";\nimport { CludoContext } from \"../../context\";\nimport { ThemeBaseProps } from \"../types/types\";\n\ninterface LoadMoreProps extends ThemeBaseProps<\n 'root' |\n 'loadMoreButton'\n> {\n onClick: (wasKeyboardClick?: boolean) => void;\n label?: string;\n}\n\nexport function LoadMore(props: LoadMoreProps) {\n const context = useContext(CludoContext);\n\n const loadMoreStr: string = props.label || context.translateProvider.translate('load_more');\n\n function handleClick(e: React.MouseEvent) {\n const wasKeyboardClick = e.detail === 0 ? true : false;\n props.onClick(wasKeyboardClick);\n }\n\n return (\n <div className={`${props.classNames?.root ?? ''} ${props.className ?? ''}`} id=\"cludo-load-more\" {...props.attributes?.root}>\n <button className={props.classNames?.loadMoreButton ?? ''} type=\"button\" onClick={handleClick} {...props.attributes?.loadMoreButton}>\n { loadMoreStr }\n </button>\n </div>\n )\n}","import React, { useContext } from \"react\";\nimport { CludoContext } from \"../../context\";\nimport { useSearchResults } from \"../../hooks/use-search-results\";\nimport { usePagination } from \"../../hooks/use-pagination\";\nimport { LoadMore } from \"./cludo-load-more\";\nimport { generateThemeCss } from \"../../utils/theme-provider\";\nimport { ThemeBaseProps } from \"../types/types\";\n\ninterface LoadMoreResultsProps extends ThemeBaseProps<\n // Child component custom class names definition\n 'root' |\n 'loadMoreButton'\n> { \n label?: string;\n onLoadMore?: (wasKeyboardClick?: boolean) => void;\n disableKeyboardFocusHandling?: boolean;\n}\n\nexport function LoadMoreResults(props: LoadMoreResultsProps) {\n const [searchResultsState, searchResultsDispatchers] = useSearchResults();\n const [paginationState, paginationDispatchers] = usePagination();\n const context = useContext(CludoContext);\n\n const loadMoreStr: string = props.label || context.translateProvider.translate('load_more');\n const showLoadMore = searchResultsState.endlessScrollOptions.isEnabled\n && searchResultsState.resultCount > 0\n && searchResultsState.endlessScrollOptions?.stopAfterPage\n && searchResultsState.endlessScrollOptions?.stopAfterPage <= paginationState.currentPage\n && paginationState.currentPage !== paginationState.maxPages\n && !searchResultsState.isLoading;\n \n // Set theme css\n const rootCss = generateThemeCss('', props.disableTheme, props.className, props.classNames?.root)\n const buttonCss = generateThemeCss('cludo-theme-btn-accent-secondary cludo-font-size-sm cludo-font-weight-bold cludo-width-100 cludo-mt-3', props.disableTheme, props.classNames?.loadMoreButton);\n const classNamesObj = {\n root: rootCss,\n loadMoreButton: buttonCss\n }\n const attrsObj = {\n root: props.attributes?.root,\n loadMoreButton: props.attributes?.loadMoreButton\n }\n\n function handleLoadMore(wasKeyboardClick?: boolean) {\n if (wasKeyboardClick && !props.disableKeyboardFocusHandling) {\n context.focusIndex = searchResultsState.results.length;\n } else {\n context.focusIndex = undefined;\n }\n props.onLoadMore && props.onLoadMore(wasKeyboardClick);\n searchResultsDispatchers.loadMore();\n }\n\n return (\n showLoadMore ?\n <LoadMore classNames={classNamesObj} attributes={attrsObj} label={loadMoreStr} onClick={handleLoadMore}/> : null\n )\n}","import { TypedDocument } from \"@cludosearch/cludo-api-client/dist/interfaces/api/search.interface\";\nimport { ExternalFacet } from \"../../utils/cludo-search-context\";\nimport { SortOption } from \"../../utils/models/instantiator-types\";\nimport { CludoSearchResponseState, TopHit } from \"../../types/core-script-types\";\nimport { FacetMap } from \"../../types/core-script-types\";\n\ntype FormattedTextDisplayType = 'default' | 'highlight';\n\nexport type CssUnit = 'px'|'pt'|'pc'|'in'|'Q'|'mm'|'cm'|'em'|'rem'|'ex'|'ch'|'lh'|'rlh'|'vw'|'vh'|'vmin'|'vmax'|'vb'|'vi'|'svw'|'svh'|'lvh'|'lvw'|'dvw'|'dvh';\nexport type HeadingLevel = 'h1'|'h2'|'h3'|'h4'|'h5'|'h6';\nexport type LayoutColumnOptions = 1|2|3|4|5|6|7|8|9|10|11|12;\nexport type StandardResultWidgetType = 'title' | 'description' | 'url' | 'badge';\n\nexport enum AutocompleteItemType {\n Result = 'result',\n CategorizedResult = 'categorized-result',\n Suggestion = 'suggestion',\n RecentSearch = 'recent-search'\n}\n\nexport interface FormattedTextChunk {\n text: string;\n displayType: FormattedTextDisplayType;\n}\n\ninterface AutocompleteBaseItem {\n title: string;\n chunkedTitle: FormattedTextChunk[];\n}\n\nexport interface AutocompleteResult extends AutocompleteBaseItem {\n document: TypedDocument;\n}\n\nexport interface AutocompleteSuggestion extends AutocompleteBaseItem {}\n\nexport interface AutocompleteRecentSearch extends AutocompleteBaseItem {}\n\nexport interface AutocompleteTopHit {\n Field: string;\n Values: AutocompleteTopHitValue[];\n}\n\nexport interface AutocompleteTopHitValue {\n Value: string;\n Hits: AutocompleteResult[];\n AllCount?: number;\n}\n\nexport interface FormattedCludoAutocompleteResponse {\n query: string;\n facets?: FacetMap;\n totalResults?: number;\n totalSuggestions?: number;\n totalRecentSearches?: number;\n results?: AutocompleteResult[];\n suggestions?: AutocompleteSuggestion[];\n instantSuggestions?: AutocompleteSuggestion[];\n recentSearches?: AutocompleteRecentSearch[];\n categorizedResults?: AutocompleteTopHit[];\n}\n\nexport type CludoAutocompleteBaseProps = { \n data: FormattedCludoAutocompleteResponse,\n isLoading: boolean;\n};\n\nexport type ThemeBaseProps<T extends string = never> = {\n disableTheme?: boolean;\n className?: string;\n classNames?: Partial<Record<T, string>>;\n attributes?: Partial<Record<'root' | T, React.HTMLAttributes<HTMLElement> & Record<string, string>>>;\n};\nexport type CludoFacetBaseProps = { facet: ExternalFacet };\nexport type CludoControlsBaseProps = { facets: ExternalFacet[]; sortItems: SortOption[]; };\nexport type ResultItemBaseProps = { result: TypedDocument, shouldBeFocused?: boolean }\nexport type BaseResultProps = ThemeBaseProps & { result?: TypedDocument }\n\nexport type LoaderProps = { isLoading: boolean }\n\nexport type CludoSearchResultsBaseProps = { cludoSearchResponse: CludoSearchResponseState };\nexport type CludoLoaderBaseProps = { isLoading: boolean };","import React from \"react\";\nimport { StandardResult } from \"./items/standard-result\";\nimport { Pagination } from \"./pagination/pagination\";\nimport { LoaderProps, ResultItemBaseProps } from \"../types/types\";\nimport { BannerGroup } from \"../elements/banner-group/banner-group\";\nimport { ResultsSummary } from \"./header/results-summary\";\nimport { SearchResultsCompositionOptions } from \"../../utils/models/instantiator-types\";\nimport { CludoLoader } from \"./cludo-loader\";\nimport { useSearchResults } from \"../../hooks/use-search-results\";\nimport { ResultsList, ResultsListProps } from \"./list/results-list\";\nimport { LoadMoreResults } from \"./load-more-results\";\n\n\n// Default search results template\nexport const CludoSearchResults = composeResults({});\n\nexport function composeResults(options: SearchResultsCompositionOptions): () => JSX.Element {\n const ResultComponent: React.ComponentType<ResultItemBaseProps> = options.result || StandardResult;\n const ListComponent: React.ComponentType<ResultsListProps> = options.list || ResultsList;\n const LoaderComponent: React.ComponentType<LoaderProps> = options.loader || CludoLoader;\n const PaginationComponent = options.pagination || Pagination;\n\n return () => {\n // Use custom hook to derive state and access relevant events\n const [ searchResultsState, searchResultsDispatchers ] = useSearchResults();\n\n const suggestion: string = searchResultsState.suggestions[0] ? searchResultsState.suggestions[0] : '';\n\n return (\n <>\n {/* Render header elements */}\n <ResultsSummary {...searchResultsState.resultsSummary} suggestedQuery={suggestion} />\n\n {/* Render banners */}\n <BannerGroup />\n \n <ListComponent template={(result) => <ResultComponent result={result} />} />\n\n <LoaderComponent isLoading={searchResultsState.isLoading} />\n\n <PaginationComponent />\n\n <LoadMoreResults />\n </>\n );\n }\n}","import React, { useContext, useEffect } from \"react\";\nimport { ResultLink } from \"../../elements/result-link\";\nimport { AutocompleteItemType, AutocompleteResult, ThemeBaseProps } from \"../../types/types\";\nimport { HighlightedText } from \"../../elements/cludo-highlighted-text\";\nimport { EventControllerContext } from \"../../../context\";\nimport { generateThemeCss } from \"../../../utils/theme-provider\";\n\nexport interface SaytResultProps extends ThemeBaseProps {\n result: AutocompleteResult;\n isSelected: boolean;\n resultIndex: number;\n resultType?: AutocompleteItemType.Result | AutocompleteItemType.CategorizedResult;\n children?: React.ReactNode;\n}\n\nexport function SaytResult(props: SaytResultProps) {\n const eventController = useContext(EventControllerContext);\n const id = `cludo-result-item-${props.resultIndex}`;\n const suggestionCSS = generateThemeCss(`cludo-p-2 cludo-font-family-default cludo-border-b-1-neutral cludo-border-b-solid cludo-border-radius-button cludo-cursor-pointer cludo-bg-hover-gray-light ${props.isSelected ? 'cludo-bg-color-gray-light' : 'cludo-bg-color-white'}`,\n props.disableTheme, props.className) + (props.isSelected ? ' active' : '');\n const resultChildren = props.children ?? <HighlightedText chunkedText={props.result.chunkedTitle} wrapDefaultText></HighlightedText>;\n const itemType = props.resultType || AutocompleteItemType.Result\n\n useEffect(()=> {\n if (props.isSelected) {\n eventController.setActiveDescendantToSuggestions(id);\n }\n }, [props.isSelected])\n\n return (\n <li\n id={id}\n tabIndex={0}\n aria-selected={props.isSelected ? 'true' : undefined}\n role=\"option\"\n className={suggestionCSS}\n data-cludo-autocomplete={itemType}\n data-cludo-autocomplete-index={props.resultIndex}\n {...props.attributes?.root}\n onClick={() => eventController.selectResult(props.result.document)}\n >\n <ResultLink result={props.result.document}>\n { resultChildren }\n </ResultLink>\n </li>\n )\n}","import React, { useContext, useEffect } from \"react\";\nimport { HighlightedText } from \"../../elements/cludo-highlighted-text\";\nimport { AutocompleteItemType, AutocompleteSuggestion, ThemeBaseProps } from \"../../types/types\";\nimport { EventControllerContext } from \"../../../context\";\nimport { generateThemeCss } from \"../../../utils/theme-provider\";\n\nexport interface SaytSuggestionProps extends ThemeBaseProps {\n suggestion: AutocompleteSuggestion;\n isSelected: boolean;\n suggestionIndex: number;\n}\n\nexport function SaytSuggestion(props: SaytSuggestionProps) {\n const eventController = useContext(EventControllerContext);\n const id = `cludo-suggestion-item-${props.suggestionIndex}`;\n const suggestionCSS = generateThemeCss(`cludo-p-2 cludo-font-family-default cludo-border-b-1-neutral cludo-border-b-solid cludo-border-radius-button cludo-cursor-pointer cludo-bg-hover-gray-light ${props.isSelected ? 'cludo-bg-color-gray-light' : 'cludo-bg-color-white'}`,\n props.disableTheme, props.className) + (props.isSelected ? ' active' : '')\n \n useEffect(() => {\n if (props.isSelected) {\n eventController.setActiveDescendantToSuggestions(id)\n }\n }, [props.isSelected])\n\n return (\n <li\n id={id}\n tabIndex={0}\n aria-selected={props.isSelected ? 'true' : undefined}\n role=\"option\"\n className={suggestionCSS}\n data-cludo-autocomplete={AutocompleteItemType.Suggestion}\n data-cludo-autocomplete-index={props.suggestionIndex}\n {...props.attributes?.root}\n onClick={() =>eventController.selectSuggestion(props.suggestion.title, props.suggestionIndex)}\n >\n <HighlightedText chunkedText={props.suggestion.chunkedTitle} wrapDefaultText></HighlightedText>\n </li>\n )\n}","import React, { useContext, useEffect } from \"react\";\nimport { HighlightedText } from \"../../elements/cludo-highlighted-text\";\nimport { AutocompleteItemType, AutocompleteSuggestion, ThemeBaseProps } from \"../../types/types\";\nimport { EventControllerContext } from \"../../../context\";\nimport { generateThemeCss } from \"../../../utils/theme-provider\";\n\nexport interface SaytRecentSearchProps extends ThemeBaseProps {\n recentSearch: AutocompleteSuggestion;\n isSelected: boolean;\n recentSearchIndex: number;\n}\n\nexport function SaytRecentSearch(props: SaytRecentSearchProps) {\n const eventController = useContext(EventControllerContext);\n const id = `cludo-recent-search-item-${props.recentSearchIndex}`;\n const suggestionCSS = generateThemeCss(`cludo-p-2 cludo-font-family-default cludo-border-b-1-neutral cludo-border-b-solid cludo-border-radius-button cludo-cursor-pointer cludo-bg-hover-gray-light ${props.isSelected ? 'cludo-bg-color-gray-light' : 'cludo-bg-color-white'}`,\n props.disableTheme, props.className) + (props.isSelected ? ' active' : '')\n\n useEffect(() => {\n if (props.isSelected) {\n eventController.setActiveDescendantToSuggestions(id);\n }\n }, [props.isSelected])\n\n return (\n <li\n id={id}\n tabIndex={0}\n aria-selected={props.isSelected ? 'true' : undefined}\n role=\"option\"\n className={suggestionCSS}\n data-cludo-autocomplete={AutocompleteItemType.RecentSearch}\n data-cludo-autocomplete-index={props.recentSearchIndex}\n {...props.attributes?.root}\n onClick={() =>eventController.selectSuggestion(props.recentSearch.title, props.recentSearchIndex)}\n >\n <HighlightedText chunkedText={props.recentSearch.chunkedTitle} wrapDefaultText></HighlightedText>\n </li>\n )\n}","// Utility function to check if code is being executed on the client\n// Used to guard against accessing window or document when using SSR.\nexport function isOnClient(): boolean {\n return !(typeof window === 'undefined' || typeof document === 'undefined');\n}","import { useRef, useState, useEffect } from \"react\";\nimport { useCludoContext } from \"./use-cludo-context\";\nimport { AutocompleteResult, AutocompleteSuggestion, AutocompleteTopHit } from \"../components/types/types\";\nimport { getAutocompleteResultsFromTopHits, isAutocompleteItem } from \"../utils/result-utils\";\nimport { TopHit } from \"../types/core-script-types\";\nimport { isOnClient } from \"../utils/render-utils\";\n\nexport interface AutocompleteState {\n suggestions: AutocompleteSuggestion[];\n instantSuggestions: AutocompleteSuggestion[];\n results: AutocompleteResult[];\n recentSearches: AutocompleteSuggestion[];\n categorizedResults: AutocompleteTopHit[];\n selectedSuggestion: number;\n selectedResult: number;\n selectedRecentSearch: number;\n suggestionsTitle: string;\n resultsTitle: string;\n recentSearchesTitle: string;\n}\n\nexport interface AutocompleteDispatchers {\n /** Performs a request to retrieve autocomplete results for the given query */\n initiateAutocompleteRequest: (query: string) => void;\n /** Takes a keyboard input event and selects the next available autocomplete item */\n autocompleteSelectionNext: () => void;\n /** Takes a keyboard input event and selects the previous available autocomplete item */\n autocompleteSelectionPrev: () => void;\n /** Takes the currently active autocomplete item and performs a search (or clicks, if the item is a search result) */\n autocompleteSelect: (e?: React.KeyboardEvent<HTMLInputElement>) => void;\n /** Clears out stored autocomplete data */\n clear: () => void;\n}\n\n/** Expose state and handle mouse/keyboard input listening for an autocomplete component \n * @returns cludoState (all relevant autocomplete state properties) and cludoDispatchers (ability to kick off autocomplete requests by query)\n*/\nexport function useAutocomplete(): [AutocompleteState, AutocompleteDispatchers] {\n const { context, eventController } = useCludoContext();\n\n // Keep track of list index\n const selectedIndex = useRef(-1);\n\n // Autocomplete keyboard event handling -- get all autocomplete elements using data attributes\n const keydownListener = (key: string) => {\n if (!isOnClient()) return;\n const suggestions = context.storedAutocompleteResponse?.data.suggestions || [];\n const instantSuggestions = context.storedAutocompleteResponse?.data.instantSuggestions || [];\n const results = context.storedAutocompleteResponse?.data.results || [];\n const recentSearches = context.storedAutocompleteResponse?.data.recentSearches || [];\n const categorizedResults = getAutocompleteResultsFromTopHits(context.storedAutocompleteResponse?.data.categorizedResults || []);\n const listItems = document.querySelectorAll<HTMLLIElement>('[data-cludo-autocomplete]');\n let tempSelectedSuggestion, tempSelectedResult, tempSelectedRecentSearch;\n tempSelectedSuggestion = tempSelectedResult = tempSelectedRecentSearch = -1;\n let tempIndex = selectedIndex.current;\n const numSuggestions = listItems.length;\n // Handle search via enter key\n if (key === 'Enter' && tempIndex === -1) {\n eventController.search();\n } else if (listItems && listItems.length > 0) {\n if (key === 'ArrowKeyUp') {\n tempIndex = (tempIndex === -1) ? 0 : tempIndex;\n tempIndex = ((((tempIndex - 1) % numSuggestions) + numSuggestions) % numSuggestions);\n }\n if (key === 'ArrowKeyDown') {\n tempIndex = ((((tempIndex + 1) % numSuggestions) + numSuggestions) % numSuggestions);\n }\n // Update selectedIndex for sublists\n if (listItems[tempIndex]) {\n switch (listItems[tempIndex].getAttribute('data-cludo-autocomplete')) {\n case 'suggestion':\n tempSelectedSuggestion = parseInt(listItems[tempIndex].getAttribute('data-cludo-autocomplete-index') as string);\n const suggestion = suggestions[tempSelectedSuggestion] ?? instantSuggestions[tempSelectedSuggestion];\n if (key === 'Enter') {\n eventController.selectSuggestion(suggestion.title, tempSelectedSuggestion);\n }\n break;\n case 'result':\n tempSelectedResult = parseInt(listItems[tempIndex].getAttribute('data-cludo-autocomplete-index') as string);\n const result = results[tempSelectedResult];\n if (key === 'Enter') {\n eventController.selectResult(result.document);\n }\n break;\n case 'categorized-result':\n tempSelectedResult = parseInt(listItems[tempIndex].getAttribute('data-cludo-autocomplete-index') as string);\n const categorizedResult = categorizedResults[tempSelectedResult];\n if (key === 'Enter') {\n eventController.selectResult(categorizedResult.document);\n }\n break;\n case 'recent-search':\n tempSelectedRecentSearch = parseInt(listItems[tempIndex].getAttribute('data-cludo-autocomplete-index') as string);\n const recentSearch = recentSearches[tempSelectedRecentSearch];\n if (key === 'Enter') {\n eventController.selectRecentSearch(recentSearch.title, tempSelectedRecentSearch);\n }\n break;\n }\n }\n }\n selectedIndex.current = tempIndex;\n const newState: AutocompleteState = {\n ...deriveAutocompleteState(),\n selectedSuggestion: tempSelectedSuggestion,\n selectedResult: tempSelectedResult,\n selectedRecentSearch: tempSelectedRecentSearch\n }\n setAutocompleteState(newState)\n }\n\n const clearSelectedIndices = () => {\n selectedIndex.current = -1;\n const newState: AutocompleteState = {\n ...deriveAutocompleteState(),\n suggestions: context.storedAutocompleteResponse?.data.suggestions || [],\n results: context.storedAutocompleteResponse?.data.results || [],\n selectedSuggestion: -1,\n selectedResult: -1,\n selectedRecentSearch: -1\n }\n setAutocompleteState(newState)\n }\n\n // Attach keyboard event handlers \n useEffect(() => {\n const eventControllerIsDefined = Object.keys(eventController).length > 0;\n const keyboardNextSubscription = eventControllerIsDefined ? eventController.subscribe('autocompleteSelectionNext', () => { keydownListener('ArrowKeyDown')}) : -1;\n const keyboardPrevSubscription = eventControllerIsDefined ? eventController.subscribe('autocompleteSelectionPrev', () => { keydownListener('ArrowKeyUp')}) : -1;\n const keyboardEnterSubscription = eventControllerIsDefined ? eventController.subscribe('autocompleteSetSelection', () => { keydownListener('Enter')}) : -1;\n const autocompleteCompleteSubscription = eventControllerIsDefined ? eventController.subscribe('afterautocomplete', () => { clearSelectedIndices() }) : -1;\n\n return () => {\n if (eventControllerIsDefined) {\n eventController.unsubscribe(keyboardNextSubscription);\n eventController.unsubscribe(keyboardPrevSubscription);\n eventController.unsubscribe(keyboardEnterSubscription);\n eventController.unsubscribe(autocompleteCompleteSubscription);\n }\n }\n });\n\n // Initial autocomplete state\n const [autocompleteState, setAutocompleteState] = useState<AutocompleteState>({\n suggestions: [],\n instantSuggestions: context.storedAutocompleteResponse?.data.instantSuggestions || [],\n results: [],\n recentSearches: context.storedAutocompleteResponse?.data.recentSearches || [],\n categorizedResults: [],\n selectedSuggestion: -1,\n selectedResult: -1,\n selectedRecentSearch: -1,\n suggestionsTitle: context.translateProvider?.translate('template_suggestions') || '' || '',\n resultsTitle: context.translateProvider?.translate('template_search_results') || '',\n recentSearchesTitle: context.translateProvider?.translate('recent_searches_title') || ''\n });\n\n const initiateAutocompleteRequest = (query: string) => {\n return eventController.initiateAutocompleteRequest(query);\n }\n\n const autocompleteSelectionNext = () => {\n eventController.emitEvent('autocompleteSelectionNext', {});\n }\n\n const autocompleteSelectionPrev = () => {\n eventController.emitEvent('autocompleteSelectionPrev', {});\n }\n\n const clear = () => {\n eventController.clearAutocomplete();\n }\n\n const autocompleteSelect = (e?: React.KeyboardEvent<HTMLInputElement>) => {\n if (autocompleteState.selectedSuggestion !== -1) {\n e && e.preventDefault();\n const suggestion = autocompleteState.suggestions[autocompleteState.selectedSuggestion] ?? autocompleteState.instantSuggestions[autocompleteState.selectedSuggestion];\n if (suggestion) {\n eventController.selectSuggestion(suggestion.title, autocompleteState.selectedSuggestion);\n }\n }\n if (autocompleteState.selectedResult !== -1) {\n e && e.preventDefault();\n const result = autocompleteState.results[autocompleteState.selectedResult];\n if (result) {\n eventController.selectResult(result.document);\n }\n }\n if (autocompleteState.selectedRecentSearch !== -1) {\n e && e.preventDefault();\n const recentSearch = autocompleteState.recentSearches[autocompleteState.selectedRecentSearch];\n if (recentSearch) {\n eventController.selectRecentSearch(recentSearch.title, autocompleteState.selectedRecentSearch);\n }\n }\n }\n \n\n const autocompleteDispatchers: AutocompleteDispatchers = {\n initiateAutocompleteRequest,\n autocompleteSelectionNext,\n autocompleteSelectionPrev,\n autocompleteSelect,\n clear\n }\n\n const deriveAutocompleteState: () => AutocompleteState = () => {\n const newState: AutocompleteState = {\n ...autocompleteState,\n suggestions: context.storedAutocompleteResponse?.data.suggestions || [],\n instantSuggestions: context.storedAutocompleteResponse?.data.instantSuggestions || [],\n results: context.storedAutocompleteResponse?.data.results || [],\n recentSearches: context.storedAutocompleteResponse?.data.recentSearches || [],\n categorizedResults: context.storedAutocompleteResponse?.data.categorizedResults || [],\n suggestionsTitle: context.translateProvider?.translate('template_suggestions') || '' || '',\n resultsTitle: context.translateProvider?.translate('template_search_results') || '',\n recentSearchesTitle: context.translateProvider?.translate('recent_searches_title') || ''\n }\n\n return newState;\n }\n\n return [ autocompleteState, autocompleteDispatchers ];\n}\n\n/** Handle navigating and selecting autocomplete suggestions from a search input */\nexport const autocompleteHandleInputKeyDown = (e: React.KeyboardEvent<HTMLInputElement>, autocompleteDispatchers: AutocompleteDispatchers) => {\n switch (e.key) {\n case 'ArrowDown':\n e.preventDefault();\n autocompleteDispatchers.autocompleteSelectionNext();\n break;\n case 'ArrowUp':\n e.preventDefault();\n autocompleteDispatchers.autocompleteSelectionPrev();\n break;\n case 'Enter':\n autocompleteDispatchers.autocompleteSelect(e);\n break;\n }\n}\n\n/** Handle clearing autocomplete state when the input loses focus */\nexport const autocompleteHandleInputBlur = (e: React.FocusEvent<HTMLInputElement>, autocompleteDispatchers: AutocompleteDispatchers) => {\n if (!isAutocompleteItem(e.relatedTarget)) {\n autocompleteDispatchers.clear();\n }\n}\n\n/** Handle initiating an autocomplete request when the input changes */\nexport const autocompleteHandleInputChange = (e: React.ChangeEvent<HTMLInputElement>, autocompleteDispatchers: AutocompleteDispatchers) => {\n autocompleteDispatchers.initiateAutocompleteRequest(e.target.value);\n}","import React from \"react\";\nimport { AutocompleteResult, AutocompleteSuggestion } from \"../types/types\";\nimport { SaytResult } from \"./items/sayt-result\";\nimport { SaytSuggestion } from \"./items/sayt-suggestion\";\nimport { SaytRecentSearch } from \"./items/sayt-recent-search\";\nimport { useAutocomplete } from \"../../hooks/use-autocomplete\";\n\n\nexport function CludoSearchAutocomplete() {\n const [autocompleteState] = useAutocomplete();\n const {\n suggestions,\n results,\n recentSearches,\n selectedSuggestion,\n selectedResult,\n selectedRecentSearch,\n suggestionsTitle,\n resultsTitle,\n recentSearchesTitle\n } = autocompleteState;\n\n return (\n <>\n { suggestions.length ? \n <>\n <h3>{ suggestionsTitle }</h3>\n <div className=\"section-divider\"></div>\n <ul className=\"cludo-search-autocomplete-suggestions\">\n {suggestions.map((suggestion: AutocompleteSuggestion, i: number) => {\n const isSelected = (i === selectedSuggestion);\n return <SaytSuggestion key={i} suggestion={suggestion} isSelected={isSelected} suggestionIndex={i} />\n })}\n </ul>\n </> :\n null\n }\n { results.length ?\n <>\n <h3>{ resultsTitle }</h3>\n <ul className=\"cludo-search-autocomplete-results\">\n {results.map((result: AutocompleteResult, i: number) => {\n const isSelected = (i === selectedResult);\n return <SaytResult key={i} result={result} isSelected={isSelected} resultIndex={i} />\n })}\n </ul>\n </> :\n null\n }\n { recentSearches.length ? \n <>\n <h3>{ recentSearchesTitle }</h3>\n <div className=\"section-divider\"></div>\n <ul className=\"cludo-search-autocomplete-recent-searches\">\n {recentSearches.map((recentSearch: AutocompleteSuggestion, i: number) => {\n const isSelected = (i === selectedRecentSearch);\n return <SaytRecentSearch key={i} recentSearch={recentSearch} isSelected={isSelected} recentSearchIndex={i}/>\n })}\n </ul>\n </> :\n null\n }\n </>\n );\n\n}","import { CludoFeature, InstantSuggestionsConfiguration } from \"@cludosearch/cludo-api-client/dist/interfaces/api/public-settings.interface\";\nimport { Facets, Facet, FacetValue, TypedDocument } from \"@cludosearch/cludo-api-client/dist/interfaces/api/search.interface\";\nimport { AutocompleteResult, AutocompleteSuggestion, AutocompleteTopHit, CludoAutocompleteBaseProps, CludoSearchResultsBaseProps, FormattedTextChunk } from \"../components/types/types\";\nimport { EndlessScrollOptions, SortOption } from \"./models/instantiator-types\";\nimport { getFieldValue, getTopHitTotalCount } from \"./result-utils\";\nimport { CludoSearch, SearchRequestParams, SortOrder, FacetMapRequest, CludoErrorState, CludoAutocompleteState, FilterMap, TopHit, TopHitValue } from \"../types/core-script-types\";\nimport { TranslateProvider } from \"../types/translation-types\";\n\n// just an idea for now -- potentially useful for simplifying access to features\n // TO-DO -- better name for ExternalFacet?\nexport interface ExternalFacet {\n allCount: number;\n hasSelection: boolean;\n key: string;\n missingCount?: number;\n values: FacetItem[];\n selectedValues: string[];\n}\n\nexport interface FacetItem {\n facetName: string;\n value: string;\n isSelected: boolean;\n count?: number;\n}\n\nexport interface TemplateState {\n focusIndex?: number;\n}\n\n/**\n * This object is meant to provide access to the CludoSearch object properties, but modified such that:\n * - Only the properties that we intend to be public are accessible\n * - Properties that are poorly named have been renamed for clarity\n * - Properties that are not well-organized or well-structured have been transformed for ease of use\n */\nexport class CludoSearchContext {\n private _cludoSearch: CludoSearch;\n private _templateState: TemplateState;\n\n constructor(cludoSearch: CludoSearch) {\n this._cludoSearch = cludoSearch;\n this._templateState = {};\n }\n\n // Internal template state\n\n public get focusIndex(): number | undefined {\n return this._templateState.focusIndex;\n }\n\n public set focusIndex(index: number | undefined) {\n this._templateState.focusIndex = index;\n }\n\n // Cludo instance state\n\n private get params(): SearchRequestParams {\n return this._cludoSearch.params;\n }\n\n public get customerId(): number {\n return this._cludoSearch.customerId;\n }\n\n public get engineId(): number {\n return this._cludoSearch.engineId;\n }\n\n public get query(): string {\n return this._cludoSearch.params.query;\n }\n\n public set query(query: string) {\n this._cludoSearch.params.query = query;\n }\n\n public get currentPage(): number {\n return this._cludoSearch.params.page;\n }\n\n public get resultsPerPage(): number {\n return this._cludoSearch.params.perPage;\n }\n\n public get sort(): SortOrder {\n return this._cludoSearch.params.sort;\n }\n\n public get sortItems(): SortOption[] {\n // default to empty array if not found\n return this._cludoSearch.clientTemplateSortOptions || [];\n }\n\n // FUTURE -- consider defining experience keys here (or potentially leave them up to the experience scripts)\n public get experienceConfigs(): { [key: string]: any } {\n return this._cludoSearch.websiteSettings.configurations;\n }\n\n public get translateProvider(): TranslateProvider {\n return this._cludoSearch.translateProvider;\n }\n\n public isFacetSelected(key: string, value: string): boolean {\n return (this.params.facets[key] && this.params.facets[key].indexOf(value) !== -1);\n }\n\n public isFilterSelected(key: string, value: string): boolean {\n return (this.params.filters[key] && this.params.filters[key].indexOf(value) !== -1);\n }\n\n private getSelectedMapItem<T extends FilterMap | FacetMapRequest>(arrayToCheck: T): T {\n const selected: T = {} as T;\n\n for(var item in arrayToCheck) {\n if (arrayToCheck[item].length) {\n selected[item] = arrayToCheck[item];\n }\n }\n \n return selected;\n }\n\n public get selectedFacets(){ return this.getSelectedMapItem(this.params.facets) };\n\n public get selectedFilters(){ return this.getSelectedMapItem(this.params.filters) };\n\n public get facets(): ExternalFacet[] {\n let facetsInResponse: Facets = this.storedSearchResponseData.cludoSearchResponse.Facets;\n let facetsToRender = Object.keys(this._cludoSearch.facets);\n\n return Object.entries(facetsInResponse)\n .filter(([key, _]) => facetsToRender.includes(key)) \n .map(\n (facetMapItem: [string, Facet]) => {\n const facetKey: string = facetMapItem[0];\n const facetObj: Facet = facetMapItem[1];\n\n const facet: ExternalFacet = {\n key: facetKey,\n hasSelection: this.params.facets[facetKey] ? this.params.facets[facetKey].length > 0 : false,\n values: facetObj.Items.map((facetValue: FacetValue) => {\n return {\n facetName: facetKey,\n count: facetValue.Count,\n value: facetValue.Key,\n isSelected: this.isFacetSelected(facetKey, facetValue.Key)\n }\n }),\n selectedValues: this.params.facets[facetKey] ?? [],\n allCount: facetObj.AllCount,\n missingCount: facetObj.MissingCount\n };\n\n // Here we address an edge case where a facet is selected, then a search is made that\n // returns 0 results. We need to add the selected facet as an option to indicate in the\n // UI that it is selected.\n const facetValues = new Set(facet.values.map(item => item.value));\n const selectedValuesNotInResponse = facet.selectedValues.filter(str => !facetValues.has(str));\n selectedValuesNotInResponse.forEach(value => {\n const newValue: FacetItem = {\n facetName: facetKey,\n count: 0,\n value: value,\n isSelected: true\n }\n facet.values.push(newValue);\n });\n\n return facet;\n }\n )\n }\n\n public get isLoadingResults(): boolean {\n return this._cludoSearch.isLoadingResults;\n }\n\n public get enabledFeatures(): CludoFeature[] {\n return this._cludoSearch.enabledFeatures;\n }\n\n public isFeatureEnabled(featureKey: CludoFeature): boolean {\n return this._cludoSearch.enabledFeatures.includes(featureKey);\n }\n\n public get endlessScroll(): EndlessScrollOptions | null {\n return this._cludoSearch.endlessScroll || null;\n }\n\n public set endlessScroll(options: EndlessScrollOptions) {\n this._cludoSearch.endlessScroll = options;\n }\n\n public get isEndlessScrollEnabled(): boolean {\n return this._cludoSearch.endlessScroll\n ? true\n : false;\n }\n\n public get isAutocompleteEnabled(): boolean {\n return this._cludoSearch.richAutocomplete;\n }\n\n public get paramsPrefix(): string {\n return this._cludoSearch.paramsPrefix;\n }\n\n public set linkFragment(fragmentText: string) {\n this._cludoSearch.linkFragment = fragmentText;\n }\n\n public get storedSearchResponseData(): CludoSearchResultsBaseProps {\n return { \n cludoSearchResponse: {\n ...this._cludoSearch.storedSearchResponseData,\n TopHits: this._cludoSearch.storedSearchResponseData.TopHits.map(hit => {\n return getTopHitTotalCount(hit, this._cludoSearch.storedSearchResponseData.Facets);\n }\n )\n }\n };\n }\n\n public get focusOnResultsAfterSearch(): boolean {\n return this._cludoSearch.focusOnResultsAfterSearch;\n }\n\n public get customEngineSettings(): {\n [featureConfigKey: string]: object,\n } {\n let customEngineSettings: {\n [featureConfigKey: string]: object\n } = {};\n\n try {\n customEngineSettings = JSON.parse(this._cludoSearch.websiteSettings.customEngineSettings) ?? customEngineSettings; \n } catch (error) {\n // TODO consider logging this error\n }\n\n if (!this._cludoSearch.websiteSettings.configurations) {\n return customEngineSettings;\n }\n\n // add feature keys from configuration\n const featureConfigKeys = Object.keys(this._cludoSearch.websiteSettings.configurations);\n\n featureConfigKeys.forEach((featureConfigKey: string) => {\n customEngineSettings[featureConfigKey] = this._cludoSearch.websiteSettings.configurations[featureConfigKey];\n });\n\n return customEngineSettings;\n }\n\n public get instantSuggestionsConfiguration(): InstantSuggestionsConfiguration | undefined {\n return this._cludoSearch.websiteSettings.instantSuggestionsConfiguration;\n }\n\n public get recentSearches(): string[] {\n return this._cludoSearch.recentSearches;\n }\n\n public get storedError(): CludoErrorState {\n return this._cludoSearch.storedError;\n }\n /**\n * Given a source string, and a search string, returns an array of\n * FormattedTextChunk objects marked as either \"default\" (no special handling\n * should be applied), or \"highlight\" (the first segment of the source string that matches\n * the search string, which can be formatted in a way to bring attention to the match)\n * @param input \n * @param needle \n * @returns \n */\n private chunkString(input: string, needle: string): FormattedTextChunk[] {\n const needleIndex: number = input.toLowerCase().indexOf(needle.toLowerCase());\n\n if (needleIndex === -1) {\n return [{\n text: input,\n displayType: 'default'\n }]\n }\n\n return [\n {\n text: input.substring(0, needleIndex),\n displayType: 'default'\n },\n {\n text: input.substring(needleIndex, needleIndex + needle.length),\n displayType: 'highlight'\n },\n {\n text: input.substring(needleIndex + needle.length),\n displayType: 'default'\n }\n ];\n }\n\n private mapTypedDocumentToResult(document: TypedDocument, query: string): AutocompleteResult {\n const title: string = getFieldValue(document, 'Title') ?? '';\n\n return {\n title: title,\n chunkedTitle: this.chunkString(title, query),\n document: document\n };\n }\n \n private mapTypedDocumentToSuggestion(document: TypedDocument, query: string): AutocompleteSuggestion {\n const title: string = getFieldValue(document, 'Title') ?? '';\n\n return {\n title: title,\n chunkedTitle: this.chunkString(title, query)\n };\n }\n\n private mapStringToSuggestion(str: string): AutocompleteSuggestion {\n return {\n title: str,\n chunkedTitle: this.chunkString(str, '')\n }\n }\n\n private mapTopHitsToCategorizedResults(hit: TopHit, query: string): AutocompleteTopHit {\n return {\n Field: hit.Field,\n Values: hit.Values.map(value => this.mapHitValuesToResults(value, query))\n }\n }\n\n private mapHitValuesToResults(value: TopHitValue, query: string) {\n return {\n Value: value.Value,\n Hits: value.Hits.map(document => {\n return this.mapTypedDocumentToResult(document, query);\n })\n }\n }\n\n public get storedAutocompleteResponse(): CludoAutocompleteBaseProps {\n const coreAutocompleteData: CludoAutocompleteState = this._cludoSearch.storedAutocompleteResponse;\n\n return {\n data: {\n query: coreAutocompleteData.cludoAutocompleteResponse.query,\n facets: coreAutocompleteData.cludoAutocompleteResponse.facets,\n totalResults: coreAutocompleteData.cludoAutocompleteResponse.totalResults,\n totalSuggestions: coreAutocompleteData.cludoAutocompleteResponse.totalSuggestions,\n totalRecentSearches: coreAutocompleteData.cludoAutocompleteResponse.totalRecentSearches,\n results: coreAutocompleteData.cludoAutocompleteResponse.results\n ?.map((document: TypedDocument) => this.mapTypedDocumentToResult(document, coreAutocompleteData.cludoAutocompleteResponse.query)),\n suggestions: coreAutocompleteData.cludoAutocompleteResponse.suggestions\n ?.map((document: TypedDocument) => this.mapTypedDocumentToSuggestion(document, coreAutocompleteData.cludoAutocompleteResponse.query)),\n instantSuggestions: coreAutocompleteData.cludoAutocompleteResponse.instantSuggestions\n ?.map((document: TypedDocument) => this.mapTypedDocumentToSuggestion(document, coreAutocompleteData.cludoAutocompleteResponse.query)),\n recentSearches: coreAutocompleteData.cludoAutocompleteResponse.recentSearches\n ?.map((search: string) => this.mapStringToSuggestion(search)),\n categorizedResults: coreAutocompleteData.cludoAutocompleteResponse.topHits\n ?.map((hit: TopHit) => {\n const mappedHit = this.mapTopHitsToCategorizedResults(hit, coreAutocompleteData.cludoAutocompleteResponse.query);\n const hitWithCount = getTopHitTotalCount(mappedHit, coreAutocompleteData.cludoAutocompleteResponse.facets);\n return hitWithCount;\n })\n },\n isLoading: coreAutocompleteData.isLoading\n }\n }\n\n public get isTrackedSession(): boolean {\n return this._cludoSearch.isTrackedSession !== 0;\n }\n\n public set canUserBeTracked(canUserBeTracked: () => boolean) {\n this._cludoSearch.canUserBeTracked = canUserBeTracked;\n }\n\n public get queryId(): string {\n return this._cludoSearch.queryId;\n }\n\n public get sessionId(): string {\n return this._cludoSearch.getSessionId();\n }\n\n public get querySessionId(): string {\n return this._cludoSearch.querySessionId;\n }\n\n public get deviceType(): string {\n return this._cludoSearch.deviceType;\n }\n\n public get traits(): string[] {\n const traits = this._cludoSearch.getTraitsFromStorage();\n return traits ? traits : [];\n }\n}","const __WEBPACK_NAMESPACE_OBJECT__ = require(\"react-dom\");","import React from \"react\";\nimport ReactDOM from \"react-dom\";\nimport { CludoSearchContext } from \"./cludo-search-context\";\nimport { CludoContext, EventControllerContext } from \"../context\";\nimport { EventController } from \"./event-controller\";\nimport { CludoSearch } from \"../types/core-script-types\";\nimport { ThemeProvider } from \"./theme-provider\";\nimport { isOnClient } from \"./render-utils\";\n\ninterface ManagedComponent {\n component: React.ComponentType;\n elem: HTMLElement | null;\n elemSelector?: string;\n observedEventTypes: EventType[];\n hasRendered: boolean;\n}\n\nexport type EventType = 'beforesearch'\n| 'aftersearch'\n| 'beforeredirect'\n| 'afterautocomplete'\n| 'autocompleteSelectionNext'\n| 'autocompleteSelectionPrev'\n| 'autocompleteSetSelection'\n| 'afterinputfocus'\n| 'afterpageload'\n| 'error';\n\nexport enum TemplateType {\n Results = 'results',\n Autocomplete = 'autocomplete',\n Controls = 'controls',\n Loader = 'loader',\n Custom = 'custom'\n}\n\n/**\n * This object provides a way to manage tracked components; it exposes\n * - methods for registering standard components (registerSearchResultsTemplate, registerFacetsTemplate, etc.)\n * - a method for registering generic components (registerTemplate)\n * - an interface to notify the components that an event has occurred in the core script, and allow them to handle events\n */\nexport class ComponentsController {\n private managedComponents: ManagedComponent[] = [];\n private _searchContext: CludoSearchContext;\n private _cssTheme: string | undefined;\n public events: EventController;\n\n constructor(\n cludoSearch: CludoSearch,\n searchContext: CludoSearchContext,\n cssTheme?: string\n ) {\n this._searchContext = searchContext;\n this.events = new EventController(cludoSearch, searchContext);\n this._cssTheme = cssTheme;\n }\n\n /**\n * Register a search results component; will be updated on search events\n * @param component\n * @param element HTMLElement reference or CSS selector\n */\n public registerSearchResultsComponent(\n component: React.ComponentType,\n element: HTMLElement | string): void {\n this.addManagedComponent(\n component,\n element,\n ['beforesearch', 'aftersearch']\n );\n }\n\n /**\n * Register a controls template; will be updated on search events\n * \n * Controls, by default, contains facets and sort-picker components\n * @param component\n * @param element HTMLElement reference or CSS selector\n */\n public registerControlsComponent(\n component: React.ComponentType,\n element: HTMLElement | string): void {\n this.addManagedComponent(\n component,\n element,\n ['beforesearch', 'aftersearch']\n );\n }\n\n /**\n * Register an autocomplete template; will be updated on afterautocomplete events\n * @param component\n * @param element HTMLElement reference or CSS selector\n */\n public registerAutocompleteComponent(\n component: React.ComponentType,\n element: HTMLElement | string): void {\n this.addManagedComponent(\n component,\n element,\n ['afterautocomplete', 'afterinputfocus']\n );\n }\n\n /**\n * \n * @param component\n * @param element HTMLElement reference or CSS selector\n * @param observedEventTypes The list of event types that trigger an update of props; if not specified, \n * all events are treated as relevant\n */\n public registerComponent(\n component: React.ComponentType,\n element: HTMLElement | string,\n observedEventTypes: EventType[] = [],\n renderImmediately = true\n ): void {\n this.addManagedComponent(\n component,\n element,\n observedEventTypes,\n renderImmediately\n );\n }\n\n /**\n * Adds a managed component to the array stored in the managedComponents property\n * @param component\n * @param element\n * @param elemSelector\n * @param observedEventTypes \n */\n private addManagedComponent(\n component: React.ComponentType,\n element: HTMLElement | string,\n observedEventTypes: EventType[] = [],\n renderImmediately: boolean = false\n ): void {\n if (!isOnClient()) return;\n const resolvedElement: HTMLElement | null =\n (typeof element === 'string')\n ? document.querySelector(element)\n : element;\n\n const resolvedSelector: string | undefined =\n (typeof element === 'string')\n ? element\n : undefined;\n\n const managedComponent: ManagedComponent = {\n component: component,\n elem: resolvedElement,\n elemSelector: resolvedSelector,\n observedEventTypes: observedEventTypes,\n hasRendered: false\n } \n\n this.managedComponents.push(managedComponent);\n\n if (renderImmediately) {\n this.renderComponent(managedComponent);\n }\n }\n\n /**\n * Processes an event from the core script\n * \n * - Emits the event to any subscribing components\n * \n * @param type\n * @param data \n * @param callbackFnc \n */\n public processEvent(type: EventType, data?: any, callbackFnc?: () => void): void {\n this.events.emitEvent(type, data);\n\n this.managedComponents\n .filter((component: ManagedComponent) => component.observedEventTypes.length === 0 || component.observedEventTypes.includes(type))\n .forEach((component: ManagedComponent) => this.renderComponent(component));\n\n if (callbackFnc) {\n callbackFnc();\n }\n }\n\n /**\n * Renders a managed component\n * @param component\n */\n private renderComponent(component: ManagedComponent): void {\n const RenderedComponent = component.component;\n\n // Removing this for now - investigate bug it creates for addWidget() components\n // if (component.hasRendered) {\n // return;\n // }\n\n // try to grab a reference to the element if it wasn't found on mount\n if (!component.elem && isOnClient()) {\n component.elem = document.querySelector(component.elemSelector!);\n }\n\n // if element still found, skip -- React would throw an error\n if (!component.elem) { return; }\n\n component.hasRendered = true;\n \n ReactDOM.render(\n <React.StrictMode>\n <CludoContext.Provider value={this._searchContext}>\n <EventControllerContext.Provider value={this.events}>\n <ThemeProvider theme={this._cssTheme}>\n <RenderedComponent />\n </ThemeProvider>\n </EventControllerContext.Provider>\n </CludoContext.Provider>\n </React.StrictMode>,\n component.elem,\n () => {}\n );\n }\n}","import { ChatRequestBody, ChatResponse, ChatFeedbackData } from \"../types/conversation-types\";\nimport { ClientSearchResponse, CludoSearch, FilterMap, RelatedPagesRequestParams, TypedDocument } from \"../types/core-script-types\";\nimport { FeedbackData } from \"../types/feedback-module-types\";\nimport { QueryLogObject, ClickLogObject, ChatClickLog } from \"../types/tracking-types\";\nimport { TrendingPagesResponse } from \"../types/trending-pages-types\";\nimport { CludoSearchContext } from \"./cludo-search-context\";\nimport { EventType } from \"./components-controller\";\n\ninterface CallbackMeta {\n id: number;\n type: EventType;\n fnc: Function;\n}\n\nexport class EventController {\n private _cludoSearch: CludoSearch;\n private _searchContext: CludoSearchContext;\n\n private keyedSubscriptions: CallbackMeta[] = [];\n\n private _curSubscriptionIndex: number = 1;\n\n constructor(\n cludoSearch: CludoSearch,\n searchContext: CludoSearchContext) {\n this._cludoSearch = cludoSearch;\n this._searchContext = searchContext;\n }\n\n /**\n * Registers a callback function to be called whenever a\n * trigger of a certain type (beforesearch, aftersearch, etc) occurs\n * @param key \n * @param callback \n * @returns Subscription id -- necessary for unsubscribing\n */\n public subscribe(type: EventType, callback: Function): number {\n const subscriptionId: number = this._curSubscriptionIndex++;\n\n this.keyedSubscriptions.push({\n id: subscriptionId,\n type: type,\n fnc: callback,\n });\n\n return subscriptionId;\n }\n\n /**\n * Registers a callback function to be called whenever any trigger occurs\n * @param callback \n * @returns Subscription id -- necessary for unsubscribing\n */\n public subscribeToAllEvents(callback: Function): number {\n const subscriptionId: number = this._curSubscriptionIndex++;\n const allEventTypes: EventType[] = [\n 'afterautocomplete',\n 'aftersearch',\n 'autocompleteSelectionNext',\n 'autocompleteSelectionPrev',\n 'autocompleteSetSelection',\n 'beforeredirect',\n 'beforesearch',\n 'error'\n ]\n\n // Subscribe to all with the same subscription ID\n allEventTypes.forEach((type: EventType) => {\n this.keyedSubscriptions.push({\n id: subscriptionId,\n type: type,\n fnc: callback\n });\n });\n\n return subscriptionId;\n }\n\n /**\n * Unregisters a previously defined callback\n * @param subscriptionId\n */\n public unsubscribe(subscriptionId: number): void {\n this.keyedSubscriptions =\n this.keyedSubscriptions.filter(\n // keep all subscriptions that don't match the passed sub id\n (sub: CallbackMeta) => sub.id !== subscriptionId);\n }\n\n /**\n * Emits an event that will then be transmitted via the callbacks to all subscribers for the specific type\n * @param key \n * @param data \n */\n public emitEvent(key: EventType, data: any): void {\n this.executeCallbacksForType(key, data);\n }\n\n // FUTURE -- might be possible to better type the payload object\n private executeCallbacksForType(eventType: EventType, payload: any): void {\n this.subscribersForType(eventType)\n .forEach((callback: CallbackMeta) => {\n // call the provided function and pass the payload object as a param\n callback.fnc(payload);\n });\n }\n\n private subscribersForType(eventType: EventType): CallbackMeta[] {\n return this.keyedSubscriptions.filter(\n (callback: CallbackMeta) => callback.type === eventType\n );\n }\n\n public search(query?: string): void {\n if (query) {\n this._cludoSearch.params.query = query;\n }\n if (this._cludoSearch._handleQuickLinks()) {\n return;\n }\n this._cludoSearch.search();\n }\n\n public clearResults(): void {\n this._cludoSearch.clearStoredSearchResponseData();\n }\n\n //#region results\n public get searchResultKeyUpEvent(): (e: KeyboardEvent) => void {\n return this._cludoSearch.searchResultKeyUpEvent;\n }\n\n public get searchResultTrackClickEventHandler(): (e: MouseEvent | KeyboardEvent, target?: HTMLElement) => void {\n return this._cludoSearch.searchResultTrackClickEventHandler;\n }\n\n public get linkToSearchClickEvent(): (anchor: HTMLAnchorElement) => void {\n return this._cludoSearch.linkToSearchClickEvent;\n }\n //#endregion\n\n //#region facets\n public selectFacet(field: string, value: string, multi: boolean = false, shouldSearch = true): void {\n this._cludoSearch.facet(field, value, multi, shouldSearch);\n }\n\n public deselectFacet(field: string, value: string, shouldSearch = true): void {\n this._cludoSearch.clearFacet(field, value, shouldSearch);\n }\n\n public clearFacet(field: string, shouldSearch = true): void {\n this._cludoSearch.clearFacetByName(field, shouldSearch);\n }\n\n public clearAllFacets(shouldSearch = true): void {\n this._cludoSearch.clearAllFacetsAndSearch(shouldSearch);\n }\n\n // Deprecated - use clearAllFacets(false) going forward\n public softClearAllFacets(): void {\n this._cludoSearch.clearAllFacets();\n }\n\n public setDateRangeFacet = (field: string, from: string, to: string, shouldSearch = true) => {\n this._cludoSearch.setDateRangeFacet(field, from, to, shouldSearch);\n }\n\n public setNumberRangeFacet = (field: string, from: number, to: number, shouldSearch = true) => {\n this._cludoSearch.setNumberRangeFacet(field, from, to, shouldSearch);\n }\n\n public clearDateRangeFacet = (shouldSearch = true) => { \n this._cludoSearch.clearFacetByName('date', shouldSearch)\n };\n\n public clearNumberRangeFacet = (shouldSearch = true) => {\n this._cludoSearch.clearFacetByName('range', shouldSearch)\n };\n\n // #region filters\n\n public setFilter(facetKey: string, value: string[], shouldSearch = true): void {\n this._cludoSearch.filter(facetKey, value, shouldSearch);\n }\n\n public setFilters(filters: FilterMap): void {\n this._cludoSearch.params.filters = filters;\n }\n\n public clearAllFilters(shouldSearch = true): void {\n this._cludoSearch.clearAllFilters(shouldSearch);\n }\n\n // #endregion\n\n // replacement for handleFacetValueClick, onFacetValueClick\n public toggleFacetValue(facetField: string, facetValue: string, shouldSearch = true): void {\n if (!this._searchContext.isFacetSelected(facetField, facetValue)) {\n this.selectFacet(facetField, facetValue, undefined, shouldSearch);\n } else {\n this.deselectFacet(facetField, facetValue, shouldSearch);\n }\n }\n //#endregion\n\n //#region did you mean\n private set didYouMean(didYouMeanText: string) {\n this._cludoSearch.didYouMean = didYouMeanText;\n }\n\n public handleDidYouMeanSelect(didYouMeanText: string): void {\n this.didYouMean = didYouMeanText;\n\n this._cludoSearch.setDidYouMean();\n }\n //#endregion\n\n //#region pagination\n public goToPage(pageNumber: number): void {\n this._cludoSearch.page(pageNumber, true);\n }\n public setPerPage(perPage: number): void {\n this._cludoSearch.params.perPage = perPage;\n this._cludoSearch.page(1);\n }\n //#endregion\n\n //#region sort\n /** Clears sorting parameters and performs a search */\n public clearSortOrder(shouldSearch = true): void {\n this._cludoSearch.clearSortOrder(shouldSearch);\n }\n\n /** Clears sorting parameters */\n public clearSortParams(): void {\n this._cludoSearch.clearSortParams();\n }\n\n /** Augments current sort order with passed arguments and performs a search */\n public addToSortOrder(field: string, dir: string, shouldSearch = true): void {\n this._cludoSearch.setSortOrder(field, dir, shouldSearch);\n }\n\n /** Sets the sort order according to passed arguments and performs a search */\n public setSortOrder(field: string, dir: string, shouldSearch = true): void {\n this.clearSortParams();\n this.addToSortOrder(field, dir, shouldSearch);\n }\n //#endregion\n\n // #region autocomplete\n /** Performs an autocomplete request which, when complete, updates the list of autocomplete items */\n public initiateAutocompleteRequest(query: string): void {\n // FUTURE: Debouncing is handled within CoreJS in this function. Consider optionally ignoring it in the core script and handling debouncing in the component\n this._cludoSearch.autocompleteByQuery(query);\n }\n\n public selectSuggestion(suggestion: string, suggestionIndex: number) {\n this._cludoSearch.autocompleteSetSelectedSuggestion(suggestion, suggestionIndex);\n }\n\n public selectResult(result: TypedDocument) {\n this._cludoSearch.autocompleteSetSelectedResult(result);\n }\n\n public selectRecentSearch(recentSearch: string, recentSearchIndex: number) {\n this._cludoSearch.autocompleteSetSelectedRecentSearch(recentSearch, recentSearchIndex);\n }\n\n public clearRecentSearches() {\n this._cludoSearch.clearRecentSearches();\n }\n\n public clearAutocomplete() {\n this._cludoSearch.autocompleteRestoreClient();\n }\n\n public setActiveDescendantToSuggestions(id: string) {\n this._cludoSearch.setActiveDescendantToSuggestions(id);\n }\n // #endregion\n\n // #region endless scroll\n public endlessScrollLoadMore(): void {\n this._cludoSearch.endlessScrollLoadMoreClickEvent();\n }\n // #endregion\n\n // #region tracking\n /** Refer to https://docs.cludo.com/#tracking_queries for Query Log properties */\n public trackQuery(queryLog: QueryLogObject) {\n return this._cludoSearch.trackQuery(queryLog);\n }\n\n /** Refer to https://docs.cludo.com/#tracking_clicks for Click Log properties */\n public trackClick(clickLog: ClickLogObject) {\n return this._cludoSearch.trackClick(clickLog);\n }\n\n /** Sends a click log associated with a chat result */\n public trackChatClick(clickLog: ChatClickLog) {\n return this._cludoSearch.trackChatClick(clickLog);\n }\n // #endregion\n\n // #region Conversations\n\n /** Get conversations from storage */\n public getConversations(): any[] {\n return this._cludoSearch.conversationService.getConversationsFromStorage();\n }\n\n /** Store conversations */\n public storeConversations(conversations: any): void {\n this._cludoSearch.conversationService.storeConversations(conversations);\n }\n\n /** Send a question to our QA service */\n public sendQuestion(customerId: number, engineId: number, requestBody: ChatRequestBody, controller: AbortController): Promise<ChatResponse> {\n return this._cludoSearch.conversationService.sendQuestion(customerId, engineId, requestBody, controller);\n }\n\n /** Send feedback data regarding an exchange */\n public sendChatFeedbackData(customerId: number, engineId: number, feedbackData: ChatFeedbackData): Promise<void> {\n return this._cludoSearch.conversationService.sendFeedbackData(customerId, engineId, feedbackData);\n }\n\n /** Send feedback data from the feedback module experience */\n public sendFeedbackData(customerId: number, engineId: number, feedbackData: FeedbackData): Promise<void> {\n return this._cludoSearch.feedbackService.sendFeedback(customerId, engineId, feedbackData);\n }\n\n // #endregion\n\n // #region Trending pages\n\n /** Get trending pages for the current customer/engine */\n public getTrendingPages(daysBack: number, limit?: number, timezone?: string): Promise<TrendingPagesResponse> {\n return this._cludoSearch.getTrendingPages(daysBack, limit, timezone);\n }\n\n /** Get popular pages for the current customer/engine */\n public getPopularPages(daysBack: number, limit?: number, timezone?: string): Promise<TrendingPagesResponse> {\n return this._cludoSearch.getPopularPages(daysBack, limit, timezone);\n }\n\n /** Get related pages for the current customer/engine */\n public getRelatedPages(url: string, overrideParams?: RelatedPagesRequestParams): Promise<ClientSearchResponse> {\n return this._cludoSearch.getRelatedPages(url, overrideParams);\n }\n\n // #endregion\n}","import { CludoSearch, FilterMap } from \"../types/core-script-types\";\nimport { StringOverrideKeys, SupportedLanguage } from \"../types/translation-types\";\nimport { CludoSearchContext } from \"./cludo-search-context\";\nimport { ComponentsController, TemplateType } from \"./components-controller\";\nimport { CoreScriptStringOverrides } from \"./models/instantiator-types\";\n\n/**\n * Abstraction layer for interacting with the core Cludo script\n * \n * Provides public functions that are available to consumers and seals away internal functions that should not be callable\n */\nexport class CludoInstanceController {\n \n private _cludoSearch: CludoSearch;\n\n // TO-DO -- maybe there is a better name for this property?\n public instance: CludoSearchContext;\n\n public components: ComponentsController;\n\n constructor(cludoSearch: CludoSearch, cssTheme?: string) {\n this._cludoSearch = cludoSearch;\n\n this.instance = new CludoSearchContext(this._cludoSearch);\n this.components = new ComponentsController(this._cludoSearch, this.instance, cssTheme);\n }\n\n // FUTURE -- provide \"on init\" callback\n \n /**\n * Trigger a new search, which includes\n * - ensuring that the observed input values reflect the query value\n * - resets the page number\n * - resets the facets\n * - restores autocomplete\n * - restores endless scroll\n * - resets sort\n * \n * FUTURE -- provide a one-time callback specific to this search call\n */\n public search(): void {\n this._cludoSearch.search();\n }\n\n // Below methods intentionally all return an instance of the CludoSearchController class\n // so that the method calls can be chained\n\n /**\n * Registers a component for a specific type of widget\n * @param widgetType \n * @param widgetComponent \n * @returns Instance of CludoInstanceController (to allow chaining of calls)\n */\n public addWidget(\n widgetType: TemplateType,\n widgetComponent: React.ComponentType,\n element: HTMLElement | string\n ): CludoInstanceController {\n switch(widgetType) {\n case TemplateType.Results:\n this.components.registerSearchResultsComponent(\n widgetComponent,\n element);\n case TemplateType.Controls:\n this.components.registerControlsComponent(\n widgetComponent,\n element);\n case TemplateType.Autocomplete:\n this.components.registerAutocompleteComponent(\n widgetComponent,\n element);\n }\n\n return this;\n }\n\n /**\n * Override the translation for a given token and language\n * @param key The translation token to assign\n * @param value The value of the translation\n * @param language The language the translation should override\n * @returns Instance of CludoInstanceController (to allow chaining of calls)\n */\n public setOverrideString(key: StringOverrideKeys, value: string, language: SupportedLanguage): CludoInstanceController {\n const languageSpecificTranslationSet = this._cludoSearch.translateProvider.translations[language];\n\n if (languageSpecificTranslationSet) {\n languageSpecificTranslationSet[key] = value;\n }\n \n return this;\n }\n \n /**\n * Assign a collection of override strings for the current language\n * @param overrides The collection of override strings for the current language\n * @returns Instance of CludoInstanceController (to allow chaining of calls)\n */\n public setOverrideStrings(overrides: CoreScriptStringOverrides): CludoInstanceController {\n const language = this.instance.translateProvider.language;\n Object.keys(overrides).map( (key) => {\n const value = overrides[key];\n if (key && value) {\n this.setOverrideString(key as StringOverrideKeys, value, language)\n }\n });\n\n return this;\n }\n\n /**\n * Assigns the current language for the Cludo instance\n * @param language The language to set as the current language\n */\n public setLanguage(language: SupportedLanguage): CludoInstanceController {\n this.instance.translateProvider.language = language;\n\n return this;\n }\n\n // FUTURE -- consider adding chainable utility functions for updating the CludoSearch options\n // Potential options:\n // setAutocompleteOptions(options: AutocompleteInitializationOptions): CludoInstanceController\n // addCallback(type: CallbackType, callback: Function): CludoInstanceController\n}","import { useState } from \"react\";\nimport { useCludoContext } from \"./use-cludo-context\";\nimport { SortOrder } from \"../types/core-script-types\";\nimport { SortOption } from \"../utils/models/instantiator-types\";\nimport { useEventSubscriptions } from \"./use-event-subscription\";\n\nexport interface SortByState {\n sortOrder: SortOrder;\n sortItems: SortOption[];\n}\n\nexport interface SortByDispatchers {\n setSortOrder: (field: string, direction: string, shouldSearch?: boolean) => void;\n addToSortOrder: (field: string, direction: string, shouldSearch?: boolean) => void;\n clearSortOrder: (shouldSearch?: boolean) => void;\n}\n\n/** Expose state and dispatchers for controlling sorting \n * @returns cludoState (sortOrder, sortItems) and cludoDispatchers (events for setting/clearing sort order)\n*/\nexport function useSortBy(): [SortByState, SortByDispatchers] {\n const { context, eventController } = useCludoContext();\n\n // Derive state from CludoSearchContext\n const deriveState : () => SortByState = () => {\n return {\n sortOrder: context.sort || {},\n sortItems: context.sortItems || [],\n }\n };\n\n // Derive dispatchers from EventController\n // FUTURE: Investigate getting rid of bind here\n const deriveDispatchers : () => SortByDispatchers = () => {\n return {\n setSortOrder: eventController?.setSortOrder?.bind(eventController) || (() => {}),\n addToSortOrder: eventController?.addToSortOrder?.bind(eventController) || (() => {}),\n clearSortOrder: eventController?.clearSortOrder?.bind(eventController) || (() => {}),\n\n }\n }\n\n // When eventController changes, derive state and dispatchers again\n useEventSubscriptions(() => {\n setCludoState(deriveState());\n setCludoDispatchers(deriveDispatchers());\n });\n\n const [cludoState, setCludoState] = useState(deriveState());\n const [cludoDispatchers, setCludoDispatchers] = useState(deriveDispatchers());\n\n return [ cludoState, cludoDispatchers ];\n}","import React from 'react';\nimport { useSortBy } from '../../../hooks/use-sort-by';\n\n/** Props interface */\nexport type CludoSortBaseProps = {\n relevanceLabel?: string;\n}\n\nexport function CludoSortPicker(props: CludoSortBaseProps) {\n\n const [sortByState, sortByDispatchers] = useSortBy();\n\n // If set to nothing, keep translation to be Relevance\n const relTranslation = (props.relevanceLabel) ? props.relevanceLabel : 'Relevance';\n\n // Length of sort object\n let sortObject = Object.keys(sortByState.sortOrder);\n // If sort is active\n let sortActive = sortObject.length > 0;\n // Active class for relevance field\n let relActive = (sortActive) ? undefined : 'active';\n\n return (\n <div className='cludo-sort-picker'>\n <ul className=\"cludo-sort-picker-list\">\n <li className={`cludo-sort-picker-item ${relActive}`}>\n <a onClick={() => sortByDispatchers.clearSortOrder() }>{relTranslation}</a>\n </li>\n\n {sortByState.sortItems.map(sortItem => {\n const isActive =\n (sortActive && (sortObject[0] == sortItem.key) && sortByState.sortOrder[sortItem.key] == sortItem.direction)\n ? 'active'\n : undefined;\n\n return (\n <li className={`cludo-sort-picker-item ${isActive}`}\n key={sortItem.key + sortItem.direction}>\n <a onClick={() => sortByDispatchers.setSortOrder(sortItem.key, sortItem.direction) }>\n {sortItem.displayText}\n </a>\n </li>\n );\n })}\n </ul>\n </div>\n )\n}\n\n","import React, { PropsWithChildren } from \"react\";\n\ninterface PseudoLinkProps {\n className: string;\n onClick: () => void;\n}\n\nexport function PseudoLink(props: PropsWithChildren<PseudoLinkProps>) {\n const interceptClick: (event: React.MouseEvent) => void =\n (event: React.MouseEvent) => {\n event.preventDefault();\n props.onClick();\n }\n\n return (\n <a className={props.className} href=\"#\"\n onClick={(e) => interceptClick(e) }>\n { props.children}\n </a>\n )\n}","import { useState } from \"react\";\nimport { ExternalFacet } from \"../utils/cludo-search-context\";\nimport { useCludoContext } from \"./use-cludo-context\";\nimport { useEventSubscriptions } from \"./use-event-subscription\";\n\nexport interface FacetState {\n facet: ExternalFacet | null;\n}\n\nexport interface FacetDispatchers {\n selectFacet: (value: string, multi?: boolean, shouldSearch?: boolean) => void;\n deselectFacet: (value: string, shouldSearch?: boolean) => void;\n toggleFacetValue: (value: string) => void;\n clearFacet: (shouldSearch?: boolean) => void;\n setDateRangeFacet: (from: string, to: string, shouldSearch?: boolean) => void;\n setNumberRangeFacet: (from: number, to: number, shouldSearch?: boolean) => void;\n}\n\n/** Expose data and dispatchers for a facet component \n * @returns cludoState (data of facet for inputted facet field) and cludoDispatchers (select, deselect, and toggle facet events)\n*/\nexport function useFacet(facetField: string) : [FacetState, FacetDispatchers] {\n const { context, eventController } = useCludoContext();\n\n // Derive state from CludoSearchContext\n const deriveState : () => FacetState = () => {\n const facet = context?.facets?.find(facet => facet.key === facetField) || null;\n return {\n facet\n }\n }\n\n // Derive dispatchers from EventController\n // FUTURE: Investigate getting rid of bind here\n const deriveDispatchers : () => FacetDispatchers = () => {\n return {\n selectFacet: eventController?.selectFacet?.bind(eventController, facetField) || (() => {}),\n deselectFacet: eventController?.deselectFacet?.bind(eventController, facetField) || (() => {}),\n toggleFacetValue: eventController?.toggleFacetValue?.bind(eventController, facetField) || (() => {}),\n clearFacet: eventController?.clearFacet?.bind(eventController, facetField) || (() => {}),\n setDateRangeFacet: eventController?.setDateRangeFacet?.bind(eventController, facetField) || (() => {}),\n setNumberRangeFacet: eventController?.setNumberRangeFacet?.bind(eventController, facetField) || (() => {})\n }\n }\n\n // When eventController changes, derive state and dispatchers again\n useEventSubscriptions(() => {\n setCludoState(deriveState());\n setCludoDispatchers(deriveDispatchers());\n });\n\n const [cludoState, setCludoState] = useState(deriveState());\n const [cludoDispatchers, setCludoDispatchers] = useState(deriveDispatchers());\n\n return [ cludoState, cludoDispatchers ];\n}","import React from \"react\";\nimport { PseudoLink } from \"../../../utility/pseudo-link\";\nimport { FacetItemProps } from \"../base-facet\";\nimport { useFacet } from \"../../../../hooks/use-facet\";\nimport { generateThemeCss } from \"../../../../utils/theme-provider\";\n\n/** Renders a single facet item */\nexport function StandardFacetItem(props: FacetItemProps) {\n const [facetState, facetDispatchers] = useFacet(props.facetItem.facetName);\n\n // Set theme css\n const optionThemeCss = generateThemeCss('cludo-theme-facet-option', props.disableTheme, props.className);\n const activeThemeCss = generateThemeCss('cludo-theme-facet-option cludo-font-weight-bold', props.disableTheme, props.className) + ' cludo-active';\n const countThemeCss = generateThemeCss('cludo-theme-facet-count', props.disableTheme, props.className);\n\n const valueClass = props.facetItem.isSelected ?\n activeThemeCss :\n optionThemeCss;\n\n const handleFacetClick = () => {\n // Override used mostly for \"All results\" option to clear any set facet values\n if (props.overrideOnChange) {\n props.overrideOnChange();\n return;\n }\n facetDispatchers.toggleFacetValue(props.facetItem.value);\n if (props.onChange) props.onChange();\n }\n\n return (\n <PseudoLink className={valueClass}\n onClick={handleFacetClick}>\n { props.facetItem.value }\n {\n (!props.hideCount && props.facetItem.count !== undefined) ? \n <> <span className={countThemeCss}>{props.facetItem.count}</span></>\n : null\n }\n </PseudoLink>\n )\n}","import React, { ReactNode } from \"react\";\nimport { StandardFacet } from \"../components/controls/facets/standard-facet\";\n\n\n/** Takes in unordered facet field/option array and order reference array and returns ordered facet field/option array */\nexport function setOrderBasedOnReference(unordered: string[], reference: string[]): string[] {\n let unorderedArr = [...unordered];\n let referenceArr = [...reference];\n\n const wildcards = referenceArr.filter(x => x === \"*\").length;\n if (wildcards > 1) {\n throw new Error('Only one wildcard (*) allowed in a reference order');\n }\n\n // Sorting is done by first removing any elements from reference array that don't exist in original array\n // Remaining reference elements are removed from original unordered array\n referenceArr = referenceArr.filter(x => unorderedArr.includes(x) || x === \"*\");\n unorderedArr = unorderedArr.filter(x => !referenceArr.includes(x));\n\n // Remaining unordered elements (unorderedArr) are either inserted into wildcard (*) position\n // or simply added to end of ordered reference array and returned\n const wildcardIndex = referenceArr.indexOf(\"*\");\n if (wildcardIndex > -1) {\n referenceArr.splice(wildcardIndex, 1, ...unorderedArr);\n return referenceArr;\n } \n else {\n return referenceArr.concat(unorderedArr);\n }\n}\n\n\n/** Takes in facet field array and collection of child components that should override default component */\n/** Returns map with key set to facet field string and value set to facet component that should be rendered for field */\nexport function populateFacetGroupMap(facetFields: string[], facetOverrides: React.ReactNode): Map<string, React.ReactNode> {\n let DefaultComponent: React.ReactElement;\n const facetMap = new Map<string, React.ReactNode>(facetFields.map(field => [field, null]));\n\n if (facetOverrides) {\n React.Children.forEach(facetOverrides, override => {\n\n // Make sure any overrides are valid React elements and have a \"field\" prop\n if (!React.isValidElement(override)) return;\n const { field } = override.props;\n const { type, props } = override;\n if (!field) {\n throw new Error(\n `Could not find \"field\" prop for facet group override ${type || 'unknown'}.`\n );\n }\n\n // If default (*) override set, make sure it is the first default override\n // Set default component to instance of override type with any pre-set props (will add field prop later)\n if (override.props.field === \"*\") {\n if (DefaultComponent) {\n throw new Error('Only one override component with wildcard (*) field allowed in a facet group');\n } else {\n DefaultComponent = React.createElement(type, {...props});\n }\n }\n // Otherwise, set instance of specific override with field prop in map\n else {\n facetMap.set(field, \n React.createElement(type, {field: field, ...props})\n );\n } \n });\n }\n\n // Check map for any facet fields that still have null component value\n // Set component instance to either the default component override, if it was set, or standand facet\n facetMap.forEach((value, key, map) => {\n if(value === null) {\n const fallback = DefaultComponent ? \n React.cloneElement(DefaultComponent, {field: key}) : \n React.createElement(StandardFacet, {field: key});\n map.set(key, fallback);\n }\n })\n \n return facetMap;\n}\n\n","import React from \"react\"\nimport { ExternalFacet } from \"../../../../utils/cludo-search-context\"\nimport { generateThemeCss } from \"../../../../utils/theme-provider\";\nimport { ThemeBaseProps } from \"../../../types/types\";\n\nexport function FacetHeader(props: ThemeBaseProps<\n // Child component custom class names definition\n 'root' |\n 'header' |\n 'clearButton'\n> & {\n facet: ExternalFacet | null,\n label: string,\n hideClear?: boolean,\n clearLabel?: string,\n onClear?: (e?: React.SyntheticEvent) => void\n}) {\n \n // Set theme css\n const rootCss = generateThemeCss('cludo-display-flex cludo-align-items-center cludo-mb-2', props.disableTheme, props.className, props.classNames?.root)\n const headerThemeCss = generateThemeCss('cludo-font-size-lg cludo-m-0 cludo-mr-3 cludo-line-height-2', props.disableTheme, props.classNames?.header);\n const clearThemeCss = generateThemeCss('cludo-theme-btn-gray', props.disableTheme, props.classNames?.clearButton);\n\n return ( \n props.facet ?\n <div className={rootCss} {...props.attributes?.root}>\n <h3 className={headerThemeCss} {...props.attributes?.header}>{ props.label }</h3>\n {!props.hideClear && props.facet.hasSelection ?\n // TODO: future task will add translation/override support for 'clear'\n <button \n className={clearThemeCss}\n onClick={props.onClear}\n {...props.attributes?.clearButton}>\n { props.clearLabel || 'Clear' }\n </button> : null\n }\n </div> :\n null\n )\n}","import React from \"react\"\nimport { FacetItem } from \"../../../../utils/cludo-search-context\";\nimport { generateThemeCss } from \"../../../../utils/theme-provider\";\nimport { ThemeBaseProps } from \"../../../types/types\";\n\nexport function FacetSearch(props: ThemeBaseProps & {\n facetItems: FacetItem[],\n onChange: (filteredList: FacetItem[]) => void,\n placeholder?: string,\n hideSelected?: boolean\n}) {\n const unfilteredList = props.facetItems;\n const placeholderOption = props.placeholder || 'Search options'\n const hideSelectedOption = props.hideSelected || false\n\n // Set theme css\n const themeCss = generateThemeCss('cludo-theme-searchbar', props.disableTheme, props.className);\n\n function filterBySearch(event: React.ChangeEvent<HTMLInputElement>) {\n const query = event.currentTarget?.value;\n const filteredList = unfilteredList?.filter((item) => {\n return (\n item.value.toLowerCase().includes(query.toLowerCase()) ||\n (item.isSelected && !hideSelectedOption)\n )\n });\n props.onChange(filteredList);\n };\n\n return (\n <input placeholder={placeholderOption} className={themeCss} onChange={filterBySearch} {...props.attributes?.root} />\n )\n}","import React, { useEffect, useState } from \"react\";\nimport { FacetItem } from \"../../../../utils/cludo-search-context\";\nimport { FacetItemProps } from \"../base-facet\";\nimport { LoadMore } from \"../../../results/cludo-load-more\";\nimport { generateThemeCss } from \"../../../../utils/theme-provider\";\nimport { ThemeBaseProps } from \"../../../types/types\";\nimport { useCludoContext } from \"../../../../hooks/use-cludo-context\";\n\nexport function FacetItemsList(props: ThemeBaseProps<\n // Child component custom class names definition\n 'root' |\n 'listItem' |\n 'allResultsListItem' |\n 'loadMoreButton'\n> & {\n facetItems: FacetItem[],\n itemComponent: React.ComponentType<FacetItemProps>,\n limit?: number,\n showMoreLabel?: string,\n hideShowMore?: boolean,\n hideCount?: boolean,\n includeAllResultsOption?: boolean,\n allResultsOptionLabel?: string,\n allCount?: number\n}) {\n\n const facetLimitOption = props.limit || Infinity;\n const facetHideShowMoreOption = props.hideShowMore || false;\n const facetHideCountOption = props.hideCount || false;\n\n const {context, eventController} = useCludoContext();\n const [visibleFacets, setVisibleFacets] = useState(facetLimitOption);\n\n const allResultsOption: FacetItem = {\n facetName: props.facetItems[0]?.facetName ?? '',\n value: props.allResultsOptionLabel ?? context.translateProvider.translate('template_all_results'),\n isSelected: !props.facetItems.some(item => item.isSelected),\n count: props.allCount\n }\n\n function handleAllResultsClick() {\n if (!allResultsOption.isSelected && allResultsOption.facetName) {\n eventController.clearFacet(allResultsOption.facetName);\n }\n }\n\n // FUTURE: we apply structural css here no matter what - need to rethink how we handle structural css\n const listCss =\n (props.className ? props.className + ' ' : '') +\n (props.classNames?.root ? props.classNames.root + ' ' : '') +\n 'cludo-list-style-none cludo-p-0 cludo-mt-0 cludo-mb-3';\n const listItemCss =\n (props.classNames?.listItem ? props.classNames.listItem + ' ' : '')\n const loadMoreThemeCss =\n generateThemeCss('cludo-theme-btn-accent-secondary cludo-font-weight-bold', props.disableTheme, props.classNames?.loadMoreButton);\n\n function shouldBeHidden(item: FacetItem, i: number) {\n return (\n !item.isSelected &&\n (i > (visibleFacets - 1))\n )\n }\n\n useEffect(() => {\n setVisibleFacets(facetLimitOption);\n }, [props.limit]);\n\n return (\n <>\n <ul className={listCss} {...props.attributes?.root}>\n {props.includeAllResultsOption ?\n <li\n className={props.classNames?.allResultsListItem ?? listItemCss}\n {...props.attributes?.listItem}\n {...props.attributes?.allResultsListItem}\n key={`facet-value-all-results`}>\n <props.itemComponent\n key={`facet-value-all-results`}\n facetItem={allResultsOption}\n hideCount={facetHideCountOption}\n disableTheme={props.disableTheme}\n overrideOnChange={handleAllResultsClick}\n />\n </li> : <></>\n\n }\n {props.facetItems.map((facetItem, i) => {\n return (\n <li\n className={listItemCss}\n {...props.attributes?.listItem}\n style={shouldBeHidden(facetItem, i) ? {display: 'none'} : undefined}\n key={`facet-value-${facetItem.value}`}>\n <props.itemComponent\n key={`facet-value-${facetItem.value}`}\n facetItem={facetItem}\n hideCount={facetHideCountOption}\n disableTheme={props.disableTheme}\n />\n </li>\n );\n })}\n </ul>\n {\n !facetHideShowMoreOption && (visibleFacets < props.facetItems.length) ?\n <LoadMore label={props.showMoreLabel} classNames={{ loadMoreButton: loadMoreThemeCss }} attributes={{loadMoreButton: props.attributes?.loadMoreButton}} onClick={() => setVisibleFacets(Infinity)} /> :\n null\n }\n </>\n )\n}","import React, { useContext, useEffect, useState } from \"react\";\nimport { useFacet } from \"../../../hooks/use-facet\";\nimport { ExternalFacet, FacetItem } from \"../../../utils/cludo-search-context\";\nimport { setOrderBasedOnReference } from \"../../../utils/facet-utils\";\nimport { FacetHeader } from \"./elements/facet-header\";\nimport { FacetSearch } from \"./elements/facet-search\";\nimport { FacetItemsList } from \"./elements/facet-items-list\";\nimport { ThemeBaseProps } from \"../../types/types\";\nimport { generateThemeCss } from \"../../../utils/theme-provider\";\nimport { CludoContext } from \"../../../context\";\n\nexport type FacetProps = ThemeBaseProps<\n // Child component custom class names definition\n 'root' |\n 'header' |\n 'clearButton' |\n 'search' |\n 'facetListContainer' |\n 'facetListItem' |\n 'facetAllResultsListItem' |\n 'loadMoreButton'\n> & {\n field: string;\n facet?: ExternalFacet;\n label?: string;\n clearLabel?: string;\n showMoreLabel?: string;\n searchPlaceholder?: string;\n includeAllResultsOption?: boolean,\n allResultsOptionLabel?: string,\n sortBy?: \"count\" | \"alphabetical\";\n order?: string [];\n exclude?: string [];\n hideCount?: boolean;\n hideClear?: boolean;\n hideSearchBar?: boolean;\n limit?: number;\n hideShowMore?: boolean;\n onChange?: () => {}; \n}\n\nexport type FacetItemProps = ThemeBaseProps & { \n facetItem: FacetItem,\n hideCount?: boolean,\n onChange?: Function,\n overrideOnChange?: Function\n}\n\nexport function BaseFacet(props: FacetProps & {itemComponent: React.ComponentType<FacetItemProps>}) {\n const [facetState, facetDispatchers ] = useFacet(props.field);\n const context = useContext(CludoContext);\n\n // Set options from props or use defaults\n const facetSortByOption = props.sortBy || \"count\";\n const facetOrderOption = props.order || [];\n const facetExcludeOption = props.exclude || [];\n \n // Set theme css\n const containerThemeCss = generateThemeCss('cludo-box-shadow-card cludo-border-radius-card cludo-p-4 cludo-mb-5 cludo-font-family-default cludo-bg-color-white', props.disableTheme, props.className, props.classNames?.root);\n const loadingCss = generateThemeCss(' cludo-theme-loading-disable-children', props.disableTheme || !context.isLoadingResults);\n\n // Consuming component can pass in facet data directly\n // or just pass in field prop and facet data will be retrieved from facet hook\n const facet = props.facet || facetState.facet;\n const [localFacetState, setLocalFacetState] = useState<ExternalFacet | null>(null);\n const [facetItemsSavedCopy, setFacetItemsSavedCopy] = useState<FacetItem[]>([]);\n const [facetItemsToRender, setFacetItemsToRender] = useState<FacetItem[]>([]);\n\n const handleClearFacet = () => {\n facetDispatchers.clearFacet();\n }\n\n useEffect(() => {\n if (!context.isLoadingResults) {\n setLocalFacetState(facet);\n }\n }, [facetState]);\n\n useEffect(() => {\n if (localFacetState?.values?.length) {\n let facetItemValues = localFacetState.values.map(x => x.value);\n // Set sort\n if (facetSortByOption) {\n switch(facetSortByOption) {\n case 'count':\n facetItemValues = localFacetState.values.sort((a, b) => (b.count || -1) - (a.count || -1)).map(facet => facet.value)\n break;\n case 'alphabetical':\n facetItemValues = localFacetState.values.sort((a, b) => a.value.localeCompare(b.value)).map(facet => facet.value)\n break;\n default:\n break;\n }\n }\n // Set exclusions\n if (facetExcludeOption.length) {\n facetItemValues = facetItemValues.filter(x => !facetExcludeOption.includes(x));\n }\n // Set custom order\n if (facetOrderOption.length) {\n facetItemValues = setOrderBasedOnReference(facetItemValues, facetOrderOption);\n }\n // Take filtered/sorted/etc array of facet items values (strings) and push corresponding\n // facet items into an array of facet items that should be rendered\n const facetItemsMap = new Map<string, FacetItem>(localFacetState.values?.map(option => [option.value, option]));\n const filteredFacetItemsList = [] as FacetItem[];\n facetItemValues.forEach(item => {\n const mappedItem = facetItemsMap.get(item);\n if (mappedItem) filteredFacetItemsList.push(mappedItem);\n })\n setFacetItemsSavedCopy(filteredFacetItemsList);\n setFacetItemsToRender(filteredFacetItemsList);\n }\n }, [localFacetState]);\n\n\n return (\n localFacetState?.values.length ?\n <div className={containerThemeCss + loadingCss} {...props.attributes?.root}>\n <FacetHeader\n classNames={{\n header: props.classNames?.header,\n clearButton: props.classNames?.clearButton\n }}\n attributes={{\n header: props.attributes?.header,\n clearButton: props.attributes?.clearButton\n }}\n facet={localFacetState}\n label={props.label ? props.label : localFacetState?.key || ''}\n clearLabel={props.clearLabel}\n hideClear={props.hideClear}\n onClear={handleClearFacet}\n disableTheme={props.disableTheme} />\n {\n !props.hideSearchBar ?\n <FacetSearch\n className={props.classNames?.search}\n attributes={{\n root: props.attributes?.search\n }}\n facetItems={facetItemsSavedCopy}\n placeholder={props.searchPlaceholder}\n onChange={(filteredList) => {setFacetItemsToRender(filteredList)}}\n disableTheme={props.disableTheme} />\n : null\n }\n <FacetItemsList\n classNames={{\n root: props.classNames?.facetListContainer,\n listItem: props.classNames?.facetListItem,\n allResultsListItem: props.classNames?.facetAllResultsListItem,\n loadMoreButton: props.classNames?.loadMoreButton\n }}\n attributes={{\n root: props.attributes?.facetListContainer,\n listItem: props.attributes?.facetListItem,\n allResultsListItem: props.attributes?.facetAllResultsListItem,\n loadMoreButton: props.attributes?.loadMoreButton\n }}\n facetItems={facetItemsToRender}\n itemComponent={props.itemComponent}\n showMoreLabel={props.showMoreLabel}\n limit={props.limit}\n hideShowMore={props.hideShowMore}\n hideCount={props.hideCount}\n disableTheme={props.disableTheme}\n includeAllResultsOption={props.includeAllResultsOption}\n allResultsOptionLabel={props.allResultsOptionLabel}\n allCount={facet?.allCount} />\n\n </div> : null\n )\n}","import React from \"react\";\nimport { StandardFacetItem } from \"./items/standard-facet-item\";\nimport { BaseFacet, FacetProps } from \"./base-facet\";\n\nexport function StandardFacet(props: FacetProps) { \n\n return (\n <BaseFacet itemComponent={StandardFacetItem} {...props} />\n )\n}","import React from \"react\";\nimport { CludoSortPicker } from \"./sort-picker/cludo-sort-picker\";\nimport { ControlsCompositionOptions } from \"../../utils/models/instantiator-types\";\nimport { StandardFacet } from \"./facets/standard-facet\";\nimport { useSortBy } from \"../../hooks/use-sort-by\";\nimport { useFacetGroup } from \"../../hooks/use-facet-group\";\n\nexport const CludoSearchControls = composeControls({});\n\nexport function composeControls(options: ControlsCompositionOptions): () => JSX.Element {\n const SortPickerComponent = options.sortPicker || CludoSortPicker;\n const FacetComponent = options.facet || StandardFacet;\n\n return () => {\n const [ sortByState ] = useSortBy();\n const [ facetsState ] = useFacetGroup();\n const shouldShowSortPicker: boolean = sortByState.sortItems.length > 0;\n const facets = facetsState.facets;\n\n return (\n <>\n {\n shouldShowSortPicker\n ? <SortPickerComponent />\n : <></>\n }\n\n {/* Render facet components */}\n {\n facets.map((facet) => {\n return <FacetComponent key={facet.key} field={facet.key} />\n })\n }\n </>\n \n );\n }\n}\n","import { CludoSearchResults } from '../components/results/cludo-search-results';\nimport { CludoSearchAutocomplete } from '../components/sayt/cludo-search-autocomplete';\nimport { CludoInstanceController } from './cludo-instance-controller';\nimport { CustomComponentConfig, CustomComponentMap, ExternalCludoSearchOptions, PublicSettingsRequestOptions } from './models/instantiator-types';\nimport { CludoSearchControls } from '../components/controls/cludo-search-controls';\nimport { PublicSettings } from '@cludosearch/cludo-api-client/dist/interfaces/api/public-settings.interface';\nimport { SupportedLanguage } from '../types/translation-types';\nimport { CludoSearchOptions, PublicSettingsLocal } from '../types/core-script-types';\nimport { isOnClient } from './render-utils';\nimport styles from \"../styles/all.scss?lazy\";\n\nconst defaultLanguage: SupportedLanguage = 'da';\nconst coreScriptUrl = 'https://customer.cludo.com/scripts/bundles/search-script.min.js';\n\nexport async function getPublicSettings(options: PublicSettingsRequestOptions): Promise<PublicSettings> {\n try {\n let publicSettingsDataStr: string = '';\n publicSettingsDataStr = await window.Cludo.getPublicSettingsByOptions({\n customerId: options.customerId,\n engineId: options.engineId,\n experienceId: options.experienceId,\n apiUrl: undefined,\n authKey: undefined,\n searchSiteKey: undefined,\n isIntranet: options.isIntranet\n } as PublicSettingsRequestOptions);\n\n // Parse public settings from the response (instantSuggestionsConfiguration is double encoded for some reason)\n const publicSettings: PublicSettingsLocal = JSON.parse(publicSettingsDataStr);\n publicSettings.instantSuggestionsConfiguration = JSON.parse(publicSettings.instantSuggestionsConfiguration as any);\n\n return publicSettings;\n\n } catch {\n throw('Unable to resolve public settings via web service');\n }\n}\n\n// FUTURE: This may be replaced by a CoreJS package in the future\nexport async function injectCoreScript(overrideCoreScriptUrl?: string): Promise<void> {\n if (!isOnClient()) return;\n return new Promise(function(resolve, reject) {\n \n const scriptUrl = overrideCoreScriptUrl ?? coreScriptUrl;\n\n if (!isOnClient()) resolve();\n if (document.querySelector(`script[src=\"${scriptUrl}\"]`)){\n resolve();\n } else {\n let script = document.createElement('script');\n script.onload = () => resolve();\n script.onerror = () => reject();\n script.src = scriptUrl;\n document.body.appendChild(script);\n }\n });\n}\n\nexport async function initCludo(options: ExternalCludoSearchOptions): Promise<CludoInstanceController> {\n \n if (!isOnClient()) return {} as CludoInstanceController;\n\n const publicSettingsOptions: PublicSettingsRequestOptions = {\n customerId: options.customerId,\n engineId: options.engineId,\n experienceId: options.experienceId,\n isIntranet: options.secureSearch?.enable\n };\n\n // Get core script (headless only)\n if (options.headless) {\n await injectCoreScript(options.overrideCoreScriptUrl);\n }\n\n // If theme set, inject css\n if (options.cssTheme && styles) {\n styles.use();\n }\n\n // Get public settings\n const publicSettings = await getPublicSettings(publicSettingsOptions);\n\n // Init and return instance controller\n const controller = initCludoWithPublicSettings(options, publicSettings);\n return controller;\n}\n\nexport function initCludoWithPublicSettings(options: ExternalCludoSearchOptions, publicSettings: PublicSettings): CludoInstanceController {\n let cludoSettings: CludoSearchOptions = {\n customerId: options.customerId,\n engineId: options.engineId,\n language: options.language,\n searchUrl: options.searchUrl,\n paramsPrefix: options.instanceId,\n clientTemplates: true, // always true\n publicSettings: publicSettings,\n searchInputs: options.searchInputSelectors,\n headlessSearch: options.headless,\n searchResultsWrapper: options.searchResultsWrapperSelector,\n intranetSearch: options.secureSearch?.enable,\n searchApiUrl: options.secureSearch?.proxyApiUrl,\n customHttpHeaders: options.secureSearch?.customHttpHeaders,\n disableAutocomplete: options.autocomplete?.disable,\n facets: options.facets?.keys,\n initFacets: options.facets?.defaultValues,\n filters: options.filters,\n perPage: options.theme?.resultsPerPage,\n hideResultsCount: options.theme?.hideResultsCount,\n hideSearchFilters: options.theme?.hideSearchFilters,\n hideSearchDidYouMean: options.theme?.hideSearchDidYouMean,\n type: options.theme?.type,\n sortOrder: options.sort?.defaultOrder,\n sortOptions: options.sort?.options,\n logPageVisits: !options.tracking?.skipLoggingPageVisits,\n richAutocomplete: options.autocomplete?.useSearchAsYouType,\n autocompleteForceUseTemplate: options.autocomplete?.renderTemplateWhenNoResults,\n autocompleteMinimumQueryLength: options.autocomplete?.minimumQueryLength,\n applyMultiLevelFacets: options.facets?.applyMultiLevel,\n rangeFacets: options.facets?.rangeValues,\n pierceShadowDom: options.behavior?.pierceShadowDom,\n enableRelatedSearches: options.behavior?.enableRelatedSearches,\n customNoResultsMessage: options.overrideStrings?.noResultsMessage,\n enableVoiceSearch: options.voiceSearch?.enable,\n disableVoiceSearchActiveAnimation: options.voiceSearch?.disableActiveAnimation,\n useFixedQueryInResultsCount: options.theme?.showFixedQueryInResultsCount,\n allowSearchWithoutSearchword: options.behavior?.allowSearchWithoutSearchword,\n jumpToTopOnFacetClick: options.behavior?.jumpToTopOnFacetClick,\n endlessScroll: options.behavior?.endlessScroll,\n enableExtendedTracking: !options.tracking?.disableExtendedTracking,\n customCallbackAfterSearch: options.callbacks?.afterSearch,\n customCallbackBeforeSearch: options.callbacks?.beforeSearch,\n customCallbackBeforeRedirect: options.callbacks?.beforeRedirect,\n customCallbackAfterAutocomplete: options.callbacks?.afterAutocomplete,\n customCallbackBeforeQuicklink: options.callbacks?.beforeQuicklink,\n canUserBeTracked: options.tracking?.canUserBeTracked,\n ovarlayResultsWrapperOpenClass: options.theme?.overlayResultsWrapperOpenClass,\n theme: {\n searchBoxPosition: options.theme?.searchBoxPosition,\n themeColor: options.theme?.themeColor,\n elementFocusColor: options.theme?.elementFocusColor,\n themeBannerColor: options.theme?.themeBannerColor,\n textColor: options.theme?.textColor,\n borderRadius: options.theme?.borderRadius,\n borderRadiusInput: options.theme?.borderRadius\n },\n showInstantSuggestions: options.autocomplete?.showInstantSuggestions,\n suggestedSearchesHeader: options.overrideStrings?.suggestedSearchesHeader,\n recentSearchesHeader: options.overrideStrings?.recentSearchesHeader,\n googleAnalyticsTrackingId: options.tracking?.googleAnalyticsId,\n focusOnResultsAfterSearch: options.behavior?.focusOnResultsAfterSearch,\n translateSearchTemplates: true, // FUTURE -- resolve; theoretically, this shouldn't be necessary\n changeWindowLocation: options.behavior?.updateUrlOnSearch !== undefined ? options.behavior?.updateUrlOnSearch : true,\n urlListDelimiter: options.behavior?.urlListDelimiter\n };\n\n const cludoInstance = new window.Cludo(cludoSettings);\n\n // Get a reference to the current translation object to use for overrides\n let translationRef = cludoInstance.translateProvider\n .translations[options.language || options.filters?.Language[0] || defaultLanguage];\n\n\n // Copy the custom strings into the translateProvider object\n if (translationRef) {\n translationRef = Object.assign(translationRef, options.overrideStrings);\n } else {\n console.warn('Cludo: Translations not found for language ' + options.language);\n }\n\n // Apply any categorize by field settings\n if (options.categorizeResultsByField) {\n cludoInstance.params.topHitsFields = [{\n // Set required field\n field: options.categorizeResultsByField.field,\n // Conditionally set max results and categories\n ...(options.categorizeResultsByField.maxResultsPerCategory &&\n {size: options.categorizeResultsByField.maxResultsPerCategory}),\n ...(options.categorizeResultsByField.maxCategories &&\n {MaxFieldValues: options.categorizeResultsByField.maxCategories})\n }];\n }\n\n const controller: CludoInstanceController = new CludoInstanceController(cludoInstance, options.cssTheme);\n\n // FUTURE -- remove if / once supported in corejs\n if (cludoInstance.setClientTemplateComponentsController) {\n cludoInstance.setClientTemplateComponentsController(controller.components);\n }\n\n cludoInstance.configureFeaturesFromPublicSettings(publicSettings);\n cludoInstance.init();\n\n // render any custom components, or their defaults if not defined\n if (options.headless !== true) {\n const searchComponentMap = {\n results: {} as CustomComponentConfig,\n controls: {} as CustomComponentConfig,\n autocomplete: {} as CustomComponentConfig,\n };\n\n // Since v1.1, we accept components as either a plain component type or a CustomComponentConfig \n // to accommodate custom render events and container selectors. Here, we check which type each\n // component is, and map them all to a CustomcomponentConfig before registering them\n if (isComponentConfigObject(options.components?.results)) {\n searchComponentMap.results = options.components?.results as CustomComponentConfig;\n } else {\n searchComponentMap.results = {\n component: options.components?.results ?? CludoSearchResults,\n containerSelector: cludoSettings.searchResultsWrapper ?? '.search-results .search-results-container',\n renderEvents: ['beforesearch', 'aftersearch']\n } as CustomComponentConfig\n }\n\n if (isComponentConfigObject(options.components?.controls)) {\n searchComponentMap.controls = options.components?.controls as CustomComponentConfig;\n } else {\n searchComponentMap.controls = {\n component: options.components?.controls ?? CludoSearchControls,\n containerSelector: options.controlsWrapperSelector ?? '.search-filters',\n renderEvents: ['beforesearch', 'aftersearch']\n } as CustomComponentConfig\n }\n\n if (isComponentConfigObject(options.components?.autocomplete)) {\n searchComponentMap.autocomplete = options.components?.autocomplete as CustomComponentConfig;\n } else {\n searchComponentMap.autocomplete = {\n component: options.components?.autocomplete ?? CludoSearchAutocomplete,\n containerSelector: '#cludo-search-input #search_autocomplete',\n renderEvents: ['afterautocomplete', 'afterinputfocus']\n } as CustomComponentConfig\n }\n\n // Register components\n\n registerComponent(searchComponentMap.results);\n\n !cludoSettings.hideSearchFilters && registerComponent(searchComponentMap.controls);\n\n if (options.autocomplete?.disable !== true) {\n // register autocomplete for each configured search input or fall back to default input selector\n if (options.searchInputSelectors?.length) {\n options.searchInputSelectors.forEach(selector => {\n registerComponent(searchComponentMap.autocomplete, selector + ' #search_autocomplete');\n })\n } else {\n registerComponent(searchComponentMap.autocomplete);\n }\n }\n\n options.components?.custom?.forEach(component => registerComponent(component));\n }\n\n // Helpers\n function registerComponent(config: CustomComponentConfig, overrideSelector?: string) {\n controller.components.registerComponent(\n config.component,\n overrideSelector ?? config.containerSelector,\n config.renderEvents,\n config.renderEvents.includes('afterpageload')\n );\n }\n\n function isComponentConfigObject(component: any): boolean {\n return component !== null &&\n component !== undefined &&\n typeof component === 'object' &&\n typeof component.containerSelector === 'string' &&\n Array.isArray(component.renderEvents);\n }\n\n return controller;\n}\n\n\n// DROPPED PROPERTIES\n // The below properties are supported in the Cludo constructor but have been dropped from this\n // implementation for the sake of clarity and simplicity\n\n // siteId: number -- dropping siteId as it seems to be a legacy property; only a couple uses found in the customers repo\n // clientTemplates: any -- dropping as we should be able to default this to true\n // searchApiUrlPublic?: string -- dropping as it doesn't appear to be used\n // statisticsApiUrl?: dropping as it's used extremely rarely\n // searchSiteKey?: string; // dropping, custom value doesn't appear to be used and has default\n // customerTemplate?: string; // dropping, not used with the client template approach\n // loading?: string; // dropping, should be overridden as a component instead\n // paramsPrefix?: string // dropping, appears to be unused and has a default ('cludo')\n // showSearchPage?: boolean; // dropping, appeard to be unused and has a default (true)\n // bannerIsInSearchTemplate?: boolean; // dropping for now, not compatible with client-side templates (needs to default to true)\n // xhrRequestHeader?: string; // dropping, not used and has a default ('application/json')\n // hideSearchFiltersIfNoResult?: boolean; // drop, for now at least. I believe the decision \n // on whether to show the filters when there are no\n // results should be delegated to the React components\n // resetFiltersBeforeSearch?: boolean; // dropping as it's used extremely rarely\n // resetSortBeforeSearch?: boolean; // dropping as it's used extremely rarely\n // voiceGrammar?: string[]; // drop for now, as it's not currently supported\n // template?: CludoSearchTemplate; // dropping as it can be recreated with other properties\n // updateInputOnBlur?: boolean; // dropping as it's used rarely and has a default (true) in corejs\n // useStandardSearchTemplate?: boolean; // dropping as it's not currently supported for client side templating\n // translateSearchTemplates?: boolean; dropping as it's not currently supported for client-side templating\n // suggestedSearchesHeader?: boolean; // duplicative with the translateProvider key suggested_searches_title\n // recentSearchesHeader?: string; // duplicative with the translateProvider key recent_searches_title","import React from \"react\";\nimport { SelectorTypeProps } from \"../../../types/control-types\";\nimport { generateThemeCss } from \"../../../utils/theme-provider\";\nimport { ThemeBaseProps } from \"../../types/types\";\n\ntype DropdownInputProps = SelectorTypeProps & ThemeBaseProps<\n 'root' |\n 'label' |\n 'dropdown' |\n 'dropdownOption'\n>\n\nexport function DropdownInput(props: DropdownInputProps) {\n\n const labelThemeCss = generateThemeCss('cludo-font-family-default cludo-font-size-md cludo-font-weight-bold cludo-mr-2', props.disableTheme, props.className, props.classNames?.label)\n const selectThemeCss = generateThemeCss('cludo-p-1 cludo-border-radius-button cludo-height-sm', props.disableTheme, props.className, props.classNames?.dropdown);\n\n return (\n <div className={props.classNames?.root ?? ''} {...props.attributes?.root}>\n { props.label ?\n <label htmlFor={props.id} className={labelThemeCss} {...props.attributes?.label}>\n {props.label}\n </label> : null\n }\n <select \n id={props.id}\n className={selectThemeCss}\n {...props.attributes?.dropdown}\n value={props.currentValue}\n defaultValue={props.default}\n onChange={(event) => props.onChange(event.target.value)}>\n {\n props.options.map((option, i) =>\n <option className={props.classNames?.dropdownOption ?? ''} {...props.attributes?.dropdownOption} key={i} value={option.value}>\n {option.label}\n </option> \n )\n }\n </select>\n </div>\n )\n}","import React, { useContext, useEffect, useState } from \"react\";\nimport { PaginationState, usePagination } from \"../../../hooks/use-pagination\";\nimport { DropdownInput } from \"../../controls/inputs/dropdown-input\";\nimport { ThemeBaseProps } from \"../../types/types\";\nimport { generateThemeCss } from \"../../../utils/theme-provider\";\nimport { useSearchResults } from \"../../../hooks/use-search-results\";\nimport { CludoContext } from \"../../../context\";\n\ninterface ResultsPerPageProps extends ThemeBaseProps<\n 'root' |\n 'label' |\n 'selector' |\n 'selectorOption'\n> {\n options?: number[];\n label?: string;\n // FUTURE: Support more selector types like button list\n // selectorType?: SelectorType;\n}\n\nexport function ResultsPerPage(props: ResultsPerPageProps) {\n const [paginationState, paginationDispatchers] = usePagination();\n const [resultsState] = useSearchResults();\n const [ localPaginationState, setLocalPaginationState ] = useState<PaginationState>(paginationState);\n const context = useContext(CludoContext);\n\n useEffect(() => {\n if (!context.isLoadingResults) {\n setLocalPaginationState(paginationState);\n }\n }, [paginationState])\n\n const options = props.options || [10, 20, 50];\n const optionsMap = options.map(option => { return {label: option.toString(), value: option} });\n const label = props.label || 'Results per page: ';\n const currentPerPage = localPaginationState.itemsPerPage;\n \n const themeCss = generateThemeCss('cludo-mt-3', props.disableTheme, props.className);\n const loadingCss = generateThemeCss(' cludo-theme-loading-disable', props.disableTheme || !resultsState.isLoading);\n \n // FUTURE: Support more selector types like button list\n const SelectorComponent = DropdownInput;\n\n return (\n localPaginationState.showResultsPerPage ?\n <>\n <SelectorComponent\n options={optionsMap} \n id=\"perpage\"\n label={label}\n disableTheme={props.disableTheme}\n className={loadingCss}\n classNames={{\n root: props.classNames?.root,\n label: props.classNames?.label,\n dropdown: `${themeCss} ${props.classNames?.selector ?? ''}`,\n dropdownOption: props.classNames?.selectorOption\n }}\n attributes={{\n root: props.attributes?.root,\n label: props.attributes?.label,\n dropdown: props.attributes?.selector,\n dropdownOption: props.attributes?.selectorOption\n }}\n currentValue={currentPerPage} \n onChange={(value) => paginationDispatchers.setPerPage(Number(value))} />\n </> : null\n )\n}","import React from \"react\";\nimport { SaytResult, SaytResultProps } from \"./sayt-result\";\nimport { AutocompleteItemType } from \"../../types/types\";\n\nexport function SaytCategorizedResult(props: SaytResultProps) {\n return (\n <SaytResult {...props} resultType={AutocompleteItemType.CategorizedResult} />\n )\n}","import React, {Fragment, useMemo, useRef} from \"react\";\nimport {useFacetGroup} from \"../../../../hooks/use-facet-group\";\nimport { populateFacetGroupMap, setOrderBasedOnReference } from \"../../../../utils/facet-utils\";\n\n\nexport function FacetGroup(props : {\n order? : string[],\n exclude? : string[],\n children? : React.ReactNode\n}) {\n const [facetsState] = useFacetGroup();\n const facetOrder = props.order || [];\n const facetExclude = props.exclude || [];\n const facetOverrides = (props.children as React.ReactElement)?.type === Fragment\n ? (props.children as React.ReactElement).props.children\n : props.children;\n\n let facetFields = facetsState.facets.map(x => x.key);\n const facetFieldsRef = useRef<string[]>([]);\n const facetMap = useRef(new Map<string, React.ReactNode>());\n\n useMemo(() => {\n if (facetFields.length) {\n facetFieldsRef.current = facetFields;\n // Set exclusions\n if (facetExclude.length) {\n facetFieldsRef.current = facetFields.filter(x => !facetExclude.includes(x));\n }\n // Set custom order\n if (facetOrder.length) {\n facetFieldsRef.current = setOrderBasedOnReference(facetFields, facetOrder);\n }\n // Populate facet map\n facetMap.current = populateFacetGroupMap(facetFields, facetOverrides);\n }\n }, [facetsState]);\n\n return (\n <>\n { facetFieldsRef.current.map((field) => {\n return <Fragment key={field}>\n {facetMap.current.get(field)}\n </Fragment>\n })\n }\n </>\n )\n}\n","import React from \"react\";\nimport { FacetItemProps } from \"../base-facet\";\nimport { useFacet } from \"../../../../hooks/use-facet\";\nimport { generateThemeCss } from \"../../../../utils/theme-provider\";\n\n\nexport function CheckboxFacetItem(props: FacetItemProps) {\n const [facetState, facetDispatchers] = useFacet(props.facetItem.facetName)\n \n const optionThemeCss = generateThemeCss('cludo-theme-facet-option', props.disableTheme);\n const activeThemeCss = generateThemeCss('cludo-theme-facet-option cludo-font-weight-bold', props.disableTheme) + ' cludo-active';\n const countThemeCss = generateThemeCss('cludo-theme-facet-count', props.disableTheme);\n const inputThemeCss = generateThemeCss('cludo-m-0 cludo-mr-2', props.disableTheme);\n\n const handleFacetChange = (event: React.ChangeEvent<HTMLInputElement>, facetValue: string) => {\n // Override used mostly for \"All results\" option to clear any set facet values\n if (props.overrideOnChange) {\n props.overrideOnChange();\n return;\n }\n const target = event.target;\n const value: boolean = target.checked;\n\n if (value) {\n facetDispatchers.selectFacet(facetValue, true);\n } else {\n facetDispatchers.deselectFacet(facetValue);\n }\n if (props.onChange) props.onChange();\n }\n\n return (\n <label className={ (props.className ? props.className + ' ': '') + (props.facetItem.isSelected ? activeThemeCss : optionThemeCss )}>\n <input\n name={ props.facetItem.facetName }\n type=\"checkbox\"\n checked={ props.facetItem.isSelected }\n className={inputThemeCss} \n onChange={(event) => handleFacetChange(event, props.facetItem.value)} />\n { props.facetItem.value }\n {\n (!props.hideCount && props.facetItem.count !== undefined) ? \n <> <span className={countThemeCss}>{props.facetItem.count}</span></>\n : null\n }\n </label>\n )\n}","import React from \"react\";\nimport { BaseFacet, FacetProps } from \"./base-facet\";\nimport { CheckboxFacetItem } from \"./items/checkbox-facet-item\";\n\nexport function CheckboxFacet(props: FacetProps) { \n\n return (\n <BaseFacet itemComponent={CheckboxFacetItem} {...props} />\n )\n}","import React from \"react\";\nimport { FacetItemProps } from \"../base-facet\";\nimport { useFacet } from \"../../../../hooks/use-facet\";\nimport { generateThemeCss } from \"../../../../utils/theme-provider\";\n\nexport function RadioFacetItem(props: FacetItemProps) {\n const [facetState, facetDispatchers] = useFacet(props.facetItem.facetName);\n \n // Set theme css\n const optionThemeCss = generateThemeCss('cludo-theme-facet-option', props.disableTheme, props.className);\n const activeThemeCss = generateThemeCss('cludo-theme-facet-option cludo-font-weight-bold', props.disableTheme, props.className) + ' cludo-active';\n const countThemeCss = generateThemeCss('cludo-theme-facet-count', props.disableTheme, props.className);\n const inputThemeCss = generateThemeCss('cludo-m-0 cludo-mr-2', props.disableTheme, props.className);\n\n const handleFacetChange = (event: React.ChangeEvent<HTMLInputElement>, facetValue: string) => {\n // Override used mostly for \"All results\" option to clear any set facet values\n if (props.overrideOnChange) {\n props.overrideOnChange();\n return;\n }\n const target = event.target;\n const value: boolean = target.checked;\n\n if (value) {\n facetDispatchers.selectFacet(facetValue);\n }\n if (props.onChange) props.onChange();\n }\n\n return (\n <label className={ props.facetItem.isSelected ? activeThemeCss : optionThemeCss }>\n <input\n name={ props.facetItem.facetName }\n type=\"radio\"\n checked={ props.facetItem.isSelected }\n className={inputThemeCss} \n onChange={(event) => handleFacetChange(event, props.facetItem.value)} />\n { props.facetItem.value }\n {\n (!props.hideCount && props.facetItem.count !== undefined) ? \n <> <span className={countThemeCss}>{props.facetItem.count}</span></>\n : null\n }\n </label>\n )\n}","import React from \"react\";\nimport { BaseFacet, FacetProps } from \"./base-facet\";\nimport { RadioFacetItem } from \"./items/radio-facet-item\";\n\nexport function RadioFacet(props: FacetProps) { \n\n return (\n <BaseFacet itemComponent={RadioFacetItem} {...props} />\n )\n}","import React from \"react\";\n\nconst DEFAULT_HEIGHT = '200';\nconst DEFAULT_WIDTH = '200';\nconst DEFAULT_COLOR = '#000';\nconst DEFAULT_VIEWBOX = '0 0 200 200';\n\nexport interface IconProps {\n height?: string;\n width?: string;\n viewbox?: string;\n color?: string;\n className?: string;\n}\n\nexport interface IconChildProps {\n color?: string;\n}\n\ninterface BaseIconProps extends IconProps {\n children: React.ReactElement<IconChildProps>;\n}\n\nexport const BaseIcon = (props: BaseIconProps) => {\n const width = props.width || DEFAULT_WIDTH;\n const height = props.height || DEFAULT_HEIGHT;\n const viewbox = props.viewbox || DEFAULT_VIEWBOX;\n const color = props.color || DEFAULT_COLOR;\n\n return (\n <svg className={props.className} aria-hidden=\"true\" focusable=\"false\" width={width} height={height} viewBox={viewbox} fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n { React.cloneElement(props.children, { color: color }, null) }\n </svg>\n );\n};\n\n\n","import React from \"react\";\nimport { BaseIcon, IconProps } from \"./base-icon\";\n\nexport function CloseIcon(props: IconProps) {\n return (\n <BaseIcon {...props} >\n <path \n d=\"M4.62154 23.33C-0.245279 28.1934 -0.245271 36.0785 4.62155 40.9419L59.6556 95.9373L4.5986 150.956C-0.268218 155.819 -0.268218 163.704 4.5986 168.567L23.3455 187.301C28.2123 192.165 36.103 192.165 40.9698 187.301L96.0267 132.283L150.927 187.145C155.794 192.008 163.685 192.008 168.551 187.145L187.298 168.411C192.165 163.548 192.165 155.663 187.298 150.799L132.398 95.9373L187.275 41.0983C192.142 36.2349 192.142 28.3498 187.275 23.4864L168.529 4.75271C163.662 -0.11069 155.771 -0.110682 150.904 4.75272L96.0267 59.5916L40.9927 4.59628C36.1259 -0.267119 28.2352 -0.267119 23.3684 4.59628L4.62154 23.33Z\"\n fill={props.color}/>\n </BaseIcon>\n )\n}","import React from \"react\";\nimport { useFacetGroup } from \"../../../../hooks/use-facet-group\";\nimport { generateThemeCss } from \"../../../../utils/theme-provider\";\nimport { ThemeBaseProps } from \"../../../types/types\";\nimport { CloseIcon } from \"../../../icons/close-icon\";\nimport { useSearchResults } from \"../../../../hooks/use-search-results\";\n\ninterface CurrentFacetsProps extends ThemeBaseProps<\n 'root' |\n 'facetContainer' |\n 'facetLabel' |\n 'facetValue' |\n 'facetRemoveButton'\n> {\n exclude?: string[];\n labelsMap?: {[key: string]: string};\n}\n\n// FUTURE: share these values in variables that SCSS and JS can access\nconst ICON_DIMENSION = \"10\";\nconst ICON_FILL_COLOR = \"#344054\";\n\nexport function CurrentFacets(props: CurrentFacetsProps) {\n const [facetGroupState, facetGroupDispatchers] = useFacetGroup();\n const [resultsState] = useSearchResults();\n const selected = facetGroupState.selectedFacets;\n \n // Set theme css\n const rootThemeCss = generateThemeCss('cludo-display-flex cludo-align-items-start cludo-flex-wrap', props.disableTheme, props.className, props.classNames?.root);\n const containerThemeCss = generateThemeCss('cludo-theme-current-facets', props.disableTheme, props.classNames?.facetContainer); \n const labelThemeCss = generateThemeCss('cludo-font-weight-bold', props.disableTheme, props.classNames?.facetLabel); \n const valueThemeCss = generateThemeCss('cludo-ml-2 cludo-display-inline-block', props.disableTheme, props.classNames?.facetValue); \n const buttonThemeCss = generateThemeCss('cludo-theme-current-facets-btn cludo-height-xs', props.disableTheme, props.classNames?.facetRemoveButton); \n const loadingCss = generateThemeCss(' cludo-theme-loading-disable', props.disableTheme || !resultsState.isLoading);\n\n return(\n <div className={rootThemeCss} {...props.attributes?.root}>\n { Object.keys(selected).map((key, i) => {\n if (props.exclude?.includes(key)) {\n return null;\n } else {\n return (\n <div className={containerThemeCss + loadingCss} {...props.attributes?.facetContainer} key={i}>\n <label className={labelThemeCss} {...props.attributes?.facetLabel}>\n { props.labelsMap ? props.labelsMap[key] || key : key }: \n </label>\n <div>\n {\n selected[key].map((value, i) => \n <span key={i} className={valueThemeCss} {...props.attributes?.facetValue}>\n { value } \n <button className={buttonThemeCss} {...props.attributes?.facetRemoveButton} onClick={ () => facetGroupDispatchers.deselectFacet(key, value) }>\n <CloseIcon height={ICON_DIMENSION} width={ICON_DIMENSION} color={ICON_FILL_COLOR} />\n </button>\n </span> \n )\n }\n </div>\n </div>\n )\n }\n })}\n </div>\n )\n}","import React from \"react\";\nimport { useFacetGroup } from \"../../../../hooks/use-facet-group\";\nimport { ThemeBaseProps } from \"../../../types/types\";\nimport { generateThemeCss } from \"../../../../utils/theme-provider\";\n\ninterface ClearAllFacetsProps extends ThemeBaseProps {\n label?: string;\n}\n\nexport function ClearAllFacets(props: ClearAllFacetsProps) {\n const [facetGroupState, facetGroupDispatchers] = useFacetGroup();\n \n // Set theme css\n const themeCss = generateThemeCss('cludo-theme-btn-accent-secondary cludo-font-weight-bold cludo-mb-2', props.disableTheme, props.className);\n\n return ( \n <>\n { facetGroupState.facets.some(facet => facet.hasSelection) ?\n <button className={themeCss} {...props.attributes?.root} onClick={() => facetGroupDispatchers.clearAllFacets()}>\n { props.label || 'Clear all' }\n </button> : <></>\n }\n </>\n )\n}","import React, { useContext } from \"react\";\nimport { ResultContext } from \"../results/items/custom-result\";\nimport { getFieldValue, logMissingResultError } from \"../../utils/result-utils\";\nimport { BaseResultProps } from \"../types/types\";\n\ninterface ResultImageProps extends BaseResultProps {\n altText?: string;\n imageField?: string;\n}\n\nexport function ResultImage(props: ResultImageProps) {\n const resultContext = useContext(ResultContext);\n const result = props.result || resultContext;\n if (!result) {\n logMissingResultError('ResultImage');\n return null;\n }\n\n const imageField = props.imageField || 'Image';\n const imageSrc = getFieldValue(result, imageField);\n const imageAltText = props.altText || getFieldValue(result, 'Title');\n\n return (\n imageSrc ?\n <img src={imageSrc} alt={imageAltText} className={props.className} {...props.attributes?.root} /> :\n null\n )\n}","import React, { useContext, useMemo, useRef } from \"react\";\nimport { ResultContext } from \"../results/items/custom-result\";\nimport { getFieldValue, getFieldValues, logMissingResultError } from \"../../utils/result-utils\";\nimport { ThemeBaseProps } from \"../types/types\";\nimport { generateThemeCss } from \"../../utils/theme-provider\";\nimport { TypedDocument } from \"@cludosearch/cludo-api-client/dist/interfaces/api/search.interface\";\n\ninterface ResultBreadcrumbsProps extends ThemeBaseProps<\n 'root' |\n 'list' |\n 'listItem' |\n 'listItemLink' |\n 'separator'\n> {\n result?: TypedDocument;\n textField: string | string[];\n textFieldDelimiter?: string;\n linkField?: string | string[];\n linkFieldDelimiter?: string;\n separator?: string | React.ReactNode;\n template?: (text: string) => React.ReactNode;\n}\n\nexport function ResultBreadcrumbs(props: ResultBreadcrumbsProps) {\n const resultContext = useContext(ResultContext);\n const result = props.result || resultContext;\n if (!result) {\n logMissingResultError('ResultBreadcrumbs');\n return null;\n }\n\n const templateFn = props.template || ((text: string) => <span>{ text }</span>);\n const separator = props.separator || <span className=\"cludo-px-1\">/</span>;\n const textArray = useRef<(string|undefined)[]>([]);\n const linkArray = useRef<(string|undefined)[]>([]);\n\n const navCss = generateThemeCss('cludo-font-family-default cludo-font-size-sm cludo-mb-2 cludo-font-color-gray', props.disableTheme, props.className, props.classNames?.root);\n const listCss = generateThemeCss('cludo-list-style-none cludo-p-0 cludo-display-flex', props.disableTheme, props.classNames?.list);\n const listItemCss = generateThemeCss('', props.disableTheme, props.classNames?.listItem);\n const listItemLinkCss = generateThemeCss('cludo-font-color-gray', props.disableTheme, props.classNames?.listItemLink);\n const separatorCss = generateThemeCss('', props.disableTheme, props.classNames?.separator);\n\n /**\n * populateBreadcrumbArr function populates an array of breadcrumb data one of two ways:\n * - If array of fields entered through props, loop through array to get field values to add to our array\n * - If single field entered, get value from this field and attempt to split it by an optionally added delimiter before adding to our array\n */\n function populateBreadcrumbArr(field: string | string[], arr: React.MutableRefObject<(string|undefined)[]>, delim?: string) {\n arr.current = [];\n // If array of fields entered, loop through and add values to array\n if (Array.isArray(field)) {\n field.forEach(field => {\n const text = getFieldValue(result, field);\n arr.current.push(text ?? undefined);\n })\n // Otherwise get single field value as an array and split by delimiter if it exists\n } else {\n const text = getFieldValues(result, field);\n if (text && text[0]) {\n const textSubarr = (delim ? text[0].split(delim) : text);\n arr.current.push(...textSubarr);\n } else {\n arr.current.push(undefined);\n }\n }\n }\n\n useMemo(() => {\n populateBreadcrumbArr(props.textField, textArray, props.textFieldDelimiter);\n if (props.linkField) {\n populateBreadcrumbArr(props.linkField, linkArray, props.linkFieldDelimiter);\n }\n }, [result])\n\n return (\n textArray.current.length && !textArray.current.every(x => x === undefined) ?\n <nav className={navCss} aria-label=\"breadcrumb\" {...props.attributes?.root}>\n <ol className={listCss} {...props.attributes?.list}>\n { textArray.current.map((text, i) => {\n \n if (text !== undefined) {\n // If link array populated, wrap breadcrumbs with links\n if (linkArray.current[i] !== undefined) {\n return <React.Fragment key={i}>\n <li className={listItemCss} {...props.attributes?.listItem}>\n <a className={listItemLinkCss} {...props.attributes?.listItemLink} href={linkArray.current[i]}>\n { templateFn(text) }\n </a>\n </li>\n { i !== textArray.current.length - 1 ?\n <li className={separatorCss} aria-hidden=\"true\" {...props.attributes?.separator}>\n { separator }\n </li> : null\n }\n </React.Fragment>\n // Otherwise, render read-only breadcrumbs\n } else {\n return <React.Fragment key={i}>\n <li className={listItemCss} {...props.attributes?.listItem}>\n <>\n { templateFn(text) }\n </>\n </li>\n \n { i !== textArray.current.length - 1 ?\n <li className={separatorCss} aria-hidden=\"true\" {...props.attributes?.separator}>\n { separator }\n </li> : null\n }\n </React.Fragment>\n }\n } else {\n return null;\n }\n }) }\n </ol>\n </nav> : <></>\n )\n}","import React, { ReactNode, useEffect, useState } from \"react\";\nimport { ExternalCludoSearchOptions } from \"../../utils/models/instantiator-types\";\nimport { initCludo, initCludoWithPublicSettings } from \"../../utils/instantiator\";\nimport { CludoContext, EventControllerContext } from \"../../context\";\nimport { CludoSearchContext } from \"../../utils/cludo-search-context\";\nimport { CludoInstanceController } from \"../../utils/cludo-instance-controller\";\nimport { EventController } from \"../../utils/event-controller\";\nimport { CludoSearch } from \"../../types/core-script-types\";\nimport { ThemeProvider } from \"../../utils/theme-provider\";\nimport { PublicSettings } from \"@cludosearch/cludo-api-client/dist/interfaces/api/public-settings.interface\";\n\ninterface CludoWrapperProps {\n config: ExternalCludoSearchOptions,\n publicSettings?: PublicSettings,\n onInit?: (controller: CludoInstanceController) => void,\n children?: ReactNode\n}\n\n/** This component wraps React components with a Cludo Search Context, and should be used to wrap input elements and search containers */\nexport function CludoWrapper(props: CludoWrapperProps) {\n const [searchContext, setSearchContext] = useState({} as CludoSearchContext);\n const [eventContext, setEventContext] = useState({} as EventController);\n const [hasInitialized, setHasInitialized] = useState(false);\n\n // Once we get the instance controller, save the context to state so we can provide it \n useEffect(() => {\n if(props.publicSettings) {\n // if the publicSettings property is set, we can skip the initCludo call and just use the public settings\n // to create the search context via initCludoFromPublicSettings (which resolves synchronously)\n const controller = initCludoWithPublicSettings(props.config, props.publicSettings);\n\n if (props.onInit) {\n props.onInit(controller);\n }\n setSearchContext(controller.instance);\n setEventContext(controller.components.events);\n setHasInitialized(true);\n } else {\n // Set headless to true by default (overwritten by passed config)\n const config: ExternalCludoSearchOptions = {\n headless: true,\n ...props.config\n }\n\n // If the public settings are not provided, we need to use the config to create the search context\n // via initCludo (which resolves asynchronously via a Promise)\n initCludo(config).then( (controller: CludoInstanceController) => {\n if (props.onInit) {\n props.onInit(controller);\n }\n setSearchContext(controller.instance);\n setEventContext(controller.components.events);\n setHasInitialized(true);\n });\n }\n\n return () => {\n // Remove the instance from the global array of instances\n const windowObject = window as any;\n if (windowObject?.CludoSearchInstances?.length) {\n windowObject.CludoSearchInstances = windowObject.CludoSearchInstances.filter((instance: CludoSearch) => instance.engineId !== props.config.engineId);\n }\n }\n }, []);\n\n return(\n !hasInitialized ? null :\n <CludoContext.Provider value={searchContext}>\n <EventControllerContext.Provider value={eventContext}>\n <ThemeProvider theme={props.config.cssTheme}>\n {/* FUTURE -- consider deferred rendering of the children until the public settings have been retrieved */}\n { props.children }\n </ThemeProvider>\n </EventControllerContext.Provider>\n </CludoContext.Provider>\n )\n\n}","import React, { useContext } from \"react\";\nimport { CludoContext } from \"../../context\";\n\nexport function CludoAutocompleteContainer() {\n const context = useContext(CludoContext);\n const autocompleteHintText = context.translateProvider?.translate('template_autocomplete_hint');\n\n return (\n <>\n {/* Container */}\n <div className=\"search_autocomplete\" id=\"search_autocomplete\" tabIndex={0}></div>\n\n {/* Hint element */}\n <span id=\"autocomplete_hint\" aria-hidden=\"false\" aria-atomic=\"true\" role=\"status\" aria-live=\"polite\">\n { autocompleteHintText }\n </span>\n </>\n )\n}","import React from \"react\";\n\n/** We mount the Search Results Component here */\nexport function CludoResultsContainer(props: {id?: string}) {\n const resultsWrapperId = props.id ? props.id : \"cludo-search-results\";\n return (\n <div id={resultsWrapperId}></div>\n )\n}","import React, { useContext } from \"react\";\nimport { CludoContext } from \"../../context\";\n\nexport function CludoSearchInput() {\n const context = useContext(CludoContext);\n const placeholder = context.translateProvider?.translate('search_input_label');\n const ariaLabel = context.translateProvider?.translate('search_input_label');\n\n const autocompleteEnabled = context.isAutocompleteEnabled;\n\n if (autocompleteEnabled) {\n return (\n <input \n type=\"search\" \n className=\"cludo-search-input\" \n aria-label={ariaLabel} \n placeholder={placeholder}\n aria-describedby=\"autocomplete_hint\"\n aria-autocomplete=\"list\"\n aria-controls=\"search_autocomplete\"\n />\n );\n } else {\n return (\n <input \n type=\"search\" \n className=\"cludo-search-input\" \n aria-label={ariaLabel} \n placeholder={placeholder}\n />\n );\n }\n\n}","import React, { useContext } from \"react\";\nimport { CludoContext } from \"../../context\";\nimport { CludoSearchInput } from \"./cludo-search-input\";\nimport { CludoAutocompleteContainer } from \"./cludo-autocomplete-container\";\n\nexport function CludoSearchForm(props: {uniqueFormId?: string}) {\n const context = useContext(CludoContext);\n const ariaLabel = context.translateProvider?.translate('search_input_label');\n const autocompleteEnabled = context.isAutocompleteEnabled;\n \n const formId = props.uniqueFormId ? props.uniqueFormId : 'cludo-search-input';\n\n return(\n <form id={formId} role=\"search\">\n <CludoSearchInput />\n <button type=\"submit\" \n className=\"cludo-search-button\"\n aria-label={ariaLabel} />\n { autocompleteEnabled ? <CludoAutocompleteContainer /> : <></> }\n </form>\n )\n}","import { useEffect, useState } from \"react\";\nimport { useCludoContext } from \"./use-cludo-context\";\n\nexport interface SearchInputState {\n query: string;\n}\nexport interface SearchInputDispatchers {\n search: (updatedQuery: string) => void;\n setQuery: (updatedQuery: string) => void;\n}\n\n/** Expose state and dispatchers necessary to create a functional search input\n * @returns cludoState (current query) and cludoDispatchers (search event)\n */\nexport function useSearchInput(): [SearchInputState, SearchInputDispatchers] {\n const { context, eventController } = useCludoContext();\n\n const [searchInputState, setSearchInputState] = useState({\n query: context.query || ''\n });\n\n // Derive dispatchers from CludoSearchContext\n const searchInputDispatchers: SearchInputDispatchers = {\n search: (updatedQuery: string) => {\n eventController.search(updatedQuery);\n },\n setQuery: (updatedQuery: string) => {\n setSearchInputState({query: updatedQuery})\n }\n };\n\n // Update search input state whenever the context's query changes\n useEffect(() => {\n setSearchInputState({query: context.query || ''})\n }, [context.query]);\n\n return [searchInputState, searchInputDispatchers];\n}","import React from \"react\";\nimport { BaseIcon, IconProps } from \"./base-icon\";\n\nexport function SearchIcon(props: IconProps) {\n return (\n <BaseIcon {...props} >\n <path \n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M112.092 140.376C101.162 146.595 88.5179 150.147 75.0446 150.147C33.5986 150.147 0 116.535 0 75.0733C0 33.6115 33.5986 0 75.0446 0C116.491 0 150.089 33.6115 150.089 75.0733C150.089 88.5145 146.558 101.131 140.374 112.044L186.485 158.173C191.17 162.86 191.17 170.46 186.485 175.147L175.151 186.485C170.466 191.172 162.869 191.172 158.184 186.485L112.092 140.376ZM120.071 75.0733C120.071 99.9504 99.9122 120.117 75.0446 120.117C50.177 120.117 30.0179 99.9504 30.0179 75.0733C30.0179 50.1962 50.177 30.0293 75.0446 30.0293C99.9122 30.0293 120.071 50.1962 120.071 75.0733Z\"\n fill={props.color}/>\n </BaseIcon>\n )\n}","import React, { useContext } from \"react\";\nimport { useSearchInput } from \"../../hooks/use-search-input\";\nimport { generateThemeCss } from \"../../utils/theme-provider\";\nimport { ThemeBaseProps } from \"../types/types\";\nimport { SearchIcon } from \"../icons/search-icon\";\nimport { CludoContext } from \"../../context\";\n\nexport interface SearchInputProps extends ThemeBaseProps<\n 'root' |\n 'input' |\n 'submitButton'\n> {\n placeholder?: string;\n className?: string;\n formId?: string;\n submitIcon?: React.ReactNode;\n onChange?: (event: React.ChangeEvent<HTMLInputElement>) => void;\n onSubmit?: (event: React.FormEvent<HTMLFormElement>) => void;\n onFocus?: (event: React.FocusEvent<HTMLInputElement>) => void;\n onBlur?: (event: React.FocusEvent<HTMLInputElement>) => void;\n onKeyDown?: (event: React.KeyboardEvent<HTMLInputElement>) => void;\n}\n\n/** Search input component that can perform search requests */\nexport function SearchInput(props: SearchInputProps) {\n const [ cludoState, cludoDispatchers ] = useSearchInput(); \n const context = useContext(CludoContext);\n const placeholder = props.placeholder || 'Enter a search term';\n const buttonAriaLabel = context.translateProvider?.translate('search_button_text');\n const inputAriaLabel = context.translateProvider?.translate('search_input_label');\n\n const handleSubmit = (event: React.FormEvent<HTMLFormElement>) => {\n event.preventDefault();\n cludoDispatchers.search(cludoState.query);\n if (props.onSubmit) {\n props.onSubmit(event);\n }\n }\n\n const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {\n cludoDispatchers.setQuery(event.target.value);\n if (props.onChange) {\n props.onChange(event);\n }\n }\n \n // Set theme css\n const formCss = generateThemeCss('cludo-display-flex cludo-box-shadow-card cludo-border-radius-card cludo-p-4 cludo-mb-3 cludo-align-items-center cludo-bg-color-white', props.disableTheme, props.className, props.classNames?.root);\n const inputCss = generateThemeCss('cludo-font-size-md cludo-py-1 cludo-px-2 cludo-font-family-default cludo-border-radius-button cludo-border-1-neutral cludo-height-sm cludo-flex-grow-1 cludo-bg-color-gray-light', props.disableTheme, props.classNames?.input);\n const buttonCss = generateThemeCss('cludo-theme-icon-btn-secondary cludo-ml-1', props.disableTheme, props.classNames?.submitButton);\n\n const submitButtonContent: React.ReactNode = props.submitIcon ? props.submitIcon : <SearchIcon width=\"100%\" height=\"100%\" color=\"#fff\" />; \n\n return (\n <form id={props.formId} onSubmit={handleSubmit} className={formCss} {...props.attributes?.root}>\n <input \n type=\"search\" \n aria-label={inputAriaLabel}\n className={inputCss}\n placeholder={placeholder}\n onChange={handleChange}\n onBlur={props.onBlur}\n onFocus={props.onFocus}\n onKeyDown={props.onKeyDown}\n value={cludoState.query}\n {...props.attributes?.input}\n />\n <button\n aria-label={buttonAriaLabel}\n className={buttonCss}\n type=\"submit\"\n {...props.attributes?.submitButton}\n >\n {submitButtonContent}\n </button>\n </form>\n );\n}","import { useState, useEffect } from \"react\";\nimport { SearchResultsState, useSearchResults } from \"./use-search-results\";\nimport { EndlessScrollOptions } from \"../utils/models/instantiator-types\";\nimport { useCludoContext } from \"./use-cludo-context\";\nimport { isOnClient } from \"../utils/render-utils\";\n\nexport interface EndlessScrollState {\n showLoadMore: boolean;\n isLoading: boolean;\n};\n\nexport function useEndlessScroll(options: EndlessScrollOptions): EndlessScrollState {\n const { context } = useCludoContext();\n const [searchResultsState, searchResultsDispatchers] = useSearchResults();\n\n // Needed so that the results add to themselves, instead of replacing them\n context.endlessScroll = options;\n\n // This use effect handles the endless scroll\n useEffect(() => {\n if (!isOnClient()) return;\n\n const handleScroll = () => {\n if (searchResultsState.isLoading) { return; }\n if (scrolledElement instanceof Element) {\n handleElementScroll(scrolledElement);\n } else {\n handleWindowScroll();\n }\n }\n \n const handleElementScroll = (element: Element) => {\n if (element.scrollTop + element.clientHeight >= element.scrollHeight - options.bottomOffset) {\n if (\n (searchResultsState.currentPage < options.stopAfterPage) &&\n (searchResultsState.resultCount > options.resultsPerPage) &&\n (searchResultsState.currentPage < Math.ceil(searchResultsState.resultCount / options.resultsPerPage))\n ){\n // Load more results\n searchResultsDispatchers.loadMore();\n }\n }\n }\n \n const handleWindowScroll = () => {\n if (!isOnClient()) return;\n if (window.scrollY + window.innerHeight >= document.body.scrollHeight - options.bottomOffset) {\n if (\n (searchResultsState.currentPage < options.stopAfterPage) &&\n (searchResultsState.resultCount > options.resultsPerPage) &&\n (searchResultsState.currentPage < Math.ceil(searchResultsState.resultCount / options.resultsPerPage))\n ){\n // Load more results\n searchResultsDispatchers.loadMore();\n }\n }\n }\n\n const scrolledElement = (options.scrolledElementSelector ? document.querySelector(options.scrolledElementSelector) : window) || window;\n scrolledElement.addEventListener('scroll', handleScroll);\n return () => {\n scrolledElement.removeEventListener('scroll', handleScroll);\n }\n }, [options]);\n\n\n // Derive state when search results change\n const deriveState = (state: SearchResultsState) => {\n return {\n showLoadMore: (state.currentPage >= options.stopAfterPage) && (state.resultCount > options.resultsPerPage) && (state.currentPage < Math.ceil(state.resultCount / options.resultsPerPage)),\n isLoading: state.isLoading\n }\n }\n\n // Update state based on search results\n useEffect(() => {\n setEndlessScrollState(deriveState(searchResultsState));\n }, [searchResultsState]);\n\n // State\n const [endlessScrollState, setEndlessScrollState] = useState({showLoadMore: false, isLoading: false});\n\n return endlessScrollState;\n}"],"names":["root","factory","exports","module","define","amd","this","CludoFeature","__webpack_module_cache__","__webpack_require__","moduleId","cachedModule","undefined","__webpack_modules__","n","getter","__esModule","d","a","definition","key","o","Object","defineProperty","enumerable","get","obj","prop","prototype","hasOwnProperty","call","r","Symbol","toStringTag","value","require","CludoContext","EventControllerContext","getUrl","result","Fields","Value","hasField","fieldName","FieldNames","indexOf","getFieldValue","maxWords","wordDelim","splitDelim","joinDelim","words","split","length","slice","join","getFieldValues","Values","getHighlightsOrValues","delim","getHighlightsOrValuesArray","Highlights","values","returnValues","wordCount","i","stringArray","trim","splice","push","trimArrayToMaxWords","getFormattedHTML","val","__html","logMissingResultError","component","console","error","isAutocompleteItem","element","hasAttribute","getTopHitTotalCount","hit","facets","Field","map","hitValue","facetMatch","facetValueMatch","Items","find","Key","count","Count","AllCount","getLinkFragmentUrlPart","fragment","context","isFeatureEnabled","WebContentHighlighter","innerText","replace","encodeURIComponent","LinkContext","ResultLink","props","useContext","eventController","resultContext","ResultContext","initalFragment","highlightQueryOnClickedPage","query","useState","fragmentUrlPart","setFragmentUrlPart","model","eleClass","className","titleField","url","linkField","urlWithFragments","anchorElem","useRef","LinkContextInstance","onFragmentHover","urlFragmentPart","onFragmentSelect","current","click","useEffect","shouldBeFocused","focus","ref","href","ResultIndex","currentPage","target","openNewTab","attributes","onKeyUp","e","searchResultKeyUpEvent","nativeEvent","onKeyUpHandler","onClick","searchResultTrackClickEventHandler","onClickHandler","Provider","children","ThemeContext","ThemeProvider","theme","generateThemeCss","themeCss","disableTheme","classNameProps","filter","Boolean","CustomResult","focusOnResultsAfterSearch","wrapWithLink","HighlightedText","chunkedText","input","hightlightTag","match","regex","lastIndex","exec","index","displayType","text","splitByHighlightTags","splitByTag","HighlightTag","role","wrapDefaultText","ResultTitle","showRawText","Heading","headingElement","fileType","title","FragmentHighlight","linkContext","classStr","tabIndex","onKeyDown","code","onFocus","onMouseEnter","onMouseLeave","FragmentHighlightGroup","field","fragments","descriptionPart","maxFragments","ResultDescription","descriptionField","makeHighlightsClickable","maxWordCount","description","highlightDelimiter","ResultUrl","showRelativeUrl","urlObj","URL","toString","substring","origin","DEFAULT_BADGE_FIELD","ResultBadge","displayText","defaultOrder","StandardResult","propOrder","renderOrder","order","concat","el","hideTitle","hideDescription","hideUrl","hideBadge","widgetMap","Map","classNames","descriptionMaxWordCount","badge","badgeField","useCludoContext","useEventSubscriptions","callback","events","subscriptions","keys","forEach","eventType","subscribe","subscribeToAllEvents","unsubscribe","subscriptionId","usePagination","searchResponse","storedSearchResponseData","cludoSearchResponse","deriveState","resultsPerPage","itemsPerPage","maxPages","Math","ceil","ResultCount","nextPageLabel","translateProvider","translate","prevPageLabel","showPagination","isEndlessScrollEnabled","showResultsPerPage","deriveDispatchers","goToPage","bind","setPerPage","setCludoState","setCludoDispatchers","cludoState","cludoDispatchers","useSearchResults","resultsSummary","resultCount","resultCountMessage","ResultCountMessage","fixedQuery","FixedQuery","Facets","didYouMean","Suggestions","suggestions","results","TypedDocuments","categorizedResults","TopHits","paginationOptions","endlessScrollOptions","isEnabled","endlessScroll","banners","Banners","relatedSearches","RelatedSearchDocuments","isLoading","isLoadingResults","loadMore","endlessScrollLoadMore","searchResultKeyUp","linkToSearchClickEvent","handleDidYouMeanSelect","Pagination","paginationState","paginationDispatchers","resultsState","localPaginationState","setLocalPaginationState","previousButtonIcon","nextButtonIcon","firstButtonIcon","lastButtonIcon","startPage","prevPageTranslation","nextPageTranslation","activeBtnCss","inactiveBtnCss","loadingCss","list","hideFirst","listItem","firstButton","hidePrevious","previousButton","currentPageNum","pageNumberButtons","pageTranslation","pageNumberButton","currentPageButton","renderPageNumberButtons","hideNext","nextButton","hideLast","lastButton","Banner","bannerRef","banner","bannerLinks","querySelectorAll","paramsPrefix","link","anchor","bannerId","String","Id","bannerTitle","Name","setAttribute","addBannerAttributesToAnchor","decodeURIComponent","addEventListener","preventDefault","onBannerLoad","bannerCss","dangerouslySetInnerHTML","useBanners","BannerGroup","bannersState","bannerComponents","DidYouMean","suggestionFromContext","suggestedQuery","didYouMeanInnerHTML","event","suggestion","HTMLElement","closest","onDidYouMeanClick","useFacetGroup","selectedFacets","clearAllFacets","softClearAllFacets","deselectFacet","facetsState","resultTextState","setResultTextState","Query","yourSearchMsg","totalMsg","inCategoryMsg","selectedValues","entries","Array","isArray","searchedInsteadMsg","resultMsg","ResultsSummary","CludoLoader","loadingAltText","src","alt","StandardLoader","ResultsList","templateFn","template","columns","loader","customLoader","resultSpacing","cssUnit","focusIndex","resultsToRender","setResultsToRender","bannersToRender","setBannersToRender","cssString","containerCss","listCss","resultsListContainer","listItemCss","resultsListItem","loaderCss","loaderContainer","hideBanners","columnsBreakpoint","LoadMore","loadMoreStr","label","id","loadMoreButton","type","wasKeyboardClick","detail","LoadMoreResults","searchResultsState","searchResultsDispatchers","showLoadMore","stopAfterPage","classNamesObj","attrsObj","disableKeyboardFocusHandling","onLoadMore","AutocompleteItemType","CludoSearchResults","composeResults","options","ResultComponent","ListComponent","LoaderComponent","PaginationComponent","pagination","SaytResult","resultIndex","suggestionCSS","isSelected","resultChildren","chunkedTitle","itemType","resultType","Result","setActiveDescendantToSuggestions","selectResult","document","SaytSuggestion","suggestionIndex","Suggestion","selectSuggestion","SaytRecentSearch","recentSearchIndex","RecentSearch","recentSearch","isOnClient","window","useAutocomplete","selectedIndex","keydownListener","tempSelectedSuggestion","tempSelectedResult","tempSelectedRecentSearch","storedAutocompleteResponse","data","instantSuggestions","recentSearches","categorizedResultGroups","resultGroup","resultValue","Hits","getAutocompleteResultsFromTopHits","listItems","tempIndex","numSuggestions","search","getAttribute","parseInt","categorizedResult","selectRecentSearch","newState","deriveAutocompleteState","selectedSuggestion","selectedResult","selectedRecentSearch","setAutocompleteState","eventControllerIsDefined","keyboardNextSubscription","keyboardPrevSubscription","keyboardEnterSubscription","autocompleteCompleteSubscription","clearSelectedIndices","suggestionsTitle","resultsTitle","recentSearchesTitle","autocompleteState","autocompleteDispatchers","initiateAutocompleteRequest","autocompleteSelectionNext","emitEvent","autocompleteSelectionPrev","autocompleteSelect","clear","clearAutocomplete","autocompleteHandleInputKeyDown","autocompleteHandleInputBlur","relatedTarget","autocompleteHandleInputChange","CludoSearchAutocomplete","cludoSearch","_cludoSearch","_templateState","params","customerId","engineId","page","perPage","sort","clientTemplateSortOptions","websiteSettings","configurations","isFacetSelected","isFilterSelected","filters","getSelectedMapItem","arrayToCheck","selected","item","facetsInResponse","facetsToRender","includes","facetMapItem","facetKey","facetObj","facet","hasSelection","facetValue","facetName","allCount","missingCount","MissingCount","facetValues","Set","str","has","newValue","enabledFeatures","featureKey","richAutocomplete","fragmentText","linkFragment","customEngineSettings","JSON","parse","featureConfigKey","instantSuggestionsConfiguration","storedError","chunkString","needle","needleIndex","toLowerCase","mapTypedDocumentToResult","mapTypedDocumentToSuggestion","mapStringToSuggestion","mapTopHitsToCategorizedResults","mapHitValuesToResults","coreAutocompleteData","cludoAutocompleteResponse","totalResults","totalSuggestions","totalRecentSearches","topHits","isTrackedSession","canUserBeTracked","queryId","getSessionId","querySessionId","deviceType","getTraitsFromStorage","TemplateType","searchContext","keyedSubscriptions","_curSubscriptionIndex","setDateRangeFacet","from","to","shouldSearch","setNumberRangeFacet","clearDateRangeFacet","clearFacetByName","clearNumberRangeFacet","_searchContext","fnc","sub","executeCallbacksForType","payload","subscribersForType","_handleQuickLinks","clearResults","clearStoredSearchResponseData","selectFacet","multi","clearFacet","clearAllFacetsAndSearch","setFilter","setFilters","clearAllFilters","toggleFacetValue","facetField","didYouMeanText","setDidYouMean","pageNumber","clearSortOrder","clearSortParams","addToSortOrder","dir","setSortOrder","autocompleteByQuery","autocompleteSetSelectedSuggestion","autocompleteSetSelectedResult","autocompleteSetSelectedRecentSearch","clearRecentSearches","autocompleteRestoreClient","endlessScrollLoadMoreClickEvent","trackQuery","queryLog","trackClick","clickLog","trackChatClick","getConversations","conversationService","getConversationsFromStorage","storeConversations","conversations","sendQuestion","requestBody","controller","sendChatFeedbackData","feedbackData","sendFeedbackData","feedbackService","sendFeedback","getTrendingPages","daysBack","limit","timezone","getPopularPages","getRelatedPages","overrideParams","cssTheme","managedComponents","EventController","_cssTheme","registerSearchResultsComponent","addManagedComponent","registerControlsComponent","registerAutocompleteComponent","registerComponent","observedEventTypes","renderImmediately","managedComponent","elem","querySelector","elemSelector","hasRendered","renderComponent","processEvent","callbackFnc","RenderedComponent","instance","CludoSearchContext","components","ComponentsController","addWidget","widgetType","widgetComponent","Results","Controls","Autocomplete","setOverrideString","language","languageSpecificTranslationSet","translations","setOverrideStrings","overrides","setLanguage","useSortBy","sortOrder","sortItems","CludoSortPicker","sortByState","sortByDispatchers","relTranslation","relevanceLabel","sortObject","sortActive","relActive","sortItem","isActive","direction","PseudoLink","useFacet","StandardFacetItem","facetItem","facetDispatchers","optionThemeCss","activeThemeCss","countThemeCss","valueClass","overrideOnChange","onChange","hideCount","setOrderBasedOnReference","unordered","reference","unorderedArr","referenceArr","x","Error","wildcardIndex","FacetHeader","rootCss","headerThemeCss","header","clearThemeCss","clearButton","hideClear","onClear","clearLabel","FacetSearch","unfilteredList","facetItems","placeholderOption","placeholder","hideSelectedOption","hideSelected","currentTarget","filteredList","FacetItemsList","facetLimitOption","Infinity","facetHideShowMoreOption","hideShowMore","facetHideCountOption","visibleFacets","setVisibleFacets","allResultsOption","allResultsOptionLabel","some","loadMoreThemeCss","shouldBeHidden","includeAllResultsOption","allResultsListItem","itemComponent","style","display","showMoreLabel","BaseFacet","facetState","facetSortByOption","sortBy","facetOrderOption","facetExcludeOption","exclude","containerThemeCss","localFacetState","setLocalFacetState","facetItemsSavedCopy","setFacetItemsSavedCopy","facetItemsToRender","setFacetItemsToRender","facetItemValues","b","localeCompare","option","mappedItem","hideSearchBar","searchPlaceholder","facetListContainer","facetListItem","facetAllResultsListItem","StandardFacet","CludoSearchControls","composeControls","SortPickerComponent","sortPicker","FacetComponent","shouldShowSortPicker","defaultLanguage","coreScriptUrl","getPublicSettings","publicSettingsDataStr","Cludo","getPublicSettingsByOptions","experienceId","apiUrl","authKey","searchSiteKey","isIntranet","publicSettings","injectCoreScript","overrideCoreScriptUrl","Promise","resolve","reject","scriptUrl","script","createElement","onload","onerror","body","appendChild","initCludo","publicSettingsOptions","secureSearch","enable","headless","use","initCludoWithPublicSettings","cludoSettings","searchUrl","instanceId","clientTemplates","searchInputs","searchInputSelectors","headlessSearch","searchResultsWrapper","searchResultsWrapperSelector","intranetSearch","searchApiUrl","proxyApiUrl","customHttpHeaders","disableAutocomplete","autocomplete","disable","initFacets","defaultValues","hideResultsCount","hideSearchFilters","hideSearchDidYouMean","sortOptions","logPageVisits","tracking","skipLoggingPageVisits","useSearchAsYouType","autocompleteForceUseTemplate","renderTemplateWhenNoResults","autocompleteMinimumQueryLength","minimumQueryLength","applyMultiLevelFacets","applyMultiLevel","rangeFacets","rangeValues","pierceShadowDom","behavior","enableRelatedSearches","customNoResultsMessage","overrideStrings","noResultsMessage","enableVoiceSearch","voiceSearch","disableVoiceSearchActiveAnimation","disableActiveAnimation","useFixedQueryInResultsCount","showFixedQueryInResultsCount","allowSearchWithoutSearchword","jumpToTopOnFacetClick","enableExtendedTracking","disableExtendedTracking","customCallbackAfterSearch","callbacks","afterSearch","customCallbackBeforeSearch","beforeSearch","customCallbackBeforeRedirect","beforeRedirect","customCallbackAfterAutocomplete","afterAutocomplete","customCallbackBeforeQuicklink","beforeQuicklink","ovarlayResultsWrapperOpenClass","overlayResultsWrapperOpenClass","searchBoxPosition","themeColor","elementFocusColor","themeBannerColor","textColor","borderRadius","borderRadiusInput","showInstantSuggestions","suggestedSearchesHeader","recentSearchesHeader","googleAnalyticsTrackingId","googleAnalyticsId","translateSearchTemplates","changeWindowLocation","updateUrlOnSearch","urlListDelimiter","cludoInstance","translationRef","Language","assign","warn","categorizeResultsByField","topHitsFields","maxResultsPerCategory","size","maxCategories","MaxFieldValues","CludoInstanceController","setClientTemplateComponentsController","configureFeaturesFromPublicSettings","init","controls","isComponentConfigObject","containerSelector","renderEvents","controlsWrapperSelector","selector","custom","config","overrideSelector","DropdownInput","labelThemeCss","selectThemeCss","dropdown","htmlFor","currentValue","defaultValue","default","dropdownOption","ResultsPerPage","optionsMap","currentPerPage","SelectorComponent","selectorOption","Number","SaytCategorizedResult","CategorizedResult","FacetGroup","facetOrder","facetExclude","facetOverrides","Fragment","facetFields","facetFieldsRef","facetMap","useMemo","DefaultComponent","override","set","fallback","populateFacetGroupMap","CheckboxFacetItem","inputThemeCss","name","checked","handleFacetChange","CheckboxFacet","RadioFacetItem","RadioFacet","BaseIcon","width","height","viewbox","color","focusable","viewBox","fill","xmlns","CloseIcon","ICON_DIMENSION","ICON_FILL_COLOR","CurrentFacets","facetGroupState","facetGroupDispatchers","rootThemeCss","facetContainer","facetLabel","valueThemeCss","buttonThemeCss","facetRemoveButton","labelsMap","ClearAllFacets","ResultImage","imageSrc","imageField","imageAltText","altText","ResultBreadcrumbs","separator","textArray","linkArray","navCss","listItemLinkCss","listItemLink","separatorCss","populateBreadcrumbArr","arr","textSubarr","textField","textFieldDelimiter","linkFieldDelimiter","every","CludoWrapper","setSearchContext","eventContext","setEventContext","hasInitialized","setHasInitialized","onInit","then","windowObject","CludoSearchInstances","CludoAutocompleteContainer","autocompleteHintText","CludoResultsContainer","resultsWrapperId","CludoSearchInput","ariaLabel","isAutocompleteEnabled","CludoSearchForm","autocompleteEnabled","formId","uniqueFormId","useSearchInput","searchInputState","setSearchInputState","searchInputDispatchers","updatedQuery","setQuery","SearchIcon","fillRule","clipRule","SearchInput","buttonAriaLabel","inputAriaLabel","formCss","inputCss","buttonCss","submitButton","submitButtonContent","submitIcon","onSubmit","onBlur","useEndlessScroll","handleScroll","scrolledElement","Element","handleElementScroll","handleWindowScroll","scrollTop","clientHeight","scrollHeight","bottomOffset","scrollY","innerHeight","scrolledElementSelector","removeEventListener","state","setEndlessScrollState","endlessScrollState"],"sourceRoot":""}
|