UNPKG

1.21 MBSource Map (JSON)View Raw
1{"version":3,"file":"instantsearch.production.min.js","sources":["../node_modules/algoliasearch-helper/src/functions/merge.js","../node_modules/algoliasearch-helper/src/functions/defaultsPure.js","../node_modules/algoliasearch-helper/src/functions/intersection.js","../node_modules/algoliasearch-helper/src/functions/find.js","../node_modules/algoliasearch-helper/src/functions/valToNumber.js","../node_modules/algoliasearch-helper/src/functions/omit.js","../node_modules/algoliasearch-helper/src/functions/objectHasKeys.js","../node_modules/algoliasearch-helper/src/utils/isValidUserToken.js","../node_modules/algoliasearch-helper/src/SearchParameters/RefinementList.js","../node_modules/algoliasearch-helper/src/SearchParameters/index.js","../node_modules/algoliasearch-helper/src/functions/orderBy.js","../node_modules/algoliasearch-helper/src/functions/compact.js","../node_modules/algoliasearch-helper/src/functions/findIndex.js","../node_modules/algoliasearch-helper/src/functions/formatSort.js","../node_modules/algoliasearch-helper/src/SearchResults/generate-hierarchical-tree.js","../node_modules/algoliasearch-helper/src/SearchResults/index.js","../node_modules/@algolia/events/events.js","../node_modules/algoliasearch-helper/src/functions/inherits.js","../node_modules/algoliasearch-helper/src/DerivedHelper/index.js","../node_modules/algoliasearch-helper/src/requestBuilder.js","../node_modules/algoliasearch-helper/src/version.js","../node_modules/algoliasearch-helper/src/algoliasearch.helper.js","../node_modules/algoliasearch-helper/index.js","../src/lib/utils/defer.ts","../src/lib/utils/getContainerNode.ts","../src/lib/utils/isDomElement.ts","../src/lib/utils/isSpecialClick.ts","../src/lib/utils/uniq.ts","../src/lib/utils/prepareTemplateProps.ts","../node_modules/hogan.js/lib/compiler.js","../node_modules/hogan.js/lib/template.js","../node_modules/hogan.js/lib/hogan.js","../src/lib/utils/renderTemplate.ts","../src/lib/utils/find.ts","../src/lib/utils/unescapeRefinement.ts","../src/lib/utils/getRefinements.ts","../src/lib/utils/clearRefinements.ts","../src/lib/utils/escapeRefinement.ts","../src/lib/utils/checkRendering.ts","../src/lib/utils/getObjectType.ts","../src/lib/utils/noop.ts","../src/lib/utils/logger.ts","../src/lib/utils/getPropertyByPath.ts","../src/lib/utils/isFiniteNumber.ts","../src/lib/utils/isPlainObject.ts","../src/lib/utils/range.ts","../src/lib/utils/isEqual.ts","../src/lib/utils/escape.ts","../src/lib/utils/unescape.ts","../src/lib/utils/escape-highlight.ts","../src/lib/utils/concatHighlightedParts.ts","../src/lib/utils/getHighlightedParts.ts","../src/lib/utils/getHighlightFromSiblings.ts","../src/lib/utils/reverseHighlightedParts.ts","../src/lib/utils/mergeSearchParameters.ts","../src/lib/utils/findIndex.ts","../src/lib/utils/toArray.ts","../src/lib/utils/documentation.ts","../src/lib/utils/geo-search.ts","../src/lib/utils/hits-absolute-position.ts","../src/lib/utils/hits-query-id.ts","../src/lib/utils/createSendEventForFacet.ts","../src/lib/utils/isFacetRefined.ts","../src/lib/utils/serializer.ts","../src/lib/utils/createSendEventForHits.ts","../src/lib/utils/convertNumericRefinementsToFilters.ts","../src/lib/utils/debounce.ts","../src/lib/utils/getWidgetAttribute.ts","../src/lib/utils/safelyRunOnBrowser.ts","../src/widgets/index/index.ts","../src/lib/utils/resolveSearchParameters.ts","../src/lib/suit.ts","../src/helpers/highlight.ts","../src/helpers/reverseHighlight.ts","../src/helpers/snippet.ts","../src/helpers/reverseSnippet.ts","../src/helpers/insights.ts","../src/helpers/get-insights-anonymous-user-token.ts","../src/lib/stateMappings/simple.ts","../node_modules/qs/lib/utils.js","../node_modules/qs/lib/stringify.js","../node_modules/qs/lib/parse.js","../src/lib/routers/history.ts","../node_modules/qs/lib/formats.js","../node_modules/qs/lib/index.js","../src/middlewares/createRouterMiddleware.ts","../src/middlewares/createMetadataMiddleware.ts","../src/lib/InstantSearch.ts","../src/connectors/clear-refinements/connectClearRefinements.ts","../src/lib/version.ts","../src/lib/createHelpers.ts","../src/connectors/current-refinements/connectCurrentRefinements.ts","../src/connectors/hierarchical-menu/connectHierarchicalMenu.ts","../src/connectors/hits/connectHits.ts","../src/lib/insights/client.ts","../node_modules/preact/dist/preact.module.js","../src/lib/insights/listener.tsx","../src/connectors/hits-per-page/connectHitsPerPage.ts","../src/connectors/hits/connectHitsWithInsights.ts","../src/connectors/infinite-hits/connectInfiniteHits.ts","../src/connectors/menu/connectMenu.ts","../src/connectors/numeric-menu/connectNumericMenu.ts","../src/connectors/infinite-hits/connectInfiniteHitsWithInsights.ts","../src/connectors/pagination/connectPagination.ts","../src/connectors/pagination/Paginator.ts","../src/connectors/range/connectRange.ts","../src/connectors/refinement-list/connectRefinementList.ts","../src/connectors/search-box/connectSearchBox.ts","../src/connectors/sort-by/connectSortBy.ts","../src/connectors/rating-menu/connectRatingMenu.ts","../src/connectors/stats/connectStats.ts","../src/connectors/toggle-refinement/connectToggleRefinement.ts","../src/connectors/breadcrumb/connectBreadcrumb.ts","../src/connectors/geo-search/connectGeoSearch.ts","../src/connectors/powered-by/connectPoweredBy.ts","../src/connectors/configure/connectConfigure.ts","../src/connectors/configure-related-items/connectConfigureRelatedItems.ts","../src/connectors/autocomplete/connectAutocomplete.ts","../src/connectors/query-rules/connectQueryRules.ts","../src/lib/voiceSearchHelper/index.ts","../src/connectors/voice-search/connectVoiceSearch.ts","../src/connectors/answers/connectAnswers.ts","../src/lib/utils/createConcurrentSafePromise.ts","../src/connectors/relevant-sort/connectRelevantSort.ts","../src/connectors/dynamic-widgets/connectDynamicWidgets.ts","../src/connectors/index.ts","../src/widgets/analytics/analytics.ts","../node_modules/classnames/index.js","../src/components/Template/Template.tsx","../src/components/Breadcrumb/Breadcrumb.tsx","../src/components/ClearRefinements/ClearRefinements.tsx","../src/components/CurrentRefinements/CurrentRefinements.tsx","../src/lib/utils/capitalize.ts","../src/widgets/current-refinements/current-refinements.tsx","../src/components/Answers/Answers.tsx","../src/widgets/breadcrumb/defaultTemplates.ts","../src/widgets/breadcrumb/breadcrumb.tsx","../src/widgets/clear-refinements/defaultTemplates.ts","../src/widgets/clear-refinements/clear-refinements.tsx","../src/widgets/answers/defaultTemplates.ts","../src/widgets/answers/answers.tsx","../src/widgets/dynamic-widgets/dynamic-widgets.ts","../src/components/GeoSearchControls/GeoSearchButton.tsx","../src/components/GeoSearchControls/GeoSearchToggle.tsx","../src/components/GeoSearchControls/GeoSearchControls.tsx","../src/widgets/geo-search/GeoSearchRenderer.js","../src/widgets/geo-search/defaultTemplates.ts","../src/widgets/geo-search/geo-search.ts","../src/components/RefinementList/RefinementListItem.tsx","../src/components/SearchBox/SearchBox.tsx","../src/components/RefinementList/RefinementList.tsx","../src/components/Hits/Hits.tsx","../src/widgets/hierarchical-menu/defaultTemplates.ts","../src/widgets/hierarchical-menu/hierarchical-menu.tsx","../src/widgets/hits/defaultTemplates.ts","../src/widgets/hits/hits.tsx","../src/components/Selector/Selector.tsx","../src/widgets/hits-per-page/hits-per-page.tsx","../src/widgets/infinite-hits/defaultTemplates.ts","../src/widgets/infinite-hits/infinite-hits.tsx","../src/components/InfiniteHits/InfiniteHits.tsx","../src/widgets/menu/defaultTemplates.ts","../src/widgets/menu/menu.tsx","../src/components/MenuSelect/MenuSelect.tsx","../src/components/Pagination/PaginationLink.tsx","../src/widgets/menu-select/defaultTemplates.ts","../src/widgets/menu-select/menu-select.tsx","../src/widgets/numeric-menu/defaultTemplates.ts","../src/widgets/numeric-menu/numeric-menu.tsx","../src/components/Pagination/Pagination.tsx","../src/widgets/pagination/pagination.tsx","../node_modules/preact/hooks/dist/hooks.module.js","../src/components/Panel/Panel.tsx","../src/components/PoweredBy/PoweredBy.tsx","../src/components/QueryRuleCustomData/QueryRuleCustomData.tsx","../src/widgets/panel/panel.tsx","../src/widgets/powered-by/powered-by.tsx","../src/widgets/query-rule-context/query-rule-context.tsx","../src/widgets/query-rule-custom-data/query-rule-custom-data.tsx","../src/components/RangeInput/RangeInput.tsx","../src/widgets/range-input/range-input.tsx","../src/components/Slider/Rheostat.tsx","../src/components/Slider/Pit.tsx","../src/components/RelevantSort/RelevantSort.tsx","../src/components/Stats/Stats.tsx","../src/components/ToggleRefinement/ToggleRefinement.tsx","../src/components/VoiceSearch/VoiceSearch.tsx","../src/components/Slider/Slider.tsx","../src/widgets/range-slider/range-slider.tsx","../src/widgets/rating-menu/defaultTemplates.ts","../src/widgets/rating-menu/rating-menu.tsx","../src/widgets/search-box/defaultTemplates.ts","../src/widgets/refinement-list/defaultTemplates.ts","../src/widgets/refinement-list/refinement-list.tsx","../src/widgets/relevant-sort/defaultTemplates.ts","../src/widgets/relevant-sort/relevant-sort.tsx","../src/widgets/search-box/search-box.tsx","../src/widgets/sort-by/sort-by.tsx","../src/widgets/stats/stats.tsx","../src/widgets/toggle-refinement/defaultTemplates.ts","../src/widgets/toggle-refinement/toggle-refinement.tsx","../src/widgets/voice-search/defaultTemplates.ts","../src/widgets/voice-search/voice-search.tsx","../src/widgets/index.ts","../src/widgets/configure/configure.ts","../src/widgets/configure-related-items/configure-related-items.ts","../src/widgets/geo-search/createHTMLMarker.ts","../src/widgets/places/places.ts","../src/middlewares/createInsightsMiddleware.ts","../src/lib/utils/getAppIdAndApiKey.ts","../src/lib/stateMappings/singleIndex.ts","../src/lib/infiniteHitsCache/sessionStorage.ts","../src/index.ts"],"sourcesContent":["'use strict';\n\nfunction clone(value) {\n if (typeof value === 'object' && value !== null) {\n return _merge(Array.isArray(value) ? [] : {}, value);\n }\n return value;\n}\n\nfunction isObjectOrArrayOrFunction(value) {\n return (\n typeof value === 'function' ||\n Array.isArray(value) ||\n Object.prototype.toString.call(value) === '[object Object]'\n );\n}\n\nfunction _merge(target, source) {\n if (target === source) {\n return target;\n }\n\n for (var key in source) {\n if (\n !Object.prototype.hasOwnProperty.call(source, key) ||\n key === '__proto__'\n ) {\n continue;\n }\n\n var sourceVal = source[key];\n var targetVal = target[key];\n\n if (typeof targetVal !== 'undefined' && typeof sourceVal === 'undefined') {\n continue;\n }\n\n if (\n isObjectOrArrayOrFunction(targetVal) &&\n isObjectOrArrayOrFunction(sourceVal)\n ) {\n target[key] = _merge(targetVal, sourceVal);\n } else {\n target[key] = clone(sourceVal);\n }\n }\n return target;\n}\n\n/**\n * This method is like Object.assign, but recursively merges own and inherited\n * enumerable keyed properties of source objects into the destination object.\n *\n * NOTE: this behaves like lodash/merge, but:\n * - does mutate functions if they are a source\n * - treats non-plain objects as plain\n * - does not work for circular objects\n * - treats sparse arrays as sparse\n * - does not convert Array-like objects (Arguments, NodeLists, etc.) to arrays\n *\n * @param {Object} object The destination object.\n * @param {...Object} [sources] The source objects.\n * @returns {Object} Returns `object`.\n */\n\nfunction merge(target) {\n if (!isObjectOrArrayOrFunction(target)) {\n target = {};\n }\n\n for (var i = 1, l = arguments.length; i < l; i++) {\n var source = arguments[i];\n\n if (isObjectOrArrayOrFunction(source)) {\n _merge(target, source);\n }\n }\n return target;\n}\n\nmodule.exports = merge;\n","'use strict';\n\n// NOTE: this behaves like lodash/defaults, but doesn't mutate the target\n// it also preserve keys order\nmodule.exports = function defaultsPure() {\n var sources = Array.prototype.slice.call(arguments);\n\n return sources.reduceRight(function(acc, source) {\n Object.keys(Object(source)).forEach(function(key) {\n if (source[key] === undefined) {\n return;\n }\n if (acc[key] !== undefined) {\n // remove if already added, so that we can add it in correct order\n delete acc[key];\n }\n acc[key] = source[key];\n });\n return acc;\n }, {});\n};\n","'use strict';\n\nfunction intersection(arr1, arr2) {\n return arr1.filter(function(value, index) {\n return (\n arr2.indexOf(value) > -1 &&\n arr1.indexOf(value) === index /* skips duplicates */\n );\n });\n}\n\nmodule.exports = intersection;\n","'use strict';\n\n// @MAJOR can be replaced by native Array#find when we change support\nmodule.exports = function find(array, comparator) {\n if (!Array.isArray(array)) {\n return undefined;\n }\n\n for (var i = 0; i < array.length; i++) {\n if (comparator(array[i])) {\n return array[i];\n }\n }\n};\n","'use strict';\n\nfunction valToNumber(v) {\n if (typeof v === 'number') {\n return v;\n } else if (typeof v === 'string') {\n return parseFloat(v);\n } else if (Array.isArray(v)) {\n return v.map(valToNumber);\n }\n\n throw new Error('The value should be a number, a parsable string or an array of those.');\n}\n\nmodule.exports = valToNumber;\n","'use strict';\n\n// https://github.com/babel/babel/blob/3aaafae053fa75febb3aa45d45b6f00646e30ba4/packages/babel-helpers/src/helpers.js#L604-L620\nfunction _objectWithoutPropertiesLoose(source, excluded) {\n if (source === null) return {};\n var target = {};\n var sourceKeys = Object.keys(source);\n var key;\n var i;\n for (i = 0; i < sourceKeys.length; i++) {\n key = sourceKeys[i];\n if (excluded.indexOf(key) >= 0) continue;\n target[key] = source[key];\n }\n return target;\n}\n\nmodule.exports = _objectWithoutPropertiesLoose;\n","'use strict';\n\nfunction objectHasKeys(obj) {\n return obj && Object.keys(obj).length > 0;\n}\n\nmodule.exports = objectHasKeys;\n","'use strict';\n\nmodule.exports = function isValidUserToken(userToken) {\n if (userToken === null) {\n return false;\n }\n return /^[a-zA-Z0-9_-]{1,64}$/.test(userToken);\n};\n","'use strict';\n\n/**\n * Functions to manipulate refinement lists\n *\n * The RefinementList is not formally defined through a prototype but is based\n * on a specific structure.\n *\n * @module SearchParameters.refinementList\n *\n * @typedef {string[]} SearchParameters.refinementList.Refinements\n * @typedef {Object.<string, SearchParameters.refinementList.Refinements>} SearchParameters.refinementList.RefinementList\n */\n\nvar defaultsPure = require('../functions/defaultsPure');\nvar omit = require('../functions/omit');\nvar objectHasKeys = require('../functions/objectHasKeys');\n\nvar lib = {\n /**\n * Adds a refinement to a RefinementList\n * @param {RefinementList} refinementList the initial list\n * @param {string} attribute the attribute to refine\n * @param {string} value the value of the refinement, if the value is not a string it will be converted\n * @return {RefinementList} a new and updated refinement list\n */\n addRefinement: function addRefinement(refinementList, attribute, value) {\n if (lib.isRefined(refinementList, attribute, value)) {\n return refinementList;\n }\n\n var valueAsString = '' + value;\n\n var facetRefinement = !refinementList[attribute] ?\n [valueAsString] :\n refinementList[attribute].concat(valueAsString);\n\n var mod = {};\n\n mod[attribute] = facetRefinement;\n\n return defaultsPure({}, mod, refinementList);\n },\n /**\n * Removes refinement(s) for an attribute:\n * - if the value is specified removes the refinement for the value on the attribute\n * - if no value is specified removes all the refinements for this attribute\n * @param {RefinementList} refinementList the initial list\n * @param {string} attribute the attribute to refine\n * @param {string} [value] the value of the refinement\n * @return {RefinementList} a new and updated refinement lst\n */\n removeRefinement: function removeRefinement(refinementList, attribute, value) {\n if (value === undefined) {\n // we use the \"filter\" form of clearRefinement, since it leaves empty values as-is\n // the form with a string will remove the attribute completely\n return lib.clearRefinement(refinementList, function(v, f) {\n return attribute === f;\n });\n }\n\n var valueAsString = '' + value;\n\n return lib.clearRefinement(refinementList, function(v, f) {\n return attribute === f && valueAsString === v;\n });\n },\n /**\n * Toggles the refinement value for an attribute.\n * @param {RefinementList} refinementList the initial list\n * @param {string} attribute the attribute to refine\n * @param {string} value the value of the refinement\n * @return {RefinementList} a new and updated list\n */\n toggleRefinement: function toggleRefinement(refinementList, attribute, value) {\n if (value === undefined) throw new Error('toggleRefinement should be used with a value');\n\n if (lib.isRefined(refinementList, attribute, value)) {\n return lib.removeRefinement(refinementList, attribute, value);\n }\n\n return lib.addRefinement(refinementList, attribute, value);\n },\n /**\n * Clear all or parts of a RefinementList. Depending on the arguments, three\n * kinds of behavior can happen:\n * - if no attribute is provided: clears the whole list\n * - if an attribute is provided as a string: clears the list for the specific attribute\n * - if an attribute is provided as a function: discards the elements for which the function returns true\n * @param {RefinementList} refinementList the initial list\n * @param {string} [attribute] the attribute or function to discard\n * @param {string} [refinementType] optional parameter to give more context to the attribute function\n * @return {RefinementList} a new and updated refinement list\n */\n clearRefinement: function clearRefinement(refinementList, attribute, refinementType) {\n if (attribute === undefined) {\n if (!objectHasKeys(refinementList)) {\n return refinementList;\n }\n return {};\n } else if (typeof attribute === 'string') {\n return omit(refinementList, [attribute]);\n } else if (typeof attribute === 'function') {\n var hasChanged = false;\n\n var newRefinementList = Object.keys(refinementList).reduce(function(memo, key) {\n var values = refinementList[key] || [];\n var facetList = values.filter(function(value) {\n return !attribute(value, key, refinementType);\n });\n\n if (facetList.length !== values.length) {\n hasChanged = true;\n }\n memo[key] = facetList;\n\n return memo;\n }, {});\n\n if (hasChanged) return newRefinementList;\n return refinementList;\n }\n },\n /**\n * Test if the refinement value is used for the attribute. If no refinement value\n * is provided, test if the refinementList contains any refinement for the\n * given attribute.\n * @param {RefinementList} refinementList the list of refinement\n * @param {string} attribute name of the attribute\n * @param {string} [refinementValue] value of the filter/refinement\n * @return {boolean}\n */\n isRefined: function isRefined(refinementList, attribute, refinementValue) {\n var containsRefinements = !!refinementList[attribute] &&\n refinementList[attribute].length > 0;\n\n if (refinementValue === undefined || !containsRefinements) {\n return containsRefinements;\n }\n\n var refinementValueAsString = '' + refinementValue;\n\n return refinementList[attribute].indexOf(refinementValueAsString) !== -1;\n }\n};\n\nmodule.exports = lib;\n","'use strict';\n\nvar merge = require('../functions/merge');\nvar defaultsPure = require('../functions/defaultsPure');\nvar intersection = require('../functions/intersection');\nvar find = require('../functions/find');\nvar valToNumber = require('../functions/valToNumber');\nvar omit = require('../functions/omit');\nvar objectHasKeys = require('../functions/objectHasKeys');\nvar isValidUserToken = require('../utils/isValidUserToken');\n\nvar RefinementList = require('./RefinementList');\n\n/**\n * isEqual, but only for numeric refinement values, possible values:\n * - 5\n * - [5]\n * - [[5]]\n * - [[5,5],[4]]\n */\nfunction isEqualNumericRefinement(a, b) {\n if (Array.isArray(a) && Array.isArray(b)) {\n return (\n a.length === b.length &&\n a.every(function(el, i) {\n return isEqualNumericRefinement(b[i], el);\n })\n );\n }\n return a === b;\n}\n\n/**\n * like _.find but using deep equality to be able to use it\n * to find arrays.\n * @private\n * @param {any[]} array array to search into (elements are base or array of base)\n * @param {any} searchedValue the value we're looking for (base or array of base)\n * @return {any} the searched value or undefined\n */\nfunction findArray(array, searchedValue) {\n return find(array, function(currentValue) {\n return isEqualNumericRefinement(currentValue, searchedValue);\n });\n}\n\n/**\n * The facet list is the structure used to store the list of values used to\n * filter a single attribute.\n * @typedef {string[]} SearchParameters.FacetList\n */\n\n/**\n * Structure to store numeric filters with the operator as the key. The supported operators\n * are `=`, `>`, `<`, `>=`, `<=` and `!=`.\n * @typedef {Object.<string, Array.<number|number[]>>} SearchParameters.OperatorList\n */\n\n/**\n * SearchParameters is the data structure that contains all the information\n * usable for making a search to Algolia API. It doesn't do the search itself,\n * nor does it contains logic about the parameters.\n * It is an immutable object, therefore it has been created in a way that each\n * changes does not change the object itself but returns a copy with the\n * modification.\n * This object should probably not be instantiated outside of the helper. It will\n * be provided when needed. This object is documented for reference as you'll\n * get it from events generated by the {@link AlgoliaSearchHelper}.\n * If need be, instantiate the Helper from the factory function {@link SearchParameters.make}\n * @constructor\n * @classdesc contains all the parameters of a search\n * @param {object|SearchParameters} newParameters existing parameters or partial object\n * for the properties of a new SearchParameters\n * @see SearchParameters.make\n * @example <caption>SearchParameters of the first query in\n * <a href=\"http://demos.algolia.com/instant-search-demo/\">the instant search demo</a></caption>\n{\n \"query\": \"\",\n \"disjunctiveFacets\": [\n \"customerReviewCount\",\n \"category\",\n \"salePrice_range\",\n \"manufacturer\"\n ],\n \"maxValuesPerFacet\": 30,\n \"page\": 0,\n \"hitsPerPage\": 10,\n \"facets\": [\n \"type\",\n \"shipping\"\n ]\n}\n */\nfunction SearchParameters(newParameters) {\n var params = newParameters ? SearchParameters._parseNumbers(newParameters) : {};\n\n if (params.userToken !== undefined && !isValidUserToken(params.userToken)) {\n console.warn('[algoliasearch-helper] The `userToken` parameter is invalid. This can lead to wrong analytics.\\n - Format: [a-zA-Z0-9_-]{1,64}');\n }\n /**\n * This attribute contains the list of all the conjunctive facets\n * used. This list will be added to requested facets in the\n * [facets attribute](https://www.algolia.com/doc/rest-api/search#param-facets) sent to algolia.\n * @member {string[]}\n */\n this.facets = params.facets || [];\n /**\n * This attribute contains the list of all the disjunctive facets\n * used. This list will be added to requested facets in the\n * [facets attribute](https://www.algolia.com/doc/rest-api/search#param-facets) sent to algolia.\n * @member {string[]}\n */\n this.disjunctiveFacets = params.disjunctiveFacets || [];\n /**\n * This attribute contains the list of all the hierarchical facets\n * used. This list will be added to requested facets in the\n * [facets attribute](https://www.algolia.com/doc/rest-api/search#param-facets) sent to algolia.\n * Hierarchical facets are a sub type of disjunctive facets that\n * let you filter faceted attributes hierarchically.\n * @member {string[]|object[]}\n */\n this.hierarchicalFacets = params.hierarchicalFacets || [];\n\n // Refinements\n /**\n * This attribute contains all the filters that need to be\n * applied on the conjunctive facets. Each facet must be properly\n * defined in the `facets` attribute.\n *\n * The key is the name of the facet, and the `FacetList` contains all\n * filters selected for the associated facet name.\n *\n * When querying algolia, the values stored in this attribute will\n * be translated into the `facetFilters` attribute.\n * @member {Object.<string, SearchParameters.FacetList>}\n */\n this.facetsRefinements = params.facetsRefinements || {};\n /**\n * This attribute contains all the filters that need to be\n * excluded from the conjunctive facets. Each facet must be properly\n * defined in the `facets` attribute.\n *\n * The key is the name of the facet, and the `FacetList` contains all\n * filters excluded for the associated facet name.\n *\n * When querying algolia, the values stored in this attribute will\n * be translated into the `facetFilters` attribute.\n * @member {Object.<string, SearchParameters.FacetList>}\n */\n this.facetsExcludes = params.facetsExcludes || {};\n /**\n * This attribute contains all the filters that need to be\n * applied on the disjunctive facets. Each facet must be properly\n * defined in the `disjunctiveFacets` attribute.\n *\n * The key is the name of the facet, and the `FacetList` contains all\n * filters selected for the associated facet name.\n *\n * When querying algolia, the values stored in this attribute will\n * be translated into the `facetFilters` attribute.\n * @member {Object.<string, SearchParameters.FacetList>}\n */\n this.disjunctiveFacetsRefinements = params.disjunctiveFacetsRefinements || {};\n /**\n * This attribute contains all the filters that need to be\n * applied on the numeric attributes.\n *\n * The key is the name of the attribute, and the value is the\n * filters to apply to this attribute.\n *\n * When querying algolia, the values stored in this attribute will\n * be translated into the `numericFilters` attribute.\n * @member {Object.<string, SearchParameters.OperatorList>}\n */\n this.numericRefinements = params.numericRefinements || {};\n /**\n * This attribute contains all the tags used to refine the query.\n *\n * When querying algolia, the values stored in this attribute will\n * be translated into the `tagFilters` attribute.\n * @member {string[]}\n */\n this.tagRefinements = params.tagRefinements || [];\n /**\n * This attribute contains all the filters that need to be\n * applied on the hierarchical facets. Each facet must be properly\n * defined in the `hierarchicalFacets` attribute.\n *\n * The key is the name of the facet, and the `FacetList` contains all\n * filters selected for the associated facet name. The FacetList values\n * are structured as a string that contain the values for each level\n * separated by the configured separator.\n *\n * When querying algolia, the values stored in this attribute will\n * be translated into the `facetFilters` attribute.\n * @member {Object.<string, SearchParameters.FacetList>}\n */\n this.hierarchicalFacetsRefinements = params.hierarchicalFacetsRefinements || {};\n\n var self = this;\n Object.keys(params).forEach(function(paramName) {\n var isKeyKnown = SearchParameters.PARAMETERS.indexOf(paramName) !== -1;\n var isValueDefined = params[paramName] !== undefined;\n\n if (!isKeyKnown && isValueDefined) {\n self[paramName] = params[paramName];\n }\n });\n}\n\n/**\n * List all the properties in SearchParameters and therefore all the known Algolia properties\n * This doesn't contain any beta/hidden features.\n * @private\n */\nSearchParameters.PARAMETERS = Object.keys(new SearchParameters());\n\n/**\n * @private\n * @param {object} partialState full or part of a state\n * @return {object} a new object with the number keys as number\n */\nSearchParameters._parseNumbers = function(partialState) {\n // Do not reparse numbers in SearchParameters, they ought to be parsed already\n if (partialState instanceof SearchParameters) return partialState;\n\n var numbers = {};\n\n var numberKeys = [\n 'aroundPrecision',\n 'aroundRadius',\n 'getRankingInfo',\n 'minWordSizefor2Typos',\n 'minWordSizefor1Typo',\n 'page',\n 'maxValuesPerFacet',\n 'distinct',\n 'minimumAroundRadius',\n 'hitsPerPage',\n 'minProximity'\n ];\n\n numberKeys.forEach(function(k) {\n var value = partialState[k];\n if (typeof value === 'string') {\n var parsedValue = parseFloat(value);\n // global isNaN is ok to use here, value is only number or NaN\n numbers[k] = isNaN(parsedValue) ? value : parsedValue;\n }\n });\n\n // there's two formats of insideBoundingBox, we need to parse\n // the one which is an array of float geo rectangles\n if (Array.isArray(partialState.insideBoundingBox)) {\n numbers.insideBoundingBox = partialState.insideBoundingBox.map(function(geoRect) {\n if (Array.isArray(geoRect)) {\n return geoRect.map(function(value) {\n return parseFloat(value);\n });\n }\n return geoRect;\n });\n }\n\n if (partialState.numericRefinements) {\n var numericRefinements = {};\n Object.keys(partialState.numericRefinements).forEach(function(attribute) {\n var operators = partialState.numericRefinements[attribute] || {};\n numericRefinements[attribute] = {};\n Object.keys(operators).forEach(function(operator) {\n var values = operators[operator];\n var parsedValues = values.map(function(v) {\n if (Array.isArray(v)) {\n return v.map(function(vPrime) {\n if (typeof vPrime === 'string') {\n return parseFloat(vPrime);\n }\n return vPrime;\n });\n } else if (typeof v === 'string') {\n return parseFloat(v);\n }\n return v;\n });\n numericRefinements[attribute][operator] = parsedValues;\n });\n });\n numbers.numericRefinements = numericRefinements;\n }\n\n return merge({}, partialState, numbers);\n};\n\n/**\n * Factory for SearchParameters\n * @param {object|SearchParameters} newParameters existing parameters or partial\n * object for the properties of a new SearchParameters\n * @return {SearchParameters} frozen instance of SearchParameters\n */\nSearchParameters.make = function makeSearchParameters(newParameters) {\n var instance = new SearchParameters(newParameters);\n\n var hierarchicalFacets = newParameters.hierarchicalFacets || [];\n hierarchicalFacets.forEach(function(facet) {\n if (facet.rootPath) {\n var currentRefinement = instance.getHierarchicalRefinement(facet.name);\n\n if (currentRefinement.length > 0 && currentRefinement[0].indexOf(facet.rootPath) !== 0) {\n instance = instance.clearRefinements(facet.name);\n }\n\n // get it again in case it has been cleared\n currentRefinement = instance.getHierarchicalRefinement(facet.name);\n if (currentRefinement.length === 0) {\n instance = instance.toggleHierarchicalFacetRefinement(facet.name, facet.rootPath);\n }\n }\n });\n\n return instance;\n};\n\n/**\n * Validates the new parameters based on the previous state\n * @param {SearchParameters} currentState the current state\n * @param {object|SearchParameters} parameters the new parameters to set\n * @return {Error|null} Error if the modification is invalid, null otherwise\n */\nSearchParameters.validate = function(currentState, parameters) {\n var params = parameters || {};\n\n if (currentState.tagFilters && params.tagRefinements && params.tagRefinements.length > 0) {\n return new Error(\n '[Tags] Cannot switch from the managed tag API to the advanced API. It is probably ' +\n 'an error, if it is really what you want, you should first clear the tags with clearTags method.');\n }\n\n if (currentState.tagRefinements.length > 0 && params.tagFilters) {\n return new Error(\n '[Tags] Cannot switch from the advanced tag API to the managed API. It is probably ' +\n 'an error, if it is not, you should first clear the tags with clearTags method.');\n }\n\n if (\n currentState.numericFilters &&\n params.numericRefinements &&\n objectHasKeys(params.numericRefinements)\n ) {\n return new Error(\n \"[Numeric filters] Can't switch from the advanced to the managed API. It\" +\n ' is probably an error, if this is really what you want, you have to first' +\n ' clear the numeric filters.'\n );\n }\n\n if (objectHasKeys(currentState.numericRefinements) && params.numericFilters) {\n return new Error(\n \"[Numeric filters] Can't switch from the managed API to the advanced. It\" +\n ' is probably an error, if this is really what you want, you have to first' +\n ' clear the numeric filters.');\n }\n\n return null;\n};\n\nSearchParameters.prototype = {\n constructor: SearchParameters,\n\n /**\n * Remove all refinements (disjunctive + conjunctive + excludes + numeric filters)\n * @method\n * @param {undefined|string|SearchParameters.clearCallback} [attribute] optional string or function\n * - If not given, means to clear all the filters.\n * - If `string`, means to clear all refinements for the `attribute` named filter.\n * - If `function`, means to clear all the refinements that return truthy values.\n * @return {SearchParameters}\n */\n clearRefinements: function clearRefinements(attribute) {\n var patch = {\n numericRefinements: this._clearNumericRefinements(attribute),\n facetsRefinements: RefinementList.clearRefinement(\n this.facetsRefinements,\n attribute,\n 'conjunctiveFacet'\n ),\n facetsExcludes: RefinementList.clearRefinement(\n this.facetsExcludes,\n attribute,\n 'exclude'\n ),\n disjunctiveFacetsRefinements: RefinementList.clearRefinement(\n this.disjunctiveFacetsRefinements,\n attribute,\n 'disjunctiveFacet'\n ),\n hierarchicalFacetsRefinements: RefinementList.clearRefinement(\n this.hierarchicalFacetsRefinements,\n attribute,\n 'hierarchicalFacet'\n )\n };\n if (\n patch.numericRefinements === this.numericRefinements &&\n patch.facetsRefinements === this.facetsRefinements &&\n patch.facetsExcludes === this.facetsExcludes &&\n patch.disjunctiveFacetsRefinements === this.disjunctiveFacetsRefinements &&\n patch.hierarchicalFacetsRefinements === this.hierarchicalFacetsRefinements\n ) {\n return this;\n }\n return this.setQueryParameters(patch);\n },\n /**\n * Remove all the refined tags from the SearchParameters\n * @method\n * @return {SearchParameters}\n */\n clearTags: function clearTags() {\n if (this.tagFilters === undefined && this.tagRefinements.length === 0) return this;\n\n return this.setQueryParameters({\n tagFilters: undefined,\n tagRefinements: []\n });\n },\n /**\n * Set the index.\n * @method\n * @param {string} index the index name\n * @return {SearchParameters}\n */\n setIndex: function setIndex(index) {\n if (index === this.index) return this;\n\n return this.setQueryParameters({\n index: index\n });\n },\n /**\n * Query setter\n * @method\n * @param {string} newQuery value for the new query\n * @return {SearchParameters}\n */\n setQuery: function setQuery(newQuery) {\n if (newQuery === this.query) return this;\n\n return this.setQueryParameters({\n query: newQuery\n });\n },\n /**\n * Page setter\n * @method\n * @param {number} newPage new page number\n * @return {SearchParameters}\n */\n setPage: function setPage(newPage) {\n if (newPage === this.page) return this;\n\n return this.setQueryParameters({\n page: newPage\n });\n },\n /**\n * Facets setter\n * The facets are the simple facets, used for conjunctive (and) faceting.\n * @method\n * @param {string[]} facets all the attributes of the algolia records used for conjunctive faceting\n * @return {SearchParameters}\n */\n setFacets: function setFacets(facets) {\n return this.setQueryParameters({\n facets: facets\n });\n },\n /**\n * Disjunctive facets setter\n * Change the list of disjunctive (or) facets the helper chan handle.\n * @method\n * @param {string[]} facets all the attributes of the algolia records used for disjunctive faceting\n * @return {SearchParameters}\n */\n setDisjunctiveFacets: function setDisjunctiveFacets(facets) {\n return this.setQueryParameters({\n disjunctiveFacets: facets\n });\n },\n /**\n * HitsPerPage setter\n * Hits per page represents the number of hits retrieved for this query\n * @method\n * @param {number} n number of hits retrieved per page of results\n * @return {SearchParameters}\n */\n setHitsPerPage: function setHitsPerPage(n) {\n if (this.hitsPerPage === n) return this;\n\n return this.setQueryParameters({\n hitsPerPage: n\n });\n },\n /**\n * typoTolerance setter\n * Set the value of typoTolerance\n * @method\n * @param {string} typoTolerance new value of typoTolerance (\"true\", \"false\", \"min\" or \"strict\")\n * @return {SearchParameters}\n */\n setTypoTolerance: function setTypoTolerance(typoTolerance) {\n if (this.typoTolerance === typoTolerance) return this;\n\n return this.setQueryParameters({\n typoTolerance: typoTolerance\n });\n },\n /**\n * Add a numeric filter for a given attribute\n * When value is an array, they are combined with OR\n * When value is a single value, it will combined with AND\n * @method\n * @param {string} attribute attribute to set the filter on\n * @param {string} operator operator of the filter (possible values: =, >, >=, <, <=, !=)\n * @param {number | number[]} value value of the filter\n * @return {SearchParameters}\n * @example\n * // for price = 50 or 40\n * searchparameter.addNumericRefinement('price', '=', [50, 40]);\n * @example\n * // for size = 38 and 40\n * searchparameter.addNumericRefinement('size', '=', 38);\n * searchparameter.addNumericRefinement('size', '=', 40);\n */\n addNumericRefinement: function(attribute, operator, v) {\n var value = valToNumber(v);\n\n if (this.isNumericRefined(attribute, operator, value)) return this;\n\n var mod = merge({}, this.numericRefinements);\n\n mod[attribute] = merge({}, mod[attribute]);\n\n if (mod[attribute][operator]) {\n // Array copy\n mod[attribute][operator] = mod[attribute][operator].slice();\n // Add the element. Concat can't be used here because value can be an array.\n mod[attribute][operator].push(value);\n } else {\n mod[attribute][operator] = [value];\n }\n\n return this.setQueryParameters({\n numericRefinements: mod\n });\n },\n /**\n * Get the list of conjunctive refinements for a single facet\n * @param {string} facetName name of the attribute used for faceting\n * @return {string[]} list of refinements\n */\n getConjunctiveRefinements: function(facetName) {\n if (!this.isConjunctiveFacet(facetName)) {\n return [];\n }\n return this.facetsRefinements[facetName] || [];\n },\n /**\n * Get the list of disjunctive refinements for a single facet\n * @param {string} facetName name of the attribute used for faceting\n * @return {string[]} list of refinements\n */\n getDisjunctiveRefinements: function(facetName) {\n if (!this.isDisjunctiveFacet(facetName)) {\n return [];\n }\n return this.disjunctiveFacetsRefinements[facetName] || [];\n },\n /**\n * Get the list of hierarchical refinements for a single facet\n * @param {string} facetName name of the attribute used for faceting\n * @return {string[]} list of refinements\n */\n getHierarchicalRefinement: function(facetName) {\n // we send an array but we currently do not support multiple\n // hierarchicalRefinements for a hierarchicalFacet\n return this.hierarchicalFacetsRefinements[facetName] || [];\n },\n /**\n * Get the list of exclude refinements for a single facet\n * @param {string} facetName name of the attribute used for faceting\n * @return {string[]} list of refinements\n */\n getExcludeRefinements: function(facetName) {\n if (!this.isConjunctiveFacet(facetName)) {\n return [];\n }\n return this.facetsExcludes[facetName] || [];\n },\n\n /**\n * Remove all the numeric filter for a given (attribute, operator)\n * @method\n * @param {string} attribute attribute to set the filter on\n * @param {string} [operator] operator of the filter (possible values: =, >, >=, <, <=, !=)\n * @param {number} [number] the value to be removed\n * @return {SearchParameters}\n */\n removeNumericRefinement: function(attribute, operator, paramValue) {\n if (paramValue !== undefined) {\n if (!this.isNumericRefined(attribute, operator, paramValue)) {\n return this;\n }\n return this.setQueryParameters({\n numericRefinements: this._clearNumericRefinements(function(value, key) {\n return (\n key === attribute &&\n value.op === operator &&\n isEqualNumericRefinement(value.val, valToNumber(paramValue))\n );\n })\n });\n } else if (operator !== undefined) {\n if (!this.isNumericRefined(attribute, operator)) return this;\n return this.setQueryParameters({\n numericRefinements: this._clearNumericRefinements(function(value, key) {\n return key === attribute && value.op === operator;\n })\n });\n }\n\n if (!this.isNumericRefined(attribute)) return this;\n return this.setQueryParameters({\n numericRefinements: this._clearNumericRefinements(function(value, key) {\n return key === attribute;\n })\n });\n },\n /**\n * Get the list of numeric refinements for a single facet\n * @param {string} facetName name of the attribute used for faceting\n * @return {SearchParameters.OperatorList} list of refinements\n */\n getNumericRefinements: function(facetName) {\n return this.numericRefinements[facetName] || {};\n },\n /**\n * Return the current refinement for the (attribute, operator)\n * @param {string} attribute attribute in the record\n * @param {string} operator operator applied on the refined values\n * @return {Array.<number|number[]>} refined values\n */\n getNumericRefinement: function(attribute, operator) {\n return this.numericRefinements[attribute] && this.numericRefinements[attribute][operator];\n },\n /**\n * Clear numeric filters.\n * @method\n * @private\n * @param {string|SearchParameters.clearCallback} [attribute] optional string or function\n * - If not given, means to clear all the filters.\n * - If `string`, means to clear all refinements for the `attribute` named filter.\n * - If `function`, means to clear all the refinements that return truthy values.\n * @return {Object.<string, OperatorList>}\n */\n _clearNumericRefinements: function _clearNumericRefinements(attribute) {\n if (attribute === undefined) {\n if (!objectHasKeys(this.numericRefinements)) {\n return this.numericRefinements;\n }\n return {};\n } else if (typeof attribute === 'string') {\n return omit(this.numericRefinements, [attribute]);\n } else if (typeof attribute === 'function') {\n var hasChanged = false;\n var numericRefinements = this.numericRefinements;\n var newNumericRefinements = Object.keys(numericRefinements).reduce(function(memo, key) {\n var operators = numericRefinements[key];\n var operatorList = {};\n\n operators = operators || {};\n Object.keys(operators).forEach(function(operator) {\n var values = operators[operator] || [];\n var outValues = [];\n values.forEach(function(value) {\n var predicateResult = attribute({val: value, op: operator}, key, 'numeric');\n if (!predicateResult) outValues.push(value);\n });\n if (outValues.length !== values.length) {\n hasChanged = true;\n }\n operatorList[operator] = outValues;\n });\n\n memo[key] = operatorList;\n\n return memo;\n }, {});\n\n if (hasChanged) return newNumericRefinements;\n return this.numericRefinements;\n }\n },\n /**\n * Add a facet to the facets attribute of the helper configuration, if it\n * isn't already present.\n * @method\n * @param {string} facet facet name to add\n * @return {SearchParameters}\n */\n addFacet: function addFacet(facet) {\n if (this.isConjunctiveFacet(facet)) {\n return this;\n }\n\n return this.setQueryParameters({\n facets: this.facets.concat([facet])\n });\n },\n /**\n * Add a disjunctive facet to the disjunctiveFacets attribute of the helper\n * configuration, if it isn't already present.\n * @method\n * @param {string} facet disjunctive facet name to add\n * @return {SearchParameters}\n */\n addDisjunctiveFacet: function addDisjunctiveFacet(facet) {\n if (this.isDisjunctiveFacet(facet)) {\n return this;\n }\n\n return this.setQueryParameters({\n disjunctiveFacets: this.disjunctiveFacets.concat([facet])\n });\n },\n /**\n * Add a hierarchical facet to the hierarchicalFacets attribute of the helper\n * configuration.\n * @method\n * @param {object} hierarchicalFacet hierarchical facet to add\n * @return {SearchParameters}\n * @throws will throw an error if a hierarchical facet with the same name was already declared\n */\n addHierarchicalFacet: function addHierarchicalFacet(hierarchicalFacet) {\n if (this.isHierarchicalFacet(hierarchicalFacet.name)) {\n throw new Error(\n 'Cannot declare two hierarchical facets with the same name: `' + hierarchicalFacet.name + '`');\n }\n\n return this.setQueryParameters({\n hierarchicalFacets: this.hierarchicalFacets.concat([hierarchicalFacet])\n });\n },\n /**\n * Add a refinement on a \"normal\" facet\n * @method\n * @param {string} facet attribute to apply the faceting on\n * @param {string} value value of the attribute (will be converted to string)\n * @return {SearchParameters}\n */\n addFacetRefinement: function addFacetRefinement(facet, value) {\n if (!this.isConjunctiveFacet(facet)) {\n throw new Error(facet + ' is not defined in the facets attribute of the helper configuration');\n }\n if (RefinementList.isRefined(this.facetsRefinements, facet, value)) return this;\n\n return this.setQueryParameters({\n facetsRefinements: RefinementList.addRefinement(this.facetsRefinements, facet, value)\n });\n },\n /**\n * Exclude a value from a \"normal\" facet\n * @method\n * @param {string} facet attribute to apply the exclusion on\n * @param {string} value value of the attribute (will be converted to string)\n * @return {SearchParameters}\n */\n addExcludeRefinement: function addExcludeRefinement(facet, value) {\n if (!this.isConjunctiveFacet(facet)) {\n throw new Error(facet + ' is not defined in the facets attribute of the helper configuration');\n }\n if (RefinementList.isRefined(this.facetsExcludes, facet, value)) return this;\n\n return this.setQueryParameters({\n facetsExcludes: RefinementList.addRefinement(this.facetsExcludes, facet, value)\n });\n },\n /**\n * Adds a refinement on a disjunctive facet.\n * @method\n * @param {string} facet attribute to apply the faceting on\n * @param {string} value value of the attribute (will be converted to string)\n * @return {SearchParameters}\n */\n addDisjunctiveFacetRefinement: function addDisjunctiveFacetRefinement(facet, value) {\n if (!this.isDisjunctiveFacet(facet)) {\n throw new Error(\n facet + ' is not defined in the disjunctiveFacets attribute of the helper configuration');\n }\n\n if (RefinementList.isRefined(this.disjunctiveFacetsRefinements, facet, value)) return this;\n\n return this.setQueryParameters({\n disjunctiveFacetsRefinements: RefinementList.addRefinement(\n this.disjunctiveFacetsRefinements, facet, value)\n });\n },\n /**\n * addTagRefinement adds a tag to the list used to filter the results\n * @param {string} tag tag to be added\n * @return {SearchParameters}\n */\n addTagRefinement: function addTagRefinement(tag) {\n if (this.isTagRefined(tag)) return this;\n\n var modification = {\n tagRefinements: this.tagRefinements.concat(tag)\n };\n\n return this.setQueryParameters(modification);\n },\n /**\n * Remove a facet from the facets attribute of the helper configuration, if it\n * is present.\n * @method\n * @param {string} facet facet name to remove\n * @return {SearchParameters}\n */\n removeFacet: function removeFacet(facet) {\n if (!this.isConjunctiveFacet(facet)) {\n return this;\n }\n\n return this.clearRefinements(facet).setQueryParameters({\n facets: this.facets.filter(function(f) {\n return f !== facet;\n })\n });\n },\n /**\n * Remove a disjunctive facet from the disjunctiveFacets attribute of the\n * helper configuration, if it is present.\n * @method\n * @param {string} facet disjunctive facet name to remove\n * @return {SearchParameters}\n */\n removeDisjunctiveFacet: function removeDisjunctiveFacet(facet) {\n if (!this.isDisjunctiveFacet(facet)) {\n return this;\n }\n\n return this.clearRefinements(facet).setQueryParameters({\n disjunctiveFacets: this.disjunctiveFacets.filter(function(f) {\n return f !== facet;\n })\n });\n },\n /**\n * Remove a hierarchical facet from the hierarchicalFacets attribute of the\n * helper configuration, if it is present.\n * @method\n * @param {string} facet hierarchical facet name to remove\n * @return {SearchParameters}\n */\n removeHierarchicalFacet: function removeHierarchicalFacet(facet) {\n if (!this.isHierarchicalFacet(facet)) {\n return this;\n }\n\n return this.clearRefinements(facet).setQueryParameters({\n hierarchicalFacets: this.hierarchicalFacets.filter(function(f) {\n return f.name !== facet;\n })\n });\n },\n /**\n * Remove a refinement set on facet. If a value is provided, it will clear the\n * refinement for the given value, otherwise it will clear all the refinement\n * values for the faceted attribute.\n * @method\n * @param {string} facet name of the attribute used for faceting\n * @param {string} [value] value used to filter\n * @return {SearchParameters}\n */\n removeFacetRefinement: function removeFacetRefinement(facet, value) {\n if (!this.isConjunctiveFacet(facet)) {\n throw new Error(facet + ' is not defined in the facets attribute of the helper configuration');\n }\n if (!RefinementList.isRefined(this.facetsRefinements, facet, value)) return this;\n\n return this.setQueryParameters({\n facetsRefinements: RefinementList.removeRefinement(this.facetsRefinements, facet, value)\n });\n },\n /**\n * Remove a negative refinement on a facet\n * @method\n * @param {string} facet name of the attribute used for faceting\n * @param {string} value value used to filter\n * @return {SearchParameters}\n */\n removeExcludeRefinement: function removeExcludeRefinement(facet, value) {\n if (!this.isConjunctiveFacet(facet)) {\n throw new Error(facet + ' is not defined in the facets attribute of the helper configuration');\n }\n if (!RefinementList.isRefined(this.facetsExcludes, facet, value)) return this;\n\n return this.setQueryParameters({\n facetsExcludes: RefinementList.removeRefinement(this.facetsExcludes, facet, value)\n });\n },\n /**\n * Remove a refinement on a disjunctive facet\n * @method\n * @param {string} facet name of the attribute used for faceting\n * @param {string} value value used to filter\n * @return {SearchParameters}\n */\n removeDisjunctiveFacetRefinement: function removeDisjunctiveFacetRefinement(facet, value) {\n if (!this.isDisjunctiveFacet(facet)) {\n throw new Error(\n facet + ' is not defined in the disjunctiveFacets attribute of the helper configuration');\n }\n if (!RefinementList.isRefined(this.disjunctiveFacetsRefinements, facet, value)) return this;\n\n return this.setQueryParameters({\n disjunctiveFacetsRefinements: RefinementList.removeRefinement(\n this.disjunctiveFacetsRefinements, facet, value)\n });\n },\n /**\n * Remove a tag from the list of tag refinements\n * @method\n * @param {string} tag the tag to remove\n * @return {SearchParameters}\n */\n removeTagRefinement: function removeTagRefinement(tag) {\n if (!this.isTagRefined(tag)) return this;\n\n var modification = {\n tagRefinements: this.tagRefinements.filter(function(t) {\n return t !== tag;\n })\n };\n\n return this.setQueryParameters(modification);\n },\n /**\n * Generic toggle refinement method to use with facet, disjunctive facets\n * and hierarchical facets\n * @param {string} facet the facet to refine\n * @param {string} value the associated value\n * @return {SearchParameters}\n * @throws will throw an error if the facet is not declared in the settings of the helper\n * @deprecated since version 2.19.0, see {@link SearchParameters#toggleFacetRefinement}\n */\n toggleRefinement: function toggleRefinement(facet, value) {\n return this.toggleFacetRefinement(facet, value);\n },\n /**\n * Generic toggle refinement method to use with facet, disjunctive facets\n * and hierarchical facets\n * @param {string} facet the facet to refine\n * @param {string} value the associated value\n * @return {SearchParameters}\n * @throws will throw an error if the facet is not declared in the settings of the helper\n */\n toggleFacetRefinement: function toggleFacetRefinement(facet, value) {\n if (this.isHierarchicalFacet(facet)) {\n return this.toggleHierarchicalFacetRefinement(facet, value);\n } else if (this.isConjunctiveFacet(facet)) {\n return this.toggleConjunctiveFacetRefinement(facet, value);\n } else if (this.isDisjunctiveFacet(facet)) {\n return this.toggleDisjunctiveFacetRefinement(facet, value);\n }\n\n throw new Error('Cannot refine the undeclared facet ' + facet +\n '; it should be added to the helper options facets, disjunctiveFacets or hierarchicalFacets');\n },\n /**\n * Switch the refinement applied over a facet/value\n * @method\n * @param {string} facet name of the attribute used for faceting\n * @param {value} value value used for filtering\n * @return {SearchParameters}\n */\n toggleConjunctiveFacetRefinement: function toggleConjunctiveFacetRefinement(facet, value) {\n if (!this.isConjunctiveFacet(facet)) {\n throw new Error(facet + ' is not defined in the facets attribute of the helper configuration');\n }\n\n return this.setQueryParameters({\n facetsRefinements: RefinementList.toggleRefinement(this.facetsRefinements, facet, value)\n });\n },\n /**\n * Switch the refinement applied over a facet/value\n * @method\n * @param {string} facet name of the attribute used for faceting\n * @param {value} value value used for filtering\n * @return {SearchParameters}\n */\n toggleExcludeFacetRefinement: function toggleExcludeFacetRefinement(facet, value) {\n if (!this.isConjunctiveFacet(facet)) {\n throw new Error(facet + ' is not defined in the facets attribute of the helper configuration');\n }\n\n return this.setQueryParameters({\n facetsExcludes: RefinementList.toggleRefinement(this.facetsExcludes, facet, value)\n });\n },\n /**\n * Switch the refinement applied over a facet/value\n * @method\n * @param {string} facet name of the attribute used for faceting\n * @param {value} value value used for filtering\n * @return {SearchParameters}\n */\n toggleDisjunctiveFacetRefinement: function toggleDisjunctiveFacetRefinement(facet, value) {\n if (!this.isDisjunctiveFacet(facet)) {\n throw new Error(\n facet + ' is not defined in the disjunctiveFacets attribute of the helper configuration');\n }\n\n return this.setQueryParameters({\n disjunctiveFacetsRefinements: RefinementList.toggleRefinement(\n this.disjunctiveFacetsRefinements, facet, value)\n });\n },\n /**\n * Switch the refinement applied over a facet/value\n * @method\n * @param {string} facet name of the attribute used for faceting\n * @param {value} value value used for filtering\n * @return {SearchParameters}\n */\n toggleHierarchicalFacetRefinement: function toggleHierarchicalFacetRefinement(facet, value) {\n if (!this.isHierarchicalFacet(facet)) {\n throw new Error(\n facet + ' is not defined in the hierarchicalFacets attribute of the helper configuration');\n }\n\n var separator = this._getHierarchicalFacetSeparator(this.getHierarchicalFacetByName(facet));\n\n var mod = {};\n\n var upOneOrMultipleLevel = this.hierarchicalFacetsRefinements[facet] !== undefined &&\n this.hierarchicalFacetsRefinements[facet].length > 0 && (\n // remove current refinement:\n // refinement was 'beer > IPA', call is toggleRefine('beer > IPA'), refinement should be `beer`\n this.hierarchicalFacetsRefinements[facet][0] === value ||\n // remove a parent refinement of the current refinement:\n // - refinement was 'beer > IPA > Flying dog'\n // - call is toggleRefine('beer > IPA')\n // - refinement should be `beer`\n this.hierarchicalFacetsRefinements[facet][0].indexOf(value + separator) === 0\n );\n\n if (upOneOrMultipleLevel) {\n if (value.indexOf(separator) === -1) {\n // go back to root level\n mod[facet] = [];\n } else {\n mod[facet] = [value.slice(0, value.lastIndexOf(separator))];\n }\n } else {\n mod[facet] = [value];\n }\n\n return this.setQueryParameters({\n hierarchicalFacetsRefinements: defaultsPure({}, mod, this.hierarchicalFacetsRefinements)\n });\n },\n\n /**\n * Adds a refinement on a hierarchical facet.\n * @param {string} facet the facet name\n * @param {string} path the hierarchical facet path\n * @return {SearchParameter} the new state\n * @throws Error if the facet is not defined or if the facet is refined\n */\n addHierarchicalFacetRefinement: function(facet, path) {\n if (this.isHierarchicalFacetRefined(facet)) {\n throw new Error(facet + ' is already refined.');\n }\n if (!this.isHierarchicalFacet(facet)) {\n throw new Error(facet + ' is not defined in the hierarchicalFacets attribute of the helper configuration.');\n }\n var mod = {};\n mod[facet] = [path];\n return this.setQueryParameters({\n hierarchicalFacetsRefinements: defaultsPure({}, mod, this.hierarchicalFacetsRefinements)\n });\n },\n\n /**\n * Removes the refinement set on a hierarchical facet.\n * @param {string} facet the facet name\n * @return {SearchParameter} the new state\n * @throws Error if the facet is not defined or if the facet is not refined\n */\n removeHierarchicalFacetRefinement: function(facet) {\n if (!this.isHierarchicalFacetRefined(facet)) {\n return this;\n }\n var mod = {};\n mod[facet] = [];\n return this.setQueryParameters({\n hierarchicalFacetsRefinements: defaultsPure({}, mod, this.hierarchicalFacetsRefinements)\n });\n },\n /**\n * Switch the tag refinement\n * @method\n * @param {string} tag the tag to remove or add\n * @return {SearchParameters}\n */\n toggleTagRefinement: function toggleTagRefinement(tag) {\n if (this.isTagRefined(tag)) {\n return this.removeTagRefinement(tag);\n }\n\n return this.addTagRefinement(tag);\n },\n /**\n * Test if the facet name is from one of the disjunctive facets\n * @method\n * @param {string} facet facet name to test\n * @return {boolean}\n */\n isDisjunctiveFacet: function(facet) {\n return this.disjunctiveFacets.indexOf(facet) > -1;\n },\n /**\n * Test if the facet name is from one of the hierarchical facets\n * @method\n * @param {string} facetName facet name to test\n * @return {boolean}\n */\n isHierarchicalFacet: function(facetName) {\n return this.getHierarchicalFacetByName(facetName) !== undefined;\n },\n /**\n * Test if the facet name is from one of the conjunctive/normal facets\n * @method\n * @param {string} facet facet name to test\n * @return {boolean}\n */\n isConjunctiveFacet: function(facet) {\n return this.facets.indexOf(facet) > -1;\n },\n /**\n * Returns true if the facet is refined, either for a specific value or in\n * general.\n * @method\n * @param {string} facet name of the attribute for used for faceting\n * @param {string} value, optional value. If passed will test that this value\n * is filtering the given facet.\n * @return {boolean} returns true if refined\n */\n isFacetRefined: function isFacetRefined(facet, value) {\n if (!this.isConjunctiveFacet(facet)) {\n return false;\n }\n return RefinementList.isRefined(this.facetsRefinements, facet, value);\n },\n /**\n * Returns true if the facet contains exclusions or if a specific value is\n * excluded.\n *\n * @method\n * @param {string} facet name of the attribute for used for faceting\n * @param {string} [value] optional value. If passed will test that this value\n * is filtering the given facet.\n * @return {boolean} returns true if refined\n */\n isExcludeRefined: function isExcludeRefined(facet, value) {\n if (!this.isConjunctiveFacet(facet)) {\n return false;\n }\n return RefinementList.isRefined(this.facetsExcludes, facet, value);\n },\n /**\n * Returns true if the facet contains a refinement, or if a value passed is a\n * refinement for the facet.\n * @method\n * @param {string} facet name of the attribute for used for faceting\n * @param {string} value optional, will test if the value is used for refinement\n * if there is one, otherwise will test if the facet contains any refinement\n * @return {boolean}\n */\n isDisjunctiveFacetRefined: function isDisjunctiveFacetRefined(facet, value) {\n if (!this.isDisjunctiveFacet(facet)) {\n return false;\n }\n return RefinementList.isRefined(this.disjunctiveFacetsRefinements, facet, value);\n },\n /**\n * Returns true if the facet contains a refinement, or if a value passed is a\n * refinement for the facet.\n * @method\n * @param {string} facet name of the attribute for used for faceting\n * @param {string} value optional, will test if the value is used for refinement\n * if there is one, otherwise will test if the facet contains any refinement\n * @return {boolean}\n */\n isHierarchicalFacetRefined: function isHierarchicalFacetRefined(facet, value) {\n if (!this.isHierarchicalFacet(facet)) {\n return false;\n }\n\n var refinements = this.getHierarchicalRefinement(facet);\n\n if (!value) {\n return refinements.length > 0;\n }\n\n return refinements.indexOf(value) !== -1;\n },\n /**\n * Test if the triple (attribute, operator, value) is already refined.\n * If only the attribute and the operator are provided, it tests if the\n * contains any refinement value.\n * @method\n * @param {string} attribute attribute for which the refinement is applied\n * @param {string} [operator] operator of the refinement\n * @param {string} [value] value of the refinement\n * @return {boolean} true if it is refined\n */\n isNumericRefined: function isNumericRefined(attribute, operator, value) {\n if (value === undefined && operator === undefined) {\n return !!this.numericRefinements[attribute];\n }\n\n var isOperatorDefined =\n this.numericRefinements[attribute] &&\n this.numericRefinements[attribute][operator] !== undefined;\n\n if (value === undefined || !isOperatorDefined) {\n return isOperatorDefined;\n }\n\n var parsedValue = valToNumber(value);\n var isAttributeValueDefined =\n findArray(this.numericRefinements[attribute][operator], parsedValue) !==\n undefined;\n\n return isOperatorDefined && isAttributeValueDefined;\n },\n /**\n * Returns true if the tag refined, false otherwise\n * @method\n * @param {string} tag the tag to check\n * @return {boolean}\n */\n isTagRefined: function isTagRefined(tag) {\n return this.tagRefinements.indexOf(tag) !== -1;\n },\n /**\n * Returns the list of all disjunctive facets refined\n * @method\n * @param {string} facet name of the attribute used for faceting\n * @param {value} value value used for filtering\n * @return {string[]}\n */\n getRefinedDisjunctiveFacets: function getRefinedDisjunctiveFacets() {\n var self = this;\n\n // attributes used for numeric filter can also be disjunctive\n var disjunctiveNumericRefinedFacets = intersection(\n Object.keys(this.numericRefinements).filter(function(facet) {\n return Object.keys(self.numericRefinements[facet]).length > 0;\n }),\n this.disjunctiveFacets\n );\n\n return Object.keys(this.disjunctiveFacetsRefinements).filter(function(facet) {\n return self.disjunctiveFacetsRefinements[facet].length > 0;\n })\n .concat(disjunctiveNumericRefinedFacets)\n .concat(this.getRefinedHierarchicalFacets());\n },\n /**\n * Returns the list of all disjunctive facets refined\n * @method\n * @param {string} facet name of the attribute used for faceting\n * @param {value} value value used for filtering\n * @return {string[]}\n */\n getRefinedHierarchicalFacets: function getRefinedHierarchicalFacets() {\n var self = this;\n return intersection(\n // enforce the order between the two arrays,\n // so that refinement name index === hierarchical facet index\n this.hierarchicalFacets.map(function(facet) { return facet.name; }),\n Object.keys(this.hierarchicalFacetsRefinements).filter(function(facet) {\n return self.hierarchicalFacetsRefinements[facet].length > 0;\n })\n );\n },\n /**\n * Returned the list of all disjunctive facets not refined\n * @method\n * @return {string[]}\n */\n getUnrefinedDisjunctiveFacets: function() {\n var refinedFacets = this.getRefinedDisjunctiveFacets();\n\n return this.disjunctiveFacets.filter(function(f) {\n return refinedFacets.indexOf(f) === -1;\n });\n },\n\n managedParameters: [\n 'index',\n\n 'facets',\n 'disjunctiveFacets',\n 'facetsRefinements',\n 'hierarchicalFacets',\n 'facetsExcludes',\n\n 'disjunctiveFacetsRefinements',\n 'numericRefinements',\n 'tagRefinements',\n 'hierarchicalFacetsRefinements'\n ],\n getQueryParams: function getQueryParams() {\n var managedParameters = this.managedParameters;\n\n var queryParams = {};\n\n var self = this;\n Object.keys(this).forEach(function(paramName) {\n var paramValue = self[paramName];\n if (managedParameters.indexOf(paramName) === -1 && paramValue !== undefined) {\n queryParams[paramName] = paramValue;\n }\n });\n\n return queryParams;\n },\n /**\n * Let the user set a specific value for a given parameter. Will return the\n * same instance if the parameter is invalid or if the value is the same as the\n * previous one.\n * @method\n * @param {string} parameter the parameter name\n * @param {any} value the value to be set, must be compliant with the definition\n * of the attribute on the object\n * @return {SearchParameters} the updated state\n */\n setQueryParameter: function setParameter(parameter, value) {\n if (this[parameter] === value) return this;\n\n var modification = {};\n\n modification[parameter] = value;\n\n return this.setQueryParameters(modification);\n },\n /**\n * Let the user set any of the parameters with a plain object.\n * @method\n * @param {object} params all the keys and the values to be updated\n * @return {SearchParameters} a new updated instance\n */\n setQueryParameters: function setQueryParameters(params) {\n if (!params) return this;\n\n var error = SearchParameters.validate(this, params);\n\n if (error) {\n throw error;\n }\n\n var self = this;\n var nextWithNumbers = SearchParameters._parseNumbers(params);\n var previousPlainObject = Object.keys(this).reduce(function(acc, key) {\n acc[key] = self[key];\n return acc;\n }, {});\n\n var nextPlainObject = Object.keys(nextWithNumbers).reduce(\n function(previous, key) {\n var isPreviousValueDefined = previous[key] !== undefined;\n var isNextValueDefined = nextWithNumbers[key] !== undefined;\n\n if (isPreviousValueDefined && !isNextValueDefined) {\n return omit(previous, [key]);\n }\n\n if (isNextValueDefined) {\n previous[key] = nextWithNumbers[key];\n }\n\n return previous;\n },\n previousPlainObject\n );\n\n return new this.constructor(nextPlainObject);\n },\n\n /**\n * Returns a new instance with the page reset. Two scenarios possible:\n * the page is omitted -> return the given instance\n * the page is set -> return a new instance with a page of 0\n * @return {SearchParameters} a new updated instance\n */\n resetPage: function() {\n if (this.page === undefined) {\n return this;\n }\n\n return this.setPage(0);\n },\n\n /**\n * Helper function to get the hierarchicalFacet separator or the default one (`>`)\n * @param {object} hierarchicalFacet\n * @return {string} returns the hierarchicalFacet.separator or `>` as default\n */\n _getHierarchicalFacetSortBy: function(hierarchicalFacet) {\n return hierarchicalFacet.sortBy || ['isRefined:desc', 'name:asc'];\n },\n\n /**\n * Helper function to get the hierarchicalFacet separator or the default one (`>`)\n * @private\n * @param {object} hierarchicalFacet\n * @return {string} returns the hierarchicalFacet.separator or `>` as default\n */\n _getHierarchicalFacetSeparator: function(hierarchicalFacet) {\n return hierarchicalFacet.separator || ' > ';\n },\n\n /**\n * Helper function to get the hierarchicalFacet prefix path or null\n * @private\n * @param {object} hierarchicalFacet\n * @return {string} returns the hierarchicalFacet.rootPath or null as default\n */\n _getHierarchicalRootPath: function(hierarchicalFacet) {\n return hierarchicalFacet.rootPath || null;\n },\n\n /**\n * Helper function to check if we show the parent level of the hierarchicalFacet\n * @private\n * @param {object} hierarchicalFacet\n * @return {string} returns the hierarchicalFacet.showParentLevel or true as default\n */\n _getHierarchicalShowParentLevel: function(hierarchicalFacet) {\n if (typeof hierarchicalFacet.showParentLevel === 'boolean') {\n return hierarchicalFacet.showParentLevel;\n }\n return true;\n },\n\n /**\n * Helper function to get the hierarchicalFacet by it's name\n * @param {string} hierarchicalFacetName\n * @return {object} a hierarchicalFacet\n */\n getHierarchicalFacetByName: function(hierarchicalFacetName) {\n return find(\n this.hierarchicalFacets,\n function(f) {\n return f.name === hierarchicalFacetName;\n }\n );\n },\n\n /**\n * Get the current breadcrumb for a hierarchical facet, as an array\n * @param {string} facetName Hierarchical facet name\n * @return {array.<string>} the path as an array of string\n */\n getHierarchicalFacetBreadcrumb: function(facetName) {\n if (!this.isHierarchicalFacet(facetName)) {\n return [];\n }\n\n var refinement = this.getHierarchicalRefinement(facetName)[0];\n if (!refinement) return [];\n\n var separator = this._getHierarchicalFacetSeparator(\n this.getHierarchicalFacetByName(facetName)\n );\n var path = refinement.split(separator);\n return path.map(function(part) {\n return part.trim();\n });\n },\n\n toString: function() {\n return JSON.stringify(this, null, 2);\n }\n};\n\n/**\n * Callback used for clearRefinement method\n * @callback SearchParameters.clearCallback\n * @param {OperatorList|FacetList} value the value of the filter\n * @param {string} key the current attribute name\n * @param {string} type `numeric`, `disjunctiveFacet`, `conjunctiveFacet`, `hierarchicalFacet` or `exclude`\n * depending on the type of facet\n * @return {boolean} `true` if the element should be removed. `false` otherwise.\n */\nmodule.exports = SearchParameters;\n","'use strict';\n\nfunction compareAscending(value, other) {\n if (value !== other) {\n var valIsDefined = value !== undefined;\n var valIsNull = value === null;\n\n var othIsDefined = other !== undefined;\n var othIsNull = other === null;\n\n if (\n (!othIsNull && value > other) ||\n (valIsNull && othIsDefined) ||\n !valIsDefined\n ) {\n return 1;\n }\n if (\n (!valIsNull && value < other) ||\n (othIsNull && valIsDefined) ||\n !othIsDefined\n ) {\n return -1;\n }\n }\n return 0;\n}\n\n/**\n * @param {Array<object>} collection object with keys in attributes\n * @param {Array<string>} iteratees attributes\n * @param {Array<string>} orders asc | desc\n */\nfunction orderBy(collection, iteratees, orders) {\n if (!Array.isArray(collection)) {\n return [];\n }\n\n if (!Array.isArray(orders)) {\n orders = [];\n }\n\n var result = collection.map(function(value, index) {\n return {\n criteria: iteratees.map(function(iteratee) {\n return value[iteratee];\n }),\n index: index,\n value: value\n };\n });\n\n result.sort(function comparer(object, other) {\n var index = -1;\n\n while (++index < object.criteria.length) {\n var res = compareAscending(object.criteria[index], other.criteria[index]);\n if (res) {\n if (index >= orders.length) {\n return res;\n }\n if (orders[index] === 'desc') {\n return -res;\n }\n return res;\n }\n }\n\n // This ensures a stable sort in V8 and other engines.\n // See https://bugs.chromium.org/p/v8/issues/detail?id=90 for more details.\n return object.index - other.index;\n });\n\n return result.map(function(res) {\n return res.value;\n });\n}\n\nmodule.exports = orderBy;\n","'use strict';\n\nmodule.exports = function compact(array) {\n if (!Array.isArray(array)) {\n return [];\n }\n\n return array.filter(Boolean);\n};\n","'use strict';\n\n// @MAJOR can be replaced by native Array#findIndex when we change support\nmodule.exports = function find(array, comparator) {\n if (!Array.isArray(array)) {\n return -1;\n }\n\n for (var i = 0; i < array.length; i++) {\n if (comparator(array[i])) {\n return i;\n }\n }\n return -1;\n};\n","'use strict';\n\nvar find = require('./find');\n\n/**\n * Transform sort format from user friendly notation to lodash format\n * @param {string[]} sortBy array of predicate of the form \"attribute:order\"\n * @param {string[]} [defaults] array of predicate of the form \"attribute:order\"\n * @return {array.<string[]>} array containing 2 elements : attributes, orders\n */\nmodule.exports = function formatSort(sortBy, defaults) {\n var defaultInstructions = (defaults || []).map(function(sort) {\n return sort.split(':');\n });\n\n return sortBy.reduce(\n function preparePredicate(out, sort) {\n var sortInstruction = sort.split(':');\n\n var matchingDefault = find(defaultInstructions, function(\n defaultInstruction\n ) {\n return defaultInstruction[0] === sortInstruction[0];\n });\n\n if (sortInstruction.length > 1 || !matchingDefault) {\n out[0].push(sortInstruction[0]);\n out[1].push(sortInstruction[1]);\n return out;\n }\n\n out[0].push(matchingDefault[0]);\n out[1].push(matchingDefault[1]);\n return out;\n },\n [[], []]\n );\n};\n","'use strict';\n\nmodule.exports = generateTrees;\n\nvar orderBy = require('../functions/orderBy');\nvar find = require('../functions/find');\nvar prepareHierarchicalFacetSortBy = require('../functions/formatSort');\n\nfunction generateTrees(state) {\n return function generate(hierarchicalFacetResult, hierarchicalFacetIndex) {\n var hierarchicalFacet = state.hierarchicalFacets[hierarchicalFacetIndex];\n var hierarchicalFacetRefinement =\n (state.hierarchicalFacetsRefinements[hierarchicalFacet.name] &&\n state.hierarchicalFacetsRefinements[hierarchicalFacet.name][0]) ||\n '';\n var hierarchicalSeparator = state._getHierarchicalFacetSeparator(\n hierarchicalFacet\n );\n var hierarchicalRootPath = state._getHierarchicalRootPath(\n hierarchicalFacet\n );\n var hierarchicalShowParentLevel = state._getHierarchicalShowParentLevel(\n hierarchicalFacet\n );\n var sortBy = prepareHierarchicalFacetSortBy(\n state._getHierarchicalFacetSortBy(hierarchicalFacet)\n );\n\n var rootExhaustive = hierarchicalFacetResult.every(function(facetResult) {\n return facetResult.exhaustive;\n });\n\n var generateTreeFn = generateHierarchicalTree(\n sortBy,\n hierarchicalSeparator,\n hierarchicalRootPath,\n hierarchicalShowParentLevel,\n hierarchicalFacetRefinement\n );\n\n var results = hierarchicalFacetResult;\n\n if (hierarchicalRootPath) {\n results = hierarchicalFacetResult.slice(\n hierarchicalRootPath.split(hierarchicalSeparator).length\n );\n }\n\n return results.reduce(generateTreeFn, {\n name: state.hierarchicalFacets[hierarchicalFacetIndex].name,\n count: null, // root level, no count\n isRefined: true, // root level, always refined\n path: null, // root level, no path\n exhaustive: rootExhaustive,\n data: null\n });\n };\n}\n\nfunction generateHierarchicalTree(\n sortBy,\n hierarchicalSeparator,\n hierarchicalRootPath,\n hierarchicalShowParentLevel,\n currentRefinement\n) {\n return function generateTree(\n hierarchicalTree,\n hierarchicalFacetResult,\n currentHierarchicalLevel\n ) {\n var parent = hierarchicalTree;\n\n if (currentHierarchicalLevel > 0) {\n var level = 0;\n\n parent = hierarchicalTree;\n\n while (level < currentHierarchicalLevel) {\n /**\n * @type {object[]]} hierarchical data\n */\n var data = parent && Array.isArray(parent.data) ? parent.data : [];\n parent = find(data, function(subtree) {\n return subtree.isRefined;\n });\n level++;\n }\n }\n\n // we found a refined parent, let's add current level data under it\n if (parent) {\n // filter values in case an object has multiple categories:\n // {\n // categories: {\n // level0: ['beers', 'bières'],\n // level1: ['beers > IPA', 'bières > Belges']\n // }\n // }\n //\n // If parent refinement is `beers`, then we do not want to have `bières > Belges`\n // showing up\n\n var picked = Object.keys(hierarchicalFacetResult.data)\n .map(function(facetValue) {\n return [facetValue, hierarchicalFacetResult.data[facetValue]];\n })\n .filter(function(tuple) {\n var facetValue = tuple[0];\n return onlyMatchingTree(\n facetValue,\n parent.path || hierarchicalRootPath,\n currentRefinement,\n hierarchicalSeparator,\n hierarchicalRootPath,\n hierarchicalShowParentLevel\n );\n });\n\n parent.data = orderBy(\n picked.map(function(tuple) {\n var facetValue = tuple[0];\n var facetCount = tuple[1];\n\n return format(\n facetCount,\n facetValue,\n hierarchicalSeparator,\n currentRefinement,\n hierarchicalFacetResult.exhaustive\n );\n }),\n sortBy[0],\n sortBy[1]\n );\n }\n\n return hierarchicalTree;\n };\n}\n\nfunction onlyMatchingTree(\n facetValue,\n parentPath,\n currentRefinement,\n hierarchicalSeparator,\n hierarchicalRootPath,\n hierarchicalShowParentLevel\n) {\n // we want the facetValue is a child of hierarchicalRootPath\n if (\n hierarchicalRootPath &&\n (facetValue.indexOf(hierarchicalRootPath) !== 0 ||\n hierarchicalRootPath === facetValue)\n ) {\n return false;\n }\n\n // we always want root levels (only when there is no prefix path)\n return (\n (!hierarchicalRootPath &&\n facetValue.indexOf(hierarchicalSeparator) === -1) ||\n // if there is a rootPath, being root level mean 1 level under rootPath\n (hierarchicalRootPath &&\n facetValue.split(hierarchicalSeparator).length -\n hierarchicalRootPath.split(hierarchicalSeparator).length ===\n 1) ||\n // if current refinement is a root level and current facetValue is a root level,\n // keep the facetValue\n (facetValue.indexOf(hierarchicalSeparator) === -1 &&\n currentRefinement.indexOf(hierarchicalSeparator) === -1) ||\n // currentRefinement is a child of the facet value\n currentRefinement.indexOf(facetValue) === 0 ||\n // facetValue is a child of the current parent, add it\n (facetValue.indexOf(parentPath + hierarchicalSeparator) === 0 &&\n (hierarchicalShowParentLevel ||\n facetValue.indexOf(currentRefinement) === 0))\n );\n}\n\nfunction format(\n facetCount,\n facetValue,\n hierarchicalSeparator,\n currentRefinement,\n exhaustive\n) {\n var parts = facetValue.split(hierarchicalSeparator);\n return {\n name: parts[parts.length - 1].trim(),\n path: facetValue,\n count: facetCount,\n isRefined:\n currentRefinement === facetValue ||\n currentRefinement.indexOf(facetValue + hierarchicalSeparator) === 0,\n exhaustive: exhaustive,\n data: null\n };\n}\n","'use strict';\n\nvar merge = require('../functions/merge');\nvar defaultsPure = require('../functions/defaultsPure');\nvar orderBy = require('../functions/orderBy');\nvar compact = require('../functions/compact');\nvar find = require('../functions/find');\nvar findIndex = require('../functions/findIndex');\nvar formatSort = require('../functions/formatSort');\n\nvar generateHierarchicalTree = require('./generate-hierarchical-tree');\n\n/**\n * @typedef SearchResults.Facet\n * @type {object}\n * @property {string} name name of the attribute in the record\n * @property {object} data the faceting data: value, number of entries\n * @property {object} stats undefined unless facet_stats is retrieved from algolia\n */\n\n/**\n * @typedef SearchResults.HierarchicalFacet\n * @type {object}\n * @property {string} name name of the current value given the hierarchical level, trimmed.\n * If root node, you get the facet name\n * @property {number} count number of objects matching this hierarchical value\n * @property {string} path the current hierarchical value full path\n * @property {boolean} isRefined `true` if the current value was refined, `false` otherwise\n * @property {HierarchicalFacet[]} data sub values for the current level\n */\n\n/**\n * @typedef SearchResults.FacetValue\n * @type {object}\n * @property {string} name the facet value itself\n * @property {number} count times this facet appears in the results\n * @property {boolean} isRefined is the facet currently selected\n * @property {boolean} isExcluded is the facet currently excluded (only for conjunctive facets)\n */\n\n/**\n * @typedef Refinement\n * @type {object}\n * @property {string} type the type of filter used:\n * `numeric`, `facet`, `exclude`, `disjunctive`, `hierarchical`\n * @property {string} attributeName name of the attribute used for filtering\n * @property {string} name the value of the filter\n * @property {number} numericValue the value as a number. Only for numeric filters.\n * @property {string} operator the operator used. Only for numeric filters.\n * @property {number} count the number of computed hits for this filter. Only on facets.\n * @property {boolean} exhaustive if the count is exhaustive\n */\n\n/**\n * @param {string[]} attributes\n */\nfunction getIndices(attributes) {\n var indices = {};\n\n attributes.forEach(function(val, idx) {\n indices[val] = idx;\n });\n\n return indices;\n}\n\nfunction assignFacetStats(dest, facetStats, key) {\n if (facetStats && facetStats[key]) {\n dest.stats = facetStats[key];\n }\n}\n\n/**\n * @typedef {Object} HierarchicalFacet\n * @property {string} name\n * @property {string[]} attributes\n */\n\n/**\n * @param {HierarchicalFacet[]} hierarchicalFacets\n * @param {string} hierarchicalAttributeName\n */\nfunction findMatchingHierarchicalFacetFromAttributeName(\n hierarchicalFacets,\n hierarchicalAttributeName\n) {\n return find(hierarchicalFacets, function facetKeyMatchesAttribute(\n hierarchicalFacet\n ) {\n var facetNames = hierarchicalFacet.attributes || [];\n return facetNames.indexOf(hierarchicalAttributeName) > -1;\n });\n}\n\n/*eslint-disable */\n/**\n * Constructor for SearchResults\n * @class\n * @classdesc SearchResults contains the results of a query to Algolia using the\n * {@link AlgoliaSearchHelper}.\n * @param {SearchParameters} state state that led to the response\n * @param {array.<object>} results the results from algolia client\n * @example <caption>SearchResults of the first query in\n * <a href=\"http://demos.algolia.com/instant-search-demo\">the instant search demo</a></caption>\n{\n \"hitsPerPage\": 10,\n \"processingTimeMS\": 2,\n \"facets\": [\n {\n \"name\": \"type\",\n \"data\": {\n \"HardGood\": 6627,\n \"BlackTie\": 550,\n \"Music\": 665,\n \"Software\": 131,\n \"Game\": 456,\n \"Movie\": 1571\n },\n \"exhaustive\": false\n },\n {\n \"exhaustive\": false,\n \"data\": {\n \"Free shipping\": 5507\n },\n \"name\": \"shipping\"\n }\n ],\n \"hits\": [\n {\n \"thumbnailImage\": \"http://img.bbystatic.com/BestBuy_US/images/products/1688/1688832_54x108_s.gif\",\n \"_highlightResult\": {\n \"shortDescription\": {\n \"matchLevel\": \"none\",\n \"value\": \"Safeguard your PC, Mac, Android and iOS devices with comprehensive Internet protection\",\n \"matchedWords\": []\n },\n \"category\": {\n \"matchLevel\": \"none\",\n \"value\": \"Computer Security Software\",\n \"matchedWords\": []\n },\n \"manufacturer\": {\n \"matchedWords\": [],\n \"value\": \"Webroot\",\n \"matchLevel\": \"none\"\n },\n \"name\": {\n \"value\": \"Webroot SecureAnywhere Internet Security (3-Device) (1-Year Subscription) - Mac/Windows\",\n \"matchedWords\": [],\n \"matchLevel\": \"none\"\n }\n },\n \"image\": \"http://img.bbystatic.com/BestBuy_US/images/products/1688/1688832_105x210_sc.jpg\",\n \"shipping\": \"Free shipping\",\n \"bestSellingRank\": 4,\n \"shortDescription\": \"Safeguard your PC, Mac, Android and iOS devices with comprehensive Internet protection\",\n \"url\": \"http://www.bestbuy.com/site/webroot-secureanywhere-internet-security-3-devi…d=1219060687969&skuId=1688832&cmp=RMX&ky=2d3GfEmNIzjA0vkzveHdZEBgpPCyMnLTJ\",\n \"name\": \"Webroot SecureAnywhere Internet Security (3-Device) (1-Year Subscription) - Mac/Windows\",\n \"category\": \"Computer Security Software\",\n \"salePrice_range\": \"1 - 50\",\n \"objectID\": \"1688832\",\n \"type\": \"Software\",\n \"customerReviewCount\": 5980,\n \"salePrice\": 49.99,\n \"manufacturer\": \"Webroot\"\n },\n ....\n ],\n \"nbHits\": 10000,\n \"disjunctiveFacets\": [\n {\n \"exhaustive\": false,\n \"data\": {\n \"5\": 183,\n \"12\": 112,\n \"7\": 149,\n ...\n },\n \"name\": \"customerReviewCount\",\n \"stats\": {\n \"max\": 7461,\n \"avg\": 157.939,\n \"min\": 1\n }\n },\n {\n \"data\": {\n \"Printer Ink\": 142,\n \"Wireless Speakers\": 60,\n \"Point & Shoot Cameras\": 48,\n ...\n },\n \"name\": \"category\",\n \"exhaustive\": false\n },\n {\n \"exhaustive\": false,\n \"data\": {\n \"> 5000\": 2,\n \"1 - 50\": 6524,\n \"501 - 2000\": 566,\n \"201 - 500\": 1501,\n \"101 - 200\": 1360,\n \"2001 - 5000\": 47\n },\n \"name\": \"salePrice_range\"\n },\n {\n \"data\": {\n \"Dynex™\": 202,\n \"Insignia™\": 230,\n \"PNY\": 72,\n ...\n },\n \"name\": \"manufacturer\",\n \"exhaustive\": false\n }\n ],\n \"query\": \"\",\n \"nbPages\": 100,\n \"page\": 0,\n \"index\": \"bestbuy\"\n}\n **/\n/*eslint-enable */\nfunction SearchResults(state, results) {\n var mainSubResponse = results[0];\n\n this._rawResults = results;\n\n var self = this;\n\n // https://www.algolia.com/doc/api-reference/api-methods/search/#response\n Object.keys(mainSubResponse).forEach(function(key) {\n self[key] = mainSubResponse[key];\n });\n\n /**\n * query used to generate the results\n * @name query\n * @member {string}\n * @memberof SearchResults\n * @instance\n */\n /**\n * The query as parsed by the engine given all the rules.\n * @name parsedQuery\n * @member {string}\n * @memberof SearchResults\n * @instance\n */\n /**\n * all the records that match the search parameters. Each record is\n * augmented with a new attribute `_highlightResult`\n * which is an object keyed by attribute and with the following properties:\n * - `value` : the value of the facet highlighted (html)\n * - `matchLevel`: full, partial or none depending on how the query terms match\n * @name hits\n * @member {object[]}\n * @memberof SearchResults\n * @instance\n */\n /**\n * index where the results come from\n * @name index\n * @member {string}\n * @memberof SearchResults\n * @instance\n */\n /**\n * number of hits per page requested\n * @name hitsPerPage\n * @member {number}\n * @memberof SearchResults\n * @instance\n */\n /**\n * total number of hits of this query on the index\n * @name nbHits\n * @member {number}\n * @memberof SearchResults\n * @instance\n */\n /**\n * total number of pages with respect to the number of hits per page and the total number of hits\n * @name nbPages\n * @member {number}\n * @memberof SearchResults\n * @instance\n */\n /**\n * current page\n * @name page\n * @member {number}\n * @memberof SearchResults\n * @instance\n */\n /**\n * The position if the position was guessed by IP.\n * @name aroundLatLng\n * @member {string}\n * @memberof SearchResults\n * @instance\n * @example \"48.8637,2.3615\",\n */\n /**\n * The radius computed by Algolia.\n * @name automaticRadius\n * @member {string}\n * @memberof SearchResults\n * @instance\n * @example \"126792922\",\n */\n /**\n * String identifying the server used to serve this request.\n *\n * getRankingInfo needs to be set to `true` for this to be returned\n *\n * @name serverUsed\n * @member {string}\n * @memberof SearchResults\n * @instance\n * @example \"c7-use-2.algolia.net\",\n */\n /**\n * Boolean that indicates if the computation of the counts did time out.\n * @deprecated\n * @name timeoutCounts\n * @member {boolean}\n * @memberof SearchResults\n * @instance\n */\n /**\n * Boolean that indicates if the computation of the hits did time out.\n * @deprecated\n * @name timeoutHits\n * @member {boolean}\n * @memberof SearchResults\n * @instance\n */\n /**\n * True if the counts of the facets is exhaustive\n * @name exhaustiveFacetsCount\n * @member {boolean}\n * @memberof SearchResults\n * @instance\n */\n /**\n * True if the number of hits is exhaustive\n * @name exhaustiveNbHits\n * @member {boolean}\n * @memberof SearchResults\n * @instance\n */\n /**\n * Contains the userData if they are set by a [query rule](https://www.algolia.com/doc/guides/query-rules/query-rules-overview/).\n * @name userData\n * @member {object[]}\n * @memberof SearchResults\n * @instance\n */\n /**\n * queryID is the unique identifier of the query used to generate the current search results.\n * This value is only available if the `clickAnalytics` search parameter is set to `true`.\n * @name queryID\n * @member {string}\n * @memberof SearchResults\n * @instance\n */\n\n /**\n * sum of the processing time of all the queries\n * @member {number}\n */\n this.processingTimeMS = results.reduce(function(sum, result) {\n return result.processingTimeMS === undefined\n ? sum\n : sum + result.processingTimeMS;\n }, 0);\n\n /**\n * disjunctive facets results\n * @member {SearchResults.Facet[]}\n */\n this.disjunctiveFacets = [];\n /**\n * disjunctive facets results\n * @member {SearchResults.HierarchicalFacet[]}\n */\n this.hierarchicalFacets = state.hierarchicalFacets.map(function initFutureTree() {\n return [];\n });\n /**\n * other facets results\n * @member {SearchResults.Facet[]}\n */\n this.facets = [];\n\n var disjunctiveFacets = state.getRefinedDisjunctiveFacets();\n\n var facetsIndices = getIndices(state.facets);\n var disjunctiveFacetsIndices = getIndices(state.disjunctiveFacets);\n var nextDisjunctiveResult = 1;\n\n // Since we send request only for disjunctive facets that have been refined,\n // we get the facets information from the first, general, response.\n\n var mainFacets = mainSubResponse.facets || {};\n\n Object.keys(mainFacets).forEach(function(facetKey) {\n var facetValueObject = mainFacets[facetKey];\n\n var hierarchicalFacet = findMatchingHierarchicalFacetFromAttributeName(\n state.hierarchicalFacets,\n facetKey\n );\n\n if (hierarchicalFacet) {\n // Place the hierarchicalFacet data at the correct index depending on\n // the attributes order that was defined at the helper initialization\n var facetIndex = hierarchicalFacet.attributes.indexOf(facetKey);\n var idxAttributeName = findIndex(state.hierarchicalFacets, function(f) {\n return f.name === hierarchicalFacet.name;\n });\n self.hierarchicalFacets[idxAttributeName][facetIndex] = {\n attribute: facetKey,\n data: facetValueObject,\n exhaustive: mainSubResponse.exhaustiveFacetsCount\n };\n } else {\n var isFacetDisjunctive = state.disjunctiveFacets.indexOf(facetKey) !== -1;\n var isFacetConjunctive = state.facets.indexOf(facetKey) !== -1;\n var position;\n\n if (isFacetDisjunctive) {\n position = disjunctiveFacetsIndices[facetKey];\n self.disjunctiveFacets[position] = {\n name: facetKey,\n data: facetValueObject,\n exhaustive: mainSubResponse.exhaustiveFacetsCount\n };\n assignFacetStats(self.disjunctiveFacets[position], mainSubResponse.facets_stats, facetKey);\n }\n if (isFacetConjunctive) {\n position = facetsIndices[facetKey];\n self.facets[position] = {\n name: facetKey,\n data: facetValueObject,\n exhaustive: mainSubResponse.exhaustiveFacetsCount\n };\n assignFacetStats(self.facets[position], mainSubResponse.facets_stats, facetKey);\n }\n }\n });\n\n // Make sure we do not keep holes within the hierarchical facets\n this.hierarchicalFacets = compact(this.hierarchicalFacets);\n\n // aggregate the refined disjunctive facets\n disjunctiveFacets.forEach(function(disjunctiveFacet) {\n var result = results[nextDisjunctiveResult];\n var facets = result && result.facets ? result.facets : {};\n var hierarchicalFacet = state.getHierarchicalFacetByName(disjunctiveFacet);\n\n // There should be only item in facets.\n Object.keys(facets).forEach(function(dfacet) {\n var facetResults = facets[dfacet];\n\n var position;\n\n if (hierarchicalFacet) {\n position = findIndex(state.hierarchicalFacets, function(f) {\n return f.name === hierarchicalFacet.name;\n });\n var attributeIndex = findIndex(self.hierarchicalFacets[position], function(f) {\n return f.attribute === dfacet;\n });\n\n // previous refinements and no results so not able to find it\n if (attributeIndex === -1) {\n return;\n }\n\n self.hierarchicalFacets[position][attributeIndex].data = merge(\n {},\n self.hierarchicalFacets[position][attributeIndex].data,\n facetResults\n );\n } else {\n position = disjunctiveFacetsIndices[dfacet];\n\n var dataFromMainRequest = mainSubResponse.facets && mainSubResponse.facets[dfacet] || {};\n\n self.disjunctiveFacets[position] = {\n name: dfacet,\n data: defaultsPure({}, facetResults, dataFromMainRequest),\n exhaustive: result.exhaustiveFacetsCount\n };\n assignFacetStats(self.disjunctiveFacets[position], result.facets_stats, dfacet);\n\n if (state.disjunctiveFacetsRefinements[dfacet]) {\n state.disjunctiveFacetsRefinements[dfacet].forEach(function(refinementValue) {\n // add the disjunctive refinements if it is no more retrieved\n if (!self.disjunctiveFacets[position].data[refinementValue] &&\n state.disjunctiveFacetsRefinements[dfacet].indexOf(refinementValue) > -1) {\n self.disjunctiveFacets[position].data[refinementValue] = 0;\n }\n });\n }\n }\n });\n nextDisjunctiveResult++;\n });\n\n // if we have some root level values for hierarchical facets, merge them\n state.getRefinedHierarchicalFacets().forEach(function(refinedFacet) {\n var hierarchicalFacet = state.getHierarchicalFacetByName(refinedFacet);\n var separator = state._getHierarchicalFacetSeparator(hierarchicalFacet);\n\n var currentRefinement = state.getHierarchicalRefinement(refinedFacet);\n // if we are already at a root refinement (or no refinement at all), there is no\n // root level values request\n if (currentRefinement.length === 0 || currentRefinement[0].split(separator).length < 2) {\n return;\n }\n\n var result = results[nextDisjunctiveResult];\n var facets = result && result.facets\n ? result.facets\n : {};\n Object.keys(facets).forEach(function(dfacet) {\n var facetResults = facets[dfacet];\n var position = findIndex(state.hierarchicalFacets, function(f) {\n return f.name === hierarchicalFacet.name;\n });\n var attributeIndex = findIndex(self.hierarchicalFacets[position], function(f) {\n return f.attribute === dfacet;\n });\n\n // previous refinements and no results so not able to find it\n if (attributeIndex === -1) {\n return;\n }\n\n // when we always get root levels, if the hits refinement is `beers > IPA` (count: 5),\n // then the disjunctive values will be `beers` (count: 100),\n // but we do not want to display\n // | beers (100)\n // > IPA (5)\n // We want\n // | beers (5)\n // > IPA (5)\n var defaultData = {};\n\n if (currentRefinement.length > 0) {\n var root = currentRefinement[0].split(separator)[0];\n defaultData[root] = self.hierarchicalFacets[position][attributeIndex].data[root];\n }\n\n self.hierarchicalFacets[position][attributeIndex].data = defaultsPure(\n defaultData,\n facetResults,\n self.hierarchicalFacets[position][attributeIndex].data\n );\n });\n\n nextDisjunctiveResult++;\n });\n\n // add the excludes\n Object.keys(state.facetsExcludes).forEach(function(facetName) {\n var excludes = state.facetsExcludes[facetName];\n var position = facetsIndices[facetName];\n\n self.facets[position] = {\n name: facetName,\n data: mainSubResponse.facets[facetName],\n exhaustive: mainSubResponse.exhaustiveFacetsCount\n };\n excludes.forEach(function(facetValue) {\n self.facets[position] = self.facets[position] || {name: facetName};\n self.facets[position].data = self.facets[position].data || {};\n self.facets[position].data[facetValue] = 0;\n });\n });\n\n /**\n * @type {Array}\n */\n this.hierarchicalFacets = this.hierarchicalFacets.map(generateHierarchicalTree(state));\n\n /**\n * @type {Array}\n */\n this.facets = compact(this.facets);\n /**\n * @type {Array}\n */\n this.disjunctiveFacets = compact(this.disjunctiveFacets);\n\n this._state = state;\n}\n\n/**\n * Get a facet object with its name\n * @deprecated\n * @param {string} name name of the faceted attribute\n * @return {SearchResults.Facet} the facet object\n */\nSearchResults.prototype.getFacetByName = function(name) {\n function predicate(facet) {\n return facet.name === name;\n }\n\n return find(this.facets, predicate) ||\n find(this.disjunctiveFacets, predicate) ||\n find(this.hierarchicalFacets, predicate);\n};\n\n/**\n * Get the facet values of a specified attribute from a SearchResults object.\n * @private\n * @param {SearchResults} results the search results to search in\n * @param {string} attribute name of the faceted attribute to search for\n * @return {array|object} facet values. For the hierarchical facets it is an object.\n */\nfunction extractNormalizedFacetValues(results, attribute) {\n function predicate(facet) {\n return facet.name === attribute;\n }\n\n if (results._state.isConjunctiveFacet(attribute)) {\n var facet = find(results.facets, predicate);\n if (!facet) return [];\n\n return Object.keys(facet.data).map(function(name) {\n return {\n name: name,\n count: facet.data[name],\n isRefined: results._state.isFacetRefined(attribute, name),\n isExcluded: results._state.isExcludeRefined(attribute, name)\n };\n });\n } else if (results._state.isDisjunctiveFacet(attribute)) {\n var disjunctiveFacet = find(results.disjunctiveFacets, predicate);\n if (!disjunctiveFacet) return [];\n\n return Object.keys(disjunctiveFacet.data).map(function(name) {\n return {\n name: name,\n count: disjunctiveFacet.data[name],\n isRefined: results._state.isDisjunctiveFacetRefined(attribute, name)\n };\n });\n } else if (results._state.isHierarchicalFacet(attribute)) {\n return find(results.hierarchicalFacets, predicate);\n }\n}\n\n/**\n * Sort nodes of a hierarchical or disjunctive facet results\n * @private\n * @param {function} sortFn\n * @param {HierarchicalFacet|Array} node node upon which we want to apply the sort\n * @param {string[]} names attribute names\n * @param {number} [level=0] current index in the names array\n */\nfunction recSort(sortFn, node, names, level) {\n level = level || 0;\n\n if (Array.isArray(node)) {\n return sortFn(node, names[level]);\n }\n\n if (!node.data || node.data.length === 0) {\n return node;\n }\n\n var children = node.data.map(function(childNode) {\n return recSort(sortFn, childNode, names, level + 1);\n });\n var sortedChildren = sortFn(children, names[level]);\n var newNode = defaultsPure({data: sortedChildren}, node);\n return newNode;\n}\n\nSearchResults.DEFAULT_SORT = ['isRefined:desc', 'count:desc', 'name:asc'];\n\nfunction vanillaSortFn(order, data) {\n return data.sort(order);\n}\n\n/**\n * @typedef FacetOrdering\n * @type {Object}\n * @property {string[]} [order]\n * @property {'count' | 'alpha' | 'hidden'} [sortRemainingBy]\n */\n\n/**\n * Sorts facet arrays via their facet ordering\n * @param {Array} facetValues the values\n * @param {FacetOrdering} facetOrdering the ordering\n * @returns {Array}\n */\nfunction sortViaFacetOrdering(facetValues, facetOrdering) {\n var orderedFacets = [];\n var remainingFacets = [];\n\n var order = facetOrdering.order || [];\n /**\n * an object with the keys being the values in order, the values their index:\n * ['one', 'two'] -> { one: 0, two: 1 }\n */\n var reverseOrder = order.reduce(function(acc, name, i) {\n acc[name] = i;\n return acc;\n }, {});\n\n facetValues.forEach(function(item) {\n // hierarchical facets get sorted using their raw name\n var name = item.path || item.name;\n if (reverseOrder[name] !== undefined) {\n orderedFacets[reverseOrder[name]] = item;\n } else {\n remainingFacets.push(item);\n }\n });\n\n orderedFacets = orderedFacets.filter(function(facet) {\n return facet;\n });\n\n var sortRemainingBy = facetOrdering.sortRemainingBy;\n var ordering;\n if (sortRemainingBy === 'hidden') {\n return orderedFacets;\n } else if (sortRemainingBy === 'alpha') {\n ordering = [['path', 'name'], ['asc', 'asc']];\n } else {\n ordering = [['count'], ['desc']];\n }\n\n return orderedFacets.concat(\n orderBy(remainingFacets, ordering[0], ordering[1])\n );\n}\n\n/**\n * @param {SearchResults} results the search results class\n * @param {string} attribute the attribute to retrieve ordering of\n * @returns {FacetOrdering=}\n */\nfunction getFacetOrdering(results, attribute) {\n return (\n results.renderingContent &&\n results.renderingContent.facetOrdering &&\n results.renderingContent.facetOrdering.values &&\n results.renderingContent.facetOrdering.values[attribute]\n );\n}\n\n/**\n * Get a the list of values for a given facet attribute. Those values are sorted\n * refinement first, descending count (bigger value on top), and name ascending\n * (alphabetical order). The sort formula can overridden using either string based\n * predicates or a function.\n *\n * This method will return all the values returned by the Algolia engine plus all\n * the values already refined. This means that it can happen that the\n * `maxValuesPerFacet` [configuration](https://www.algolia.com/doc/rest-api/search#param-maxValuesPerFacet)\n * might not be respected if you have facet values that are already refined.\n * @param {string} attribute attribute name\n * @param {object} opts configuration options.\n * @param {boolean} [opts.facetOrdering]\n * Force the use of facetOrdering from the result if a sortBy is present. If\n * sortBy isn't present, facetOrdering will be used automatically.\n * @param {Array.<string> | function} opts.sortBy\n * When using strings, it consists of\n * the name of the [FacetValue](#SearchResults.FacetValue) or the\n * [HierarchicalFacet](#SearchResults.HierarchicalFacet) attributes with the\n * order (`asc` or `desc`). For example to order the value by count, the\n * argument would be `['count:asc']`.\n *\n * If only the attribute name is specified, the ordering defaults to the one\n * specified in the default value for this attribute.\n *\n * When not specified, the order is\n * ascending. This parameter can also be a function which takes two facet\n * values and should return a number, 0 if equal, 1 if the first argument is\n * bigger or -1 otherwise.\n *\n * The default value for this attribute `['isRefined:desc', 'count:desc', 'name:asc']`\n * @return {FacetValue[]|HierarchicalFacet|undefined} depending on the type of facet of\n * the attribute requested (hierarchical, disjunctive or conjunctive)\n * @example\n * helper.on('result', function(event){\n * //get values ordered only by name ascending using the string predicate\n * event.results.getFacetValues('city', {sortBy: ['name:asc']});\n * //get values ordered only by count ascending using a function\n * event.results.getFacetValues('city', {\n * // this is equivalent to ['count:asc']\n * sortBy: function(a, b) {\n * if (a.count === b.count) return 0;\n * if (a.count > b.count) return 1;\n * if (b.count > a.count) return -1;\n * }\n * });\n * });\n */\nSearchResults.prototype.getFacetValues = function(attribute, opts) {\n var facetValues = extractNormalizedFacetValues(this, attribute);\n if (!facetValues) {\n return undefined;\n }\n\n var options = defaultsPure({}, opts, {\n sortBy: SearchResults.DEFAULT_SORT,\n // if no sortBy is given, attempt to sort based on facetOrdering\n // if it is given, we still allow to sort via facet ordering first\n facetOrdering: !(opts && opts.sortBy)\n });\n\n var results = this;\n var attributes;\n if (Array.isArray(facetValues)) {\n attributes = [attribute];\n } else {\n var config = results._state.getHierarchicalFacetByName(facetValues.name);\n attributes = config.attributes;\n }\n\n return recSort(function(data, facetName) {\n if (options.facetOrdering) {\n var facetOrdering = getFacetOrdering(results, facetName);\n if (Boolean(facetOrdering)) {\n return sortViaFacetOrdering(data, facetOrdering);\n }\n }\n\n if (Array.isArray(options.sortBy)) {\n var order = formatSort(options.sortBy, SearchResults.DEFAULT_SORT);\n return orderBy(data, order[0], order[1]);\n } else if (typeof options.sortBy === 'function') {\n return vanillaSortFn(options.sortBy, data);\n }\n throw new Error(\n 'options.sortBy is optional but if defined it must be ' +\n 'either an array of string (predicates) or a sorting function'\n );\n }, facetValues, attributes);\n};\n\n/**\n * Returns the facet stats if attribute is defined and the facet contains some.\n * Otherwise returns undefined.\n * @param {string} attribute name of the faceted attribute\n * @return {object} The stats of the facet\n */\nSearchResults.prototype.getFacetStats = function(attribute) {\n if (this._state.isConjunctiveFacet(attribute)) {\n return getFacetStatsIfAvailable(this.facets, attribute);\n } else if (this._state.isDisjunctiveFacet(attribute)) {\n return getFacetStatsIfAvailable(this.disjunctiveFacets, attribute);\n }\n\n return undefined;\n};\n\n/**\n * @typedef {Object} FacetListItem\n * @property {string} name\n */\n\n/**\n * @param {FacetListItem[]} facetList (has more items, but enough for here)\n * @param {string} facetName\n */\nfunction getFacetStatsIfAvailable(facetList, facetName) {\n var data = find(facetList, function(facet) {\n return facet.name === facetName;\n });\n return data && data.stats;\n}\n\n/**\n * Returns all refinements for all filters + tags. It also provides\n * additional information: count and exhaustiveness for each filter.\n *\n * See the [refinement type](#Refinement) for an exhaustive view of the available\n * data.\n *\n * Note that for a numeric refinement, results are grouped per operator, this\n * means that it will return responses for operators which are empty.\n *\n * @return {Array.<Refinement>} all the refinements\n */\nSearchResults.prototype.getRefinements = function() {\n var state = this._state;\n var results = this;\n var res = [];\n\n Object.keys(state.facetsRefinements).forEach(function(attributeName) {\n state.facetsRefinements[attributeName].forEach(function(name) {\n res.push(getRefinement(state, 'facet', attributeName, name, results.facets));\n });\n });\n\n Object.keys(state.facetsExcludes).forEach(function(attributeName) {\n state.facetsExcludes[attributeName].forEach(function(name) {\n res.push(getRefinement(state, 'exclude', attributeName, name, results.facets));\n });\n });\n\n Object.keys(state.disjunctiveFacetsRefinements).forEach(function(attributeName) {\n state.disjunctiveFacetsRefinements[attributeName].forEach(function(name) {\n res.push(getRefinement(state, 'disjunctive', attributeName, name, results.disjunctiveFacets));\n });\n });\n\n Object.keys(state.hierarchicalFacetsRefinements).forEach(function(attributeName) {\n state.hierarchicalFacetsRefinements[attributeName].forEach(function(name) {\n res.push(getHierarchicalRefinement(state, attributeName, name, results.hierarchicalFacets));\n });\n });\n\n\n Object.keys(state.numericRefinements).forEach(function(attributeName) {\n var operators = state.numericRefinements[attributeName];\n Object.keys(operators).forEach(function(operator) {\n operators[operator].forEach(function(value) {\n res.push({\n type: 'numeric',\n attributeName: attributeName,\n name: value,\n numericValue: value,\n operator: operator\n });\n });\n });\n });\n\n state.tagRefinements.forEach(function(name) {\n res.push({type: 'tag', attributeName: '_tags', name: name});\n });\n\n return res;\n};\n\n/**\n * @typedef {Object} Facet\n * @property {string} name\n * @property {Object} data\n * @property {boolean} exhaustive\n */\n\n/**\n * @param {*} state\n * @param {*} type\n * @param {string} attributeName\n * @param {*} name\n * @param {Facet[]} resultsFacets\n */\nfunction getRefinement(state, type, attributeName, name, resultsFacets) {\n var facet = find(resultsFacets, function(f) {\n return f.name === attributeName;\n });\n var count = facet && facet.data && facet.data[name] ? facet.data[name] : 0;\n var exhaustive = (facet && facet.exhaustive) || false;\n\n return {\n type: type,\n attributeName: attributeName,\n name: name,\n count: count,\n exhaustive: exhaustive\n };\n}\n\n/**\n * @param {*} state\n * @param {string} attributeName\n * @param {*} name\n * @param {Facet[]} resultsFacets\n */\nfunction getHierarchicalRefinement(state, attributeName, name, resultsFacets) {\n var facetDeclaration = state.getHierarchicalFacetByName(attributeName);\n var separator = state._getHierarchicalFacetSeparator(facetDeclaration);\n var split = name.split(separator);\n var rootFacet = find(resultsFacets, function(facet) {\n return facet.name === attributeName;\n });\n\n var facet = split.reduce(function(intermediateFacet, part) {\n var newFacet =\n intermediateFacet && find(intermediateFacet.data, function(f) {\n return f.name === part;\n });\n return newFacet !== undefined ? newFacet : intermediateFacet;\n }, rootFacet);\n\n var count = (facet && facet.count) || 0;\n var exhaustive = (facet && facet.exhaustive) || false;\n var path = (facet && facet.path) || '';\n\n return {\n type: 'hierarchical',\n attributeName: attributeName,\n name: path,\n count: count,\n exhaustive: exhaustive\n };\n}\n\nmodule.exports = SearchResults;\n","// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nfunction EventEmitter() {\n this._events = this._events || {};\n this._maxListeners = this._maxListeners || undefined;\n}\nmodule.exports = EventEmitter;\n\n// Backwards-compat with node 0.10.x\n// EventEmitter.EventEmitter = EventEmitter;\n\nEventEmitter.prototype._events = undefined;\nEventEmitter.prototype._maxListeners = undefined;\n\n// By default EventEmitters will print a warning if more than 10 listeners are\n// added to it. This is a useful default which helps finding memory leaks.\nEventEmitter.defaultMaxListeners = 10;\n\n// Obviously not all Emitters should be limited to 10. This function allows\n// that to be increased. Set to zero for unlimited.\nEventEmitter.prototype.setMaxListeners = function(n) {\n if (!isNumber(n) || n < 0 || isNaN(n))\n throw TypeError('n must be a positive number');\n this._maxListeners = n;\n return this;\n};\n\nEventEmitter.prototype.emit = function(type) {\n var er, handler, len, args, i, listeners;\n\n if (!this._events)\n this._events = {};\n\n // If there is no 'error' event listener then throw.\n if (type === 'error') {\n if (!this._events.error ||\n (isObject(this._events.error) && !this._events.error.length)) {\n er = arguments[1];\n if (er instanceof Error) {\n throw er; // Unhandled 'error' event\n } else {\n // At least give some kind of context to the user\n var err = new Error('Uncaught, unspecified \"error\" event. (' + er + ')');\n err.context = er;\n throw err;\n }\n }\n }\n\n handler = this._events[type];\n\n if (isUndefined(handler))\n return false;\n\n if (isFunction(handler)) {\n switch (arguments.length) {\n // fast cases\n case 1:\n handler.call(this);\n break;\n case 2:\n handler.call(this, arguments[1]);\n break;\n case 3:\n handler.call(this, arguments[1], arguments[2]);\n break;\n // slower\n default:\n args = Array.prototype.slice.call(arguments, 1);\n handler.apply(this, args);\n }\n } else if (isObject(handler)) {\n args = Array.prototype.slice.call(arguments, 1);\n listeners = handler.slice();\n len = listeners.length;\n for (i = 0; i < len; i++)\n listeners[i].apply(this, args);\n }\n\n return true;\n};\n\nEventEmitter.prototype.addListener = function(type, listener) {\n var m;\n\n if (!isFunction(listener))\n throw TypeError('listener must be a function');\n\n if (!this._events)\n this._events = {};\n\n // To avoid recursion in the case that type === \"newListener\"! Before\n // adding it to the listeners, first emit \"newListener\".\n if (this._events.newListener)\n this.emit('newListener', type,\n isFunction(listener.listener) ?\n listener.listener : listener);\n\n if (!this._events[type])\n // Optimize the case of one listener. Don't need the extra array object.\n this._events[type] = listener;\n else if (isObject(this._events[type]))\n // If we've already got an array, just append.\n this._events[type].push(listener);\n else\n // Adding the second element, need to change to array.\n this._events[type] = [this._events[type], listener];\n\n // Check for listener leak\n if (isObject(this._events[type]) && !this._events[type].warned) {\n if (!isUndefined(this._maxListeners)) {\n m = this._maxListeners;\n } else {\n m = EventEmitter.defaultMaxListeners;\n }\n\n if (m && m > 0 && this._events[type].length > m) {\n this._events[type].warned = true;\n console.error('(node) warning: possible EventEmitter memory ' +\n 'leak detected. %d listeners added. ' +\n 'Use emitter.setMaxListeners() to increase limit.',\n this._events[type].length);\n if (typeof console.trace === 'function') {\n // not supported in IE 10\n console.trace();\n }\n }\n }\n\n return this;\n};\n\nEventEmitter.prototype.on = EventEmitter.prototype.addListener;\n\nEventEmitter.prototype.once = function(type, listener) {\n if (!isFunction(listener))\n throw TypeError('listener must be a function');\n\n var fired = false;\n\n function g() {\n this.removeListener(type, g);\n\n if (!fired) {\n fired = true;\n listener.apply(this, arguments);\n }\n }\n\n g.listener = listener;\n this.on(type, g);\n\n return this;\n};\n\n// emits a 'removeListener' event iff the listener was removed\nEventEmitter.prototype.removeListener = function(type, listener) {\n var list, position, length, i;\n\n if (!isFunction(listener))\n throw TypeError('listener must be a function');\n\n if (!this._events || !this._events[type])\n return this;\n\n list = this._events[type];\n length = list.length;\n position = -1;\n\n if (list === listener ||\n (isFunction(list.listener) && list.listener === listener)) {\n delete this._events[type];\n if (this._events.removeListener)\n this.emit('removeListener', type, listener);\n\n } else if (isObject(list)) {\n for (i = length; i-- > 0;) {\n if (list[i] === listener ||\n (list[i].listener && list[i].listener === listener)) {\n position = i;\n break;\n }\n }\n\n if (position < 0)\n return this;\n\n if (list.length === 1) {\n list.length = 0;\n delete this._events[type];\n } else {\n list.splice(position, 1);\n }\n\n if (this._events.removeListener)\n this.emit('removeListener', type, listener);\n }\n\n return this;\n};\n\nEventEmitter.prototype.removeAllListeners = function(type) {\n var key, listeners;\n\n if (!this._events)\n return this;\n\n // not listening for removeListener, no need to emit\n if (!this._events.removeListener) {\n if (arguments.length === 0)\n this._events = {};\n else if (this._events[type])\n delete this._events[type];\n return this;\n }\n\n // emit removeListener for all listeners on all events\n if (arguments.length === 0) {\n for (key in this._events) {\n if (key === 'removeListener') continue;\n this.removeAllListeners(key);\n }\n this.removeAllListeners('removeListener');\n this._events = {};\n return this;\n }\n\n listeners = this._events[type];\n\n if (isFunction(listeners)) {\n this.removeListener(type, listeners);\n } else if (listeners) {\n // LIFO order\n while (listeners.length)\n this.removeListener(type, listeners[listeners.length - 1]);\n }\n delete this._events[type];\n\n return this;\n};\n\nEventEmitter.prototype.listeners = function(type) {\n var ret;\n if (!this._events || !this._events[type])\n ret = [];\n else if (isFunction(this._events[type]))\n ret = [this._events[type]];\n else\n ret = this._events[type].slice();\n return ret;\n};\n\nEventEmitter.prototype.listenerCount = function(type) {\n if (this._events) {\n var evlistener = this._events[type];\n\n if (isFunction(evlistener))\n return 1;\n else if (evlistener)\n return evlistener.length;\n }\n return 0;\n};\n\nEventEmitter.listenerCount = function(emitter, type) {\n return emitter.listenerCount(type);\n};\n\nfunction isFunction(arg) {\n return typeof arg === 'function';\n}\n\nfunction isNumber(arg) {\n return typeof arg === 'number';\n}\n\nfunction isObject(arg) {\n return typeof arg === 'object' && arg !== null;\n}\n\nfunction isUndefined(arg) {\n return arg === void 0;\n}\n","'use strict';\n\nfunction inherits(ctor, superCtor) {\n ctor.prototype = Object.create(superCtor.prototype, {\n constructor: {\n value: ctor,\n enumerable: false,\n writable: true,\n configurable: true\n }\n });\n}\n\nmodule.exports = inherits;\n","'use strict';\n\nvar EventEmitter = require('@algolia/events');\nvar inherits = require('../functions/inherits');\n\n/**\n * A DerivedHelper is a way to create sub requests to\n * Algolia from a main helper.\n * @class\n * @classdesc The DerivedHelper provides an event based interface for search callbacks:\n * - search: when a search is triggered using the `search()` method.\n * - result: when the response is retrieved from Algolia and is processed.\n * This event contains a {@link SearchResults} object and the\n * {@link SearchParameters} corresponding to this answer.\n */\nfunction DerivedHelper(mainHelper, fn) {\n this.main = mainHelper;\n this.fn = fn;\n this.lastResults = null;\n}\n\ninherits(DerivedHelper, EventEmitter);\n\n/**\n * Detach this helper from the main helper\n * @return {undefined}\n * @throws Error if the derived helper is already detached\n */\nDerivedHelper.prototype.detach = function() {\n this.removeAllListeners();\n this.main.detachDerivedHelper(this);\n};\n\nDerivedHelper.prototype.getModifiedState = function(parameters) {\n return this.fn(parameters);\n};\n\nmodule.exports = DerivedHelper;\n","'use strict';\n\nvar merge = require('./functions/merge');\n\nvar requestBuilder = {\n /**\n * Get all the queries to send to the client, those queries can used directly\n * with the Algolia client.\n * @private\n * @return {object[]} The queries\n */\n _getQueries: function getQueries(index, state) {\n var queries = [];\n\n // One query for the hits\n queries.push({\n indexName: index,\n params: requestBuilder._getHitsSearchParams(state)\n });\n\n // One for each disjunctive facets\n state.getRefinedDisjunctiveFacets().forEach(function(refinedFacet) {\n queries.push({\n indexName: index,\n params: requestBuilder._getDisjunctiveFacetSearchParams(state, refinedFacet)\n });\n });\n\n // maybe more to get the root level of hierarchical facets when activated\n state.getRefinedHierarchicalFacets().forEach(function(refinedFacet) {\n var hierarchicalFacet = state.getHierarchicalFacetByName(refinedFacet);\n\n var currentRefinement = state.getHierarchicalRefinement(refinedFacet);\n // if we are deeper than level 0 (starting from `beer > IPA`)\n // we want to get the root values\n var separator = state._getHierarchicalFacetSeparator(hierarchicalFacet);\n if (currentRefinement.length > 0 && currentRefinement[0].split(separator).length > 1) {\n queries.push({\n indexName: index,\n params: requestBuilder._getDisjunctiveFacetSearchParams(state, refinedFacet, true)\n });\n }\n });\n\n return queries;\n },\n\n /**\n * Build search parameters used to fetch hits\n * @private\n * @return {object.<string, any>}\n */\n _getHitsSearchParams: function(state) {\n var facets = state.facets\n .concat(state.disjunctiveFacets)\n .concat(requestBuilder._getHitsHierarchicalFacetsAttributes(state));\n\n\n var facetFilters = requestBuilder._getFacetFilters(state);\n var numericFilters = requestBuilder._getNumericFilters(state);\n var tagFilters = requestBuilder._getTagFilters(state);\n var additionalParams = {\n facets: facets.indexOf('*') > -1 ? ['*'] : facets,\n tagFilters: tagFilters\n };\n\n if (facetFilters.length > 0) {\n additionalParams.facetFilters = facetFilters;\n }\n\n if (numericFilters.length > 0) {\n additionalParams.numericFilters = numericFilters;\n }\n\n return merge({}, state.getQueryParams(), additionalParams);\n },\n\n /**\n * Build search parameters used to fetch a disjunctive facet\n * @private\n * @param {string} facet the associated facet name\n * @param {boolean} hierarchicalRootLevel ?? FIXME\n * @return {object}\n */\n _getDisjunctiveFacetSearchParams: function(state, facet, hierarchicalRootLevel) {\n var facetFilters = requestBuilder._getFacetFilters(state, facet, hierarchicalRootLevel);\n var numericFilters = requestBuilder._getNumericFilters(state, facet);\n var tagFilters = requestBuilder._getTagFilters(state);\n var additionalParams = {\n hitsPerPage: 1,\n page: 0,\n attributesToRetrieve: [],\n attributesToHighlight: [],\n attributesToSnippet: [],\n tagFilters: tagFilters,\n analytics: false,\n clickAnalytics: false\n };\n\n var hierarchicalFacet = state.getHierarchicalFacetByName(facet);\n\n if (hierarchicalFacet) {\n additionalParams.facets = requestBuilder._getDisjunctiveHierarchicalFacetAttribute(\n state,\n hierarchicalFacet,\n hierarchicalRootLevel\n );\n } else {\n additionalParams.facets = facet;\n }\n\n if (numericFilters.length > 0) {\n additionalParams.numericFilters = numericFilters;\n }\n\n if (facetFilters.length > 0) {\n additionalParams.facetFilters = facetFilters;\n }\n\n return merge({}, state.getQueryParams(), additionalParams);\n },\n\n /**\n * Return the numeric filters in an algolia request fashion\n * @private\n * @param {string} [facetName] the name of the attribute for which the filters should be excluded\n * @return {string[]} the numeric filters in the algolia format\n */\n _getNumericFilters: function(state, facetName) {\n if (state.numericFilters) {\n return state.numericFilters;\n }\n\n var numericFilters = [];\n\n Object.keys(state.numericRefinements).forEach(function(attribute) {\n var operators = state.numericRefinements[attribute] || {};\n Object.keys(operators).forEach(function(operator) {\n var values = operators[operator] || [];\n if (facetName !== attribute) {\n values.forEach(function(value) {\n if (Array.isArray(value)) {\n var vs = value.map(function(v) {\n return attribute + operator + v;\n });\n numericFilters.push(vs);\n } else {\n numericFilters.push(attribute + operator + value);\n }\n });\n }\n });\n });\n\n return numericFilters;\n },\n\n /**\n * Return the tags filters depending\n * @private\n * @return {string}\n */\n _getTagFilters: function(state) {\n if (state.tagFilters) {\n return state.tagFilters;\n }\n\n return state.tagRefinements.join(',');\n },\n\n\n /**\n * Build facetFilters parameter based on current refinements. The array returned\n * contains strings representing the facet filters in the algolia format.\n * @private\n * @param {string} [facet] if set, the current disjunctive facet\n * @return {array.<string>}\n */\n _getFacetFilters: function(state, facet, hierarchicalRootLevel) {\n var facetFilters = [];\n\n var facetsRefinements = state.facetsRefinements || {};\n Object.keys(facetsRefinements).forEach(function(facetName) {\n var facetValues = facetsRefinements[facetName] || [];\n facetValues.forEach(function(facetValue) {\n facetFilters.push(facetName + ':' + facetValue);\n });\n });\n\n var facetsExcludes = state.facetsExcludes || {};\n Object.keys(facetsExcludes).forEach(function(facetName) {\n var facetValues = facetsExcludes[facetName] || [];\n facetValues.forEach(function(facetValue) {\n facetFilters.push(facetName + ':-' + facetValue);\n });\n });\n\n var disjunctiveFacetsRefinements = state.disjunctiveFacetsRefinements || {};\n Object.keys(disjunctiveFacetsRefinements).forEach(function(facetName) {\n var facetValues = disjunctiveFacetsRefinements[facetName] || [];\n if (facetName === facet || !facetValues || facetValues.length === 0) {\n return;\n }\n var orFilters = [];\n\n facetValues.forEach(function(facetValue) {\n orFilters.push(facetName + ':' + facetValue);\n });\n\n facetFilters.push(orFilters);\n });\n\n var hierarchicalFacetsRefinements = state.hierarchicalFacetsRefinements || {};\n Object.keys(hierarchicalFacetsRefinements).forEach(function(facetName) {\n var facetValues = hierarchicalFacetsRefinements[facetName] || [];\n var facetValue = facetValues[0];\n\n if (facetValue === undefined) {\n return;\n }\n\n var hierarchicalFacet = state.getHierarchicalFacetByName(facetName);\n var separator = state._getHierarchicalFacetSeparator(hierarchicalFacet);\n var rootPath = state._getHierarchicalRootPath(hierarchicalFacet);\n var attributeToRefine;\n var attributesIndex;\n\n // we ask for parent facet values only when the `facet` is the current hierarchical facet\n if (facet === facetName) {\n // if we are at the root level already, no need to ask for facet values, we get them from\n // the hits query\n if (facetValue.indexOf(separator) === -1 || (!rootPath && hierarchicalRootLevel === true) ||\n (rootPath && rootPath.split(separator).length === facetValue.split(separator).length)) {\n return;\n }\n\n if (!rootPath) {\n attributesIndex = facetValue.split(separator).length - 2;\n facetValue = facetValue.slice(0, facetValue.lastIndexOf(separator));\n } else {\n attributesIndex = rootPath.split(separator).length - 1;\n facetValue = rootPath;\n }\n\n attributeToRefine = hierarchicalFacet.attributes[attributesIndex];\n } else {\n attributesIndex = facetValue.split(separator).length - 1;\n\n attributeToRefine = hierarchicalFacet.attributes[attributesIndex];\n }\n\n if (attributeToRefine) {\n facetFilters.push([attributeToRefine + ':' + facetValue]);\n }\n });\n\n return facetFilters;\n },\n\n _getHitsHierarchicalFacetsAttributes: function(state) {\n var out = [];\n\n return state.hierarchicalFacets.reduce(\n // ask for as much levels as there's hierarchical refinements\n function getHitsAttributesForHierarchicalFacet(allAttributes, hierarchicalFacet) {\n var hierarchicalRefinement = state.getHierarchicalRefinement(hierarchicalFacet.name)[0];\n\n // if no refinement, ask for root level\n if (!hierarchicalRefinement) {\n allAttributes.push(hierarchicalFacet.attributes[0]);\n return allAttributes;\n }\n\n var separator = state._getHierarchicalFacetSeparator(hierarchicalFacet);\n var level = hierarchicalRefinement.split(separator).length;\n var newAttributes = hierarchicalFacet.attributes.slice(0, level + 1);\n\n return allAttributes.concat(newAttributes);\n }, out);\n },\n\n _getDisjunctiveHierarchicalFacetAttribute: function(state, hierarchicalFacet, rootLevel) {\n var separator = state._getHierarchicalFacetSeparator(hierarchicalFacet);\n if (rootLevel === true) {\n var rootPath = state._getHierarchicalRootPath(hierarchicalFacet);\n var attributeIndex = 0;\n\n if (rootPath) {\n attributeIndex = rootPath.split(separator).length;\n }\n return [hierarchicalFacet.attributes[attributeIndex]];\n }\n\n var hierarchicalRefinement = state.getHierarchicalRefinement(hierarchicalFacet.name)[0] || '';\n // if refinement is 'beers > IPA > Flying dog',\n // then we want `facets: ['beers > IPA']` as disjunctive facet (parent level values)\n\n var parentLevel = hierarchicalRefinement.split(separator).length - 1;\n return hierarchicalFacet.attributes.slice(0, parentLevel + 1);\n },\n\n getSearchForFacetQuery: function(facetName, query, maxFacetHits, state) {\n var stateForSearchForFacetValues = state.isDisjunctiveFacet(facetName) ?\n state.clearRefinements(facetName) :\n state;\n var searchForFacetSearchParameters = {\n facetQuery: query,\n facetName: facetName\n };\n if (typeof maxFacetHits === 'number') {\n searchForFacetSearchParameters.maxFacetHits = maxFacetHits;\n }\n return merge(\n {},\n requestBuilder._getHitsSearchParams(stateForSearchForFacetValues),\n searchForFacetSearchParameters\n );\n }\n};\n\nmodule.exports = requestBuilder;\n","'use strict';\n\nmodule.exports = '3.7.0';\n","'use strict';\n\nvar SearchParameters = require('./SearchParameters');\nvar SearchResults = require('./SearchResults');\nvar DerivedHelper = require('./DerivedHelper');\nvar requestBuilder = require('./requestBuilder');\n\nvar EventEmitter = require('@algolia/events');\nvar inherits = require('./functions/inherits');\nvar objectHasKeys = require('./functions/objectHasKeys');\nvar omit = require('./functions/omit');\nvar merge = require('./functions/merge');\n\nvar version = require('./version');\n\n/**\n * Event triggered when a parameter is set or updated\n * @event AlgoliaSearchHelper#event:change\n * @property {object} event\n * @property {SearchParameters} event.state the current parameters with the latest changes applied\n * @property {SearchResults} event.results the previous results received from Algolia. `null` before the first request\n * @example\n * helper.on('change', function(event) {\n * console.log('The parameters have changed');\n * });\n */\n\n/**\n * Event triggered when a main search is sent to Algolia\n * @event AlgoliaSearchHelper#event:search\n * @property {object} event\n * @property {SearchParameters} event.state the parameters used for this search\n * @property {SearchResults} event.results the results from the previous search. `null` if it is the first search.\n * @example\n * helper.on('search', function(event) {\n * console.log('Search sent');\n * });\n */\n\n/**\n * Event triggered when a search using `searchForFacetValues` is sent to Algolia\n * @event AlgoliaSearchHelper#event:searchForFacetValues\n * @property {object} event\n * @property {SearchParameters} event.state the parameters used for this search it is the first search.\n * @property {string} event.facet the facet searched into\n * @property {string} event.query the query used to search in the facets\n * @example\n * helper.on('searchForFacetValues', function(event) {\n * console.log('searchForFacetValues sent');\n * });\n */\n\n/**\n * Event triggered when a search using `searchOnce` is sent to Algolia\n * @event AlgoliaSearchHelper#event:searchOnce\n * @property {object} event\n * @property {SearchParameters} event.state the parameters used for this search it is the first search.\n * @example\n * helper.on('searchOnce', function(event) {\n * console.log('searchOnce sent');\n * });\n */\n\n/**\n * Event triggered when the results are retrieved from Algolia\n * @event AlgoliaSearchHelper#event:result\n * @property {object} event\n * @property {SearchResults} event.results the results received from Algolia\n * @property {SearchParameters} event.state the parameters used to query Algolia. Those might be different from the one in the helper instance (for example if the network is unreliable).\n * @example\n * helper.on('result', function(event) {\n * console.log('Search results received');\n * });\n */\n\n/**\n * Event triggered when Algolia sends back an error. For example, if an unknown parameter is\n * used, the error can be caught using this event.\n * @event AlgoliaSearchHelper#event:error\n * @property {object} event\n * @property {Error} event.error the error returned by the Algolia.\n * @example\n * helper.on('error', function(event) {\n * console.log('Houston we got a problem.');\n * });\n */\n\n/**\n * Event triggered when the queue of queries have been depleted (with any result or outdated queries)\n * @event AlgoliaSearchHelper#event:searchQueueEmpty\n * @example\n * helper.on('searchQueueEmpty', function() {\n * console.log('No more search pending');\n * // This is received before the result event if we're not expecting new results\n * });\n *\n * helper.search();\n */\n\n/**\n * Initialize a new AlgoliaSearchHelper\n * @class\n * @classdesc The AlgoliaSearchHelper is a class that ease the management of the\n * search. It provides an event based interface for search callbacks:\n * - change: when the internal search state is changed.\n * This event contains a {@link SearchParameters} object and the\n * {@link SearchResults} of the last result if any.\n * - search: when a search is triggered using the `search()` method.\n * - result: when the response is retrieved from Algolia and is processed.\n * This event contains a {@link SearchResults} object and the\n * {@link SearchParameters} corresponding to this answer.\n * - error: when the response is an error. This event contains the error returned by the server.\n * @param {AlgoliaSearch} client an AlgoliaSearch client\n * @param {string} index the index name to query\n * @param {SearchParameters | object} options an object defining the initial\n * config of the search. It doesn't have to be a {SearchParameters},\n * just an object containing the properties you need from it.\n */\nfunction AlgoliaSearchHelper(client, index, options) {\n if (typeof client.addAlgoliaAgent === 'function') {\n client.addAlgoliaAgent('JS Helper (' + version + ')');\n }\n\n this.setClient(client);\n var opts = options || {};\n opts.index = index;\n this.state = SearchParameters.make(opts);\n this.lastResults = null;\n this._queryId = 0;\n this._lastQueryIdReceived = -1;\n this.derivedHelpers = [];\n this._currentNbQueries = 0;\n}\n\ninherits(AlgoliaSearchHelper, EventEmitter);\n\n/**\n * Start the search with the parameters set in the state. When the\n * method is called, it triggers a `search` event. The results will\n * be available through the `result` event. If an error occurs, an\n * `error` will be fired instead.\n * @return {AlgoliaSearchHelper}\n * @fires search\n * @fires result\n * @fires error\n * @chainable\n */\nAlgoliaSearchHelper.prototype.search = function() {\n this._search({onlyWithDerivedHelpers: false});\n return this;\n};\n\nAlgoliaSearchHelper.prototype.searchOnlyWithDerivedHelpers = function() {\n this._search({onlyWithDerivedHelpers: true});\n return this;\n};\n\n/**\n * Gets the search query parameters that would be sent to the Algolia Client\n * for the hits\n * @return {object} Query Parameters\n */\nAlgoliaSearchHelper.prototype.getQuery = function() {\n var state = this.state;\n return requestBuilder._getHitsSearchParams(state);\n};\n\n/**\n * Start a search using a modified version of the current state. This method does\n * not trigger the helper lifecycle and does not modify the state kept internally\n * by the helper. This second aspect means that the next search call will be the\n * same as a search call before calling searchOnce.\n * @param {object} options can contain all the parameters that can be set to SearchParameters\n * plus the index\n * @param {function} [callback] optional callback executed when the response from the\n * server is back.\n * @return {promise|undefined} if a callback is passed the method returns undefined\n * otherwise it returns a promise containing an object with two keys :\n * - content with a SearchResults\n * - state with the state used for the query as a SearchParameters\n * @example\n * // Changing the number of records returned per page to 1\n * // This example uses the callback API\n * var state = helper.searchOnce({hitsPerPage: 1},\n * function(error, content, state) {\n * // if an error occurred it will be passed in error, otherwise its value is null\n * // content contains the results formatted as a SearchResults\n * // state is the instance of SearchParameters used for this search\n * });\n * @example\n * // Changing the number of records returned per page to 1\n * // This example uses the promise API\n * var state1 = helper.searchOnce({hitsPerPage: 1})\n * .then(promiseHandler);\n *\n * function promiseHandler(res) {\n * // res contains\n * // {\n * // content : SearchResults\n * // state : SearchParameters (the one used for this specific search)\n * // }\n * }\n */\nAlgoliaSearchHelper.prototype.searchOnce = function(options, cb) {\n var tempState = !options ? this.state : this.state.setQueryParameters(options);\n var queries = requestBuilder._getQueries(tempState.index, tempState);\n var self = this;\n\n this._currentNbQueries++;\n\n this.emit('searchOnce', {\n state: tempState\n });\n\n if (cb) {\n this.client\n .search(queries)\n .then(function(content) {\n self._currentNbQueries--;\n if (self._currentNbQueries === 0) {\n self.emit('searchQueueEmpty');\n }\n\n cb(null, new SearchResults(tempState, content.results), tempState);\n })\n .catch(function(err) {\n self._currentNbQueries--;\n if (self._currentNbQueries === 0) {\n self.emit('searchQueueEmpty');\n }\n\n cb(err, null, tempState);\n });\n\n return undefined;\n }\n\n return this.client.search(queries).then(function(content) {\n self._currentNbQueries--;\n if (self._currentNbQueries === 0) self.emit('searchQueueEmpty');\n return {\n content: new SearchResults(tempState, content.results),\n state: tempState,\n _originalResponse: content\n };\n }, function(e) {\n self._currentNbQueries--;\n if (self._currentNbQueries === 0) self.emit('searchQueueEmpty');\n throw e;\n });\n};\n\n /**\n * Start the search for answers with the parameters set in the state.\n * This method returns a promise.\n * @param {Object} options - the options for answers API call\n * @param {string[]} options.attributesForPrediction - Attributes to use for predictions. If empty, `searchableAttributes` is used instead.\n * @param {string[]} options.queryLanguages - The languages in the query. Currently only supports ['en'].\n * @param {number} options.nbHits - Maximum number of answers to retrieve from the Answers Engine. Cannot be greater than 1000.\n *\n * @return {promise} the answer results\n */\nAlgoliaSearchHelper.prototype.findAnswers = function(options) {\n var state = this.state;\n var derivedHelper = this.derivedHelpers[0];\n if (!derivedHelper) {\n return Promise.resolve([]);\n }\n var derivedState = derivedHelper.getModifiedState(state);\n var data = merge(\n {\n attributesForPrediction: options.attributesForPrediction,\n nbHits: options.nbHits\n },\n {\n params: omit(requestBuilder._getHitsSearchParams(derivedState), [\n 'attributesToSnippet',\n 'hitsPerPage',\n 'restrictSearchableAttributes',\n 'snippetEllipsisText' // FIXME remove this line once the engine is fixed.\n ])\n }\n );\n\n var errorMessage = 'search for answers was called, but this client does not have a function client.initIndex(index).findAnswers';\n if (typeof this.client.initIndex !== 'function') {\n throw new Error(errorMessage);\n }\n var index = this.client.initIndex(derivedState.index);\n if (typeof index.findAnswers !== 'function') {\n throw new Error(errorMessage);\n }\n return index.findAnswers(derivedState.query, options.queryLanguages, data);\n};\n\n/**\n * Structure of each result when using\n * [`searchForFacetValues()`](reference.html#AlgoliaSearchHelper#searchForFacetValues)\n * @typedef FacetSearchHit\n * @type {object}\n * @property {string} value the facet value\n * @property {string} highlighted the facet value highlighted with the query string\n * @property {number} count number of occurrence of this facet value\n * @property {boolean} isRefined true if the value is already refined\n */\n\n/**\n * Structure of the data resolved by the\n * [`searchForFacetValues()`](reference.html#AlgoliaSearchHelper#searchForFacetValues)\n * promise.\n * @typedef FacetSearchResult\n * @type {object}\n * @property {FacetSearchHit} facetHits the results for this search for facet values\n * @property {number} processingTimeMS time taken by the query inside the engine\n */\n\n/**\n * Search for facet values based on an query and the name of a faceted attribute. This\n * triggers a search and will return a promise. On top of using the query, it also sends\n * the parameters from the state so that the search is narrowed down to only the possible values.\n *\n * See the description of [FacetSearchResult](reference.html#FacetSearchResult)\n * @param {string} facet the name of the faceted attribute\n * @param {string} query the string query for the search\n * @param {number} [maxFacetHits] the maximum number values returned. Should be > 0 and <= 100\n * @param {object} [userState] the set of custom parameters to use on top of the current state. Setting a property to `undefined` removes\n * it in the generated query.\n * @return {promise.<FacetSearchResult>} the results of the search\n */\nAlgoliaSearchHelper.prototype.searchForFacetValues = function(facet, query, maxFacetHits, userState) {\n var clientHasSFFV = typeof this.client.searchForFacetValues === 'function';\n if (\n !clientHasSFFV &&\n typeof this.client.initIndex !== 'function'\n ) {\n throw new Error(\n 'search for facet values (searchable) was called, but this client does not have a function client.searchForFacetValues or client.initIndex(index).searchForFacetValues'\n );\n }\n var state = this.state.setQueryParameters(userState || {});\n var isDisjunctive = state.isDisjunctiveFacet(facet);\n var algoliaQuery = requestBuilder.getSearchForFacetQuery(facet, query, maxFacetHits, state);\n\n this._currentNbQueries++;\n var self = this;\n\n this.emit('searchForFacetValues', {\n state: state,\n facet: facet,\n query: query\n });\n\n var searchForFacetValuesPromise = clientHasSFFV\n ? this.client.searchForFacetValues([{indexName: state.index, params: algoliaQuery}])\n : this.client.initIndex(state.index).searchForFacetValues(algoliaQuery);\n\n return searchForFacetValuesPromise.then(function addIsRefined(content) {\n self._currentNbQueries--;\n if (self._currentNbQueries === 0) self.emit('searchQueueEmpty');\n\n content = Array.isArray(content) ? content[0] : content;\n\n content.facetHits.forEach(function(f) {\n f.isRefined = isDisjunctive\n ? state.isDisjunctiveFacetRefined(facet, f.value)\n : state.isFacetRefined(facet, f.value);\n });\n\n return content;\n }, function(e) {\n self._currentNbQueries--;\n if (self._currentNbQueries === 0) self.emit('searchQueueEmpty');\n throw e;\n });\n};\n\n/**\n * Sets the text query used for the search.\n *\n * This method resets the current page to 0.\n * @param {string} q the user query\n * @return {AlgoliaSearchHelper}\n * @fires change\n * @chainable\n */\nAlgoliaSearchHelper.prototype.setQuery = function(q) {\n this._change({\n state: this.state.resetPage().setQuery(q),\n isPageReset: true\n });\n\n return this;\n};\n\n/**\n * Remove all the types of refinements except tags. A string can be provided to remove\n * only the refinements of a specific attribute. For more advanced use case, you can\n * provide a function instead. This function should follow the\n * [clearCallback definition](#SearchParameters.clearCallback).\n *\n * This method resets the current page to 0.\n * @param {string} [name] optional name of the facet / attribute on which we want to remove all refinements\n * @return {AlgoliaSearchHelper}\n * @fires change\n * @chainable\n * @example\n * // Removing all the refinements\n * helper.clearRefinements().search();\n * @example\n * // Removing all the filters on a the category attribute.\n * helper.clearRefinements('category').search();\n * @example\n * // Removing only the exclude filters on the category facet.\n * helper.clearRefinements(function(value, attribute, type) {\n * return type === 'exclude' && attribute === 'category';\n * }).search();\n */\nAlgoliaSearchHelper.prototype.clearRefinements = function(name) {\n this._change({\n state: this.state.resetPage().clearRefinements(name),\n isPageReset: true\n });\n\n return this;\n};\n\n/**\n * Remove all the tag filters.\n *\n * This method resets the current page to 0.\n * @return {AlgoliaSearchHelper}\n * @fires change\n * @chainable\n */\nAlgoliaSearchHelper.prototype.clearTags = function() {\n this._change({\n state: this.state.resetPage().clearTags(),\n isPageReset: true\n });\n\n return this;\n};\n\n/**\n * Adds a disjunctive filter to a faceted attribute with the `value` provided. If the\n * filter is already set, it doesn't change the filters.\n *\n * This method resets the current page to 0.\n * @param {string} facet the facet to refine\n * @param {string} value the associated value (will be converted to string)\n * @return {AlgoliaSearchHelper}\n * @fires change\n * @chainable\n */\nAlgoliaSearchHelper.prototype.addDisjunctiveFacetRefinement = function(facet, value) {\n this._change({\n state: this.state.resetPage().addDisjunctiveFacetRefinement(facet, value),\n isPageReset: true\n });\n\n return this;\n};\n\n/**\n * @deprecated since version 2.4.0, see {@link AlgoliaSearchHelper#addDisjunctiveFacetRefinement}\n */\nAlgoliaSearchHelper.prototype.addDisjunctiveRefine = function() {\n return this.addDisjunctiveFacetRefinement.apply(this, arguments);\n};\n\n/**\n * Adds a refinement on a hierarchical facet. It will throw\n * an exception if the facet is not defined or if the facet\n * is already refined.\n *\n * This method resets the current page to 0.\n * @param {string} facet the facet name\n * @param {string} path the hierarchical facet path\n * @return {AlgoliaSearchHelper}\n * @throws Error if the facet is not defined or if the facet is refined\n * @chainable\n * @fires change\n */\nAlgoliaSearchHelper.prototype.addHierarchicalFacetRefinement = function(facet, value) {\n this._change({\n state: this.state.resetPage().addHierarchicalFacetRefinement(facet, value),\n isPageReset: true\n });\n\n return this;\n};\n\n/**\n * Adds a an numeric filter to an attribute with the `operator` and `value` provided. If the\n * filter is already set, it doesn't change the filters.\n *\n * This method resets the current page to 0.\n * @param {string} attribute the attribute on which the numeric filter applies\n * @param {string} operator the operator of the filter\n * @param {number} value the value of the filter\n * @return {AlgoliaSearchHelper}\n * @fires change\n * @chainable\n */\nAlgoliaSearchHelper.prototype.addNumericRefinement = function(attribute, operator, value) {\n this._change({\n state: this.state.resetPage().addNumericRefinement(attribute, operator, value),\n isPageReset: true\n });\n\n return this;\n};\n\n/**\n * Adds a filter to a faceted attribute with the `value` provided. If the\n * filter is already set, it doesn't change the filters.\n *\n * This method resets the current page to 0.\n * @param {string} facet the facet to refine\n * @param {string} value the associated value (will be converted to string)\n * @return {AlgoliaSearchHelper}\n * @fires change\n * @chainable\n */\nAlgoliaSearchHelper.prototype.addFacetRefinement = function(facet, value) {\n this._change({\n state: this.state.resetPage().addFacetRefinement(facet, value),\n isPageReset: true\n });\n\n return this;\n};\n\n/**\n * @deprecated since version 2.4.0, see {@link AlgoliaSearchHelper#addFacetRefinement}\n */\nAlgoliaSearchHelper.prototype.addRefine = function() {\n return this.addFacetRefinement.apply(this, arguments);\n};\n\n\n/**\n * Adds a an exclusion filter to a faceted attribute with the `value` provided. If the\n * filter is already set, it doesn't change the filters.\n *\n * This method resets the current page to 0.\n * @param {string} facet the facet to refine\n * @param {string} value the associated value (will be converted to string)\n * @return {AlgoliaSearchHelper}\n * @fires change\n * @chainable\n */\nAlgoliaSearchHelper.prototype.addFacetExclusion = function(facet, value) {\n this._change({\n state: this.state.resetPage().addExcludeRefinement(facet, value),\n isPageReset: true\n });\n\n return this;\n};\n\n/**\n * @deprecated since version 2.4.0, see {@link AlgoliaSearchHelper#addFacetExclusion}\n */\nAlgoliaSearchHelper.prototype.addExclude = function() {\n return this.addFacetExclusion.apply(this, arguments);\n};\n\n/**\n * Adds a tag filter with the `tag` provided. If the\n * filter is already set, it doesn't change the filters.\n *\n * This method resets the current page to 0.\n * @param {string} tag the tag to add to the filter\n * @return {AlgoliaSearchHelper}\n * @fires change\n * @chainable\n */\nAlgoliaSearchHelper.prototype.addTag = function(tag) {\n this._change({\n state: this.state.resetPage().addTagRefinement(tag),\n isPageReset: true\n });\n\n return this;\n};\n\n/**\n * Removes an numeric filter to an attribute with the `operator` and `value` provided. If the\n * filter is not set, it doesn't change the filters.\n *\n * Some parameters are optional, triggering different behavior:\n * - if the value is not provided, then all the numeric value will be removed for the\n * specified attribute/operator couple.\n * - if the operator is not provided either, then all the numeric filter on this attribute\n * will be removed.\n *\n * This method resets the current page to 0.\n * @param {string} attribute the attribute on which the numeric filter applies\n * @param {string} [operator] the operator of the filter\n * @param {number} [value] the value of the filter\n * @return {AlgoliaSearchHelper}\n * @fires change\n * @chainable\n */\nAlgoliaSearchHelper.prototype.removeNumericRefinement = function(attribute, operator, value) {\n this._change({\n state: this.state.resetPage().removeNumericRefinement(attribute, operator, value),\n isPageReset: true\n });\n\n return this;\n};\n\n/**\n * Removes a disjunctive filter to a faceted attribute with the `value` provided. If the\n * filter is not set, it doesn't change the filters.\n *\n * If the value is omitted, then this method will remove all the filters for the\n * attribute.\n *\n * This method resets the current page to 0.\n * @param {string} facet the facet to refine\n * @param {string} [value] the associated value\n * @return {AlgoliaSearchHelper}\n * @fires change\n * @chainable\n */\nAlgoliaSearchHelper.prototype.removeDisjunctiveFacetRefinement = function(facet, value) {\n this._change({\n state: this.state.resetPage().removeDisjunctiveFacetRefinement(facet, value),\n isPageReset: true\n });\n\n return this;\n};\n\n/**\n * @deprecated since version 2.4.0, see {@link AlgoliaSearchHelper#removeDisjunctiveFacetRefinement}\n */\nAlgoliaSearchHelper.prototype.removeDisjunctiveRefine = function() {\n return this.removeDisjunctiveFacetRefinement.apply(this, arguments);\n};\n\n/**\n * Removes the refinement set on a hierarchical facet.\n * @param {string} facet the facet name\n * @return {AlgoliaSearchHelper}\n * @throws Error if the facet is not defined or if the facet is not refined\n * @fires change\n * @chainable\n */\nAlgoliaSearchHelper.prototype.removeHierarchicalFacetRefinement = function(facet) {\n this._change({\n state: this.state.resetPage().removeHierarchicalFacetRefinement(facet),\n isPageReset: true\n });\n\n return this;\n};\n\n/**\n * Removes a filter to a faceted attribute with the `value` provided. If the\n * filter is not set, it doesn't change the filters.\n *\n * If the value is omitted, then this method will remove all the filters for the\n * attribute.\n *\n * This method resets the current page to 0.\n * @param {string} facet the facet to refine\n * @param {string} [value] the associated value\n * @return {AlgoliaSearchHelper}\n * @fires change\n * @chainable\n */\nAlgoliaSearchHelper.prototype.removeFacetRefinement = function(facet, value) {\n this._change({\n state: this.state.resetPage().removeFacetRefinement(facet, value),\n isPageReset: true\n });\n\n return this;\n};\n\n/**\n * @deprecated since version 2.4.0, see {@link AlgoliaSearchHelper#removeFacetRefinement}\n */\nAlgoliaSearchHelper.prototype.removeRefine = function() {\n return this.removeFacetRefinement.apply(this, arguments);\n};\n\n/**\n * Removes an exclusion filter to a faceted attribute with the `value` provided. If the\n * filter is not set, it doesn't change the filters.\n *\n * If the value is omitted, then this method will remove all the filters for the\n * attribute.\n *\n * This method resets the current page to 0.\n * @param {string} facet the facet to refine\n * @param {string} [value] the associated value\n * @return {AlgoliaSearchHelper}\n * @fires change\n * @chainable\n */\nAlgoliaSearchHelper.prototype.removeFacetExclusion = function(facet, value) {\n this._change({\n state: this.state.resetPage().removeExcludeRefinement(facet, value),\n isPageReset: true\n });\n\n return this;\n};\n\n/**\n * @deprecated since version 2.4.0, see {@link AlgoliaSearchHelper#removeFacetExclusion}\n */\nAlgoliaSearchHelper.prototype.removeExclude = function() {\n return this.removeFacetExclusion.apply(this, arguments);\n};\n\n/**\n * Removes a tag filter with the `tag` provided. If the\n * filter is not set, it doesn't change the filters.\n *\n * This method resets the current page to 0.\n * @param {string} tag tag to remove from the filter\n * @return {AlgoliaSearchHelper}\n * @fires change\n * @chainable\n */\nAlgoliaSearchHelper.prototype.removeTag = function(tag) {\n this._change({\n state: this.state.resetPage().removeTagRefinement(tag),\n isPageReset: true\n });\n\n return this;\n};\n\n/**\n * Adds or removes an exclusion filter to a faceted attribute with the `value` provided. If\n * the value is set then it removes it, otherwise it adds the filter.\n *\n * This method resets the current page to 0.\n * @param {string} facet the facet to refine\n * @param {string} value the associated value\n * @return {AlgoliaSearchHelper}\n * @fires change\n * @chainable\n */\nAlgoliaSearchHelper.prototype.toggleFacetExclusion = function(facet, value) {\n this._change({\n state: this.state.resetPage().toggleExcludeFacetRefinement(facet, value),\n isPageReset: true\n });\n\n return this;\n};\n\n/**\n * @deprecated since version 2.4.0, see {@link AlgoliaSearchHelper#toggleFacetExclusion}\n */\nAlgoliaSearchHelper.prototype.toggleExclude = function() {\n return this.toggleFacetExclusion.apply(this, arguments);\n};\n\n/**\n * Adds or removes a filter to a faceted attribute with the `value` provided. If\n * the value is set then it removes it, otherwise it adds the filter.\n *\n * This method can be used for conjunctive, disjunctive and hierarchical filters.\n *\n * This method resets the current page to 0.\n * @param {string} facet the facet to refine\n * @param {string} value the associated value\n * @return {AlgoliaSearchHelper}\n * @throws Error will throw an error if the facet is not declared in the settings of the helper\n * @fires change\n * @chainable\n * @deprecated since version 2.19.0, see {@link AlgoliaSearchHelper#toggleFacetRefinement}\n */\nAlgoliaSearchHelper.prototype.toggleRefinement = function(facet, value) {\n return this.toggleFacetRefinement(facet, value);\n};\n\n/**\n * Adds or removes a filter to a faceted attribute with the `value` provided. If\n * the value is set then it removes it, otherwise it adds the filter.\n *\n * This method can be used for conjunctive, disjunctive and hierarchical filters.\n *\n * This method resets the current page to 0.\n * @param {string} facet the facet to refine\n * @param {string} value the associated value\n * @return {AlgoliaSearchHelper}\n * @throws Error will throw an error if the facet is not declared in the settings of the helper\n * @fires change\n * @chainable\n */\nAlgoliaSearchHelper.prototype.toggleFacetRefinement = function(facet, value) {\n this._change({\n state: this.state.resetPage().toggleFacetRefinement(facet, value),\n isPageReset: true\n });\n\n return this;\n};\n\n/**\n * @deprecated since version 2.4.0, see {@link AlgoliaSearchHelper#toggleFacetRefinement}\n */\nAlgoliaSearchHelper.prototype.toggleRefine = function() {\n return this.toggleFacetRefinement.apply(this, arguments);\n};\n\n/**\n * Adds or removes a tag filter with the `value` provided. If\n * the value is set then it removes it, otherwise it adds the filter.\n *\n * This method resets the current page to 0.\n * @param {string} tag tag to remove or add\n * @return {AlgoliaSearchHelper}\n * @fires change\n * @chainable\n */\nAlgoliaSearchHelper.prototype.toggleTag = function(tag) {\n this._change({\n state: this.state.resetPage().toggleTagRefinement(tag),\n isPageReset: true\n });\n\n return this;\n};\n\n/**\n * Increments the page number by one.\n * @return {AlgoliaSearchHelper}\n * @fires change\n * @chainable\n * @example\n * helper.setPage(0).nextPage().getPage();\n * // returns 1\n */\nAlgoliaSearchHelper.prototype.nextPage = function() {\n var page = this.state.page || 0;\n return this.setPage(page + 1);\n};\n\n/**\n * Decrements the page number by one.\n * @fires change\n * @return {AlgoliaSearchHelper}\n * @chainable\n * @example\n * helper.setPage(1).previousPage().getPage();\n * // returns 0\n */\nAlgoliaSearchHelper.prototype.previousPage = function() {\n var page = this.state.page || 0;\n return this.setPage(page - 1);\n};\n\n/**\n * @private\n */\nfunction setCurrentPage(page) {\n if (page < 0) throw new Error('Page requested below 0.');\n\n this._change({\n state: this.state.setPage(page),\n isPageReset: false\n });\n\n return this;\n}\n\n/**\n * Change the current page\n * @deprecated\n * @param {number} page The page number\n * @return {AlgoliaSearchHelper}\n * @fires change\n * @chainable\n */\nAlgoliaSearchHelper.prototype.setCurrentPage = setCurrentPage;\n\n/**\n * Updates the current page.\n * @function\n * @param {number} page The page number\n * @return {AlgoliaSearchHelper}\n * @fires change\n * @chainable\n */\nAlgoliaSearchHelper.prototype.setPage = setCurrentPage;\n\n/**\n * Updates the name of the index that will be targeted by the query.\n *\n * This method resets the current page to 0.\n * @param {string} name the index name\n * @return {AlgoliaSearchHelper}\n * @fires change\n * @chainable\n */\nAlgoliaSearchHelper.prototype.setIndex = function(name) {\n this._change({\n state: this.state.resetPage().setIndex(name),\n isPageReset: true\n });\n\n return this;\n};\n\n/**\n * Update a parameter of the search. This method reset the page\n *\n * The complete list of parameters is available on the\n * [Algolia website](https://www.algolia.com/doc/rest#query-an-index).\n * The most commonly used parameters have their own [shortcuts](#query-parameters-shortcuts)\n * or benefit from higher-level APIs (all the kind of filters and facets have their own API)\n *\n * This method resets the current page to 0.\n * @param {string} parameter name of the parameter to update\n * @param {any} value new value of the parameter\n * @return {AlgoliaSearchHelper}\n * @fires change\n * @chainable\n * @example\n * helper.setQueryParameter('hitsPerPage', 20).search();\n */\nAlgoliaSearchHelper.prototype.setQueryParameter = function(parameter, value) {\n this._change({\n state: this.state.resetPage().setQueryParameter(parameter, value),\n isPageReset: true\n });\n\n return this;\n};\n\n/**\n * Set the whole state (warning: will erase previous state)\n * @param {SearchParameters} newState the whole new state\n * @return {AlgoliaSearchHelper}\n * @fires change\n * @chainable\n */\nAlgoliaSearchHelper.prototype.setState = function(newState) {\n this._change({\n state: SearchParameters.make(newState),\n isPageReset: false\n });\n\n return this;\n};\n\n/**\n * Override the current state without triggering a change event.\n * Do not use this method unless you know what you are doing. (see the example\n * for a legit use case)\n * @param {SearchParameters} newState the whole new state\n * @return {AlgoliaSearchHelper}\n * @example\n * helper.on('change', function(state){\n * // In this function you might want to find a way to store the state in the url/history\n * updateYourURL(state)\n * })\n * window.onpopstate = function(event){\n * // This is naive though as you should check if the state is really defined etc.\n * helper.overrideStateWithoutTriggeringChangeEvent(event.state).search()\n * }\n * @chainable\n */\nAlgoliaSearchHelper.prototype.overrideStateWithoutTriggeringChangeEvent = function(newState) {\n this.state = new SearchParameters(newState);\n return this;\n};\n\n/**\n * Check if an attribute has any numeric, conjunctive, disjunctive or hierarchical filters.\n * @param {string} attribute the name of the attribute\n * @return {boolean} true if the attribute is filtered by at least one value\n * @example\n * // hasRefinements works with numeric, conjunctive, disjunctive and hierarchical filters\n * helper.hasRefinements('price'); // false\n * helper.addNumericRefinement('price', '>', 100);\n * helper.hasRefinements('price'); // true\n *\n * helper.hasRefinements('color'); // false\n * helper.addFacetRefinement('color', 'blue');\n * helper.hasRefinements('color'); // true\n *\n * helper.hasRefinements('material'); // false\n * helper.addDisjunctiveFacetRefinement('material', 'plastic');\n * helper.hasRefinements('material'); // true\n *\n * helper.hasRefinements('categories'); // false\n * helper.toggleFacetRefinement('categories', 'kitchen > knife');\n * helper.hasRefinements('categories'); // true\n *\n */\nAlgoliaSearchHelper.prototype.hasRefinements = function(attribute) {\n if (objectHasKeys(this.state.getNumericRefinements(attribute))) {\n return true;\n } else if (this.state.isConjunctiveFacet(attribute)) {\n return this.state.isFacetRefined(attribute);\n } else if (this.state.isDisjunctiveFacet(attribute)) {\n return this.state.isDisjunctiveFacetRefined(attribute);\n } else if (this.state.isHierarchicalFacet(attribute)) {\n return this.state.isHierarchicalFacetRefined(attribute);\n }\n\n // there's currently no way to know that the user did call `addNumericRefinement` at some point\n // thus we cannot distinguish if there once was a numeric refinement that was cleared\n // so we will return false in every other situations to be consistent\n // while what we should do here is throw because we did not find the attribute in any type\n // of refinement\n return false;\n};\n\n/**\n * Check if a value is excluded for a specific faceted attribute. If the value\n * is omitted then the function checks if there is any excluding refinements.\n *\n * @param {string} facet name of the attribute for used for faceting\n * @param {string} [value] optional value. If passed will test that this value\n * is filtering the given facet.\n * @return {boolean} true if refined\n * @example\n * helper.isExcludeRefined('color'); // false\n * helper.isExcludeRefined('color', 'blue') // false\n * helper.isExcludeRefined('color', 'red') // false\n *\n * helper.addFacetExclusion('color', 'red');\n *\n * helper.isExcludeRefined('color'); // true\n * helper.isExcludeRefined('color', 'blue') // false\n * helper.isExcludeRefined('color', 'red') // true\n */\nAlgoliaSearchHelper.prototype.isExcluded = function(facet, value) {\n return this.state.isExcludeRefined(facet, value);\n};\n\n/**\n * @deprecated since 2.4.0, see {@link AlgoliaSearchHelper#hasRefinements}\n */\nAlgoliaSearchHelper.prototype.isDisjunctiveRefined = function(facet, value) {\n return this.state.isDisjunctiveFacetRefined(facet, value);\n};\n\n/**\n * Check if the string is a currently filtering tag.\n * @param {string} tag tag to check\n * @return {boolean}\n */\nAlgoliaSearchHelper.prototype.hasTag = function(tag) {\n return this.state.isTagRefined(tag);\n};\n\n/**\n * @deprecated since 2.4.0, see {@link AlgoliaSearchHelper#hasTag}\n */\nAlgoliaSearchHelper.prototype.isTagRefined = function() {\n return this.hasTagRefinements.apply(this, arguments);\n};\n\n\n/**\n * Get the name of the currently used index.\n * @return {string}\n * @example\n * helper.setIndex('highestPrice_products').getIndex();\n * // returns 'highestPrice_products'\n */\nAlgoliaSearchHelper.prototype.getIndex = function() {\n return this.state.index;\n};\n\nfunction getCurrentPage() {\n return this.state.page;\n}\n\n/**\n * Get the currently selected page\n * @deprecated\n * @return {number} the current page\n */\nAlgoliaSearchHelper.prototype.getCurrentPage = getCurrentPage;\n/**\n * Get the currently selected page\n * @function\n * @return {number} the current page\n */\nAlgoliaSearchHelper.prototype.getPage = getCurrentPage;\n\n/**\n * Get all the tags currently set to filters the results.\n *\n * @return {string[]} The list of tags currently set.\n */\nAlgoliaSearchHelper.prototype.getTags = function() {\n return this.state.tagRefinements;\n};\n\n/**\n * Get the list of refinements for a given attribute. This method works with\n * conjunctive, disjunctive, excluding and numerical filters.\n *\n * See also SearchResults#getRefinements\n *\n * @param {string} facetName attribute name used for faceting\n * @return {Array.<FacetRefinement|NumericRefinement>} All Refinement are objects that contain a value, and\n * a type. Numeric also contains an operator.\n * @example\n * helper.addNumericRefinement('price', '>', 100);\n * helper.getRefinements('price');\n * // [\n * // {\n * // \"value\": [\n * // 100\n * // ],\n * // \"operator\": \">\",\n * // \"type\": \"numeric\"\n * // }\n * // ]\n * @example\n * helper.addFacetRefinement('color', 'blue');\n * helper.addFacetExclusion('color', 'red');\n * helper.getRefinements('color');\n * // [\n * // {\n * // \"value\": \"blue\",\n * // \"type\": \"conjunctive\"\n * // },\n * // {\n * // \"value\": \"red\",\n * // \"type\": \"exclude\"\n * // }\n * // ]\n * @example\n * helper.addDisjunctiveFacetRefinement('material', 'plastic');\n * // [\n * // {\n * // \"value\": \"plastic\",\n * // \"type\": \"disjunctive\"\n * // }\n * // ]\n */\nAlgoliaSearchHelper.prototype.getRefinements = function(facetName) {\n var refinements = [];\n\n if (this.state.isConjunctiveFacet(facetName)) {\n var conjRefinements = this.state.getConjunctiveRefinements(facetName);\n\n conjRefinements.forEach(function(r) {\n refinements.push({\n value: r,\n type: 'conjunctive'\n });\n });\n\n var excludeRefinements = this.state.getExcludeRefinements(facetName);\n\n excludeRefinements.forEach(function(r) {\n refinements.push({\n value: r,\n type: 'exclude'\n });\n });\n } else if (this.state.isDisjunctiveFacet(facetName)) {\n var disjRefinements = this.state.getDisjunctiveRefinements(facetName);\n\n disjRefinements.forEach(function(r) {\n refinements.push({\n value: r,\n type: 'disjunctive'\n });\n });\n }\n\n var numericRefinements = this.state.getNumericRefinements(facetName);\n\n Object.keys(numericRefinements).forEach(function(operator) {\n var value = numericRefinements[operator];\n\n refinements.push({\n value: value,\n operator: operator,\n type: 'numeric'\n });\n });\n\n return refinements;\n};\n\n/**\n * Return the current refinement for the (attribute, operator)\n * @param {string} attribute attribute in the record\n * @param {string} operator operator applied on the refined values\n * @return {Array.<number|number[]>} refined values\n */\nAlgoliaSearchHelper.prototype.getNumericRefinement = function(attribute, operator) {\n return this.state.getNumericRefinement(attribute, operator);\n};\n\n/**\n * Get the current breadcrumb for a hierarchical facet, as an array\n * @param {string} facetName Hierarchical facet name\n * @return {array.<string>} the path as an array of string\n */\nAlgoliaSearchHelper.prototype.getHierarchicalFacetBreadcrumb = function(facetName) {\n return this.state.getHierarchicalFacetBreadcrumb(facetName);\n};\n\n// /////////// PRIVATE\n\n/**\n * Perform the underlying queries\n * @private\n * @return {undefined}\n * @fires search\n * @fires result\n * @fires error\n */\nAlgoliaSearchHelper.prototype._search = function(options) {\n var state = this.state;\n var states = [];\n var mainQueries = [];\n\n if (!options.onlyWithDerivedHelpers) {\n mainQueries = requestBuilder._getQueries(state.index, state);\n\n states.push({\n state: state,\n queriesCount: mainQueries.length,\n helper: this\n });\n\n this.emit('search', {\n state: state,\n results: this.lastResults\n });\n }\n\n var derivedQueries = this.derivedHelpers.map(function(derivedHelper) {\n var derivedState = derivedHelper.getModifiedState(state);\n var derivedStateQueries = requestBuilder._getQueries(derivedState.index, derivedState);\n\n states.push({\n state: derivedState,\n queriesCount: derivedStateQueries.length,\n helper: derivedHelper\n });\n\n derivedHelper.emit('search', {\n state: derivedState,\n results: derivedHelper.lastResults\n });\n\n return derivedStateQueries;\n });\n\n var queries = Array.prototype.concat.apply(mainQueries, derivedQueries);\n var queryId = this._queryId++;\n\n this._currentNbQueries++;\n\n try {\n this.client.search(queries)\n .then(this._dispatchAlgoliaResponse.bind(this, states, queryId))\n .catch(this._dispatchAlgoliaError.bind(this, queryId));\n } catch (error) {\n // If we reach this part, we're in an internal error state\n this.emit('error', {\n error: error\n });\n }\n};\n\n/**\n * Transform the responses as sent by the server and transform them into a user\n * usable object that merge the results of all the batch requests. It will dispatch\n * over the different helper + derived helpers (when there are some).\n * @private\n * @param {array.<{SearchParameters, AlgoliaQueries, AlgoliaSearchHelper}>}\n * state state used for to generate the request\n * @param {number} queryId id of the current request\n * @param {object} content content of the response\n * @return {undefined}\n */\nAlgoliaSearchHelper.prototype._dispatchAlgoliaResponse = function(states, queryId, content) {\n // FIXME remove the number of outdated queries discarded instead of just one\n\n if (queryId < this._lastQueryIdReceived) {\n // Outdated answer\n return;\n }\n\n this._currentNbQueries -= (queryId - this._lastQueryIdReceived);\n this._lastQueryIdReceived = queryId;\n\n if (this._currentNbQueries === 0) this.emit('searchQueueEmpty');\n\n var results = content.results.slice();\n\n states.forEach(function(s) {\n var state = s.state;\n var queriesCount = s.queriesCount;\n var helper = s.helper;\n var specificResults = results.splice(0, queriesCount);\n\n var formattedResponse = helper.lastResults = new SearchResults(state, specificResults);\n\n helper.emit('result', {\n results: formattedResponse,\n state: state\n });\n });\n};\n\nAlgoliaSearchHelper.prototype._dispatchAlgoliaError = function(queryId, error) {\n if (queryId < this._lastQueryIdReceived) {\n // Outdated answer\n return;\n }\n\n this._currentNbQueries -= queryId - this._lastQueryIdReceived;\n this._lastQueryIdReceived = queryId;\n\n this.emit('error', {\n error: error\n });\n\n if (this._currentNbQueries === 0) this.emit('searchQueueEmpty');\n};\n\nAlgoliaSearchHelper.prototype.containsRefinement = function(query, facetFilters, numericFilters, tagFilters) {\n return query ||\n facetFilters.length !== 0 ||\n numericFilters.length !== 0 ||\n tagFilters.length !== 0;\n};\n\n/**\n * Test if there are some disjunctive refinements on the facet\n * @private\n * @param {string} facet the attribute to test\n * @return {boolean}\n */\nAlgoliaSearchHelper.prototype._hasDisjunctiveRefinements = function(facet) {\n return this.state.disjunctiveRefinements[facet] &&\n this.state.disjunctiveRefinements[facet].length > 0;\n};\n\nAlgoliaSearchHelper.prototype._change = function(event) {\n var state = event.state;\n var isPageReset = event.isPageReset;\n\n if (state !== this.state) {\n this.state = state;\n\n this.emit('change', {\n state: this.state,\n results: this.lastResults,\n isPageReset: isPageReset\n });\n }\n};\n\n/**\n * Clears the cache of the underlying Algolia client.\n * @return {AlgoliaSearchHelper}\n */\nAlgoliaSearchHelper.prototype.clearCache = function() {\n this.client.clearCache && this.client.clearCache();\n return this;\n};\n\n/**\n * Updates the internal client instance. If the reference of the clients\n * are equal then no update is actually done.\n * @param {AlgoliaSearch} newClient an AlgoliaSearch client\n * @return {AlgoliaSearchHelper}\n */\nAlgoliaSearchHelper.prototype.setClient = function(newClient) {\n if (this.client === newClient) return this;\n\n if (typeof newClient.addAlgoliaAgent === 'function') {\n newClient.addAlgoliaAgent('JS Helper (' + version + ')');\n }\n this.client = newClient;\n\n return this;\n};\n\n/**\n * Gets the instance of the currently used client.\n * @return {AlgoliaSearch}\n */\nAlgoliaSearchHelper.prototype.getClient = function() {\n return this.client;\n};\n\n/**\n * Creates an derived instance of the Helper. A derived helper\n * is a way to request other indices synchronised with the lifecycle\n * of the main Helper. This mechanism uses the multiqueries feature\n * of Algolia to aggregate all the requests in a single network call.\n *\n * This method takes a function that is used to create a new SearchParameter\n * that will be used to create requests to Algolia. Those new requests\n * are created just before the `search` event. The signature of the function\n * is `SearchParameters -> SearchParameters`.\n *\n * This method returns a new DerivedHelper which is an EventEmitter\n * that fires the same `search`, `result` and `error` events. Those\n * events, however, will receive data specific to this DerivedHelper\n * and the SearchParameters that is returned by the call of the\n * parameter function.\n * @param {function} fn SearchParameters -> SearchParameters\n * @return {DerivedHelper}\n */\nAlgoliaSearchHelper.prototype.derive = function(fn) {\n var derivedHelper = new DerivedHelper(this, fn);\n this.derivedHelpers.push(derivedHelper);\n return derivedHelper;\n};\n\n/**\n * This method detaches a derived Helper from the main one. Prefer using the one from the\n * derived helper itself, to remove the event listeners too.\n * @private\n * @return {undefined}\n * @throws Error\n */\nAlgoliaSearchHelper.prototype.detachDerivedHelper = function(derivedHelper) {\n var pos = this.derivedHelpers.indexOf(derivedHelper);\n if (pos === -1) throw new Error('Derived helper already detached');\n this.derivedHelpers.splice(pos, 1);\n};\n\n/**\n * This method returns true if there is currently at least one on-going search.\n * @return {boolean} true if there is a search pending\n */\nAlgoliaSearchHelper.prototype.hasPendingRequests = function() {\n return this._currentNbQueries > 0;\n};\n\n/**\n * @typedef AlgoliaSearchHelper.NumericRefinement\n * @type {object}\n * @property {number[]} value the numbers that are used for filtering this attribute with\n * the operator specified.\n * @property {string} operator the faceting data: value, number of entries\n * @property {string} type will be 'numeric'\n */\n\n/**\n * @typedef AlgoliaSearchHelper.FacetRefinement\n * @type {object}\n * @property {string} value the string use to filter the attribute\n * @property {string} type the type of filter: 'conjunctive', 'disjunctive', 'exclude'\n */\n\nmodule.exports = AlgoliaSearchHelper;\n","'use strict';\n\nvar AlgoliaSearchHelper = require('./src/algoliasearch.helper');\n\nvar SearchParameters = require('./src/SearchParameters');\nvar SearchResults = require('./src/SearchResults');\n\n/**\n * The algoliasearchHelper module is the function that will let its\n * contains everything needed to use the Algoliasearch\n * Helper. It is a also a function that instanciate the helper.\n * To use the helper, you also need the Algolia JS client v3.\n * @example\n * //using the UMD build\n * var client = algoliasearch('latency', '6be0576ff61c053d5f9a3225e2a90f76');\n * var helper = algoliasearchHelper(client, 'bestbuy', {\n * facets: ['shipping'],\n * disjunctiveFacets: ['category']\n * });\n * helper.on('result', function(event) {\n * console.log(event.results);\n * });\n * helper\n * .toggleFacetRefinement('category', 'Movies & TV Shows')\n * .toggleFacetRefinement('shipping', 'Free shipping')\n * .search();\n * @example\n * // The helper is an event emitter using the node API\n * helper.on('result', updateTheResults);\n * helper.once('result', updateTheResults);\n * helper.removeListener('result', updateTheResults);\n * helper.removeAllListeners('result');\n * @module algoliasearchHelper\n * @param {AlgoliaSearch} client an AlgoliaSearch client\n * @param {string} index the name of the index to query\n * @param {SearchParameters|object} opts an object defining the initial config of the search. It doesn't have to be a {SearchParameters}, just an object containing the properties you need from it.\n * @return {AlgoliaSearchHelper}\n */\nfunction algoliasearchHelper(client, index, opts) {\n return new AlgoliaSearchHelper(client, index, opts);\n}\n\n/**\n * The version currently used\n * @member module:algoliasearchHelper.version\n * @type {number}\n */\nalgoliasearchHelper.version = require('./src/version.js');\n\n/**\n * Constructor for the Helper.\n * @member module:algoliasearchHelper.AlgoliaSearchHelper\n * @type {AlgoliaSearchHelper}\n */\nalgoliasearchHelper.AlgoliaSearchHelper = AlgoliaSearchHelper;\n\n/**\n * Constructor for the object containing all the parameters of the search.\n * @member module:algoliasearchHelper.SearchParameters\n * @type {SearchParameters}\n */\nalgoliasearchHelper.SearchParameters = SearchParameters;\n\n/**\n * Constructor for the object containing the results of the search.\n * @member module:algoliasearchHelper.SearchResults\n * @type {SearchResults}\n */\nalgoliasearchHelper.SearchResults = SearchResults;\n\nmodule.exports = algoliasearchHelper;\n","const nextMicroTask = Promise.resolve();\n\ntype Callback = (...args: any[]) => void;\ntype Defer = Callback & {\n wait(): Promise<void>;\n cancel(): void;\n};\n\nconst defer = (callback: Callback): Defer => {\n let progress: Promise<void> | null = null;\n let cancelled = false;\n\n const fn: Defer = (...args) => {\n if (progress !== null) {\n return;\n }\n\n progress = nextMicroTask.then(() => {\n progress = null;\n\n if (cancelled) {\n cancelled = false;\n return;\n }\n\n callback(...args);\n });\n };\n\n fn.wait = () => {\n if (progress === null) {\n throw new Error(\n 'The deferred function should be called before calling `wait()`'\n );\n }\n\n return progress;\n };\n\n fn.cancel = () => {\n if (progress === null) {\n return;\n }\n\n cancelled = true;\n };\n\n return fn;\n};\n\nexport default defer;\n","import isDomElement from './isDomElement';\n\n/**\n * Return the container. If it's a string, it is considered a\n * css selector and retrieves the first matching element. Otherwise\n * test if it validates that it's a correct DOMElement.\n *\n * @param {string|HTMLElement} selectorOrHTMLElement CSS Selector or container node.\n * @return {HTMLElement} Container node\n * @throws Error when the type is not correct\n */\nfunction getContainerNode(\n selectorOrHTMLElement: string | HTMLElement\n): HTMLElement {\n const isSelectorString = typeof selectorOrHTMLElement === 'string';\n const domElement = isSelectorString\n ? document.querySelector(selectorOrHTMLElement as string)\n : selectorOrHTMLElement;\n\n if (!isDomElement(domElement)) {\n let errorMessage = 'Container must be `string` or `HTMLElement`.';\n\n if (isSelectorString) {\n errorMessage += ` Unable to find ${selectorOrHTMLElement}`;\n }\n\n throw new Error(errorMessage);\n }\n\n return domElement;\n}\n\nexport default getContainerNode;\n","function isDomElement(object: any): object is HTMLElement {\n return (\n object instanceof HTMLElement || (Boolean(object) && object.nodeType > 0)\n );\n}\n\nexport default isDomElement;\n","function isSpecialClick(event: MouseEvent): boolean {\n const isMiddleClick = event.button === 1;\n\n return (\n isMiddleClick ||\n event.altKey ||\n event.ctrlKey ||\n event.metaKey ||\n event.shiftKey\n );\n}\n\nexport default isSpecialClick;\n","function uniq<TItem>(array: TItem[]): TItem[] {\n return array.filter((value, index, self) => self.indexOf(value) === index);\n}\n\nexport default uniq;\n","import uniq from './uniq';\nimport type { HoganHelpers, Templates } from '../../types';\nimport type { HoganOptions } from 'hogan.js';\n\ntype TemplatesConfig = {\n helpers?: HoganHelpers;\n compileOptions?: HoganOptions;\n};\n\nexport type PreparedTemplateProps<TTemplates extends Templates> = {\n templatesConfig: TemplatesConfig;\n templates: TTemplates;\n useCustomCompileOptions: {\n [TKey in keyof Partial<TTemplates>]: boolean;\n };\n};\n\nfunction prepareTemplates<TTemplates extends Templates>(\n // can not use = {} here, since the template could have different constraints\n defaultTemplates?: TTemplates,\n templates: Partial<TTemplates> = {}\n) {\n const allKeys = uniq([\n ...Object.keys(defaultTemplates || {}),\n ...Object.keys(templates),\n ]);\n\n return allKeys.reduce(\n (config, key: keyof TTemplates) => {\n const defaultTemplate = defaultTemplates\n ? defaultTemplates[key]\n : undefined;\n const customTemplate = templates[key];\n const isCustomTemplate =\n customTemplate !== undefined && customTemplate !== defaultTemplate;\n\n config.templates[key] = isCustomTemplate\n ? customTemplate! // typescript doesn't recognize that this condition asserts customTemplate is defined\n : defaultTemplate!;\n\n config.useCustomCompileOptions[key] = isCustomTemplate;\n\n return config;\n },\n {\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n templates: {} as TTemplates,\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n useCustomCompileOptions: {} as {\n [TKey in keyof TTemplates]: boolean;\n },\n }\n );\n}\n\n/**\n * Prepares an object to be passed to the Template widget\n */\nfunction prepareTemplateProps<TTemplates extends Templates>({\n defaultTemplates,\n templates,\n templatesConfig,\n}: {\n defaultTemplates: TTemplates;\n templates?: Partial<TTemplates>;\n templatesConfig: TemplatesConfig;\n}): PreparedTemplateProps<TTemplates> {\n const preparedTemplates = prepareTemplates(defaultTemplates, templates);\n\n return {\n templatesConfig,\n ...preparedTemplates,\n };\n}\n\nexport default prepareTemplateProps;\n","/*\n * Copyright 2011 Twitter, Inc.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n(function (Hogan) {\n // Setup regex assignments\n // remove whitespace according to Mustache spec\n var rIsWhitespace = /\\S/,\n rQuot = /\\\"/g,\n rNewline = /\\n/g,\n rCr = /\\r/g,\n rSlash = /\\\\/g,\n rLineSep = /\\u2028/,\n rParagraphSep = /\\u2029/;\n\n Hogan.tags = {\n '#': 1, '^': 2, '<': 3, '$': 4,\n '/': 5, '!': 6, '>': 7, '=': 8, '_v': 9,\n '{': 10, '&': 11, '_t': 12\n };\n\n Hogan.scan = function scan(text, delimiters) {\n var len = text.length,\n IN_TEXT = 0,\n IN_TAG_TYPE = 1,\n IN_TAG = 2,\n state = IN_TEXT,\n tagType = null,\n tag = null,\n buf = '',\n tokens = [],\n seenTag = false,\n i = 0,\n lineStart = 0,\n otag = '{{',\n ctag = '}}';\n\n function addBuf() {\n if (buf.length > 0) {\n tokens.push({tag: '_t', text: new String(buf)});\n buf = '';\n }\n }\n\n function lineIsWhitespace() {\n var isAllWhitespace = true;\n for (var j = lineStart; j < tokens.length; j++) {\n isAllWhitespace =\n (Hogan.tags[tokens[j].tag] < Hogan.tags['_v']) ||\n (tokens[j].tag == '_t' && tokens[j].text.match(rIsWhitespace) === null);\n if (!isAllWhitespace) {\n return false;\n }\n }\n\n return isAllWhitespace;\n }\n\n function filterLine(haveSeenTag, noNewLine) {\n addBuf();\n\n if (haveSeenTag && lineIsWhitespace()) {\n for (var j = lineStart, next; j < tokens.length; j++) {\n if (tokens[j].text) {\n if ((next = tokens[j+1]) && next.tag == '>') {\n // set indent to token value\n next.indent = tokens[j].text.toString()\n }\n tokens.splice(j, 1);\n }\n }\n } else if (!noNewLine) {\n tokens.push({tag:'\\n'});\n }\n\n seenTag = false;\n lineStart = tokens.length;\n }\n\n function changeDelimiters(text, index) {\n var close = '=' + ctag,\n closeIndex = text.indexOf(close, index),\n delimiters = trim(\n text.substring(text.indexOf('=', index) + 1, closeIndex)\n ).split(' ');\n\n otag = delimiters[0];\n ctag = delimiters[delimiters.length - 1];\n\n return closeIndex + close.length - 1;\n }\n\n if (delimiters) {\n delimiters = delimiters.split(' ');\n otag = delimiters[0];\n ctag = delimiters[1];\n }\n\n for (i = 0; i < len; i++) {\n if (state == IN_TEXT) {\n if (tagChange(otag, text, i)) {\n --i;\n addBuf();\n state = IN_TAG_TYPE;\n } else {\n if (text.charAt(i) == '\\n') {\n filterLine(seenTag);\n } else {\n buf += text.charAt(i);\n }\n }\n } else if (state == IN_TAG_TYPE) {\n i += otag.length - 1;\n tag = Hogan.tags[text.charAt(i + 1)];\n tagType = tag ? text.charAt(i + 1) : '_v';\n if (tagType == '=') {\n i = changeDelimiters(text, i);\n state = IN_TEXT;\n } else {\n if (tag) {\n i++;\n }\n state = IN_TAG;\n }\n seenTag = i;\n } else {\n if (tagChange(ctag, text, i)) {\n tokens.push({tag: tagType, n: trim(buf), otag: otag, ctag: ctag,\n i: (tagType == '/') ? seenTag - otag.length : i + ctag.length});\n buf = '';\n i += ctag.length - 1;\n state = IN_TEXT;\n if (tagType == '{') {\n if (ctag == '}}') {\n i++;\n } else {\n cleanTripleStache(tokens[tokens.length - 1]);\n }\n }\n } else {\n buf += text.charAt(i);\n }\n }\n }\n\n filterLine(seenTag, true);\n\n return tokens;\n }\n\n function cleanTripleStache(token) {\n if (token.n.substr(token.n.length - 1) === '}') {\n token.n = token.n.substring(0, token.n.length - 1);\n }\n }\n\n function trim(s) {\n if (s.trim) {\n return s.trim();\n }\n\n return s.replace(/^\\s*|\\s*$/g, '');\n }\n\n function tagChange(tag, text, index) {\n if (text.charAt(index) != tag.charAt(0)) {\n return false;\n }\n\n for (var i = 1, l = tag.length; i < l; i++) {\n if (text.charAt(index + i) != tag.charAt(i)) {\n return false;\n }\n }\n\n return true;\n }\n\n // the tags allowed inside super templates\n var allowedInSuper = {'_t': true, '\\n': true, '$': true, '/': true};\n\n function buildTree(tokens, kind, stack, customTags) {\n var instructions = [],\n opener = null,\n tail = null,\n token = null;\n\n tail = stack[stack.length - 1];\n\n while (tokens.length > 0) {\n token = tokens.shift();\n\n if (tail && tail.tag == '<' && !(token.tag in allowedInSuper)) {\n throw new Error('Illegal content in < super tag.');\n }\n\n if (Hogan.tags[token.tag] <= Hogan.tags['$'] || isOpener(token, customTags)) {\n stack.push(token);\n token.nodes = buildTree(tokens, token.tag, stack, customTags);\n } else if (token.tag == '/') {\n if (stack.length === 0) {\n throw new Error('Closing tag without opener: /' + token.n);\n }\n opener = stack.pop();\n if (token.n != opener.n && !isCloser(token.n, opener.n, customTags)) {\n throw new Error('Nesting error: ' + opener.n + ' vs. ' + token.n);\n }\n opener.end = token.i;\n return instructions;\n } else if (token.tag == '\\n') {\n token.last = (tokens.length == 0) || (tokens[0].tag == '\\n');\n }\n\n instructions.push(token);\n }\n\n if (stack.length > 0) {\n throw new Error('missing closing tag: ' + stack.pop().n);\n }\n\n return instructions;\n }\n\n function isOpener(token, tags) {\n for (var i = 0, l = tags.length; i < l; i++) {\n if (tags[i].o == token.n) {\n token.tag = '#';\n return true;\n }\n }\n }\n\n function isCloser(close, open, tags) {\n for (var i = 0, l = tags.length; i < l; i++) {\n if (tags[i].c == close && tags[i].o == open) {\n return true;\n }\n }\n }\n\n function stringifySubstitutions(obj) {\n var items = [];\n for (var key in obj) {\n items.push('\"' + esc(key) + '\": function(c,p,t,i) {' + obj[key] + '}');\n }\n return \"{ \" + items.join(\",\") + \" }\";\n }\n\n function stringifyPartials(codeObj) {\n var partials = [];\n for (var key in codeObj.partials) {\n partials.push('\"' + esc(key) + '\":{name:\"' + esc(codeObj.partials[key].name) + '\", ' + stringifyPartials(codeObj.partials[key]) + \"}\");\n }\n return \"partials: {\" + partials.join(\",\") + \"}, subs: \" + stringifySubstitutions(codeObj.subs);\n }\n\n Hogan.stringify = function(codeObj, text, options) {\n return \"{code: function (c,p,i) { \" + Hogan.wrapMain(codeObj.code) + \" },\" + stringifyPartials(codeObj) + \"}\";\n }\n\n var serialNo = 0;\n Hogan.generate = function(tree, text, options) {\n serialNo = 0;\n var context = { code: '', subs: {}, partials: {} };\n Hogan.walk(tree, context);\n\n if (options.asString) {\n return this.stringify(context, text, options);\n }\n\n return this.makeTemplate(context, text, options);\n }\n\n Hogan.wrapMain = function(code) {\n return 'var t=this;t.b(i=i||\"\");' + code + 'return t.fl();';\n }\n\n Hogan.template = Hogan.Template;\n\n Hogan.makeTemplate = function(codeObj, text, options) {\n var template = this.makePartials(codeObj);\n template.code = new Function('c', 'p', 'i', this.wrapMain(codeObj.code));\n return new this.template(template, text, this, options);\n }\n\n Hogan.makePartials = function(codeObj) {\n var key, template = {subs: {}, partials: codeObj.partials, name: codeObj.name};\n for (key in template.partials) {\n template.partials[key] = this.makePartials(template.partials[key]);\n }\n for (key in codeObj.subs) {\n template.subs[key] = new Function('c', 'p', 't', 'i', codeObj.subs[key]);\n }\n return template;\n }\n\n function esc(s) {\n return s.replace(rSlash, '\\\\\\\\')\n .replace(rQuot, '\\\\\\\"')\n .replace(rNewline, '\\\\n')\n .replace(rCr, '\\\\r')\n .replace(rLineSep, '\\\\u2028')\n .replace(rParagraphSep, '\\\\u2029');\n }\n\n function chooseMethod(s) {\n return (~s.indexOf('.')) ? 'd' : 'f';\n }\n\n function createPartial(node, context) {\n var prefix = \"<\" + (context.prefix || \"\");\n var sym = prefix + node.n + serialNo++;\n context.partials[sym] = {name: node.n, partials: {}};\n context.code += 't.b(t.rp(\"' + esc(sym) + '\",c,p,\"' + (node.indent || '') + '\"));';\n return sym;\n }\n\n Hogan.codegen = {\n '#': function(node, context) {\n context.code += 'if(t.s(t.' + chooseMethod(node.n) + '(\"' + esc(node.n) + '\",c,p,1),' +\n 'c,p,0,' + node.i + ',' + node.end + ',\"' + node.otag + \" \" + node.ctag + '\")){' +\n 't.rs(c,p,' + 'function(c,p,t){';\n Hogan.walk(node.nodes, context);\n context.code += '});c.pop();}';\n },\n\n '^': function(node, context) {\n context.code += 'if(!t.s(t.' + chooseMethod(node.n) + '(\"' + esc(node.n) + '\",c,p,1),c,p,1,0,0,\"\")){';\n Hogan.walk(node.nodes, context);\n context.code += '};';\n },\n\n '>': createPartial,\n '<': function(node, context) {\n var ctx = {partials: {}, code: '', subs: {}, inPartial: true};\n Hogan.walk(node.nodes, ctx);\n var template = context.partials[createPartial(node, context)];\n template.subs = ctx.subs;\n template.partials = ctx.partials;\n },\n\n '$': function(node, context) {\n var ctx = {subs: {}, code: '', partials: context.partials, prefix: node.n};\n Hogan.walk(node.nodes, ctx);\n context.subs[node.n] = ctx.code;\n if (!context.inPartial) {\n context.code += 't.sub(\"' + esc(node.n) + '\",c,p,i);';\n }\n },\n\n '\\n': function(node, context) {\n context.code += write('\"\\\\n\"' + (node.last ? '' : ' + i'));\n },\n\n '_v': function(node, context) {\n context.code += 't.b(t.v(t.' + chooseMethod(node.n) + '(\"' + esc(node.n) + '\",c,p,0)));';\n },\n\n '_t': function(node, context) {\n context.code += write('\"' + esc(node.text) + '\"');\n },\n\n '{': tripleStache,\n\n '&': tripleStache\n }\n\n function tripleStache(node, context) {\n context.code += 't.b(t.t(t.' + chooseMethod(node.n) + '(\"' + esc(node.n) + '\",c,p,0)));';\n }\n\n function write(s) {\n return 't.b(' + s + ');';\n }\n\n Hogan.walk = function(nodelist, context) {\n var func;\n for (var i = 0, l = nodelist.length; i < l; i++) {\n func = Hogan.codegen[nodelist[i].tag];\n func && func(nodelist[i], context);\n }\n return context;\n }\n\n Hogan.parse = function(tokens, text, options) {\n options = options || {};\n return buildTree(tokens, '', [], options.sectionTags || []);\n }\n\n Hogan.cache = {};\n\n Hogan.cacheKey = function(text, options) {\n return [text, !!options.asString, !!options.disableLambda, options.delimiters, !!options.modelGet].join('||');\n }\n\n Hogan.compile = function(text, options) {\n options = options || {};\n var key = Hogan.cacheKey(text, options);\n var template = this.cache[key];\n\n if (template) {\n var partials = template.partials;\n for (var name in partials) {\n delete partials[name].instance;\n }\n return template;\n }\n\n template = this.generate(this.parse(this.scan(text, options.delimiters), text, options), text, options);\n return this.cache[key] = template;\n }\n})(typeof exports !== 'undefined' ? exports : Hogan);\n","/*\n * Copyright 2011 Twitter, Inc.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nvar Hogan = {};\n\n(function (Hogan) {\n Hogan.Template = function (codeObj, text, compiler, options) {\n codeObj = codeObj || {};\n this.r = codeObj.code || this.r;\n this.c = compiler;\n this.options = options || {};\n this.text = text || '';\n this.partials = codeObj.partials || {};\n this.subs = codeObj.subs || {};\n this.buf = '';\n }\n\n Hogan.Template.prototype = {\n // render: replaced by generated code.\n r: function (context, partials, indent) { return ''; },\n\n // variable escaping\n v: hoganEscape,\n\n // triple stache\n t: coerceToString,\n\n render: function render(context, partials, indent) {\n return this.ri([context], partials || {}, indent);\n },\n\n // render internal -- a hook for overrides that catches partials too\n ri: function (context, partials, indent) {\n return this.r(context, partials, indent);\n },\n\n // ensurePartial\n ep: function(symbol, partials) {\n var partial = this.partials[symbol];\n\n // check to see that if we've instantiated this partial before\n var template = partials[partial.name];\n if (partial.instance && partial.base == template) {\n return partial.instance;\n }\n\n if (typeof template == 'string') {\n if (!this.c) {\n throw new Error(\"No compiler available.\");\n }\n template = this.c.compile(template, this.options);\n }\n\n if (!template) {\n return null;\n }\n\n // We use this to check whether the partials dictionary has changed\n this.partials[symbol].base = template;\n\n if (partial.subs) {\n // Make sure we consider parent template now\n if (!partials.stackText) partials.stackText = {};\n for (key in partial.subs) {\n if (!partials.stackText[key]) {\n partials.stackText[key] = (this.activeSub !== undefined && partials.stackText[this.activeSub]) ? partials.stackText[this.activeSub] : this.text;\n }\n }\n template = createSpecializedPartial(template, partial.subs, partial.partials,\n this.stackSubs, this.stackPartials, partials.stackText);\n }\n this.partials[symbol].instance = template;\n\n return template;\n },\n\n // tries to find a partial in the current scope and render it\n rp: function(symbol, context, partials, indent) {\n var partial = this.ep(symbol, partials);\n if (!partial) {\n return '';\n }\n\n return partial.ri(context, partials, indent);\n },\n\n // render a section\n rs: function(context, partials, section) {\n var tail = context[context.length - 1];\n\n if (!isArray(tail)) {\n section(context, partials, this);\n return;\n }\n\n for (var i = 0; i < tail.length; i++) {\n context.push(tail[i]);\n section(context, partials, this);\n context.pop();\n }\n },\n\n // maybe start a section\n s: function(val, ctx, partials, inverted, start, end, tags) {\n var pass;\n\n if (isArray(val) && val.length === 0) {\n return false;\n }\n\n if (typeof val == 'function') {\n val = this.ms(val, ctx, partials, inverted, start, end, tags);\n }\n\n pass = !!val;\n\n if (!inverted && pass && ctx) {\n ctx.push((typeof val == 'object') ? val : ctx[ctx.length - 1]);\n }\n\n return pass;\n },\n\n // find values with dotted names\n d: function(key, ctx, partials, returnFound) {\n var found,\n names = key.split('.'),\n val = this.f(names[0], ctx, partials, returnFound),\n doModelGet = this.options.modelGet,\n cx = null;\n\n if (key === '.' && isArray(ctx[ctx.length - 2])) {\n val = ctx[ctx.length - 1];\n } else {\n for (var i = 1; i < names.length; i++) {\n found = findInScope(names[i], val, doModelGet);\n if (found !== undefined) {\n cx = val;\n val = found;\n } else {\n val = '';\n }\n }\n }\n\n if (returnFound && !val) {\n return false;\n }\n\n if (!returnFound && typeof val == 'function') {\n ctx.push(cx);\n val = this.mv(val, ctx, partials);\n ctx.pop();\n }\n\n return val;\n },\n\n // find values with normal names\n f: function(key, ctx, partials, returnFound) {\n var val = false,\n v = null,\n found = false,\n doModelGet = this.options.modelGet;\n\n for (var i = ctx.length - 1; i >= 0; i--) {\n v = ctx[i];\n val = findInScope(key, v, doModelGet);\n if (val !== undefined) {\n found = true;\n break;\n }\n }\n\n if (!found) {\n return (returnFound) ? false : \"\";\n }\n\n if (!returnFound && typeof val == 'function') {\n val = this.mv(val, ctx, partials);\n }\n\n return val;\n },\n\n // higher order templates\n ls: function(func, cx, partials, text, tags) {\n var oldTags = this.options.delimiters;\n\n this.options.delimiters = tags;\n this.b(this.ct(coerceToString(func.call(cx, text)), cx, partials));\n this.options.delimiters = oldTags;\n\n return false;\n },\n\n // compile text\n ct: function(text, cx, partials) {\n if (this.options.disableLambda) {\n throw new Error('Lambda features disabled.');\n }\n return this.c.compile(text, this.options).render(cx, partials);\n },\n\n // template result buffering\n b: function(s) { this.buf += s; },\n\n fl: function() { var r = this.buf; this.buf = ''; return r; },\n\n // method replace section\n ms: function(func, ctx, partials, inverted, start, end, tags) {\n var textSource,\n cx = ctx[ctx.length - 1],\n result = func.call(cx);\n\n if (typeof result == 'function') {\n if (inverted) {\n return true;\n } else {\n textSource = (this.activeSub && this.subsText && this.subsText[this.activeSub]) ? this.subsText[this.activeSub] : this.text;\n return this.ls(result, cx, partials, textSource.substring(start, end), tags);\n }\n }\n\n return result;\n },\n\n // method replace variable\n mv: function(func, ctx, partials) {\n var cx = ctx[ctx.length - 1];\n var result = func.call(cx);\n\n if (typeof result == 'function') {\n return this.ct(coerceToString(result.call(cx)), cx, partials);\n }\n\n return result;\n },\n\n sub: function(name, context, partials, indent) {\n var f = this.subs[name];\n if (f) {\n this.activeSub = name;\n f(context, partials, this, indent);\n this.activeSub = false;\n }\n }\n\n };\n\n //Find a key in an object\n function findInScope(key, scope, doModelGet) {\n var val;\n\n if (scope && typeof scope == 'object') {\n\n if (scope[key] !== undefined) {\n val = scope[key];\n\n // try lookup with get for backbone or similar model data\n } else if (doModelGet && scope.get && typeof scope.get == 'function') {\n val = scope.get(key);\n }\n }\n\n return val;\n }\n\n function createSpecializedPartial(instance, subs, partials, stackSubs, stackPartials, stackText) {\n function PartialTemplate() {};\n PartialTemplate.prototype = instance;\n function Substitutions() {};\n Substitutions.prototype = instance.subs;\n var key;\n var partial = new PartialTemplate();\n partial.subs = new Substitutions();\n partial.subsText = {}; //hehe. substext.\n partial.buf = '';\n\n stackSubs = stackSubs || {};\n partial.stackSubs = stackSubs;\n partial.subsText = stackText;\n for (key in subs) {\n if (!stackSubs[key]) stackSubs[key] = subs[key];\n }\n for (key in stackSubs) {\n partial.subs[key] = stackSubs[key];\n }\n\n stackPartials = stackPartials || {};\n partial.stackPartials = stackPartials;\n for (key in partials) {\n if (!stackPartials[key]) stackPartials[key] = partials[key];\n }\n for (key in stackPartials) {\n partial.partials[key] = stackPartials[key];\n }\n\n return partial;\n }\n\n var rAmp = /&/g,\n rLt = /</g,\n rGt = />/g,\n rApos = /\\'/g,\n rQuot = /\\\"/g,\n hChars = /[&<>\\\"\\']/;\n\n function coerceToString(val) {\n return String((val === null || val === undefined) ? '' : val);\n }\n\n function hoganEscape(str) {\n str = coerceToString(str);\n return hChars.test(str) ?\n str\n .replace(rAmp, '&amp;')\n .replace(rLt, '&lt;')\n .replace(rGt, '&gt;')\n .replace(rApos, '&#39;')\n .replace(rQuot, '&quot;') :\n str;\n }\n\n var isArray = Array.isArray || function(a) {\n return Object.prototype.toString.call(a) === '[object Array]';\n };\n\n})(typeof exports !== 'undefined' ? exports : Hogan);\n","/*\n * Copyright 2011 Twitter, Inc.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// This file is for use with Node.js. See dist/ for browser files.\n\nvar Hogan = require('./compiler');\nHogan.Template = require('./template').Template;\nHogan.template = Hogan.Template;\nmodule.exports = Hogan;\n","import type { HoganOptions, Template } from 'hogan.js';\nimport hogan from 'hogan.js';\nimport type { Templates, HoganHelpers } from '../../types';\nimport type { BindEventForHits } from './createSendEventForHits';\n\ntype TransformedHoganHelpers = {\n [helper: string]: () => (text: string) => string;\n};\n\n// We add all our template helper methods to the template as lambdas. Note\n// that lambdas in Mustache are supposed to accept a second argument of\n// `render` to get the rendered value, not the literal `{{value}}`. But\n// this is currently broken (see https://github.com/twitter/hogan.js/issues/222).\nfunction transformHelpersToHogan(\n helpers: HoganHelpers = {},\n compileOptions?: HoganOptions,\n data?: Record<string, any>\n) {\n return Object.keys(helpers).reduce<TransformedHoganHelpers>(\n (acc, helperKey) => ({\n ...acc,\n [helperKey]() {\n return (text) => {\n const render = (value: string) =>\n (hogan.compile(value, compileOptions) as Template).render(this);\n\n return helpers[helperKey].call(data, text, render);\n };\n },\n }),\n {}\n );\n}\n\nfunction renderTemplate({\n templates,\n templateKey,\n compileOptions,\n helpers,\n data,\n bindEvent,\n}: {\n templates: Templates;\n templateKey: string;\n compileOptions?: HoganOptions;\n helpers?: HoganHelpers;\n data?: Record<string, any>;\n bindEvent?: BindEventForHits;\n}) {\n const template = templates[templateKey];\n\n if (typeof template !== 'string' && typeof template !== 'function') {\n throw new Error(\n `Template must be 'string' or 'function', was '${typeof template}' (key: ${templateKey})`\n );\n }\n\n if (typeof template === 'function') {\n return template(data, bindEvent!);\n }\n\n const transformedHelpers = transformHelpersToHogan(\n helpers,\n compileOptions,\n data\n );\n\n return (hogan.compile(template, compileOptions) as Template)\n .render({\n ...data,\n helpers: transformedHelpers,\n })\n .replace(/[ \\n\\r\\t\\f\\xA0]+/g, (spaces) =>\n spaces.replace(/(^|\\xA0+)[^\\xA0]+/g, '$1 ')\n )\n .trim();\n}\n\nexport default renderTemplate;\n","// We aren't using the native `Array.prototype.find` because the refactor away from Lodash is not\n// published as a major version.\n// Relying on the `find` polyfill on user-land, which before was only required for niche use-cases,\n// was decided as too risky.\n// @MAJOR Replace with the native `Array.prototype.find` method\n// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find\nfunction find<TItem>(\n items: TItem[],\n predicate: (value: TItem, index: number, obj: TItem[]) => boolean\n): TItem | undefined {\n let value: TItem;\n for (let i = 0; i < items.length; i++) {\n value = items[i];\n // inlined for performance: if (Call(predicate, thisArg, [value, i, list])) {\n if (predicate(value, i, items)) {\n return value;\n }\n }\n\n return undefined;\n}\n\nexport default find;\n","function unescapeRefinement(value: string | number): string {\n return String(value).replace(/^\\\\-/, '-');\n}\n\nexport default unescapeRefinement;\n","import type { SearchParameters, SearchResults } from 'algoliasearch-helper';\nimport find from './find';\nimport unescapeRefinement from './unescapeRefinement';\n\nexport type FacetRefinement = {\n type:\n | 'facet'\n | 'exclude'\n | 'disjunctive'\n | 'hierarchical'\n | 'numeric'\n | 'tag'\n | 'query';\n attribute: string;\n name: string;\n count?: number;\n exhaustive?: boolean;\n};\n\nexport type QueryRefinement = {\n type: 'query';\n query: string;\n} & Pick<FacetRefinement, 'type' | 'attribute' | 'name'>;\n\nexport type NumericRefinement = {\n type: 'numeric';\n numericValue: number;\n operator: '<' | '<=' | '=' | '!=' | '>=' | '>';\n} & FacetRefinement;\n\nexport type FacetExcludeRefinement = {\n type: 'exclude';\n exclude: boolean;\n} & FacetRefinement;\n\nexport type Refinement =\n | FacetRefinement\n | QueryRefinement\n | NumericRefinement\n | FacetExcludeRefinement;\n\nfunction getRefinement(\n state: SearchParameters,\n type: Refinement['type'],\n attribute: Refinement['attribute'],\n name: Refinement['name'],\n resultsFacets: SearchResults['facets' | 'hierarchicalFacets'] = []\n): Refinement {\n const res: Refinement = { type, attribute, name };\n let facet: any = find(\n resultsFacets as Array<{ name: string }>,\n (resultsFacet) => resultsFacet.name === attribute\n );\n let count: number;\n\n if (type === 'hierarchical') {\n const facetDeclaration = state.getHierarchicalFacetByName(attribute);\n const nameParts = name.split(facetDeclaration.separator);\n\n const getFacetRefinement =\n (facetData: any): ((refinementKey: string) => any) =>\n (refinementKey: string): any =>\n facetData[refinementKey];\n\n for (let i = 0; facet !== undefined && i < nameParts.length; ++i) {\n facet =\n facet &&\n facet.data &&\n find(\n Object.keys(facet.data).map(getFacetRefinement(facet.data)),\n (refinement) => refinement.name === nameParts[i]\n );\n }\n\n count = facet && facet.count;\n } else {\n count = facet && facet.data && facet.data[res.name];\n }\n\n const exhaustive = facet && facet.exhaustive;\n\n if (count !== undefined) {\n res.count = count;\n }\n\n if (exhaustive !== undefined) {\n res.exhaustive = exhaustive;\n }\n\n return res;\n}\n\nfunction getRefinements(\n results: SearchResults | Record<string, never>,\n state: SearchParameters,\n includesQuery: boolean = false\n): Refinement[] {\n const refinements: Refinement[] = [];\n const {\n facetsRefinements = {},\n facetsExcludes = {},\n disjunctiveFacetsRefinements = {},\n hierarchicalFacetsRefinements = {},\n numericRefinements = {},\n tagRefinements = [],\n } = state;\n\n Object.keys(facetsRefinements).forEach((attribute) => {\n const refinementNames = facetsRefinements[attribute];\n\n refinementNames.forEach((refinementName) => {\n refinements.push(\n getRefinement(state, 'facet', attribute, refinementName, results.facets)\n );\n });\n });\n\n Object.keys(facetsExcludes).forEach((attribute) => {\n const refinementNames = facetsExcludes[attribute];\n\n refinementNames.forEach((refinementName) => {\n refinements.push({\n type: 'exclude',\n attribute,\n name: refinementName,\n exclude: true,\n });\n });\n });\n\n Object.keys(disjunctiveFacetsRefinements).forEach((attribute) => {\n const refinementNames = disjunctiveFacetsRefinements[attribute];\n\n refinementNames.forEach((refinementName) => {\n refinements.push(\n getRefinement(\n state,\n 'disjunctive',\n attribute,\n // We unescape any disjunctive refined values with `unescapeRefinement` because\n // they can be escaped on negative numeric values with `escapeRefinement`.\n unescapeRefinement(refinementName),\n results.disjunctiveFacets\n )\n );\n });\n });\n\n Object.keys(hierarchicalFacetsRefinements).forEach((attribute) => {\n const refinementNames = hierarchicalFacetsRefinements[attribute];\n\n refinementNames.forEach((refinement) => {\n refinements.push(\n getRefinement(\n state,\n 'hierarchical',\n attribute,\n refinement,\n results.hierarchicalFacets\n )\n );\n });\n });\n\n Object.keys(numericRefinements).forEach((attribute) => {\n const operators = numericRefinements[attribute];\n\n Object.keys(operators).forEach((operatorOriginal) => {\n const operator = operatorOriginal as SearchParameters.Operator;\n const valueOrValues = operators[operator];\n const refinementNames = Array.isArray(valueOrValues)\n ? valueOrValues\n : [valueOrValues];\n\n refinementNames.forEach((refinementName: any) => {\n refinements.push({\n type: 'numeric',\n attribute,\n name: `${refinementName}`,\n numericValue: refinementName,\n operator: operator as NumericRefinement['operator'],\n });\n });\n });\n });\n\n tagRefinements.forEach((refinementName) => {\n refinements.push({ type: 'tag', attribute: '_tags', name: refinementName });\n });\n\n if (includesQuery && state.query && state.query.trim()) {\n refinements.push({\n attribute: 'query',\n type: 'query',\n name: state.query,\n query: state.query,\n });\n }\n\n return refinements;\n}\n\nexport default getRefinements;\n","import type { AlgoliaSearchHelper } from 'algoliasearch-helper';\n\n/**\n * Clears the refinements of a SearchParameters object based on rules provided.\n * The included attributes list is applied before the excluded attributes list. If the list\n * is not provided, this list of all the currently refined attributes is used as included attributes.\n * @param {object} $0 parameters\n * @param {Helper} $0.helper instance of the Helper\n * @param {string[]} [$0.attributesToClear = []] list of parameters to clear\n * @returns {SearchParameters} search parameters with refinements cleared\n */\nfunction clearRefinements({\n helper,\n attributesToClear = [],\n}: {\n helper: AlgoliaSearchHelper;\n attributesToClear?: string[];\n}) {\n let finalState = helper.state.setPage(0);\n\n finalState = attributesToClear.reduce((state, attribute) => {\n if (finalState.isNumericRefined(attribute)) {\n return state.removeNumericRefinement(attribute);\n }\n if (finalState.isHierarchicalFacet(attribute)) {\n return state.removeHierarchicalFacetRefinement(attribute);\n }\n if (finalState.isDisjunctiveFacet(attribute)) {\n return state.removeDisjunctiveFacetRefinement(attribute);\n }\n if (finalState.isConjunctiveFacet(attribute)) {\n return state.removeFacetRefinement(attribute);\n }\n\n return state;\n }, finalState);\n\n if (attributesToClear.indexOf('query') !== -1) {\n finalState = finalState.setQuery('');\n }\n\n return finalState;\n}\n\nexport default clearRefinements;\n","function escapeRefinement(value: number): string | number;\nfunction escapeRefinement(value: string): string;\nfunction escapeRefinement(value: string | number): string | number {\n if (typeof value === 'number' && value < 0) {\n value = String(value).replace(/^-/, '\\\\-');\n }\n\n return value;\n}\n\nexport default escapeRefinement;\n","import type { Renderer } from '../../types/connector';\nimport getObjectType from './getObjectType';\n\nfunction checkRendering<TRenderOptions, TWidgetParams>(\n rendering: Renderer<TRenderOptions, TWidgetParams>,\n usage: string\n): void {\n if (rendering === undefined || typeof rendering !== 'function') {\n throw new Error(`The render function is not valid (received type ${getObjectType(\n rendering\n )}).\n\n${usage}`);\n }\n}\n\nexport default checkRendering;\n","function getObjectType(object: unknown): string {\n return Object.prototype.toString.call(object).slice(8, -1);\n}\n\nexport default getObjectType;\n","function noop(..._args: any[]): void {}\n\nexport default noop;\n","import noop from './noop';\n\ntype Warn = (message: string) => void;\n\ntype Warning = {\n (condition: boolean, message: string): void;\n cache: { [message: string]: boolean };\n};\n\n/**\n * Logs a warning when this function is called, in development environment only.\n */\nlet deprecate = <TCallback extends (...args: any[]) => any>(\n fn: TCallback,\n // @ts-ignore this parameter is used in the __DEV__ branch\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n message: string\n) => fn;\n\n/**\n * Logs a warning\n * This is used to log issues in development environment only.\n */\nlet warn: Warn = noop;\n\n/**\n * Logs a warning if the condition is not met.\n * This is used to log issues in development environment only.\n */\nlet warning = noop as Warning;\n\nif (__DEV__) {\n warn = (message) => {\n // eslint-disable-next-line no-console\n console.warn(`[InstantSearch.js]: ${message.trim()}`);\n };\n\n deprecate = (fn, message) => {\n let hasAlreadyPrinted = false;\n\n return function (...args) {\n if (!hasAlreadyPrinted) {\n hasAlreadyPrinted = true;\n\n warn(message);\n }\n\n return fn(...args);\n } as typeof fn;\n };\n\n warning = ((condition, message) => {\n if (condition) {\n return;\n }\n\n const hasAlreadyPrinted = warning.cache[message];\n\n if (!hasAlreadyPrinted) {\n warning.cache[message] = true;\n\n warn(message);\n }\n }) as Warning;\n\n warning.cache = {};\n}\n\nexport { warn, deprecate, warning };\n","function getPropertyByPath(\n object: Record<string, any> | undefined,\n path: string | string[]\n): any {\n const parts = Array.isArray(path) ? path : path.split('.');\n\n return parts.reduce((current, key) => current && current[key], object);\n}\n\nexport default getPropertyByPath;\n","// This is the `Number.isFinite()` polyfill recommended by MDN.\n// We do not provide any tests for this function.\n// See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isFinite#Polyfill\nfunction isFiniteNumber(value: any): value is number {\n return typeof value === 'number' && isFinite(value);\n}\n\nexport default isFiniteNumber;\n","/**\n * This implementation is taken from Lodash implementation.\n * See: https://github.com/lodash/lodash/blob/master/isPlainObject.js\n */\n\nfunction getTag(value: any): string {\n if (value === null) {\n return value === undefined ? '[object Undefined]' : '[object Null]';\n }\n\n return Object.prototype.toString.call(value);\n}\n\nfunction isObjectLike(value: any): boolean {\n return typeof value === 'object' && value !== null;\n}\n\n/**\n * Checks if `value` is a plain object.\n *\n * A plain object is an object created by the `Object`\n * constructor or with a `[[Prototype]]` of `null`.\n */\nfunction isPlainObject(value: any): boolean {\n if (!isObjectLike(value) || getTag(value) !== '[object Object]') {\n return false;\n }\n\n if (Object.getPrototypeOf(value) === null) {\n return true;\n }\n\n let proto = value;\n\n while (Object.getPrototypeOf(proto) !== null) {\n proto = Object.getPrototypeOf(proto);\n }\n\n return Object.getPrototypeOf(value) === proto;\n}\n\nexport default isPlainObject;\n","type RangeOptions = {\n start?: number;\n end: number;\n step?: number;\n};\n\nfunction range({ start = 0, end, step = 1 }: RangeOptions): number[] {\n // We can't divide by 0 so we re-assign the step to 1 if it happens.\n const limitStep = step === 0 ? 1 : step;\n\n // In some cases the array to create has a decimal length.\n // We therefore need to round the value.\n // Example:\n // { start: 1, end: 5000, step: 500 }\n // => Array length = (5000 - 1) / 500 = 9.998\n const arrayLength = Math.round((end - start) / limitStep);\n\n return [...Array(arrayLength)].map(\n (_, current) => start + current * limitStep\n );\n}\n\nexport default range;\n","function isPrimitive(obj: any): boolean {\n return obj !== Object(obj);\n}\n\nfunction isEqual(first: any, second: any): boolean {\n if (first === second) {\n return true;\n }\n\n if (\n isPrimitive(first) ||\n isPrimitive(second) ||\n typeof first === 'function' ||\n typeof second === 'function'\n ) {\n return first === second;\n }\n\n if (Object.keys(first).length !== Object.keys(second).length) {\n return false;\n }\n\n for (const key of Object.keys(first)) {\n if (!(key in second)) {\n return false;\n }\n\n if (!isEqual(first[key], second[key])) {\n return false;\n }\n }\n\n return true;\n}\n\nexport default isEqual;\n","/**\n * This implementation is taken from Lodash implementation.\n * See: https://github.com/lodash/lodash/blob/4.17.11-npm/escape.js\n */\n\n// Used to map characters to HTML entities.\nconst htmlEscapes = {\n '&': '&amp;',\n '<': '&lt;',\n '>': '&gt;',\n '\"': '&quot;',\n \"'\": '&#39;',\n};\n\n// Used to match HTML entities and HTML characters.\nconst regexUnescapedHtml = /[&<>\"']/g;\nconst regexHasUnescapedHtml = RegExp(regexUnescapedHtml.source);\n\n/**\n * Converts the characters \"&\", \"<\", \">\", '\"', and \"'\" in `string` to their\n * corresponding HTML entities.\n */\nfunction escape(value: string): string {\n return value && regexHasUnescapedHtml.test(value)\n ? value.replace(\n regexUnescapedHtml,\n (character) => htmlEscapes[character as keyof typeof htmlEscapes]\n )\n : value;\n}\n\nexport default escape;\n","/**\n * This implementation is taken from Lodash implementation.\n * See: https://github.com/lodash/lodash/blob/4.17.11-npm/unescape.js\n */\n\n// Used to map HTML entities to characters.\nconst htmlEscapes = {\n '&amp;': '&',\n '&lt;': '<',\n '&gt;': '>',\n '&quot;': '\"',\n '&#39;': \"'\",\n};\n\n// Used to match HTML entities and HTML characters.\nconst regexEscapedHtml = /&(amp|quot|lt|gt|#39);/g;\nconst regexHasEscapedHtml = RegExp(regexEscapedHtml.source);\n\n/**\n * Converts the HTML entities \"&\", \"<\", \">\", '\"', and \"'\" in `string` to their\n * characters.\n */\nexport default function unescape(value: string): string {\n return value && regexHasEscapedHtml.test(value)\n ? value.replace(\n regexEscapedHtml,\n (character) => htmlEscapes[character as keyof typeof htmlEscapes]\n )\n : value;\n}\n","import escape from './escape';\nimport isPlainObject from './isPlainObject';\nimport type { Hit, FacetHit, EscapedHits } from '../../types';\n\nexport const TAG_PLACEHOLDER = {\n highlightPreTag: '__ais-highlight__',\n highlightPostTag: '__/ais-highlight__',\n};\n\nexport const TAG_REPLACEMENT = {\n highlightPreTag: '<mark>',\n highlightPostTag: '</mark>',\n};\n\nfunction replaceTagsAndEscape(value: string): string {\n return escape(value)\n .replace(\n new RegExp(TAG_PLACEHOLDER.highlightPreTag, 'g'),\n TAG_REPLACEMENT.highlightPreTag\n )\n .replace(\n new RegExp(TAG_PLACEHOLDER.highlightPostTag, 'g'),\n TAG_REPLACEMENT.highlightPostTag\n );\n}\n\nfunction recursiveEscape(input: any): any {\n if (isPlainObject(input) && typeof input.value !== 'string') {\n return Object.keys(input).reduce(\n (acc, key) => ({\n ...acc,\n [key]: recursiveEscape(input[key]),\n }),\n {}\n );\n }\n\n if (Array.isArray(input)) {\n return input.map(recursiveEscape);\n }\n\n return {\n ...input,\n value: replaceTagsAndEscape(input.value),\n };\n}\n\nexport function escapeHits<THit extends Hit>(\n hits: THit[] | EscapedHits<THit>\n): EscapedHits<THit> {\n if ((hits as any).__escaped === undefined) {\n // We don't override the value on hit because it will mutate the raw results\n // instead we make a shallow copy and we assign the escaped values on it.\n hits = hits.map(({ ...hit }) => {\n if (hit._highlightResult) {\n hit._highlightResult = recursiveEscape(hit._highlightResult);\n }\n\n if (hit._snippetResult) {\n hit._snippetResult = recursiveEscape(hit._snippetResult);\n }\n\n return hit;\n });\n\n (hits as any).__escaped = true;\n }\n\n return hits as unknown as EscapedHits<THit>;\n}\n\nexport function escapeFacets(facetHits: FacetHit[]): FacetHit[] {\n return facetHits.map((h) => ({\n ...h,\n highlighted: replaceTagsAndEscape(h.highlighted),\n }));\n}\n","import type { HighlightedParts } from '../../types';\nimport { TAG_REPLACEMENT } from './escape-highlight';\n\nexport default function concatHighlightedParts(parts: HighlightedParts[]) {\n const { highlightPreTag, highlightPostTag } = TAG_REPLACEMENT;\n\n return parts\n .map((part) =>\n part.isHighlighted\n ? highlightPreTag + part.value + highlightPostTag\n : part.value\n )\n .join('');\n}\n","import { TAG_REPLACEMENT } from './escape-highlight';\n\nexport default function getHighlightedParts(highlightedValue: string) {\n const { highlightPostTag, highlightPreTag } = TAG_REPLACEMENT;\n\n const splitByPreTag = highlightedValue.split(highlightPreTag);\n const firstValue = splitByPreTag.shift();\n const elements = !firstValue\n ? []\n : [{ value: firstValue, isHighlighted: false }];\n\n splitByPreTag.forEach((split) => {\n const splitByPostTag = split.split(highlightPostTag);\n\n elements.push({\n value: splitByPostTag[0],\n isHighlighted: true,\n });\n\n if (splitByPostTag[1] !== '') {\n elements.push({\n value: splitByPostTag[1],\n isHighlighted: false,\n });\n }\n });\n\n return elements;\n}\n","import unescape from './unescape';\nimport type { HighlightedParts } from '../../types';\n\nconst hasAlphanumeric = new RegExp(/\\w/i);\n\nexport default function getHighlightFromSiblings(\n parts: HighlightedParts[],\n i: number\n) {\n const current = parts[i];\n const isNextHighlighted = parts[i + 1]?.isHighlighted || true;\n const isPreviousHighlighted = parts[i - 1]?.isHighlighted || true;\n\n if (\n !hasAlphanumeric.test(unescape(current.value)) &&\n isPreviousHighlighted === isNextHighlighted\n ) {\n return isPreviousHighlighted;\n }\n\n return current.isHighlighted;\n}\n","import type { HighlightedParts } from '../../types';\nimport getHighlightFromSiblings from './getHighlightFromSiblings';\n\nexport default function reverseHighlightedParts(parts: HighlightedParts[]) {\n if (!parts.some((part) => part.isHighlighted)) {\n return parts.map((part) => ({ ...part, isHighlighted: false }));\n }\n\n return parts.map((part, i) => ({\n ...part,\n isHighlighted: !getHighlightFromSiblings(parts, i),\n }));\n}\n","import type { SearchParameters } from 'algoliasearch-helper';\nimport findIndex from './findIndex';\nimport uniq from './uniq';\n\ntype Merger = (\n left: SearchParameters,\n right: SearchParameters\n) => SearchParameters;\n\nconst mergeWithRest: Merger = (left, right) => {\n const {\n facets,\n disjunctiveFacets,\n facetsRefinements,\n facetsExcludes,\n disjunctiveFacetsRefinements,\n numericRefinements,\n tagRefinements,\n hierarchicalFacets,\n hierarchicalFacetsRefinements,\n ruleContexts,\n ...rest\n } = right;\n\n return left.setQueryParameters(rest);\n};\n\n// Merge facets\nconst mergeFacets: Merger = (left, right) =>\n right.facets!.reduce((_, name) => _.addFacet(name), left);\n\nconst mergeDisjunctiveFacets: Merger = (left, right) =>\n right.disjunctiveFacets.reduce(\n (_, name) => _.addDisjunctiveFacet(name),\n left\n );\n\nconst mergeHierarchicalFacets: Merger = (left, right) =>\n left.setQueryParameters({\n hierarchicalFacets: right.hierarchicalFacets.reduce((facets, facet) => {\n const index = findIndex(facets, (_) => _.name === facet.name);\n\n if (index === -1) {\n return facets.concat(facet);\n }\n\n const nextFacets = facets.slice();\n nextFacets.splice(index, 1, facet);\n\n return nextFacets;\n }, left.hierarchicalFacets),\n });\n\n// Merge facet refinements\nconst mergeTagRefinements: Merger = (left, right) =>\n right.tagRefinements.reduce((_, value) => _.addTagRefinement(value), left);\n\nconst mergeFacetRefinements: Merger = (left, right) =>\n left.setQueryParameters({\n facetsRefinements: {\n ...left.facetsRefinements,\n ...right.facetsRefinements,\n },\n });\n\nconst mergeFacetsExcludes: Merger = (left, right) =>\n left.setQueryParameters({\n facetsExcludes: {\n ...left.facetsExcludes,\n ...right.facetsExcludes,\n },\n });\n\nconst mergeDisjunctiveFacetsRefinements: Merger = (left, right) =>\n left.setQueryParameters({\n disjunctiveFacetsRefinements: {\n ...left.disjunctiveFacetsRefinements,\n ...right.disjunctiveFacetsRefinements,\n },\n });\n\nconst mergeNumericRefinements: Merger = (left, right) =>\n left.setQueryParameters({\n numericRefinements: {\n ...left.numericRefinements,\n ...right.numericRefinements,\n },\n });\n\nconst mergeHierarchicalFacetsRefinements: Merger = (left, right) =>\n left.setQueryParameters({\n hierarchicalFacetsRefinements: {\n ...left.hierarchicalFacetsRefinements,\n ...right.hierarchicalFacetsRefinements,\n },\n });\n\nconst mergeRuleContexts: Merger = (left, right) => {\n const ruleContexts: string[] = uniq(\n ([] as any)\n .concat(left.ruleContexts)\n .concat(right.ruleContexts)\n .filter(Boolean)\n );\n\n if (ruleContexts.length > 0) {\n return left.setQueryParameters({\n ruleContexts,\n });\n }\n\n return left;\n};\n\nconst merge = (...parameters: SearchParameters[]): SearchParameters =>\n parameters.reduce((left, right) => {\n const hierarchicalFacetsRefinementsMerged =\n mergeHierarchicalFacetsRefinements(left, right);\n const hierarchicalFacetsMerged = mergeHierarchicalFacets(\n hierarchicalFacetsRefinementsMerged,\n right\n );\n const tagRefinementsMerged = mergeTagRefinements(\n hierarchicalFacetsMerged,\n right\n );\n const numericRefinementsMerged = mergeNumericRefinements(\n tagRefinementsMerged,\n right\n );\n const disjunctiveFacetsRefinementsMerged =\n mergeDisjunctiveFacetsRefinements(numericRefinementsMerged, right);\n const facetsExcludesMerged = mergeFacetsExcludes(\n disjunctiveFacetsRefinementsMerged,\n right\n );\n const facetRefinementsMerged = mergeFacetRefinements(\n facetsExcludesMerged,\n right\n );\n const disjunctiveFacetsMerged = mergeDisjunctiveFacets(\n facetRefinementsMerged,\n right\n );\n const ruleContextsMerged = mergeRuleContexts(\n disjunctiveFacetsMerged,\n right\n );\n const facetsMerged = mergeFacets(ruleContextsMerged, right);\n\n return mergeWithRest(facetsMerged, right);\n });\n\nexport default merge;\n","// We aren't using the native `Array.prototype.findIndex` because the refactor away from Lodash is not\n// published as a major version.\n// Relying on the `findIndex` polyfill on user-land, which before was only required for niche use-cases,\n// was decided as too risky.\n// @MAJOR Replace with the native `Array.prototype.findIndex` method\n// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/findIndex\nfunction findIndex<TItem>(\n array: TItem[],\n comparator: (value: TItem) => boolean\n): number {\n if (!Array.isArray(array)) {\n return -1;\n }\n\n for (let i = 0; i < array.length; i++) {\n if (comparator(array[i])) {\n return i;\n }\n }\n return -1;\n}\n\nexport default findIndex;\n","function toArray(value: any) {\n return Array.isArray(value) ? value : [value];\n}\n\nexport default toArray;\n","type WidgetParam = {\n name: string;\n connector?: boolean;\n};\n\nexport const createDocumentationLink = ({\n name,\n connector = false,\n}: WidgetParam): string => {\n return [\n 'https://www.algolia.com/doc/api-reference/widgets/',\n name,\n '/js/',\n connector ? '#connector' : '',\n ].join('');\n};\n\ntype DocumentationMessageGenerator = (message?: string) => string;\n\nexport const createDocumentationMessageGenerator = (\n ...widgets: WidgetParam[]\n): DocumentationMessageGenerator => {\n const links = widgets\n .map((widget) => createDocumentationLink(widget))\n .join(', ');\n\n return (message?: string) =>\n [message, `See documentation: ${links}`].filter(Boolean).join('\\n\\n');\n};\n","const latLngRegExp = /^(-?\\d+(?:\\.\\d+)?),\\s*(-?\\d+(?:\\.\\d+)?)$/;\n\nexport function aroundLatLngToPosition(value: string) {\n const pattern = value.match(latLngRegExp);\n\n // Since the value provided is the one send with the request, the API should\n // throw an error due to the wrong format. So throw an error should be safe.\n if (!pattern) {\n throw new Error(`Invalid value for \"aroundLatLng\" parameter: \"${value}\"`);\n }\n\n return {\n lat: parseFloat(pattern[1]),\n lng: parseFloat(pattern[2]),\n };\n}\n\nexport type LatLng = Array<[number, number, number, number]>;\n\nfunction insideBoundingBoxArrayToBoundingBox(value: LatLng) {\n const [\n [neLat, neLng, swLat, swLng] = [undefined, undefined, undefined, undefined],\n ] = value;\n\n // Since the value provided is the one send with the request, the API should\n // throw an error due to the wrong format. So throw an error should be safe.\n if (!neLat || !neLng || !swLat || !swLng) {\n throw new Error(\n `Invalid value for \"insideBoundingBox\" parameter: [${value}]`\n );\n }\n\n return {\n northEast: {\n lat: neLat,\n lng: neLng,\n },\n southWest: {\n lat: swLat,\n lng: swLng,\n },\n };\n}\n\nfunction insideBoundingBoxStringToBoundingBox(value: string) {\n const [neLat, neLng, swLat, swLng] = value.split(',').map(parseFloat);\n\n // Since the value provided is the one send with the request, the API should\n // throw an error due to the wrong format. So throw an error should be safe.\n if (!neLat || !neLng || !swLat || !swLng) {\n throw new Error(\n `Invalid value for \"insideBoundingBox\" parameter: \"${value}\"`\n );\n }\n\n return {\n northEast: {\n lat: neLat,\n lng: neLng,\n },\n southWest: {\n lat: swLat,\n lng: swLng,\n },\n };\n}\n\nexport function insideBoundingBoxToBoundingBox(value: string | LatLng) {\n if (Array.isArray(value)) {\n return insideBoundingBoxArrayToBoundingBox(value);\n }\n\n return insideBoundingBoxStringToBoundingBox(value);\n}\n","import type { AlgoliaHit } from '../../types';\n\nexport function addAbsolutePosition<THit extends AlgoliaHit>(\n hits: THit[],\n page: number,\n hitsPerPage: number\n): Array<THit & { __position: number }> {\n return hits.map((hit, idx) => ({\n ...hit,\n __position: hitsPerPage * page + idx + 1,\n }));\n}\n","import type { AlgoliaHit } from '../../types';\n\nexport function addQueryID<THit extends AlgoliaHit>(\n hits: THit[],\n queryID?: string\n): Array<THit & { __queryID?: string }> {\n if (!queryID) {\n return hits;\n }\n return hits.map((hit) => ({\n ...hit,\n __queryID: queryID,\n }));\n}\n","import type { AlgoliaSearchHelper } from 'algoliasearch-helper';\nimport type { InstantSearch } from '../../types';\nimport isFacetRefined from './isFacetRefined';\n\ntype BuiltInSendEventForFacet = (\n eventType: string,\n facetValue: string,\n eventName?: string\n) => void;\ntype CustomSendEventForFacet = (customPayload: any) => void;\n\nexport type SendEventForFacet = BuiltInSendEventForFacet &\n CustomSendEventForFacet;\n\nexport function createSendEventForFacet({\n instantSearchInstance,\n helper,\n attribute,\n widgetType,\n}: {\n instantSearchInstance: InstantSearch;\n helper: AlgoliaSearchHelper;\n attribute: string;\n widgetType: string;\n}): SendEventForFacet {\n const sendEventForFacet: SendEventForFacet = (...args: any[]) => {\n const [eventType, facetValue, eventName = 'Filter Applied'] = args;\n if (args.length === 1 && typeof args[0] === 'object') {\n instantSearchInstance.sendEventToInsights(args[0]);\n } else if (\n eventType === 'click' &&\n (args.length === 2 || args.length === 3)\n ) {\n if (!isFacetRefined(helper, attribute, facetValue)) {\n // send event only when the facet is being checked \"ON\"\n instantSearchInstance.sendEventToInsights({\n insightsMethod: 'clickedFilters',\n widgetType,\n eventType,\n payload: {\n eventName,\n index: helper.getIndex(),\n filters: [`${attribute}:${facetValue}`],\n },\n attribute,\n });\n }\n } else if (__DEV__) {\n throw new Error(\n `You need to pass two arguments like:\n sendEvent('click', facetValue);\n\nIf you want to send a custom payload, you can pass one object: sendEvent(customPayload);\n`\n );\n }\n };\n return sendEventForFacet;\n}\n","import type { AlgoliaSearchHelper } from 'algoliasearch-helper';\n\nexport default function isFacetRefined(\n helper: AlgoliaSearchHelper,\n facet: string,\n value: string\n) {\n if (helper.state.isHierarchicalFacet(facet)) {\n return helper.state.isHierarchicalFacetRefined(facet, value);\n } else if (helper.state.isConjunctiveFacet(facet)) {\n return helper.state.isFacetRefined(facet, value);\n } else {\n return helper.state.isDisjunctiveFacetRefined(facet, value);\n }\n}\n","export function serializePayload<TPayload>(payload: TPayload): string {\n return btoa(encodeURIComponent(JSON.stringify(payload)));\n}\n\nexport function deserializePayload<TPayload>(serialized: string): TPayload {\n return JSON.parse(decodeURIComponent(atob(serialized)));\n}\n","import type { InstantSearch, Hit, Hits, EscapedHits } from '../../types';\nimport { serializePayload } from '../../lib/utils/serializer';\nimport type { InsightsEvent } from '../../middlewares/createInsightsMiddleware';\n\ntype BuiltInSendEventForHits = (\n eventType: string,\n hits: Hit | Hits,\n eventName?: string\n) => void;\ntype CustomSendEventForHits = (customPayload: any) => void;\nexport type SendEventForHits = BuiltInSendEventForHits & CustomSendEventForHits;\n\ntype BuiltInBindEventForHits = (\n eventType: string,\n hits: Hit | Hits,\n eventName?: string\n) => string;\ntype CustomBindEventForHits = (customPayload: any) => string;\nexport type BindEventForHits = BuiltInBindEventForHits & CustomBindEventForHits;\n\nfunction chunk<TItem>(arr: TItem[], chunkSize: number = 20): TItem[][] {\n const chunks: TItem[][] = [];\n for (let i = 0; i < Math.ceil(arr.length / chunkSize); i++) {\n chunks.push(arr.slice(i * chunkSize, (i + 1) * chunkSize));\n }\n return chunks;\n}\n\nconst buildPayloads = ({\n index,\n widgetType,\n methodName,\n args,\n}: {\n widgetType: string;\n index: string;\n methodName: 'sendEvent' | 'bindEvent';\n args: any[];\n}): InsightsEvent[] => {\n // when there's only one argument, that means it's custom\n if (args.length === 1 && typeof args[0] === 'object') {\n return [args[0]];\n }\n const eventType: string = args[0];\n const hits: Hit | Hits | EscapedHits = args[1];\n const eventName: string | undefined = args[2];\n if (!hits) {\n if (__DEV__) {\n throw new Error(\n `You need to pass hit or hits as the second argument like:\n ${methodName}(eventType, hit);\n `\n );\n } else {\n return [];\n }\n }\n if ((eventType === 'click' || eventType === 'conversion') && !eventName) {\n if (__DEV__) {\n throw new Error(\n `You need to pass eventName as the third argument for 'click' or 'conversion' events like:\n ${methodName}('click', hit, 'Product Purchased');\n\n To learn more about event naming: https://www.algolia.com/doc/guides/getting-insights-and-analytics/search-analytics/click-through-and-conversions/in-depth/clicks-conversions-best-practices/\n `\n );\n } else {\n return [];\n }\n }\n const hitsArray: Hits = Array.isArray(hits)\n ? removeEscapedFromHits(hits)\n : [hits];\n\n if (hitsArray.length === 0) {\n return [];\n }\n const queryID = hitsArray[0].__queryID;\n const hitsChunks = chunk(hitsArray);\n const objectIDsByChunk = hitsChunks.map((batch) =>\n batch.map((hit) => hit.objectID)\n );\n const positionsByChunk = hitsChunks.map((batch) =>\n batch.map((hit) => hit.__position)\n );\n\n if (eventType === 'view') {\n return hitsChunks.map((batch, i) => {\n return {\n insightsMethod: 'viewedObjectIDs',\n widgetType,\n eventType,\n payload: {\n eventName: eventName || 'Hits Viewed',\n index,\n objectIDs: objectIDsByChunk[i],\n },\n hits: batch,\n };\n });\n } else if (eventType === 'click') {\n return hitsChunks.map((batch, i) => {\n return {\n insightsMethod: 'clickedObjectIDsAfterSearch',\n widgetType,\n eventType,\n payload: {\n eventName,\n index,\n queryID,\n objectIDs: objectIDsByChunk[i],\n positions: positionsByChunk[i],\n },\n hits: batch,\n };\n });\n } else if (eventType === 'conversion') {\n return hitsChunks.map((batch, i) => {\n return {\n insightsMethod: 'convertedObjectIDsAfterSearch',\n widgetType,\n eventType,\n payload: {\n eventName,\n index,\n queryID,\n objectIDs: objectIDsByChunk[i],\n },\n hits: batch,\n };\n });\n } else if (__DEV__) {\n throw new Error(`eventType(\"${eventType}\") is not supported.\n If you want to send a custom payload, you can pass one object: ${methodName}(customPayload);\n `);\n } else {\n return [];\n }\n};\n\nfunction removeEscapedFromHits(hits: Hits | EscapedHits): Hits {\n // remove `hits.__escaped` without mutating\n return hits.slice();\n}\n\nexport function createSendEventForHits({\n instantSearchInstance,\n index,\n widgetType,\n}: {\n instantSearchInstance: InstantSearch;\n index: string;\n widgetType: string;\n}): SendEventForHits {\n const sendEventForHits: SendEventForHits = (...args: any[]) => {\n const payloads = buildPayloads({\n widgetType,\n index,\n methodName: 'sendEvent',\n args,\n });\n\n payloads.forEach((payload) =>\n instantSearchInstance.sendEventToInsights(payload)\n );\n };\n return sendEventForHits;\n}\n\nexport function createBindEventForHits({\n index,\n widgetType,\n}: {\n index: string;\n widgetType: string;\n}): BindEventForHits {\n const bindEventForHits: BindEventForHits = (...args: any[]) => {\n const payloads = buildPayloads({\n widgetType,\n index,\n methodName: 'bindEvent',\n args,\n });\n\n return payloads.length\n ? `data-insights-event=${serializePayload(payloads)}`\n : '';\n };\n return bindEventForHits;\n}\n","import type { SearchParameters } from 'algoliasearch-helper';\n\nexport function convertNumericRefinementsToFilters(\n state: SearchParameters | null,\n attribute: string\n) {\n if (!state) {\n return null;\n }\n const filtersObj = state.numericRefinements[attribute];\n /*\n filtersObj === {\n \"<=\": [10],\n \"=\": [],\n \">=\": [5]\n }\n */\n const filters: string[] = [];\n (Object.keys(filtersObj) as SearchParameters.Operator[])\n .filter(\n (operator) =>\n Array.isArray(filtersObj[operator]) && filtersObj[operator]!.length > 0\n )\n .forEach((operator) => {\n filtersObj[operator]!.forEach((value) => {\n filters.push(`${attribute}${operator}${value}`);\n });\n });\n return filters;\n}\n","import type { Awaited } from '../../types';\n\ntype Func = (...args: any[]) => any;\n\nexport type DebouncedFunction<TFunction extends Func> = (\n this: ThisParameterType<TFunction>,\n ...args: Parameters<TFunction>\n) => Promise<Awaited<ReturnType<TFunction>>>;\n\n// Debounce a function call to the trailing edge.\n// The debounced function returns a promise.\nexport function debounce<TFunction extends Func>(\n func: TFunction,\n wait: number\n): DebouncedFunction<TFunction> {\n let lastTimeout: ReturnType<typeof setTimeout> | null = null;\n return function (...args) {\n return new Promise((resolve, reject) => {\n if (lastTimeout) {\n clearTimeout(lastTimeout);\n }\n lastTimeout = setTimeout(() => {\n lastTimeout = null;\n Promise.resolve(func(...args))\n .then(resolve)\n .catch(reject);\n }, wait);\n });\n };\n}\n","import type { InitOptions, Widget } from '../../types';\nimport type { IndexWidget } from '../../widgets/index/index';\n\nexport function getWidgetAttribute(\n widget: Widget | IndexWidget,\n initOptions: InitOptions\n): string {\n const renderState = widget.getWidgetRenderState?.(initOptions);\n\n let attribute = null;\n\n if (renderState && renderState.widgetParams) {\n // casting as widgetParams is checked just before\n const widgetParams = renderState.widgetParams as Record<string, unknown>;\n\n if (widgetParams.attribute) {\n attribute = widgetParams.attribute;\n } else if (Array.isArray(widgetParams.attributes)) {\n attribute = widgetParams.attributes[0];\n }\n }\n\n if (typeof attribute !== 'string') {\n throw new Error(`Could not find the attribute of the widget:\n\n${JSON.stringify(widget)}\n\nPlease check whether the widget's getWidgetRenderState returns widgetParams.attribute correctly.`);\n }\n\n return attribute;\n}\n","// eslint-disable-next-line no-restricted-globals\ntype BrowserCallback<TReturn> = (params: { window: typeof window }) => TReturn;\ntype SafelyRunOnBrowserOptions<TReturn> = {\n /**\n * Fallback to run on server environments.\n */\n fallback: () => TReturn;\n};\n\n/**\n * Runs code on browser enviromnents safely.\n */\nexport function safelyRunOnBrowser<TReturn>(\n callback: BrowserCallback<TReturn>,\n { fallback }: SafelyRunOnBrowserOptions<TReturn> = {\n fallback: () => undefined as any,\n }\n): TReturn {\n // eslint-disable-next-line no-restricted-globals\n if (typeof window === 'undefined') {\n return fallback();\n }\n\n // eslint-disable-next-line no-restricted-globals\n return callback({ window });\n}\n","import type {\n AlgoliaSearchHelper as Helper,\n DerivedHelper,\n PlainSearchParameters,\n SearchParameters,\n SearchResults,\n AlgoliaSearchHelper,\n} from 'algoliasearch-helper';\nimport algoliasearchHelper from 'algoliasearch-helper';\nimport type {\n InstantSearch,\n UiState,\n IndexUiState,\n Widget,\n InitOptions,\n RenderOptions,\n ScopedResult,\n SearchClient,\n IndexRenderState,\n} from '../../types';\nimport {\n checkIndexUiState,\n createDocumentationMessageGenerator,\n resolveSearchParameters,\n mergeSearchParameters,\n warning,\n} from '../../lib/utils';\n\nconst withUsage = createDocumentationMessageGenerator({\n name: 'index-widget',\n});\n\nexport type IndexWidgetParams = {\n indexName: string;\n indexId?: string;\n};\n\ntype IndexInitOptions = Pick<\n InitOptions,\n 'instantSearchInstance' | 'parent' | 'uiState'\n>;\n\ntype IndexRenderOptions = Pick<RenderOptions, 'instantSearchInstance'>;\n\ntype WidgetSearchParametersOptions = Parameters<\n NonNullable<Widget['getWidgetSearchParameters']>\n>[1];\ntype LocalWidgetSearchParametersOptions = WidgetSearchParametersOptions & {\n initialSearchParameters: SearchParameters;\n};\n\nexport type IndexWidgetDescription = {\n $$type: 'ais.index';\n $$widgetType: 'ais.index';\n};\n\nexport type IndexWidget = Omit<\n Widget<IndexWidgetDescription & { widgetParams: IndexWidgetParams }>,\n 'getWidgetUiState' | 'getWidgetState'\n> & {\n getIndexName(): string;\n getIndexId(): string;\n getHelper(): Helper | null;\n getResults(): SearchResults | null;\n getScopedResults(): ScopedResult[];\n getParent(): IndexWidget | null;\n getWidgets(): Array<Widget | IndexWidget>;\n createURL(state: SearchParameters): string;\n\n addWidgets(widgets: Array<Widget | IndexWidget>): IndexWidget;\n removeWidgets(widgets: Array<Widget | IndexWidget>): IndexWidget;\n\n init(options: IndexInitOptions): void;\n render(options: IndexRenderOptions): void;\n dispose(): void;\n /**\n * @deprecated\n */\n getWidgetState(uiState: UiState): UiState;\n getWidgetUiState<TUiState = UiState>(uiState: TUiState): TUiState;\n getWidgetSearchParameters(\n searchParameters: SearchParameters,\n searchParametersOptions: { uiState: IndexUiState }\n ): SearchParameters;\n refreshUiState(): void;\n};\n\nexport function isIndexWidget(\n widget: Widget | IndexWidget\n): widget is IndexWidget {\n return widget.$$type === 'ais.index';\n}\n\n/**\n * This is the same content as helper._change / setState, but allowing for extra\n * UiState to be synchronized.\n * see: https://github.com/algolia/algoliasearch-helper-js/blob/6b835ffd07742f2d6b314022cce6848f5cfecd4a/src/algoliasearch.helper.js#L1311-L1324\n */\nfunction privateHelperSetState(\n helper: AlgoliaSearchHelper,\n {\n state,\n isPageReset,\n _uiState,\n }: {\n state: SearchParameters;\n isPageReset?: boolean;\n _uiState?: IndexUiState;\n }\n) {\n if (state !== helper.state) {\n helper.state = state;\n\n helper.emit('change', {\n state: helper.state,\n results: helper.lastResults,\n isPageReset,\n _uiState,\n });\n }\n}\n\ntype WidgetUiStateOptions = Parameters<\n NonNullable<Widget['getWidgetUiState']>\n>[1];\n\nfunction getLocalWidgetsUiState(\n widgets: Array<Widget | IndexWidget>,\n widgetStateOptions: WidgetUiStateOptions,\n initialUiState: IndexUiState = {}\n) {\n return widgets.reduce((uiState, widget) => {\n if (isIndexWidget(widget)) {\n return uiState;\n }\n\n if (!widget.getWidgetUiState && !widget.getWidgetState) {\n return uiState;\n }\n\n if (widget.getWidgetUiState) {\n return widget.getWidgetUiState(uiState, widgetStateOptions);\n }\n\n return widget.getWidgetState!(uiState, widgetStateOptions);\n }, initialUiState);\n}\n\nfunction getLocalWidgetsSearchParameters(\n widgets: Array<Widget | IndexWidget>,\n widgetSearchParametersOptions: LocalWidgetSearchParametersOptions\n): SearchParameters {\n const { initialSearchParameters, ...rest } = widgetSearchParametersOptions;\n\n return widgets\n .filter((widget) => !isIndexWidget(widget))\n .reduce<SearchParameters>((state, widget) => {\n if (!widget.getWidgetSearchParameters) {\n return state;\n }\n\n return widget.getWidgetSearchParameters(state, rest);\n }, initialSearchParameters);\n}\n\nfunction resetPageFromWidgets(widgets: Array<Widget | IndexWidget>): void {\n const indexWidgets = widgets.filter(isIndexWidget);\n\n if (indexWidgets.length === 0) {\n return;\n }\n\n indexWidgets.forEach((widget) => {\n const widgetHelper = widget.getHelper()!;\n\n privateHelperSetState(widgetHelper, {\n state: widgetHelper.state.resetPage(),\n isPageReset: true,\n });\n\n resetPageFromWidgets(widget.getWidgets());\n });\n}\n\nfunction resolveScopedResultsFromWidgets(\n widgets: Array<Widget | IndexWidget>\n): ScopedResult[] {\n const indexWidgets = widgets.filter(isIndexWidget);\n\n return indexWidgets.reduce<ScopedResult[]>((scopedResults, current) => {\n return scopedResults.concat(\n {\n indexId: current.getIndexId(),\n results: current.getResults()!,\n helper: current.getHelper()!,\n },\n ...resolveScopedResultsFromWidgets(current.getWidgets())\n );\n }, []);\n}\n\nconst index = (widgetParams: IndexWidgetParams): IndexWidget => {\n if (widgetParams === undefined || widgetParams.indexName === undefined) {\n throw new Error(withUsage('The `indexName` option is required.'));\n }\n\n const { indexName, indexId = indexName } = widgetParams;\n\n let localWidgets: Array<Widget | IndexWidget> = [];\n let localUiState: IndexUiState = {};\n let localInstantSearchInstance: InstantSearch | null = null;\n let localParent: IndexWidget | null = null;\n let helper: Helper | null = null;\n let derivedHelper: DerivedHelper | null = null;\n\n return {\n $$type: 'ais.index',\n $$widgetType: 'ais.index',\n\n getIndexName() {\n return indexName;\n },\n\n getIndexId() {\n return indexId;\n },\n\n getHelper() {\n return helper;\n },\n\n getResults() {\n return derivedHelper && derivedHelper.lastResults;\n },\n\n getScopedResults() {\n const widgetParent = this.getParent();\n\n // If the widget is the root, we consider itself as the only sibling.\n const widgetSiblings = widgetParent ? widgetParent.getWidgets() : [this];\n\n return resolveScopedResultsFromWidgets(widgetSiblings);\n },\n\n getParent() {\n return localParent;\n },\n\n createURL(nextState: SearchParameters) {\n return localInstantSearchInstance!._createURL({\n [indexId]: getLocalWidgetsUiState(localWidgets, {\n searchParameters: nextState,\n helper: helper!,\n }),\n });\n },\n\n getWidgets() {\n return localWidgets;\n },\n\n addWidgets(widgets) {\n if (!Array.isArray(widgets)) {\n throw new Error(\n withUsage('The `addWidgets` method expects an array of widgets.')\n );\n }\n\n if (\n widgets.some(\n (widget) =>\n typeof widget.init !== 'function' &&\n typeof widget.render !== 'function'\n )\n ) {\n throw new Error(\n withUsage(\n 'The widget definition expects a `render` and/or an `init` method.'\n )\n );\n }\n\n localWidgets = localWidgets.concat(widgets);\n\n if (localInstantSearchInstance && Boolean(widgets.length)) {\n privateHelperSetState(helper!, {\n state: getLocalWidgetsSearchParameters(localWidgets, {\n uiState: localUiState,\n initialSearchParameters: helper!.state,\n }),\n _uiState: localUiState,\n });\n\n // We compute the render state before calling `init` in a separate loop\n // to construct the whole render state object that is then passed to\n // `init`.\n widgets.forEach((widget) => {\n if (widget.getRenderState) {\n const renderState = widget.getRenderState(\n localInstantSearchInstance!.renderState[this.getIndexId()] || {},\n {\n uiState: localInstantSearchInstance!._initialUiState,\n helper: this.getHelper()!,\n parent: this,\n instantSearchInstance: localInstantSearchInstance!,\n state: helper!.state,\n renderState: localInstantSearchInstance!.renderState,\n templatesConfig: localInstantSearchInstance!.templatesConfig,\n createURL: this.createURL,\n scopedResults: [],\n searchMetadata: {\n isSearchStalled: localInstantSearchInstance!._isSearchStalled,\n },\n }\n );\n\n storeRenderState({\n renderState,\n instantSearchInstance: localInstantSearchInstance!,\n parent: this,\n });\n }\n });\n\n widgets.forEach((widget) => {\n if (widget.init) {\n widget.init({\n helper: helper!,\n parent: this,\n uiState: localInstantSearchInstance!._initialUiState,\n instantSearchInstance: localInstantSearchInstance!,\n state: helper!.state,\n renderState: localInstantSearchInstance!.renderState,\n templatesConfig: localInstantSearchInstance!.templatesConfig,\n createURL: this.createURL,\n scopedResults: [],\n searchMetadata: {\n isSearchStalled: localInstantSearchInstance!._isSearchStalled,\n },\n });\n }\n });\n\n localInstantSearchInstance.scheduleSearch();\n }\n\n return this;\n },\n\n removeWidgets(widgets) {\n if (!Array.isArray(widgets)) {\n throw new Error(\n withUsage('The `removeWidgets` method expects an array of widgets.')\n );\n }\n\n if (widgets.some((widget) => typeof widget.dispose !== 'function')) {\n throw new Error(\n withUsage('The widget definition expects a `dispose` method.')\n );\n }\n\n localWidgets = localWidgets.filter(\n (widget) => widgets.indexOf(widget) === -1\n );\n\n if (localInstantSearchInstance && Boolean(widgets.length)) {\n const nextState = widgets.reduce((state, widget) => {\n // the `dispose` method exists at this point we already assert it\n const next = widget.dispose!({\n helper: helper!,\n state,\n parent: this,\n });\n\n return next || state;\n }, helper!.state);\n\n localUiState = getLocalWidgetsUiState(localWidgets, {\n searchParameters: nextState,\n helper: helper!,\n });\n\n helper!.setState(\n getLocalWidgetsSearchParameters(localWidgets, {\n uiState: localUiState,\n initialSearchParameters: nextState,\n })\n );\n\n if (localWidgets.length) {\n localInstantSearchInstance.scheduleSearch();\n }\n }\n\n return this;\n },\n\n init({ instantSearchInstance, parent, uiState }: IndexInitOptions) {\n if (helper !== null) {\n // helper is already initialized, therefore we do not need to set up\n // any listeners\n return;\n }\n\n localInstantSearchInstance = instantSearchInstance;\n localParent = parent;\n localUiState = uiState[indexId] || {};\n\n // The `mainHelper` is already defined at this point. The instance is created\n // inside InstantSearch at the `start` method, which occurs before the `init`\n // step.\n const mainHelper = instantSearchInstance.mainHelper!;\n const parameters = getLocalWidgetsSearchParameters(localWidgets, {\n uiState: localUiState,\n initialSearchParameters: new algoliasearchHelper.SearchParameters({\n index: indexName,\n }),\n });\n\n // This Helper is only used for state management we do not care about the\n // `searchClient`. Only the \"main\" Helper created at the `InstantSearch`\n // level is aware of the client.\n helper = algoliasearchHelper(\n {} as SearchClient,\n parameters.index,\n parameters\n );\n\n // We forward the call to `search` to the \"main\" instance of the Helper\n // which is responsible for managing the queries (it's the only one that is\n // aware of the `searchClient`).\n helper.search = () => {\n if (instantSearchInstance.onStateChange) {\n instantSearchInstance.onStateChange({\n uiState: instantSearchInstance.mainIndex.getWidgetUiState({}),\n setUiState: instantSearchInstance.setUiState.bind(\n instantSearchInstance\n ),\n });\n\n // We don't trigger a search when controlled because it becomes the\n // responsibility of `setUiState`.\n return mainHelper;\n }\n\n return mainHelper.search();\n };\n\n helper.searchWithoutTriggeringOnStateChange = () => {\n return mainHelper.search();\n };\n\n // We use the same pattern for the `searchForFacetValues`.\n helper.searchForFacetValues = (\n facetName,\n facetValue,\n maxFacetHits,\n userState: PlainSearchParameters\n ) => {\n const state = helper!.state.setQueryParameters(userState);\n\n return mainHelper.searchForFacetValues(\n facetName,\n facetValue,\n maxFacetHits,\n state\n );\n };\n\n derivedHelper = mainHelper.derive(() =>\n mergeSearchParameters(...resolveSearchParameters(this))\n );\n\n const indexInitialResults =\n instantSearchInstance._initialResults?.[this.getIndexId()];\n\n if (indexInitialResults) {\n // We restore the shape of the results provided to the instance to respect\n // the helper's structure.\n const results = new algoliasearchHelper.SearchResults(\n new algoliasearchHelper.SearchParameters(indexInitialResults.state),\n indexInitialResults.results\n );\n\n derivedHelper.lastResults = results;\n helper.lastResults = results;\n }\n\n // Subscribe to the Helper state changes for the page before widgets\n // are initialized. This behavior mimics the original one of the Helper.\n // It makes sense to replicate it at the `init` step. We have another\n // listener on `change` below, once `init` is done.\n helper.on('change', ({ isPageReset }) => {\n if (isPageReset) {\n resetPageFromWidgets(localWidgets);\n }\n });\n\n derivedHelper.on('search', () => {\n // The index does not manage the \"staleness\" of the search. This is the\n // responsibility of the main instance. It does not make sense to manage\n // it at the index level because it's either: all of them or none of them\n // that are stalled. The queries are performed into a single network request.\n instantSearchInstance.scheduleStalledRender();\n\n if (__DEV__) {\n checkIndexUiState({ index: this, indexUiState: localUiState });\n }\n });\n\n derivedHelper.on('result', ({ results }) => {\n // The index does not render the results it schedules a new render\n // to let all the other indices emit their own results. It allows us to\n // run the render process in one pass.\n instantSearchInstance.scheduleRender();\n\n // the derived helper is the one which actually searches, but the helper\n // which is exposed e.g. via instance.helper, doesn't search, and thus\n // does not have access to lastResults, which it used to in pre-federated\n // search behavior.\n helper!.lastResults = results;\n });\n\n // We compute the render state before calling `init` in a separate loop\n // to construct the whole render state object that is then passed to\n // `init`.\n localWidgets.forEach((widget) => {\n if (widget.getRenderState) {\n const renderState = widget.getRenderState(\n instantSearchInstance.renderState[this.getIndexId()] || {},\n {\n uiState,\n helper: helper!,\n parent: this,\n instantSearchInstance,\n state: helper!.state,\n renderState: instantSearchInstance.renderState,\n templatesConfig: instantSearchInstance.templatesConfig,\n createURL: this.createURL,\n scopedResults: [],\n searchMetadata: {\n isSearchStalled: instantSearchInstance._isSearchStalled,\n },\n }\n );\n\n storeRenderState({\n renderState,\n instantSearchInstance,\n parent: this,\n });\n }\n });\n\n localWidgets.forEach((widget) => {\n warning(\n // if it has NO getWidgetState or if it has getWidgetUiState, we don't warn\n // aka we warn if there's _only_ getWidgetState\n !widget.getWidgetState || Boolean(widget.getWidgetUiState),\n 'The `getWidgetState` method is renamed `getWidgetUiState` and will no longer exist under that name in InstantSearch.js 5.x. Please use `getWidgetUiState` instead.'\n );\n\n if (widget.init) {\n widget.init({\n uiState,\n helper: helper!,\n parent: this,\n instantSearchInstance,\n state: helper!.state,\n renderState: instantSearchInstance.renderState,\n templatesConfig: instantSearchInstance.templatesConfig,\n createURL: this.createURL,\n scopedResults: [],\n searchMetadata: {\n isSearchStalled: instantSearchInstance._isSearchStalled,\n },\n });\n }\n });\n\n // Subscribe to the Helper state changes for the `uiState` once widgets\n // are initialized. Until the first render, state changes are part of the\n // configuration step. This is mainly for backward compatibility with custom\n // widgets. When the subscription happens before the `init` step, the (static)\n // configuration of the widget is pushed in the URL. That's what we want to avoid.\n // https://github.com/algolia/instantsearch.js/pull/994/commits/4a672ae3fd78809e213de0368549ef12e9dc9454\n helper.on('change', (event) => {\n const { state } = event;\n\n const _uiState = (event as any)._uiState;\n\n localUiState = getLocalWidgetsUiState(\n localWidgets,\n {\n searchParameters: state,\n helper: helper!,\n },\n _uiState || {}\n );\n\n // We don't trigger an internal change when controlled because it\n // becomes the responsibility of `setUiState`.\n if (!instantSearchInstance.onStateChange) {\n instantSearchInstance.onInternalStateChange();\n }\n });\n\n if (indexInitialResults) {\n // If there are initial results, we're not notified of the next results\n // because we don't trigger an initial search. We therefore need to directly\n // schedule a render that will render the results injected on the helper.\n instantSearchInstance.scheduleRender();\n }\n },\n\n render({ instantSearchInstance }: IndexRenderOptions) {\n if (!this.getResults()) {\n return;\n }\n\n localWidgets.forEach((widget) => {\n if (widget.getRenderState) {\n const renderState = widget.getRenderState(\n instantSearchInstance.renderState[this.getIndexId()] || {},\n {\n helper: this.getHelper()!,\n parent: this,\n instantSearchInstance,\n results: this.getResults()!,\n scopedResults: this.getScopedResults(),\n state: this.getResults()!._state,\n renderState: instantSearchInstance.renderState,\n templatesConfig: instantSearchInstance.templatesConfig,\n createURL: this.createURL,\n searchMetadata: {\n isSearchStalled: instantSearchInstance._isSearchStalled,\n },\n }\n );\n\n storeRenderState({\n renderState,\n instantSearchInstance,\n parent: this,\n });\n }\n });\n\n localWidgets.forEach((widget) => {\n // At this point, all the variables used below are set. Both `helper`\n // and `derivedHelper` have been created at the `init` step. The attribute\n // `lastResults` might be `null` though. It's possible that a stalled render\n // happens before the result e.g with a dynamically added index the request might\n // be delayed. The render is triggered for the complete tree but some parts do\n // not have results yet.\n\n if (widget.render) {\n widget.render({\n helper: helper!,\n parent: this,\n instantSearchInstance,\n results: this.getResults()!,\n scopedResults: this.getScopedResults(),\n state: this.getResults()!._state,\n renderState: instantSearchInstance.renderState,\n templatesConfig: instantSearchInstance.templatesConfig,\n createURL: this.createURL,\n searchMetadata: {\n isSearchStalled: instantSearchInstance._isSearchStalled,\n },\n });\n }\n });\n },\n\n dispose() {\n localWidgets.forEach((widget) => {\n if (widget.dispose) {\n // The dispose function is always called once the instance is started\n // (it's an effect of `removeWidgets`). The index is initialized and\n // the Helper is available. We don't care about the return value of\n // `dispose` because the index is removed. We can't call `removeWidgets`\n // because we want to keep the widgets on the instance, to allow idempotent\n // operations on `add` & `remove`.\n widget.dispose({\n helper: helper!,\n state: helper!.state,\n parent: this,\n });\n }\n });\n\n localInstantSearchInstance = null;\n localParent = null;\n helper!.removeAllListeners();\n helper = null;\n\n derivedHelper!.detach();\n derivedHelper = null;\n },\n\n getWidgetUiState<TUiState = UiState>(uiState: TUiState) {\n return localWidgets\n .filter(isIndexWidget)\n .reduce<TUiState>(\n (previousUiState, innerIndex) =>\n innerIndex.getWidgetUiState(previousUiState),\n {\n ...uiState,\n [this.getIndexId()]: localUiState,\n }\n );\n },\n\n getWidgetState(uiState: UiState) {\n warning(\n false,\n 'The `getWidgetState` method is renamed `getWidgetUiState` and will no longer exist under that name in InstantSearch.js 5.x. Please use `getWidgetUiState` instead.'\n );\n\n return this.getWidgetUiState(uiState);\n },\n\n getWidgetSearchParameters(searchParameters, { uiState }) {\n return getLocalWidgetsSearchParameters(localWidgets, {\n uiState,\n initialSearchParameters: searchParameters,\n });\n },\n\n refreshUiState() {\n localUiState = getLocalWidgetsUiState(\n localWidgets,\n {\n searchParameters: this.getHelper()!.state,\n helper: this.getHelper()!,\n },\n localUiState\n );\n },\n };\n};\n\nexport default index;\n\nfunction storeRenderState({\n renderState,\n instantSearchInstance,\n parent,\n}: {\n renderState: IndexRenderState;\n instantSearchInstance: InstantSearch;\n parent?: IndexWidget;\n}) {\n const parentIndexName = parent\n ? parent.getIndexId()\n : instantSearchInstance.mainIndex.getIndexId();\n\n instantSearchInstance.renderState = {\n ...instantSearchInstance.renderState,\n [parentIndexName]: {\n ...instantSearchInstance.renderState[parentIndexName],\n ...renderState,\n },\n };\n}\n","import type { SearchParameters } from 'algoliasearch-helper';\nimport type { IndexWidget } from '../../widgets/index/index';\n\nconst resolveSearchParameters = (current: IndexWidget): SearchParameters[] => {\n let parent = current.getParent();\n let states = [current.getHelper()!.state];\n\n while (parent !== null) {\n states = [parent.getHelper()!.state].concat(states);\n parent = parent.getParent();\n }\n\n return states;\n};\n\nexport default resolveSearchParameters;\n","const NAMESPACE = 'ais';\n\ntype SuitOptions = {\n descendantName?: string;\n modifierName?: string;\n};\n\ntype SuitSelector = (names?: SuitOptions) => string;\n\nexport const component =\n (componentName: string): SuitSelector =>\n ({ descendantName, modifierName }: SuitOptions = {}) => {\n const descendent = descendantName ? `-${descendantName}` : '';\n const modifier = modifierName ? `--${modifierName}` : '';\n\n return `${NAMESPACE}-${componentName}${descendent}${modifier}`;\n };\n","import type { Hit } from '../types';\nimport { component } from '../lib/suit';\nimport { getPropertyByPath, TAG_REPLACEMENT } from '../lib/utils';\n\nexport type HighlightOptions = {\n // @MAJOR string should no longer be allowed to be a path, only array can be a path\n attribute: string | string[];\n highlightedTagName?: string;\n hit: Partial<Hit>;\n cssClasses?: Partial<{\n highlighted: string;\n }>;\n};\n\nconst suit = component('Highlight');\n\nexport default function highlight({\n attribute,\n highlightedTagName = 'mark',\n hit,\n cssClasses = {},\n}: HighlightOptions): string {\n const { value: attributeValue = '' } =\n getPropertyByPath(hit._highlightResult, attribute) || {};\n\n // cx is not used, since it would be bundled as a dependency for Vue & Angular\n const className =\n suit({\n descendantName: 'highlighted',\n }) + (cssClasses.highlighted ? ` ${cssClasses.highlighted}` : '');\n\n return attributeValue\n .replace(\n new RegExp(TAG_REPLACEMENT.highlightPreTag, 'g'),\n `<${highlightedTagName} class=\"${className}\">`\n )\n .replace(\n new RegExp(TAG_REPLACEMENT.highlightPostTag, 'g'),\n `</${highlightedTagName}>`\n );\n}\n","import type { Hit } from '../types';\nimport {\n TAG_REPLACEMENT,\n getPropertyByPath,\n getHighlightedParts,\n reverseHighlightedParts,\n concatHighlightedParts,\n} from '../lib/utils';\nimport { component } from '../lib/suit';\n\nexport type ReverseHighlightOptions = {\n // @MAJOR string should no longer be allowed to be a path, only array can be a path\n attribute: string | string[];\n highlightedTagName?: string;\n hit: Partial<Hit>;\n cssClasses?: Partial<{\n highlighted: string;\n }>;\n};\n\nconst suit = component('ReverseHighlight');\n\nexport default function reverseHighlight({\n attribute,\n highlightedTagName = 'mark',\n hit,\n cssClasses = {},\n}: ReverseHighlightOptions): string {\n const { value: attributeValue = '' } =\n getPropertyByPath(hit._highlightResult, attribute) || {};\n\n // cx is not used, since it would be bundled as a dependency for Vue & Angular\n const className =\n suit({\n descendantName: 'highlighted',\n }) + (cssClasses.highlighted ? ` ${cssClasses.highlighted}` : '');\n\n const reverseHighlightedValue = concatHighlightedParts(\n reverseHighlightedParts(getHighlightedParts(attributeValue))\n );\n\n return reverseHighlightedValue\n .replace(\n new RegExp(TAG_REPLACEMENT.highlightPreTag, 'g'),\n `<${highlightedTagName} class=\"${className}\">`\n )\n .replace(\n new RegExp(TAG_REPLACEMENT.highlightPostTag, 'g'),\n `</${highlightedTagName}>`\n );\n}\n","import type { Hit } from '../types';\nimport { component } from '../lib/suit';\nimport { TAG_REPLACEMENT, getPropertyByPath } from '../lib/utils';\n\nexport type SnippetOptions = {\n // @MAJOR string should no longer be allowed to be a path, only array can be a path\n attribute: string | string[];\n highlightedTagName?: string;\n hit: Partial<Hit>;\n cssClasses?: {\n highlighted?: string;\n };\n};\n\nconst suit = component('Snippet');\n\nexport default function snippet({\n attribute,\n highlightedTagName = 'mark',\n hit,\n cssClasses = {},\n}: SnippetOptions): string {\n const { value: attributeValue = '' } =\n getPropertyByPath(hit._snippetResult, attribute) || {};\n\n // cx is not used, since it would be bundled as a dependency for Vue & Angular\n const className =\n suit({\n descendantName: 'highlighted',\n }) + (cssClasses.highlighted ? ` ${cssClasses.highlighted}` : '');\n\n return attributeValue\n .replace(\n new RegExp(TAG_REPLACEMENT.highlightPreTag, 'g'),\n `<${highlightedTagName} class=\"${className}\">`\n )\n .replace(\n new RegExp(TAG_REPLACEMENT.highlightPostTag, 'g'),\n `</${highlightedTagName}>`\n );\n}\n","import type { Hit } from '../types';\nimport {\n TAG_REPLACEMENT,\n getPropertyByPath,\n getHighlightedParts,\n reverseHighlightedParts,\n concatHighlightedParts,\n} from '../lib/utils';\nimport { component } from '../lib/suit';\n\nexport type ReverseSnippetOptions = {\n // @MAJOR string should no longer be allowed to be a path, only array can be a path\n attribute: string | string[];\n highlightedTagName?: string;\n hit: Partial<Hit>;\n cssClasses?: Partial<{\n highlighted: string;\n }>;\n};\n\nconst suit = component('ReverseSnippet');\n\nexport default function reverseSnippet({\n attribute,\n highlightedTagName = 'mark',\n hit,\n cssClasses = {},\n}: ReverseSnippetOptions): string {\n const { value: attributeValue = '' } =\n getPropertyByPath(hit._snippetResult, attribute) || {};\n\n // cx is not used, since it would be bundled as a dependency for Vue & Angular\n const className =\n suit({\n descendantName: 'highlighted',\n }) + (cssClasses.highlighted ? ` ${cssClasses.highlighted}` : '');\n\n const reverseHighlightedValue = concatHighlightedParts(\n reverseHighlightedParts(getHighlightedParts(attributeValue))\n );\n\n return reverseHighlightedValue\n .replace(\n new RegExp(TAG_REPLACEMENT.highlightPreTag, 'g'),\n `<${highlightedTagName} class=\"${className}\">`\n )\n .replace(\n new RegExp(TAG_REPLACEMENT.highlightPostTag, 'g'),\n `</${highlightedTagName}>`\n );\n}\n","import type { InsightsClientMethod, InsightsClientPayload } from '../types';\nimport { warning, serializePayload, deserializePayload } from '../lib/utils';\n\nexport function readDataAttributes(domElement: HTMLElement): {\n method: InsightsClientMethod;\n payload: Partial<InsightsClientPayload>;\n} {\n const method = domElement.getAttribute(\n 'data-insights-method'\n ) as InsightsClientMethod;\n\n const serializedPayload = domElement.getAttribute('data-insights-payload');\n\n if (typeof serializedPayload !== 'string') {\n throw new Error(\n 'The insights helper expects `data-insights-payload` to be a base64-encoded JSON string.'\n );\n }\n\n try {\n const payload =\n deserializePayload<Partial<InsightsClientPayload>>(serializedPayload);\n return { method, payload };\n } catch (error) {\n throw new Error(\n 'The insights helper was unable to parse `data-insights-payload`.'\n );\n }\n}\n\nexport function hasDataAttributes(domElement: HTMLElement): boolean {\n return domElement.hasAttribute('data-insights-method');\n}\n\nexport function writeDataAttributes({\n method,\n payload,\n}: {\n method: InsightsClientMethod;\n payload: Partial<InsightsClientPayload>;\n}): string {\n if (typeof payload !== 'object') {\n throw new Error(`The insights helper expects the payload to be an object.`);\n }\n\n let serializedPayload: string;\n\n try {\n serializedPayload = serializePayload(payload);\n } catch (error) {\n throw new Error(`Could not JSON serialize the payload object.`);\n }\n\n return `data-insights-method=\"${method}\" data-insights-payload=\"${serializedPayload}\"`;\n}\n\n/**\n * @deprecated This function will be still supported in 4.x releases, but not further. It is replaced by the `insights` middleware. For more information, visit https://www.algolia.com/doc/guides/getting-insights-and-analytics/search-analytics/click-through-and-conversions/how-to/send-click-and-conversion-events-with-instantsearch/js/\n */\nexport default function insights(\n method: InsightsClientMethod,\n payload: Partial<InsightsClientPayload>\n): string {\n warning(\n false,\n `\\`insights\\` function has been deprecated. It is still supported in 4.x releases, but not further. It is replaced by the \\`insights\\` middleware.\n\nFor more information, visit https://www.algolia.com/doc/guides/getting-insights-and-analytics/search-analytics/click-through-and-conversions/how-to/send-click-and-conversion-events-with-instantsearch/js/`\n );\n return writeDataAttributes({ method, payload });\n}\n","import { warning } from '../lib/utils';\n\nexport const ANONYMOUS_TOKEN_COOKIE_KEY = '_ALGOLIA';\n\nfunction getCookie(name: string): string | undefined {\n const prefix = `${name}=`;\n const cookies = document.cookie.split(';');\n for (let i = 0; i < cookies.length; i++) {\n let cookie = cookies[i];\n while (cookie.charAt(0) === ' ') {\n cookie = cookie.substring(1);\n }\n if (cookie.indexOf(prefix) === 0) {\n return cookie.substring(prefix.length, cookie.length);\n }\n }\n return undefined;\n}\n\nexport function getInsightsAnonymousUserTokenInternal(): string | undefined {\n return getCookie(ANONYMOUS_TOKEN_COOKIE_KEY);\n}\n\n/**\n * @deprecated This function will be still supported in 4.x releases, but not further. It is replaced by the `insights` middleware. For more information, visit https://www.algolia.com/doc/guides/getting-insights-and-analytics/search-analytics/click-through-and-conversions/how-to/send-click-and-conversion-events-with-instantsearch/js/\n */\nexport default function getInsightsAnonymousUserToken(): string | undefined {\n warning(\n false,\n `\\`getInsightsAnonymousUserToken\\` function has been deprecated. It is still supported in 4.x releases, but not further. It is replaced by the \\`insights\\` middleware.\n\nFor more information, visit https://www.algolia.com/doc/guides/getting-insights-and-analytics/search-analytics/click-through-and-conversions/how-to/send-click-and-conversion-events-with-instantsearch/js/`\n );\n return getInsightsAnonymousUserTokenInternal();\n}\n","import type { UiState, IndexUiState, StateMapping } from '../../types';\n\nfunction getIndexStateWithoutConfigure<TIndexUiState extends IndexUiState>(\n uiState: TIndexUiState\n): Omit<TIndexUiState, 'configure'> {\n const { configure, ...trackedUiState } = uiState;\n return trackedUiState;\n}\n\n// technically a URL could contain any key, since users provide it,\n// which is why the input to this function is UiState, not something\n// which excludes \"configure\" as this function does.\nexport default function simpleStateMapping<\n TUiState extends UiState = UiState\n>(): StateMapping<TUiState, TUiState> {\n return {\n stateToRoute(uiState) {\n return Object.keys(uiState).reduce(\n (state, indexId) => ({\n ...state,\n [indexId]: getIndexStateWithoutConfigure(uiState[indexId]),\n }),\n {} as TUiState\n );\n },\n\n routeToState(routeState = {} as TUiState) {\n return Object.keys(routeState).reduce(\n (state, indexId) => ({\n ...state,\n [indexId]: getIndexStateWithoutConfigure(routeState[indexId]),\n }),\n {} as TUiState\n );\n },\n };\n}\n","'use strict';\n\nvar formats = require('./formats');\n\nvar has = Object.prototype.hasOwnProperty;\nvar isArray = Array.isArray;\n\nvar hexTable = (function () {\n var array = [];\n for (var i = 0; i < 256; ++i) {\n array.push('%' + ((i < 16 ? '0' : '') + i.toString(16)).toUpperCase());\n }\n\n return array;\n}());\n\nvar compactQueue = function compactQueue(queue) {\n while (queue.length > 1) {\n var item = queue.pop();\n var obj = item.obj[item.prop];\n\n if (isArray(obj)) {\n var compacted = [];\n\n for (var j = 0; j < obj.length; ++j) {\n if (typeof obj[j] !== 'undefined') {\n compacted.push(obj[j]);\n }\n }\n\n item.obj[item.prop] = compacted;\n }\n }\n};\n\nvar arrayToObject = function arrayToObject(source, options) {\n var obj = options && options.plainObjects ? Object.create(null) : {};\n for (var i = 0; i < source.length; ++i) {\n if (typeof source[i] !== 'undefined') {\n obj[i] = source[i];\n }\n }\n\n return obj;\n};\n\nvar merge = function merge(target, source, options) {\n /* eslint no-param-reassign: 0 */\n if (!source) {\n return target;\n }\n\n if (typeof source !== 'object') {\n if (isArray(target)) {\n target.push(source);\n } else if (target && typeof target === 'object') {\n if ((options && (options.plainObjects || options.allowPrototypes)) || !has.call(Object.prototype, source)) {\n target[source] = true;\n }\n } else {\n return [target, source];\n }\n\n return target;\n }\n\n if (!target || typeof target !== 'object') {\n return [target].concat(source);\n }\n\n var mergeTarget = target;\n if (isArray(target) && !isArray(source)) {\n mergeTarget = arrayToObject(target, options);\n }\n\n if (isArray(target) && isArray(source)) {\n source.forEach(function (item, i) {\n if (has.call(target, i)) {\n var targetItem = target[i];\n if (targetItem && typeof targetItem === 'object' && item && typeof item === 'object') {\n target[i] = merge(targetItem, item, options);\n } else {\n target.push(item);\n }\n } else {\n target[i] = item;\n }\n });\n return target;\n }\n\n return Object.keys(source).reduce(function (acc, key) {\n var value = source[key];\n\n if (has.call(acc, key)) {\n acc[key] = merge(acc[key], value, options);\n } else {\n acc[key] = value;\n }\n return acc;\n }, mergeTarget);\n};\n\nvar assign = function assignSingleSource(target, source) {\n return Object.keys(source).reduce(function (acc, key) {\n acc[key] = source[key];\n return acc;\n }, target);\n};\n\nvar decode = function (str, decoder, charset) {\n var strWithoutPlus = str.replace(/\\+/g, ' ');\n if (charset === 'iso-8859-1') {\n // unescape never throws, no try...catch needed:\n return strWithoutPlus.replace(/%[0-9a-f]{2}/gi, unescape);\n }\n // utf-8\n try {\n return decodeURIComponent(strWithoutPlus);\n } catch (e) {\n return strWithoutPlus;\n }\n};\n\nvar encode = function encode(str, defaultEncoder, charset, kind, format) {\n // This code was originally written by Brian White (mscdex) for the io.js core querystring library.\n // It has been adapted here for stricter adherence to RFC 3986\n if (str.length === 0) {\n return str;\n }\n\n var string = str;\n if (typeof str === 'symbol') {\n string = Symbol.prototype.toString.call(str);\n } else if (typeof str !== 'string') {\n string = String(str);\n }\n\n if (charset === 'iso-8859-1') {\n return escape(string).replace(/%u[0-9a-f]{4}/gi, function ($0) {\n return '%26%23' + parseInt($0.slice(2), 16) + '%3B';\n });\n }\n\n var out = '';\n for (var i = 0; i < string.length; ++i) {\n var c = string.charCodeAt(i);\n\n if (\n c === 0x2D // -\n || c === 0x2E // .\n || c === 0x5F // _\n || c === 0x7E // ~\n || (c >= 0x30 && c <= 0x39) // 0-9\n || (c >= 0x41 && c <= 0x5A) // a-z\n || (c >= 0x61 && c <= 0x7A) // A-Z\n || (format === formats.RFC1738 && (c === 0x28 || c === 0x29)) // ( )\n ) {\n out += string.charAt(i);\n continue;\n }\n\n if (c < 0x80) {\n out = out + hexTable[c];\n continue;\n }\n\n if (c < 0x800) {\n out = out + (hexTable[0xC0 | (c >> 6)] + hexTable[0x80 | (c & 0x3F)]);\n continue;\n }\n\n if (c < 0xD800 || c >= 0xE000) {\n out = out + (hexTable[0xE0 | (c >> 12)] + hexTable[0x80 | ((c >> 6) & 0x3F)] + hexTable[0x80 | (c & 0x3F)]);\n continue;\n }\n\n i += 1;\n c = 0x10000 + (((c & 0x3FF) << 10) | (string.charCodeAt(i) & 0x3FF));\n out += hexTable[0xF0 | (c >> 18)]\n + hexTable[0x80 | ((c >> 12) & 0x3F)]\n + hexTable[0x80 | ((c >> 6) & 0x3F)]\n + hexTable[0x80 | (c & 0x3F)];\n }\n\n return out;\n};\n\nvar compact = function compact(value) {\n var queue = [{ obj: { o: value }, prop: 'o' }];\n var refs = [];\n\n for (var i = 0; i < queue.length; ++i) {\n var item = queue[i];\n var obj = item.obj[item.prop];\n\n var keys = Object.keys(obj);\n for (var j = 0; j < keys.length; ++j) {\n var key = keys[j];\n var val = obj[key];\n if (typeof val === 'object' && val !== null && refs.indexOf(val) === -1) {\n queue.push({ obj: obj, prop: key });\n refs.push(val);\n }\n }\n }\n\n compactQueue(queue);\n\n return value;\n};\n\nvar isRegExp = function isRegExp(obj) {\n return Object.prototype.toString.call(obj) === '[object RegExp]';\n};\n\nvar isBuffer = function isBuffer(obj) {\n if (!obj || typeof obj !== 'object') {\n return false;\n }\n\n return !!(obj.constructor && obj.constructor.isBuffer && obj.constructor.isBuffer(obj));\n};\n\nvar combine = function combine(a, b) {\n return [].concat(a, b);\n};\n\nvar maybeMap = function maybeMap(val, fn) {\n if (isArray(val)) {\n var mapped = [];\n for (var i = 0; i < val.length; i += 1) {\n mapped.push(fn(val[i]));\n }\n return mapped;\n }\n return fn(val);\n};\n\nmodule.exports = {\n arrayToObject: arrayToObject,\n assign: assign,\n combine: combine,\n compact: compact,\n decode: decode,\n encode: encode,\n isBuffer: isBuffer,\n isRegExp: isRegExp,\n maybeMap: maybeMap,\n merge: merge\n};\n","'use strict';\n\nvar utils = require('./utils');\nvar formats = require('./formats');\nvar has = Object.prototype.hasOwnProperty;\n\nvar arrayPrefixGenerators = {\n brackets: function brackets(prefix) {\n return prefix + '[]';\n },\n comma: 'comma',\n indices: function indices(prefix, key) {\n return prefix + '[' + key + ']';\n },\n repeat: function repeat(prefix) {\n return prefix;\n }\n};\n\nvar isArray = Array.isArray;\nvar push = Array.prototype.push;\nvar pushToArray = function (arr, valueOrArray) {\n push.apply(arr, isArray(valueOrArray) ? valueOrArray : [valueOrArray]);\n};\n\nvar toISO = Date.prototype.toISOString;\n\nvar defaultFormat = formats['default'];\nvar defaults = {\n addQueryPrefix: false,\n allowDots: false,\n charset: 'utf-8',\n charsetSentinel: false,\n delimiter: '&',\n encode: true,\n encoder: utils.encode,\n encodeValuesOnly: false,\n format: defaultFormat,\n formatter: formats.formatters[defaultFormat],\n // deprecated\n indices: false,\n serializeDate: function serializeDate(date) {\n return toISO.call(date);\n },\n skipNulls: false,\n strictNullHandling: false\n};\n\nvar isNonNullishPrimitive = function isNonNullishPrimitive(v) {\n return typeof v === 'string'\n || typeof v === 'number'\n || typeof v === 'boolean'\n || typeof v === 'symbol'\n || typeof v === 'bigint';\n};\n\nvar stringify = function stringify(\n object,\n prefix,\n generateArrayPrefix,\n strictNullHandling,\n skipNulls,\n encoder,\n filter,\n sort,\n allowDots,\n serializeDate,\n format,\n formatter,\n encodeValuesOnly,\n charset\n) {\n var obj = object;\n if (typeof filter === 'function') {\n obj = filter(prefix, obj);\n } else if (obj instanceof Date) {\n obj = serializeDate(obj);\n } else if (generateArrayPrefix === 'comma' && isArray(obj)) {\n obj = utils.maybeMap(obj, function (value) {\n if (value instanceof Date) {\n return serializeDate(value);\n }\n return value;\n });\n }\n\n if (obj === null) {\n if (strictNullHandling) {\n return encoder && !encodeValuesOnly ? encoder(prefix, defaults.encoder, charset, 'key', format) : prefix;\n }\n\n obj = '';\n }\n\n if (isNonNullishPrimitive(obj) || utils.isBuffer(obj)) {\n if (encoder) {\n var keyValue = encodeValuesOnly ? prefix : encoder(prefix, defaults.encoder, charset, 'key', format);\n return [formatter(keyValue) + '=' + formatter(encoder(obj, defaults.encoder, charset, 'value', format))];\n }\n return [formatter(prefix) + '=' + formatter(String(obj))];\n }\n\n var values = [];\n\n if (typeof obj === 'undefined') {\n return values;\n }\n\n var objKeys;\n if (generateArrayPrefix === 'comma' && isArray(obj)) {\n // we need to join elements in\n objKeys = [{ value: obj.length > 0 ? obj.join(',') || null : undefined }];\n } else if (isArray(filter)) {\n objKeys = filter;\n } else {\n var keys = Object.keys(obj);\n objKeys = sort ? keys.sort(sort) : keys;\n }\n\n for (var i = 0; i < objKeys.length; ++i) {\n var key = objKeys[i];\n var value = typeof key === 'object' && key.value !== undefined ? key.value : obj[key];\n\n if (skipNulls && value === null) {\n continue;\n }\n\n var keyPrefix = isArray(obj)\n ? typeof generateArrayPrefix === 'function' ? generateArrayPrefix(prefix, key) : prefix\n : prefix + (allowDots ? '.' + key : '[' + key + ']');\n\n pushToArray(values, stringify(\n value,\n keyPrefix,\n generateArrayPrefix,\n strictNullHandling,\n skipNulls,\n encoder,\n filter,\n sort,\n allowDots,\n serializeDate,\n format,\n formatter,\n encodeValuesOnly,\n charset\n ));\n }\n\n return values;\n};\n\nvar normalizeStringifyOptions = function normalizeStringifyOptions(opts) {\n if (!opts) {\n return defaults;\n }\n\n if (opts.encoder !== null && opts.encoder !== undefined && typeof opts.encoder !== 'function') {\n throw new TypeError('Encoder has to be a function.');\n }\n\n var charset = opts.charset || defaults.charset;\n if (typeof opts.charset !== 'undefined' && opts.charset !== 'utf-8' && opts.charset !== 'iso-8859-1') {\n throw new TypeError('The charset option must be either utf-8, iso-8859-1, or undefined');\n }\n\n var format = formats['default'];\n if (typeof opts.format !== 'undefined') {\n if (!has.call(formats.formatters, opts.format)) {\n throw new TypeError('Unknown format option provided.');\n }\n format = opts.format;\n }\n var formatter = formats.formatters[format];\n\n var filter = defaults.filter;\n if (typeof opts.filter === 'function' || isArray(opts.filter)) {\n filter = opts.filter;\n }\n\n return {\n addQueryPrefix: typeof opts.addQueryPrefix === 'boolean' ? opts.addQueryPrefix : defaults.addQueryPrefix,\n allowDots: typeof opts.allowDots === 'undefined' ? defaults.allowDots : !!opts.allowDots,\n charset: charset,\n charsetSentinel: typeof opts.charsetSentinel === 'boolean' ? opts.charsetSentinel : defaults.charsetSentinel,\n delimiter: typeof opts.delimiter === 'undefined' ? defaults.delimiter : opts.delimiter,\n encode: typeof opts.encode === 'boolean' ? opts.encode : defaults.encode,\n encoder: typeof opts.encoder === 'function' ? opts.encoder : defaults.encoder,\n encodeValuesOnly: typeof opts.encodeValuesOnly === 'boolean' ? opts.encodeValuesOnly : defaults.encodeValuesOnly,\n filter: filter,\n format: format,\n formatter: formatter,\n serializeDate: typeof opts.serializeDate === 'function' ? opts.serializeDate : defaults.serializeDate,\n skipNulls: typeof opts.skipNulls === 'boolean' ? opts.skipNulls : defaults.skipNulls,\n sort: typeof opts.sort === 'function' ? opts.sort : null,\n strictNullHandling: typeof opts.strictNullHandling === 'boolean' ? opts.strictNullHandling : defaults.strictNullHandling\n };\n};\n\nmodule.exports = function (object, opts) {\n var obj = object;\n var options = normalizeStringifyOptions(opts);\n\n var objKeys;\n var filter;\n\n if (typeof options.filter === 'function') {\n filter = options.filter;\n obj = filter('', obj);\n } else if (isArray(options.filter)) {\n filter = options.filter;\n objKeys = filter;\n }\n\n var keys = [];\n\n if (typeof obj !== 'object' || obj === null) {\n return '';\n }\n\n var arrayFormat;\n if (opts && opts.arrayFormat in arrayPrefixGenerators) {\n arrayFormat = opts.arrayFormat;\n } else if (opts && 'indices' in opts) {\n arrayFormat = opts.indices ? 'indices' : 'repeat';\n } else {\n arrayFormat = 'indices';\n }\n\n var generateArrayPrefix = arrayPrefixGenerators[arrayFormat];\n\n if (!objKeys) {\n objKeys = Object.keys(obj);\n }\n\n if (options.sort) {\n objKeys.sort(options.sort);\n }\n\n for (var i = 0; i < objKeys.length; ++i) {\n var key = objKeys[i];\n\n if (options.skipNulls && obj[key] === null) {\n continue;\n }\n pushToArray(keys, stringify(\n obj[key],\n key,\n generateArrayPrefix,\n options.strictNullHandling,\n options.skipNulls,\n options.encode ? options.encoder : null,\n options.filter,\n options.sort,\n options.allowDots,\n options.serializeDate,\n options.format,\n options.formatter,\n options.encodeValuesOnly,\n options.charset\n ));\n }\n\n var joined = keys.join(options.delimiter);\n var prefix = options.addQueryPrefix === true ? '?' : '';\n\n if (options.charsetSentinel) {\n if (options.charset === 'iso-8859-1') {\n // encodeURIComponent('&#10003;'), the \"numeric entity\" representation of a checkmark\n prefix += 'utf8=%26%2310003%3B&';\n } else {\n // encodeURIComponent('✓')\n prefix += 'utf8=%E2%9C%93&';\n }\n }\n\n return joined.length > 0 ? prefix + joined : '';\n};\n","'use strict';\n\nvar utils = require('./utils');\n\nvar has = Object.prototype.hasOwnProperty;\nvar isArray = Array.isArray;\n\nvar defaults = {\n allowDots: false,\n allowPrototypes: false,\n arrayLimit: 20,\n charset: 'utf-8',\n charsetSentinel: false,\n comma: false,\n decoder: utils.decode,\n delimiter: '&',\n depth: 5,\n ignoreQueryPrefix: false,\n interpretNumericEntities: false,\n parameterLimit: 1000,\n parseArrays: true,\n plainObjects: false,\n strictNullHandling: false\n};\n\nvar interpretNumericEntities = function (str) {\n return str.replace(/&#(\\d+);/g, function ($0, numberStr) {\n return String.fromCharCode(parseInt(numberStr, 10));\n });\n};\n\nvar parseArrayValue = function (val, options) {\n if (val && typeof val === 'string' && options.comma && val.indexOf(',') > -1) {\n return val.split(',');\n }\n\n return val;\n};\n\n// This is what browsers will submit when the ✓ character occurs in an\n// application/x-www-form-urlencoded body and the encoding of the page containing\n// the form is iso-8859-1, or when the submitted form has an accept-charset\n// attribute of iso-8859-1. Presumably also with other charsets that do not contain\n// the ✓ character, such as us-ascii.\nvar isoSentinel = 'utf8=%26%2310003%3B'; // encodeURIComponent('&#10003;')\n\n// These are the percent-encoded utf-8 octets representing a checkmark, indicating that the request actually is utf-8 encoded.\nvar charsetSentinel = 'utf8=%E2%9C%93'; // encodeURIComponent('✓')\n\nvar parseValues = function parseQueryStringValues(str, options) {\n var obj = {};\n var cleanStr = options.ignoreQueryPrefix ? str.replace(/^\\?/, '') : str;\n var limit = options.parameterLimit === Infinity ? undefined : options.parameterLimit;\n var parts = cleanStr.split(options.delimiter, limit);\n var skipIndex = -1; // Keep track of where the utf8 sentinel was found\n var i;\n\n var charset = options.charset;\n if (options.charsetSentinel) {\n for (i = 0; i < parts.length; ++i) {\n if (parts[i].indexOf('utf8=') === 0) {\n if (parts[i] === charsetSentinel) {\n charset = 'utf-8';\n } else if (parts[i] === isoSentinel) {\n charset = 'iso-8859-1';\n }\n skipIndex = i;\n i = parts.length; // The eslint settings do not allow break;\n }\n }\n }\n\n for (i = 0; i < parts.length; ++i) {\n if (i === skipIndex) {\n continue;\n }\n var part = parts[i];\n\n var bracketEqualsPos = part.indexOf(']=');\n var pos = bracketEqualsPos === -1 ? part.indexOf('=') : bracketEqualsPos + 1;\n\n var key, val;\n if (pos === -1) {\n key = options.decoder(part, defaults.decoder, charset, 'key');\n val = options.strictNullHandling ? null : '';\n } else {\n key = options.decoder(part.slice(0, pos), defaults.decoder, charset, 'key');\n val = utils.maybeMap(\n parseArrayValue(part.slice(pos + 1), options),\n function (encodedVal) {\n return options.decoder(encodedVal, defaults.decoder, charset, 'value');\n }\n );\n }\n\n if (val && options.interpretNumericEntities && charset === 'iso-8859-1') {\n val = interpretNumericEntities(val);\n }\n\n if (part.indexOf('[]=') > -1) {\n val = isArray(val) ? [val] : val;\n }\n\n if (has.call(obj, key)) {\n obj[key] = utils.combine(obj[key], val);\n } else {\n obj[key] = val;\n }\n }\n\n return obj;\n};\n\nvar parseObject = function (chain, val, options, valuesParsed) {\n var leaf = valuesParsed ? val : parseArrayValue(val, options);\n\n for (var i = chain.length - 1; i >= 0; --i) {\n var obj;\n var root = chain[i];\n\n if (root === '[]' && options.parseArrays) {\n obj = [].concat(leaf);\n } else {\n obj = options.plainObjects ? Object.create(null) : {};\n var cleanRoot = root.charAt(0) === '[' && root.charAt(root.length - 1) === ']' ? root.slice(1, -1) : root;\n var index = parseInt(cleanRoot, 10);\n if (!options.parseArrays && cleanRoot === '') {\n obj = { 0: leaf };\n } else if (\n !isNaN(index)\n && root !== cleanRoot\n && String(index) === cleanRoot\n && index >= 0\n && (options.parseArrays && index <= options.arrayLimit)\n ) {\n obj = [];\n obj[index] = leaf;\n } else {\n obj[cleanRoot] = leaf;\n }\n }\n\n leaf = obj;\n }\n\n return leaf;\n};\n\nvar parseKeys = function parseQueryStringKeys(givenKey, val, options, valuesParsed) {\n if (!givenKey) {\n return;\n }\n\n // Transform dot notation to bracket notation\n var key = options.allowDots ? givenKey.replace(/\\.([^.[]+)/g, '[$1]') : givenKey;\n\n // The regex chunks\n\n var brackets = /(\\[[^[\\]]*])/;\n var child = /(\\[[^[\\]]*])/g;\n\n // Get the parent\n\n var segment = options.depth > 0 && brackets.exec(key);\n var parent = segment ? key.slice(0, segment.index) : key;\n\n // Stash the parent if it exists\n\n var keys = [];\n if (parent) {\n // If we aren't using plain objects, optionally prefix keys that would overwrite object prototype properties\n if (!options.plainObjects && has.call(Object.prototype, parent)) {\n if (!options.allowPrototypes) {\n return;\n }\n }\n\n keys.push(parent);\n }\n\n // Loop through children appending to the array until we hit depth\n\n var i = 0;\n while (options.depth > 0 && (segment = child.exec(key)) !== null && i < options.depth) {\n i += 1;\n if (!options.plainObjects && has.call(Object.prototype, segment[1].slice(1, -1))) {\n if (!options.allowPrototypes) {\n return;\n }\n }\n keys.push(segment[1]);\n }\n\n // If there's a remainder, just add whatever is left\n\n if (segment) {\n keys.push('[' + key.slice(segment.index) + ']');\n }\n\n return parseObject(keys, val, options, valuesParsed);\n};\n\nvar normalizeParseOptions = function normalizeParseOptions(opts) {\n if (!opts) {\n return defaults;\n }\n\n if (opts.decoder !== null && opts.decoder !== undefined && typeof opts.decoder !== 'function') {\n throw new TypeError('Decoder has to be a function.');\n }\n\n if (typeof opts.charset !== 'undefined' && opts.charset !== 'utf-8' && opts.charset !== 'iso-8859-1') {\n throw new TypeError('The charset option must be either utf-8, iso-8859-1, or undefined');\n }\n var charset = typeof opts.charset === 'undefined' ? defaults.charset : opts.charset;\n\n return {\n allowDots: typeof opts.allowDots === 'undefined' ? defaults.allowDots : !!opts.allowDots,\n allowPrototypes: typeof opts.allowPrototypes === 'boolean' ? opts.allowPrototypes : defaults.allowPrototypes,\n arrayLimit: typeof opts.arrayLimit === 'number' ? opts.arrayLimit : defaults.arrayLimit,\n charset: charset,\n charsetSentinel: typeof opts.charsetSentinel === 'boolean' ? opts.charsetSentinel : defaults.charsetSentinel,\n comma: typeof opts.comma === 'boolean' ? opts.comma : defaults.comma,\n decoder: typeof opts.decoder === 'function' ? opts.decoder : defaults.decoder,\n delimiter: typeof opts.delimiter === 'string' || utils.isRegExp(opts.delimiter) ? opts.delimiter : defaults.delimiter,\n // eslint-disable-next-line no-implicit-coercion, no-extra-parens\n depth: (typeof opts.depth === 'number' || opts.depth === false) ? +opts.depth : defaults.depth,\n ignoreQueryPrefix: opts.ignoreQueryPrefix === true,\n interpretNumericEntities: typeof opts.interpretNumericEntities === 'boolean' ? opts.interpretNumericEntities : defaults.interpretNumericEntities,\n parameterLimit: typeof opts.parameterLimit === 'number' ? opts.parameterLimit : defaults.parameterLimit,\n parseArrays: opts.parseArrays !== false,\n plainObjects: typeof opts.plainObjects === 'boolean' ? opts.plainObjects : defaults.plainObjects,\n strictNullHandling: typeof opts.strictNullHandling === 'boolean' ? opts.strictNullHandling : defaults.strictNullHandling\n };\n};\n\nmodule.exports = function (str, opts) {\n var options = normalizeParseOptions(opts);\n\n if (str === '' || str === null || typeof str === 'undefined') {\n return options.plainObjects ? Object.create(null) : {};\n }\n\n var tempObj = typeof str === 'string' ? parseValues(str, options) : str;\n var obj = options.plainObjects ? Object.create(null) : {};\n\n // Iterate over the keys and setup the new object\n\n var keys = Object.keys(tempObj);\n for (var i = 0; i < keys.length; ++i) {\n var key = keys[i];\n var newObj = parseKeys(key, tempObj[key], options, typeof str === 'string');\n obj = utils.merge(obj, newObj, options);\n }\n\n return utils.compact(obj);\n};\n","import qs from 'qs';\nimport type { Router, UiState } from '../../types';\nimport { safelyRunOnBrowser } from '../utils';\n\ntype CreateURL<TRouteState> = (args: {\n qsModule: typeof qs;\n routeState: TRouteState;\n location: Location;\n}) => string;\n\ntype ParseURL<TRouteState> = (args: {\n qsModule: typeof qs;\n location: Location;\n}) => TRouteState;\n\ntype BrowserHistoryArgs<TRouteState> = {\n windowTitle?: (routeState: TRouteState) => string;\n writeDelay: number;\n createURL: CreateURL<TRouteState>;\n parseURL: ParseURL<TRouteState>;\n // @MAJOR: The `Location` type is hard to simulate in non-browser environments\n // so we should accept a subset of it that is easier to work with in any\n // environments.\n getLocation(): Location;\n};\n\nconst setWindowTitle = (title?: string): void => {\n if (title) {\n // This function is only executed on browsers so we can disable this check.\n // eslint-disable-next-line no-restricted-globals\n window.document.title = title;\n }\n};\n\nclass BrowserHistory<TRouteState> implements Router<TRouteState> {\n /**\n * Transforms a UI state into a title for the page.\n */\n private readonly windowTitle?: BrowserHistoryArgs<TRouteState>['windowTitle'];\n /**\n * Time in milliseconds before performing a write in the history.\n * It prevents from adding too many entries in the history and\n * makes the back button more usable.\n *\n * @default 400\n */\n private readonly writeDelay: Required<\n BrowserHistoryArgs<TRouteState>\n >['writeDelay'];\n /**\n * Creates a full URL based on the route state.\n * The storage adaptor maps all syncable keys to the query string of the URL.\n */\n private readonly _createURL: Required<\n BrowserHistoryArgs<TRouteState>\n >['createURL'];\n /**\n * Parses the URL into a route state.\n * It should be symmetrical to `createURL`.\n */\n private readonly parseURL: Required<\n BrowserHistoryArgs<TRouteState>\n >['parseURL'];\n /**\n * Returns the location to store in the history.\n * @default () => window.location\n */\n private readonly getLocation: Required<\n BrowserHistoryArgs<TRouteState>\n >['getLocation'];\n\n private writeTimer?: ReturnType<typeof setTimeout>;\n private _onPopState?(event: PopStateEvent): void;\n\n /**\n * Indicates if history.pushState should be executed.\n * It needs to avoid pushing state to history in case of back/forward in browser\n */\n private shouldPushState: boolean = true;\n\n /**\n * Initializes a new storage provider that syncs the search state to the URL\n * using web APIs (`window.location.pushState` and `onpopstate` event).\n */\n public constructor({\n windowTitle,\n writeDelay = 400,\n createURL,\n parseURL,\n getLocation,\n }: BrowserHistoryArgs<TRouteState>) {\n this.windowTitle = windowTitle;\n this.writeTimer = undefined;\n this.writeDelay = writeDelay;\n this._createURL = createURL;\n this.parseURL = parseURL;\n this.getLocation = getLocation;\n\n safelyRunOnBrowser(() => {\n const title = this.windowTitle && this.windowTitle(this.read());\n setWindowTitle(title);\n });\n }\n\n /**\n * Reads the URL and returns a syncable UI search state.\n */\n public read(): TRouteState {\n return this.parseURL({ qsModule: qs, location: this.getLocation() });\n }\n\n /**\n * Pushes a search state into the URL.\n */\n public write(routeState: TRouteState): void {\n safelyRunOnBrowser(({ window }) => {\n const url = this.createURL(routeState);\n const title = this.windowTitle && this.windowTitle(routeState);\n\n if (this.writeTimer) {\n clearTimeout(this.writeTimer);\n }\n\n this.writeTimer = setTimeout(() => {\n setWindowTitle(title);\n if (this.shouldPushState) {\n window.history.pushState(routeState, title || '', url);\n }\n this.shouldPushState = true;\n this.writeTimer = undefined;\n }, this.writeDelay);\n });\n }\n\n /**\n * Sets a callback on the `onpopstate` event of the history API of the current page.\n * It enables the URL sync to keep track of the changes.\n */\n public onUpdate(callback: (routeState: TRouteState) => void): void {\n this._onPopState = (event) => {\n if (this.writeTimer) {\n clearTimeout(this.writeTimer);\n this.writeTimer = undefined;\n }\n\n this.shouldPushState = false;\n const routeState = event.state;\n\n // At initial load, the state is read from the URL without update.\n // Therefore the state object is not available.\n // In this case, we fallback and read the URL.\n if (!routeState) {\n callback(this.read());\n } else {\n callback(routeState);\n }\n };\n\n safelyRunOnBrowser(({ window }) => {\n window.addEventListener('popstate', this._onPopState!);\n });\n }\n\n /**\n * Creates a complete URL from a given syncable UI state.\n *\n * It always generates the full URL, not a relative one.\n * This allows to handle cases like using a <base href>.\n * See: https://github.com/algolia/instantsearch.js/issues/790\n */\n public createURL(routeState: TRouteState): string {\n return this._createURL({\n qsModule: qs,\n routeState,\n location: this.getLocation(),\n });\n }\n\n /**\n * Removes the event listener and cleans up the URL.\n */\n public dispose(): void {\n safelyRunOnBrowser(({ window }) => {\n if (this._onPopState) {\n window.removeEventListener('popstate', this._onPopState);\n }\n });\n\n if (this.writeTimer) {\n clearTimeout(this.writeTimer);\n }\n\n this.write({} as TRouteState);\n }\n}\n\nexport default function historyRouter<TRouteState = UiState>({\n createURL = ({ qsModule, routeState, location }) => {\n const { protocol, hostname, port = '', pathname, hash } = location;\n const queryString = qsModule.stringify(routeState);\n const portWithPrefix = port === '' ? '' : `:${port}`;\n\n // IE <= 11 has no proper `location.origin` so we cannot rely on it.\n if (!queryString) {\n return `${protocol}//${hostname}${portWithPrefix}${pathname}${hash}`;\n }\n\n return `${protocol}//${hostname}${portWithPrefix}${pathname}?${queryString}${hash}`;\n },\n parseURL = ({ qsModule, location }) => {\n // `qs` by default converts arrays with more than 20 items to an object.\n // We want to avoid this because the data structure manipulated can therefore vary.\n // Setting the limit to `100` seems a good number because the engine's default is 100\n // (it can go up to 1000 but it is very unlikely to select more than 100 items in the UI).\n //\n // Using an `arrayLimit` of `n` allows `n + 1` items.\n //\n // See:\n // - https://github.com/ljharb/qs#parsing-arrays\n // - https://www.algolia.com/doc/api-reference/api-parameters/maxValuesPerFacet/\n return qsModule.parse(location.search.slice(1), { arrayLimit: 99 });\n },\n writeDelay = 400,\n windowTitle,\n getLocation = () => {\n return safelyRunOnBrowser<Location>(({ window }) => window.location, {\n fallback: () => {\n throw new Error(\n 'You need to provide `getLocation` to the `history` router in environments where `window` does not exist.'\n );\n },\n });\n },\n}: Partial<BrowserHistoryArgs<TRouteState>> = {}): BrowserHistory<TRouteState> {\n return new BrowserHistory({\n createURL,\n parseURL,\n writeDelay,\n windowTitle,\n getLocation,\n });\n}\n","'use strict';\n\nvar replace = String.prototype.replace;\nvar percentTwenties = /%20/g;\n\nvar Format = {\n RFC1738: 'RFC1738',\n RFC3986: 'RFC3986'\n};\n\nmodule.exports = {\n 'default': Format.RFC3986,\n formatters: {\n RFC1738: function (value) {\n return replace.call(value, percentTwenties, '+');\n },\n RFC3986: function (value) {\n return String(value);\n }\n },\n RFC1738: Format.RFC1738,\n RFC3986: Format.RFC3986\n};\n","'use strict';\n\nvar stringify = require('./stringify');\nvar parse = require('./parse');\nvar formats = require('./formats');\n\nmodule.exports = {\n formats: formats,\n parse: parse,\n stringify: stringify\n};\n","import simpleStateMapping from '../lib/stateMappings/simple';\nimport historyRouter from '../lib/routers/history';\nimport type {\n Router,\n StateMapping,\n UiState,\n InternalMiddleware,\n CreateURL,\n} from '../types';\nimport { isEqual } from '../lib/utils';\n\nexport type RouterProps<\n TUiState extends UiState = UiState,\n TRouteState = TUiState\n> = {\n router?: Router<TRouteState>;\n // ideally stateMapping should be required if TRouteState is given,\n // but there's no way to check if a generic is provided or the default value.\n stateMapping?: StateMapping<TUiState, TRouteState>;\n};\n\nexport const createRouterMiddleware = <\n TUiState extends UiState = UiState,\n TRouteState = TUiState\n>(\n props: RouterProps<TUiState, TRouteState> = {}\n): InternalMiddleware<TUiState> => {\n const {\n router = historyRouter<TRouteState>(),\n // We have to cast simpleStateMapping as a StateMapping<TUiState, TRouteState>.\n // this is needed because simpleStateMapping is StateMapping<TUiState, TUiState>.\n // While it's only used when UiState and RouteState are the same, unfortunately\n // TypeScript still considers them separate types.\n stateMapping = simpleStateMapping<TUiState>() as unknown as StateMapping<\n TUiState,\n TRouteState\n >,\n } = props;\n\n return ({ instantSearchInstance }) => {\n function topLevelCreateURL(nextState: TUiState) {\n const uiState: TUiState = Object.keys(nextState).reduce(\n (acc, indexId) => ({\n ...acc,\n [indexId]: nextState[indexId],\n }),\n instantSearchInstance.mainIndex.getWidgetUiState<TUiState>(\n {} as TUiState\n )\n );\n\n const route = stateMapping.stateToRoute(uiState);\n\n return router.createURL(route);\n }\n\n // casting to UiState here to keep createURL unaware of custom UiState\n // (as long as it's an object, it's ok)\n instantSearchInstance._createURL = topLevelCreateURL as CreateURL<UiState>;\n\n let lastRouteState: TRouteState | undefined = undefined;\n\n const initialUiState = instantSearchInstance._initialUiState;\n\n return {\n onStateChange({ uiState }) {\n const routeState = stateMapping.stateToRoute(uiState);\n\n if (\n lastRouteState === undefined ||\n !isEqual(lastRouteState, routeState)\n ) {\n router.write(routeState);\n lastRouteState = routeState;\n }\n },\n\n subscribe() {\n instantSearchInstance._initialUiState = {\n ...initialUiState,\n ...stateMapping.routeToState(router.read()),\n };\n\n router.onUpdate((route) => {\n instantSearchInstance.setUiState(stateMapping.routeToState(route));\n });\n },\n\n unsubscribe() {\n router.dispose();\n },\n };\n };\n};\n","import { safelyRunOnBrowser } from '../lib/utils';\nimport type { InstantSearch, InternalMiddleware, Widget } from '../types';\nimport type { IndexWidget } from '../widgets/index/index';\n\ntype WidgetMetaData = {\n type: string | undefined;\n widgetType: string | undefined;\n params: string[];\n};\n\ntype Payload = {\n widgets: WidgetMetaData[];\n ua?: string;\n};\n\nfunction extractPayload(\n widgets: Array<Widget | IndexWidget>,\n instantSearchInstance: InstantSearch,\n payload: Payload\n) {\n const parent = instantSearchInstance.mainIndex;\n\n const initOptions = {\n instantSearchInstance,\n parent,\n scopedResults: [],\n state: parent.getHelper()!.state,\n helper: parent.getHelper()!,\n createURL: parent.createURL,\n uiState: instantSearchInstance._initialUiState,\n renderState: instantSearchInstance.renderState,\n templatesConfig: instantSearchInstance.templatesConfig,\n searchMetadata: {\n isSearchStalled: instantSearchInstance._isSearchStalled,\n },\n };\n\n widgets.forEach((widget) => {\n let widgetParams: Record<string, unknown> = {};\n\n if (widget.getWidgetRenderState) {\n const renderState = widget.getWidgetRenderState(initOptions);\n\n if (renderState && renderState.widgetParams) {\n // casting, as we just earlier checked widgetParams exists, and thus an object\n widgetParams = renderState.widgetParams as Record<string, unknown>;\n }\n }\n\n // since we destructure in all widgets, the parameters with defaults are set to \"undefined\"\n const params = Object.keys(widgetParams).filter(\n (key) => widgetParams[key] !== undefined\n );\n\n payload.widgets.push({\n type: widget.$$type,\n widgetType: widget.$$widgetType,\n params,\n });\n\n if (widget.$$type === 'ais.index') {\n extractPayload(\n (widget as IndexWidget).getWidgets(),\n instantSearchInstance,\n payload\n );\n }\n });\n}\n\nexport function isMetadataEnabled() {\n return safelyRunOnBrowser(\n ({ window }) => window.navigator.userAgent.indexOf('Algolia Crawler') > -1,\n { fallback: () => false }\n );\n}\n\n/**\n * Exposes the metadata of mounted widgets in a custom\n * `<meta name=\"instantsearch:widgets\" />` tag. The metadata per widget is:\n * - applied parameters\n * - widget name\n * - connector name\n */\nexport function createMetadataMiddleware(): InternalMiddleware {\n return ({ instantSearchInstance }) => {\n const payload: Payload = {\n widgets: [],\n };\n const payloadContainer = document.createElement('meta');\n const refNode = document.querySelector('head')!;\n payloadContainer.name = 'instantsearch:widgets';\n\n return {\n onStateChange() {},\n subscribe() {\n // using setTimeout here to delay extraction until widgets have been added in a tick (e.g. Vue)\n setTimeout(() => {\n const client = instantSearchInstance.client as any;\n payload.ua =\n client.transporter && client.transporter.userAgent\n ? client.transporter.userAgent.value\n : client._ua;\n\n extractPayload(\n instantSearchInstance.mainIndex.getWidgets(),\n instantSearchInstance,\n payload\n );\n\n payloadContainer.content = JSON.stringify(payload);\n refNode.appendChild(payloadContainer);\n }, 0);\n },\n\n unsubscribe() {\n payloadContainer.remove();\n },\n };\n };\n}\n","import type { AlgoliaSearchHelper } from 'algoliasearch-helper';\nimport algoliasearchHelper from 'algoliasearch-helper';\nimport EventEmitter from '@algolia/events';\n\nimport type { IndexWidget } from '../widgets/index/index';\nimport index, { isIndexWidget } from '../widgets/index/index';\nimport version from './version';\nimport createHelpers from './createHelpers';\nimport {\n createDocumentationMessageGenerator,\n createDocumentationLink,\n defer,\n noop,\n warning,\n checkIndexUiState,\n} from './utils';\nimport type {\n InsightsClient as AlgoliaInsightsClient,\n SearchClient,\n Widget,\n UiState,\n CreateURL,\n Middleware,\n MiddlewareDefinition,\n RenderState,\n InitialResults,\n} from '../types';\nimport type { RouterProps } from '../middlewares/createRouterMiddleware';\nimport { createRouterMiddleware } from '../middlewares/createRouterMiddleware';\nimport type { InsightsEvent } from '../middlewares/createInsightsMiddleware';\nimport {\n createMetadataMiddleware,\n isMetadataEnabled,\n} from '../middlewares/createMetadataMiddleware';\n\nconst withUsage = createDocumentationMessageGenerator({\n name: 'instantsearch',\n});\n\nfunction defaultCreateURL() {\n return '#';\n}\n\n/**\n * Global options for an InstantSearch instance.\n */\nexport type InstantSearchOptions<\n TUiState extends UiState = UiState,\n TRouteState = TUiState\n> = {\n /**\n * The name of the main index\n */\n indexName: string;\n\n /**\n * The search client to plug to InstantSearch.js\n *\n * Usage:\n * ```javascript\n * // Using the default Algolia search client\n * instantsearch({\n * indexName: 'indexName',\n * searchClient: algoliasearch('appId', 'apiKey')\n * });\n *\n * // Using a custom search client\n * instantsearch({\n * indexName: 'indexName',\n * searchClient: {\n * search(requests) {\n * // fetch response based on requests\n * return response;\n * },\n * searchForFacetValues(requests) {\n * // fetch response based on requests\n * return response;\n * }\n * }\n * });\n * ```\n */\n searchClient: SearchClient;\n\n /**\n * The locale used to display numbers. This will be passed\n * to `Number.prototype.toLocaleString()`\n */\n numberLocale?: string;\n\n /**\n * A hook that will be called each time a search needs to be done, with the\n * helper as a parameter. It's your responsibility to call `helper.search()`.\n * This option allows you to avoid doing searches at page load for example.\n */\n searchFunction?: (helper: AlgoliaSearchHelper) => void;\n\n /**\n * Function called when the state changes.\n *\n * Using this function makes the instance controlled. This means that you\n * become in charge of updating the UI state with the `setUiState` function.\n */\n onStateChange?: (params: {\n uiState: UiState;\n setUiState(\n uiState: UiState | ((previousUiState: UiState) => UiState)\n ): void;\n }) => void;\n\n /**\n * Injects a `uiState` to the `instantsearch` instance. You can use this option\n * to provide an initial state to a widget. Note that the state is only used\n * for the first search. To unconditionally pass additional parameters to the\n * Algolia API, take a look at the `configure` widget.\n */\n initialUiState?: TUiState;\n\n /**\n * Time before a search is considered stalled. The default is 200ms\n */\n stalledSearchDelay?: number;\n\n /**\n * Router configuration used to save the UI State into the URL or any other\n * client side persistence. Passing `true` will use the default URL options.\n */\n routing?: RouterProps<TUiState, TRouteState> | boolean;\n\n /**\n * the instance of search-insights to use for sending insights events inside\n * widgets like `hits`.\n *\n * @deprecated This property will be still supported in 4.x releases, but not further. It is replaced by the `insights` middleware. For more information, visit https://www.algolia.com/doc/guides/getting-insights-and-analytics/search-analytics/click-through-and-conversions/how-to/send-click-and-conversion-events-with-instantsearch/js/\n */\n insightsClient?: AlgoliaInsightsClient;\n};\n\n/**\n * The actual implementation of the InstantSearch. This is\n * created using the `instantsearch` factory function.\n * It emits the 'render' event every time a search is done\n */\nclass InstantSearch<\n TUiState extends UiState = UiState,\n TRouteState = TUiState\n> extends EventEmitter {\n public client: InstantSearchOptions['searchClient'];\n public indexName: string;\n public insightsClient: AlgoliaInsightsClient | null;\n public onStateChange: InstantSearchOptions['onStateChange'] | null = null;\n public helper: AlgoliaSearchHelper | null;\n public mainHelper: AlgoliaSearchHelper | null;\n public mainIndex: IndexWidget;\n public started: boolean;\n public templatesConfig: Record<string, unknown>;\n public renderState: RenderState = {};\n public _stalledSearchDelay: number;\n public _searchStalledTimer: any;\n public _isSearchStalled: boolean;\n public _initialUiState: UiState;\n public _initialResults: InitialResults | null;\n public _createURL: CreateURL<UiState>;\n public _searchFunction?: InstantSearchOptions['searchFunction'];\n public _mainHelperSearch?: AlgoliaSearchHelper['search'];\n public middleware: Array<{\n creator: Middleware;\n instance: MiddlewareDefinition;\n }> = [];\n public sendEventToInsights: (event: InsightsEvent) => void;\n\n public constructor(options: InstantSearchOptions<TUiState, TRouteState>) {\n super();\n\n const {\n indexName = null,\n numberLocale,\n initialUiState = {},\n routing = null,\n searchFunction,\n stalledSearchDelay = 200,\n searchClient = null,\n insightsClient = null,\n onStateChange = null,\n } = options;\n\n if (indexName === null) {\n throw new Error(withUsage('The `indexName` option is required.'));\n }\n\n if (searchClient === null) {\n throw new Error(withUsage('The `searchClient` option is required.'));\n }\n\n if (typeof (searchClient as any).search !== 'function') {\n throw new Error(\n `The \\`searchClient\\` must implement a \\`search\\` method.\n\nSee: https://www.algolia.com/doc/guides/building-search-ui/going-further/backend-search/in-depth/backend-instantsearch/js/`\n );\n }\n\n if (typeof searchClient.addAlgoliaAgent === 'function') {\n searchClient.addAlgoliaAgent(`instantsearch.js (${version})`);\n }\n\n warning(\n insightsClient === null,\n `\\`insightsClient\\` property has been deprecated. It is still supported in 4.x releases, but not further. It is replaced by the \\`insights\\` middleware.\n\nFor more information, visit https://www.algolia.com/doc/guides/getting-insights-and-analytics/search-analytics/click-through-and-conversions/how-to/send-click-and-conversion-events-with-instantsearch/js/`\n );\n\n if (insightsClient && typeof insightsClient !== 'function') {\n throw new Error(\n withUsage('The `insightsClient` option should be a function.')\n );\n }\n\n warning(\n !(options as any).searchParameters,\n `The \\`searchParameters\\` option is deprecated and will not be supported in InstantSearch.js 4.x.\n\nYou can replace it with the \\`configure\\` widget:\n\n\\`\\`\\`\nsearch.addWidgets([\n configure(${JSON.stringify((options as any).searchParameters, null, 2)})\n]);\n\\`\\`\\`\n\nSee ${createDocumentationLink({\n name: 'configure',\n })}`\n );\n\n this.client = searchClient;\n this.insightsClient = insightsClient;\n this.indexName = indexName;\n this.helper = null;\n this.mainHelper = null;\n this.mainIndex = index({\n indexName,\n });\n this.onStateChange = onStateChange;\n\n this.started = false;\n this.templatesConfig = {\n helpers: createHelpers({ numberLocale }),\n compileOptions: {},\n };\n\n this._stalledSearchDelay = stalledSearchDelay;\n this._searchStalledTimer = null;\n this._isSearchStalled = false;\n\n this._createURL = defaultCreateURL;\n this._initialUiState = initialUiState;\n this._initialResults = null;\n\n if (searchFunction) {\n this._searchFunction = searchFunction;\n }\n\n this.sendEventToInsights = noop;\n\n if (routing) {\n const routerOptions = typeof routing === 'boolean' ? undefined : routing;\n this.use(createRouterMiddleware(routerOptions));\n }\n\n if (isMetadataEnabled()) {\n this.use(createMetadataMiddleware());\n }\n }\n\n /**\n * Hooks a middleware into the InstantSearch lifecycle.\n */\n public use(...middleware: Middleware[]): this {\n const newMiddlewareList = middleware.map((fn) => {\n const newMiddleware = {\n subscribe: noop,\n unsubscribe: noop,\n onStateChange: noop,\n ...fn({ instantSearchInstance: this }),\n };\n this.middleware.push({\n creator: fn,\n instance: newMiddleware,\n });\n return newMiddleware;\n });\n\n // If the instance has already started, we directly subscribe the\n // middleware so they're notified of changes.\n if (this.started) {\n newMiddlewareList.forEach((m) => {\n m.subscribe();\n });\n }\n\n return this;\n }\n\n /**\n * Removes a middleware from the InstantSearch lifecycle.\n */\n public unuse(...middlewareToUnuse: Middleware[]): this {\n this.middleware\n .filter((m) => middlewareToUnuse.includes(m.creator))\n .forEach((m) => m.instance.unsubscribe());\n\n this.middleware = this.middleware.filter(\n (m) => !middlewareToUnuse.includes(m.creator)\n );\n\n return this;\n }\n\n // @major we shipped with EXPERIMENTAL_use, but have changed that to just `use` now\n public EXPERIMENTAL_use(...middleware: Middleware[]): this {\n warning(\n false,\n 'The middleware API is now considered stable, so we recommend replacing `EXPERIMENTAL_use` with `use` before upgrading to the next major version.'\n );\n\n return this.use(...middleware);\n }\n\n /**\n * Adds a widget to the search instance.\n * A widget can be added either before or after InstantSearch has started.\n * @param widget The widget to add to InstantSearch.\n *\n * @deprecated This method will still be supported in 4.x releases, but not further. It is replaced by `addWidgets([widget])`.\n */\n public addWidget(widget: Widget) {\n warning(\n false,\n 'addWidget will still be supported in 4.x releases, but not further. It is replaced by `addWidgets([widget])`'\n );\n\n return this.addWidgets([widget]);\n }\n\n /**\n * Adds multiple widgets to the search instance.\n * Widgets can be added either before or after InstantSearch has started.\n * @param widgets The array of widgets to add to InstantSearch.\n */\n public addWidgets(widgets: Array<Widget | IndexWidget>) {\n if (!Array.isArray(widgets)) {\n throw new Error(\n withUsage(\n 'The `addWidgets` method expects an array of widgets. Please use `addWidget`.'\n )\n );\n }\n\n if (\n widgets.some(\n (widget) =>\n typeof widget.init !== 'function' &&\n typeof widget.render !== 'function'\n )\n ) {\n throw new Error(\n withUsage(\n 'The widget definition expects a `render` and/or an `init` method.'\n )\n );\n }\n\n this.mainIndex.addWidgets(widgets);\n\n return this;\n }\n\n /**\n * Removes a widget from the search instance.\n * @deprecated This method will still be supported in 4.x releases, but not further. It is replaced by `removeWidgets([widget])`\n * @param widget The widget instance to remove from InstantSearch.\n *\n * The widget must implement a `dispose()` method to clear its state.\n */\n public removeWidget(widget: Widget | IndexWidget) {\n warning(\n false,\n 'removeWidget will still be supported in 4.x releases, but not further. It is replaced by `removeWidgets([widget])`'\n );\n\n return this.removeWidgets([widget]);\n }\n\n /**\n * Removes multiple widgets from the search instance.\n * @param widgets Array of widgets instances to remove from InstantSearch.\n *\n * The widgets must implement a `dispose()` method to clear their states.\n */\n public removeWidgets(widgets: Array<Widget | IndexWidget>) {\n if (!Array.isArray(widgets)) {\n throw new Error(\n withUsage(\n 'The `removeWidgets` method expects an array of widgets. Please use `removeWidget`.'\n )\n );\n }\n\n if (widgets.some((widget) => typeof widget.dispose !== 'function')) {\n throw new Error(\n withUsage('The widget definition expects a `dispose` method.')\n );\n }\n\n this.mainIndex.removeWidgets(widgets);\n\n return this;\n }\n\n /**\n * Ends the initialization of InstantSearch.js and triggers the\n * first search. This method should be called after all widgets have been added\n * to the instance of InstantSearch.js. InstantSearch.js also supports adding and removing\n * widgets after the start as an **EXPERIMENTAL** feature.\n */\n public start() {\n if (this.started) {\n throw new Error(\n withUsage('The `start` method has already been called once.')\n );\n }\n\n // This Helper is used for the queries, we don't care about its state. The\n // states are managed at the `index` level. We use this Helper to create\n // DerivedHelper scoped into the `index` widgets.\n // In Vue InstantSearch' hydrate, a main helper gets set before start, so\n // we need to respect this helper as a way to keep all listeners correct.\n const mainHelper =\n this.mainHelper || algoliasearchHelper(this.client, this.indexName);\n\n mainHelper.search = () => {\n // This solution allows us to keep the exact same API for the users but\n // under the hood, we have a different implementation. It should be\n // completely transparent for the rest of the codebase. Only this module\n // is impacted.\n return mainHelper.searchOnlyWithDerivedHelpers();\n };\n\n if (this._searchFunction) {\n // this client isn't used to actually search, but required for the helper\n // to not throw errors\n const fakeClient = {\n search: () => new Promise(noop),\n } as any as SearchClient;\n\n this._mainHelperSearch = mainHelper.search.bind(mainHelper);\n mainHelper.search = () => {\n const mainIndexHelper = this.mainIndex.getHelper();\n const searchFunctionHelper = algoliasearchHelper(\n fakeClient,\n mainIndexHelper!.state.index,\n mainIndexHelper!.state\n );\n searchFunctionHelper.once('search', ({ state }) => {\n mainIndexHelper!.overrideStateWithoutTriggeringChangeEvent(state);\n this._mainHelperSearch!();\n });\n // Forward state changes from `searchFunctionHelper` to `mainIndexHelper`\n searchFunctionHelper.on('change', ({ state }) => {\n mainIndexHelper!.setState(state);\n });\n this._searchFunction!(searchFunctionHelper);\n return mainHelper;\n };\n }\n\n // Only the \"main\" Helper emits the `error` event vs the one for `search`\n // and `results` that are also emitted on the derived one.\n mainHelper.on('error', ({ error }) => {\n this.emit('error', {\n error,\n });\n });\n\n this.mainHelper = mainHelper;\n\n this.middleware.forEach(({ instance }) => {\n instance.subscribe();\n });\n\n this.mainIndex.init({\n instantSearchInstance: this,\n parent: null,\n uiState: this._initialUiState,\n });\n\n if (this._initialResults) {\n const originalScheduleSearch = this.scheduleSearch;\n // We don't schedule a first search when initial results are provided\n // because we already have the results to render. This skips the initial\n // network request on the browser on `start`.\n this.scheduleSearch = defer(noop);\n // We also skip the initial network request when widgets are dynamically\n // added in the first tick (that's the case in all the framework-based flavors).\n // When we add a widget to `index`, it calls `scheduleSearch`. We can rely\n // on our `defer` util to restore the original `scheduleSearch` value once\n // widgets are added to hook back to the regular lifecycle.\n defer(() => {\n this.scheduleSearch = originalScheduleSearch;\n })();\n } else {\n this.scheduleSearch();\n }\n\n // Keep the previous reference for legacy purpose, some pattern use\n // the direct Helper access `search.helper` (e.g multi-index).\n this.helper = this.mainIndex.getHelper();\n\n // track we started the search if we add more widgets,\n // to init them directly after add\n this.started = true;\n }\n\n /**\n * Removes all widgets without triggering a search afterwards. This is an **EXPERIMENTAL** feature,\n * if you find an issue with it, please\n * [open an issue](https://github.com/algolia/instantsearch.js/issues/new?title=Problem%20with%20dispose).\n * @return {undefined} This method does not return anything\n */\n public dispose(): void {\n this.scheduleSearch.cancel();\n this.scheduleRender.cancel();\n clearTimeout(this._searchStalledTimer);\n\n this.removeWidgets(this.mainIndex.getWidgets());\n this.mainIndex.dispose();\n\n // You can not start an instance two times, therefore a disposed instance\n // needs to set started as false otherwise this can not be restarted at a\n // later point.\n this.started = false;\n\n // The helper needs to be reset to perform the next search from a fresh state.\n // If not reset, it would use the state stored before calling `dispose()`.\n this.removeAllListeners();\n this.mainHelper!.removeAllListeners();\n this.mainHelper = null;\n this.helper = null;\n\n this.middleware.forEach(({ instance }) => {\n instance.unsubscribe();\n });\n }\n\n public scheduleSearch = defer(() => {\n if (this.started) {\n this.mainHelper!.search();\n }\n });\n\n public scheduleRender = defer(() => {\n if (!this.mainHelper!.hasPendingRequests()) {\n clearTimeout(this._searchStalledTimer);\n this._searchStalledTimer = null;\n this._isSearchStalled = false;\n }\n\n this.mainIndex.render({\n instantSearchInstance: this,\n });\n\n this.emit('render');\n });\n\n public scheduleStalledRender() {\n if (!this._searchStalledTimer) {\n this._searchStalledTimer = setTimeout(() => {\n this._isSearchStalled = true;\n this.scheduleRender();\n }, this._stalledSearchDelay);\n }\n }\n\n public setUiState(\n uiState: UiState | ((previousUiState: UiState) => UiState)\n ): void {\n if (!this.mainHelper) {\n throw new Error(\n withUsage('The `start` method needs to be called before `setUiState`.')\n );\n }\n\n // We refresh the index UI state to update the local UI state that the\n // main index passes to the function form of `setUiState`.\n this.mainIndex.refreshUiState();\n const nextUiState =\n typeof uiState === 'function'\n ? uiState(this.mainIndex.getWidgetUiState({}))\n : uiState;\n\n const setIndexHelperState = (indexWidget: IndexWidget) => {\n const nextIndexUiState = nextUiState[indexWidget.getIndexId()] || {};\n\n if (__DEV__) {\n checkIndexUiState({\n index: indexWidget,\n indexUiState: nextIndexUiState,\n });\n }\n\n indexWidget.getHelper()!.setState(\n indexWidget.getWidgetSearchParameters(indexWidget.getHelper()!.state, {\n uiState: nextIndexUiState,\n })\n );\n\n indexWidget\n .getWidgets()\n .filter(isIndexWidget)\n .forEach(setIndexHelperState);\n };\n\n setIndexHelperState(this.mainIndex);\n\n this.scheduleSearch();\n this.onInternalStateChange();\n }\n\n public getUiState(): UiState {\n if (this.started) {\n // We refresh the index UI state to make sure changes from `refine` are taken in account\n this.mainIndex.refreshUiState();\n }\n\n return this.mainIndex.getWidgetUiState({});\n }\n\n public onInternalStateChange = defer(() => {\n const nextUiState = this.mainIndex.getWidgetUiState({});\n\n this.middleware.forEach(({ instance }) => {\n instance.onStateChange({\n uiState: nextUiState,\n });\n });\n });\n\n public createURL(nextState: UiState = {}): string {\n if (!this.started) {\n throw new Error(\n withUsage('The `start` method needs to be called before `createURL`.')\n );\n }\n\n return this._createURL(nextState);\n }\n\n public refresh() {\n if (!this.mainHelper) {\n throw new Error(\n withUsage('The `start` method needs to be called before `refresh`.')\n );\n }\n\n this.mainHelper.clearCache().search();\n }\n}\n\nexport default InstantSearch;\n","import type { AlgoliaSearchHelper } from 'algoliasearch-helper';\nimport {\n checkRendering,\n clearRefinements,\n getRefinements,\n createDocumentationMessageGenerator,\n noop,\n uniq,\n mergeSearchParameters,\n} from '../../lib/utils';\nimport type {\n TransformItems,\n CreateURL,\n Connector,\n WidgetRenderState,\n ScopedResult,\n} from '../../types';\n\nconst withUsage = createDocumentationMessageGenerator({\n name: 'clear-refinements',\n connector: true,\n});\n\nexport type ClearRefinementsConnectorParams = {\n /**\n * The attributes to include in the refinements to clear (all by default). Cannot be used with `excludedAttributes`.\n */\n includedAttributes?: string[];\n\n /**\n * The attributes to exclude from the refinements to clear. Cannot be used with `includedAttributes`.\n */\n excludedAttributes?: string[];\n\n /**\n * Function to transform the items passed to the templates.\n */\n transformItems?: TransformItems<string>;\n};\n\nexport type ClearRefinementsRenderState = {\n /**\n * Triggers the clear of all the currently refined values.\n */\n refine: () => void;\n\n /**\n * Indicates if search state is refined.\n * @deprecated prefer reading canRefine\n */\n hasRefinements: boolean;\n\n /**\n * Indicates if search state can be refined.\n */\n canRefine: boolean;\n\n /**\n * Creates a url for the next state when refinements are cleared.\n */\n createURL: CreateURL<void>;\n};\n\nexport type ClearRefinementsWidgetDescription = {\n $$type: 'ais.clearRefinements';\n renderState: ClearRefinementsRenderState;\n indexRenderState: {\n clearRefinements: WidgetRenderState<\n ClearRefinementsRenderState,\n ClearRefinementsConnectorParams\n >;\n };\n};\n\nexport type ClearRefinementsConnector = Connector<\n ClearRefinementsWidgetDescription,\n ClearRefinementsConnectorParams\n>;\n\ntype AttributesToClear = {\n helper: AlgoliaSearchHelper;\n items: string[];\n};\n\nconst connectClearRefinements: ClearRefinementsConnector =\n function connectClearRefinements(renderFn, unmountFn = noop) {\n checkRendering(renderFn, withUsage());\n\n return (widgetParams) => {\n const {\n includedAttributes = [],\n excludedAttributes = ['query'],\n transformItems = ((items) => items) as TransformItems<string>,\n } = widgetParams || {};\n\n if (\n widgetParams &&\n widgetParams.includedAttributes &&\n widgetParams.excludedAttributes\n ) {\n throw new Error(\n withUsage(\n 'The options `includedAttributes` and `excludedAttributes` cannot be used together.'\n )\n );\n }\n\n type ConnectorState = {\n refine(): void;\n createURL(): string;\n attributesToClear: AttributesToClear[];\n };\n\n const connectorState: ConnectorState = {\n refine: noop,\n createURL: () => '',\n attributesToClear: [],\n };\n\n const cachedRefine = () => connectorState.refine();\n const cachedCreateURL = () => connectorState.createURL();\n\n return {\n $$type: 'ais.clearRefinements',\n\n init(initOptions) {\n const { instantSearchInstance } = initOptions;\n\n renderFn(\n {\n ...this.getWidgetRenderState(initOptions),\n instantSearchInstance,\n },\n true\n );\n },\n\n render(renderOptions) {\n const { instantSearchInstance } = renderOptions;\n\n renderFn(\n {\n ...this.getWidgetRenderState(renderOptions),\n instantSearchInstance,\n },\n false\n );\n },\n\n dispose() {\n unmountFn();\n },\n\n getRenderState(renderState, renderOptions) {\n return {\n ...renderState,\n clearRefinements: this.getWidgetRenderState(renderOptions),\n };\n },\n\n getWidgetRenderState({ createURL, scopedResults }) {\n connectorState.attributesToClear = scopedResults.reduce<\n Array<ReturnType<typeof getAttributesToClear>>\n >((results, scopedResult) => {\n return results.concat(\n getAttributesToClear({\n scopedResult,\n includedAttributes,\n excludedAttributes,\n transformItems,\n })\n );\n }, []);\n\n connectorState.refine = () => {\n connectorState.attributesToClear.forEach(\n ({ helper: indexHelper, items }) => {\n indexHelper\n .setState(\n clearRefinements({\n helper: indexHelper,\n attributesToClear: items,\n })\n )\n .search();\n }\n );\n };\n\n connectorState.createURL = () =>\n createURL(\n mergeSearchParameters(\n ...connectorState.attributesToClear.map(\n ({ helper: indexHelper, items }) => {\n return clearRefinements({\n helper: indexHelper,\n attributesToClear: items,\n });\n }\n )\n )\n );\n\n const canRefine = connectorState.attributesToClear.some(\n (attributeToClear) => attributeToClear.items.length > 0\n );\n\n return {\n canRefine,\n hasRefinements: canRefine,\n refine: cachedRefine,\n createURL: cachedCreateURL,\n widgetParams,\n };\n },\n };\n };\n };\n\nfunction getAttributesToClear({\n scopedResult,\n includedAttributes,\n excludedAttributes,\n transformItems,\n}: {\n scopedResult: ScopedResult;\n includedAttributes: string[];\n excludedAttributes: string[];\n transformItems: TransformItems<string>;\n}): AttributesToClear {\n const includesQuery =\n includedAttributes.indexOf('query') !== -1 ||\n excludedAttributes.indexOf('query') === -1;\n\n return {\n helper: scopedResult.helper,\n items: transformItems(\n uniq(\n getRefinements(\n scopedResult.results,\n scopedResult.helper.state,\n includesQuery\n )\n .map((refinement) => refinement.attribute)\n .filter(\n (attribute) =>\n // If the array is empty (default case), we keep all the attributes\n includedAttributes.length === 0 ||\n // Otherwise, only add the specified attributes\n includedAttributes.indexOf(attribute) !== -1\n )\n .filter(\n (attribute) =>\n // If the query is included, we ignore the default `excludedAttributes = ['query']`\n (attribute === 'query' && includesQuery) ||\n // Otherwise, ignore the excluded attributes\n excludedAttributes.indexOf(attribute) === -1\n )\n )\n ),\n };\n}\n\nexport default connectClearRefinements;\n","export default '4.36.0';\n","import type {\n HighlightOptions,\n ReverseHighlightOptions,\n SnippetOptions,\n ReverseSnippetOptions,\n} from '../helpers';\nimport {\n highlight,\n reverseHighlight,\n snippet,\n reverseSnippet,\n insights,\n} from '../helpers';\nimport type {\n Hit,\n HoganHelpers,\n InsightsClientMethod,\n InsightsClientPayload,\n} from '../types';\n\ntype DefaultHoganHelpers = HoganHelpers<\n | 'formatNumber'\n | 'highlight'\n | 'reverseHighlight'\n | 'snippet'\n | 'reverseSnippet'\n | 'insights'\n>;\n\nexport default function hoganHelpers({\n numberLocale,\n}: {\n numberLocale?: string;\n}): DefaultHoganHelpers {\n return {\n formatNumber(value, render) {\n return Number(render(value)).toLocaleString(numberLocale);\n },\n highlight(options, render) {\n try {\n const highlightOptions: Omit<HighlightOptions, 'hit'> =\n JSON.parse(options);\n\n return render(\n highlight({\n ...highlightOptions,\n hit: this,\n })\n );\n } catch (error) {\n throw new Error(`\nThe highlight helper expects a JSON object of the format:\n{ \"attribute\": \"name\", \"highlightedTagName\": \"mark\" }`);\n }\n },\n reverseHighlight(options, render) {\n try {\n const reverseHighlightOptions: Omit<ReverseHighlightOptions, 'hit'> =\n JSON.parse(options);\n\n return render(\n reverseHighlight({\n ...reverseHighlightOptions,\n hit: this,\n })\n );\n } catch (error) {\n throw new Error(`\n The reverseHighlight helper expects a JSON object of the format:\n { \"attribute\": \"name\", \"highlightedTagName\": \"mark\" }`);\n }\n },\n snippet(options, render) {\n try {\n const snippetOptions: Omit<SnippetOptions, 'hit'> = JSON.parse(options);\n\n return render(\n snippet({\n ...snippetOptions,\n hit: this,\n })\n );\n } catch (error) {\n throw new Error(`\nThe snippet helper expects a JSON object of the format:\n{ \"attribute\": \"name\", \"highlightedTagName\": \"mark\" }`);\n }\n },\n reverseSnippet(options, render) {\n try {\n const reverseSnippetOptions: Omit<ReverseSnippetOptions, 'hit'> =\n JSON.parse(options);\n\n return render(\n reverseSnippet({\n ...reverseSnippetOptions,\n hit: this,\n })\n );\n } catch (error) {\n throw new Error(`\n The reverseSnippet helper expects a JSON object of the format:\n { \"attribute\": \"name\", \"highlightedTagName\": \"mark\" }`);\n }\n },\n insights(this: Hit, options, render) {\n try {\n type InsightsHelperOptions = {\n method: InsightsClientMethod;\n payload: Partial<InsightsClientPayload>;\n };\n const { method, payload }: InsightsHelperOptions = JSON.parse(options);\n\n return render(\n insights(method, { objectIDs: [this.objectID], ...payload })\n );\n } catch (error) {\n throw new Error(`\nThe insights helper expects a JSON object of the format:\n{ \"method\": \"method-name\", \"payload\": { \"eventName\": \"name of the event\" } }`);\n }\n },\n };\n}\n","import type {\n AlgoliaSearchHelper,\n SearchParameters,\n SearchResults,\n} from 'algoliasearch-helper';\nimport {\n getRefinements,\n checkRendering,\n createDocumentationMessageGenerator,\n noop,\n warning,\n} from '../../lib/utils';\nimport type {\n Refinement,\n FacetRefinement,\n NumericRefinement,\n} from '../../lib/utils/getRefinements';\nimport type {\n Connector,\n TransformItems,\n CreateURL,\n WidgetRenderState,\n} from '../../types';\n\nexport type CurrentRefinementsConnectorParamsRefinement = {\n /**\n * The attribute on which the refinement is applied.\n */\n attribute: string;\n\n /**\n * The type of the refinement.\n *\n * It can be one of those: 'facet'|'exclude'|'disjunctive'|'hierarchical'|'numeric'|'query'|'tag'.\n */\n type: string;\n\n /**\n * The raw value of the refinement.\n */\n value: string | number;\n\n /**\n * The label of the refinement to display.\n */\n label: string;\n\n /**\n * The value of the operator (only if applicable).\n */\n operator?: string;\n\n /**\n * The number of found items (only if applicable).\n */\n count?: number;\n\n /**\n * Whether the count is exhaustive (only if applicable).\n */\n exhaustive?: boolean;\n};\n\nexport type CurrentRefinementsConnectorParamsItem = {\n /**\n * The index name.\n */\n indexName: string;\n\n /**\n * The attribute on which the refinement is applied.\n */\n attribute: string;\n\n /**\n * The textual representation of this attribute.\n */\n label: string;\n\n /**\n * Currently applied refinements.\n */\n refinements: CurrentRefinementsConnectorParamsRefinement[];\n\n /**\n * Removes the given refinement and triggers a new search.\n */\n refine(refinement: CurrentRefinementsConnectorParamsRefinement): void;\n};\n\nexport type CurrentRefinementsConnectorParams = {\n /**\n * The attributes to include in the widget (all by default).\n * Cannot be used with `excludedAttributes`.\n *\n * @default `[]`\n */\n includedAttributes?: string[];\n\n /**\n * The attributes to exclude from the widget.\n * Cannot be used with `includedAttributes`.\n *\n * @default `['query']`\n */\n excludedAttributes?: string[];\n\n /**\n * Function to transform the items passed to the templates.\n */\n transformItems?: TransformItems<CurrentRefinementsConnectorParamsItem>;\n};\n\nexport type CurrentRefinementsRenderState = {\n /**\n * All the currently refined items, grouped by attribute.\n */\n items: CurrentRefinementsConnectorParamsItem[];\n\n /**\n * Indicates if search state can be refined.\n */\n canRefine: boolean;\n\n /**\n * Removes the given refinement and triggers a new search.\n */\n refine(refinement: CurrentRefinementsConnectorParamsRefinement): void;\n\n /**\n * Generates a URL for the next state.\n */\n createURL: CreateURL<CurrentRefinementsConnectorParamsRefinement>;\n};\n\nconst withUsage = createDocumentationMessageGenerator({\n name: 'current-refinements',\n connector: true,\n});\n\nexport type CurrentRefinementsWidgetDescription = {\n $$type: 'ais.currentRefinements';\n renderState: CurrentRefinementsRenderState;\n indexRenderState: {\n currentRefinements: WidgetRenderState<\n CurrentRefinementsRenderState,\n CurrentRefinementsConnectorParams\n >;\n };\n};\n\nexport type CurrentRefinementsConnector = Connector<\n CurrentRefinementsWidgetDescription,\n CurrentRefinementsConnectorParams\n>;\n\nconst connectCurrentRefinements: CurrentRefinementsConnector =\n function connectCurrentRefinements(renderFn, unmountFn = noop) {\n checkRendering(renderFn, withUsage());\n\n return (widgetParams) => {\n if (\n (widgetParams || {}).includedAttributes &&\n (widgetParams || {}).excludedAttributes\n ) {\n throw new Error(\n withUsage(\n 'The options `includedAttributes` and `excludedAttributes` cannot be used together.'\n )\n );\n }\n\n const {\n includedAttributes,\n excludedAttributes = ['query'],\n transformItems = (items: CurrentRefinementsConnectorParamsItem[]) =>\n items,\n } = widgetParams || {};\n\n return {\n $$type: 'ais.currentRefinements',\n\n init(initOptions) {\n const { instantSearchInstance } = initOptions;\n\n renderFn(\n {\n ...this.getWidgetRenderState(initOptions),\n instantSearchInstance,\n },\n true\n );\n },\n\n render(renderOptions) {\n const { instantSearchInstance } = renderOptions;\n\n renderFn(\n {\n ...this.getWidgetRenderState(renderOptions),\n instantSearchInstance,\n },\n false\n );\n },\n\n dispose() {\n unmountFn();\n },\n\n getRenderState(renderState, renderOptions) {\n return {\n ...renderState,\n currentRefinements: this.getWidgetRenderState(renderOptions),\n };\n },\n\n getWidgetRenderState({ results, scopedResults, createURL, helper }) {\n function getItems() {\n if (!results) {\n return transformItems(\n getRefinementsItems({\n results: {},\n helper,\n includedAttributes,\n excludedAttributes,\n })\n );\n }\n\n return scopedResults.reduce<\n CurrentRefinementsConnectorParamsItem[]\n >((accResults, scopedResult) => {\n return accResults.concat(\n transformItems(\n getRefinementsItems({\n results: scopedResult.results,\n helper: scopedResult.helper,\n includedAttributes,\n excludedAttributes,\n })\n )\n );\n }, []);\n }\n\n const items = getItems();\n\n return {\n items,\n canRefine: items.length > 0,\n refine: (refinement) => clearRefinement(helper, refinement),\n createURL: (refinement) =>\n createURL(clearRefinementFromState(helper.state, refinement)),\n widgetParams,\n };\n },\n };\n };\n };\n\nfunction getRefinementsItems({\n results,\n helper,\n includedAttributes,\n excludedAttributes,\n}: {\n results: SearchResults | Record<string, never>;\n helper: AlgoliaSearchHelper;\n includedAttributes: CurrentRefinementsConnectorParams['includedAttributes'];\n excludedAttributes: CurrentRefinementsConnectorParams['excludedAttributes'];\n}): CurrentRefinementsConnectorParamsItem[] {\n const includesQuery =\n (includedAttributes || []).indexOf('query') !== -1 ||\n (excludedAttributes || []).indexOf('query') === -1;\n\n const filterFunction = includedAttributes\n ? (item: CurrentRefinementsConnectorParamsRefinement) =>\n includedAttributes.indexOf(item.attribute) !== -1\n : (item: CurrentRefinementsConnectorParamsRefinement) =>\n excludedAttributes!.indexOf(item.attribute) === -1;\n\n const items = getRefinements(results, helper.state, includesQuery)\n .map(normalizeRefinement)\n .filter(filterFunction);\n\n return items.reduce<CurrentRefinementsConnectorParamsItem[]>(\n (allItems, currentItem) => [\n ...allItems.filter((item) => item.attribute !== currentItem.attribute),\n {\n indexName: helper.state.index,\n attribute: currentItem.attribute,\n label: currentItem.attribute,\n refinements: items\n .filter((result) => result.attribute === currentItem.attribute)\n // We want to keep the order of refinements except the numeric ones.\n .sort((a, b) =>\n a.type === 'numeric' ? (a.value as number) - (b.value as number) : 0\n ),\n refine: (refinement) => clearRefinement(helper, refinement),\n },\n ],\n []\n );\n}\n\nfunction clearRefinementFromState(\n state: SearchParameters,\n refinement: CurrentRefinementsConnectorParamsRefinement\n): SearchParameters {\n switch (refinement.type) {\n case 'facet':\n return state.removeFacetRefinement(\n refinement.attribute,\n String(refinement.value)\n );\n case 'disjunctive':\n return state.removeDisjunctiveFacetRefinement(\n refinement.attribute,\n String(refinement.value)\n );\n case 'hierarchical':\n return state.removeHierarchicalFacetRefinement(refinement.attribute);\n case 'exclude':\n return state.removeExcludeRefinement(\n refinement.attribute,\n String(refinement.value)\n );\n case 'numeric':\n return state.removeNumericRefinement(\n refinement.attribute,\n refinement.operator,\n String(refinement.value)\n );\n case 'tag':\n return state.removeTagRefinement(String(refinement.value));\n case 'query':\n return state.setQueryParameter('query', '');\n default:\n warning(\n false,\n `The refinement type \"${refinement.type}\" does not exist and cannot be cleared from the current refinements.`\n );\n return state;\n }\n}\n\nfunction clearRefinement(\n helper: AlgoliaSearchHelper,\n refinement: CurrentRefinementsConnectorParamsRefinement\n): void {\n helper.setState(clearRefinementFromState(helper.state, refinement)).search();\n}\n\nfunction getOperatorSymbol(operator: SearchParameters.Operator): string {\n switch (operator) {\n case '>=':\n return '≥';\n case '<=':\n return '≤';\n default:\n return operator;\n }\n}\n\nfunction normalizeRefinement(\n refinement: Refinement\n): CurrentRefinementsConnectorParamsRefinement {\n const value =\n refinement.type === 'numeric' ? Number(refinement.name) : refinement.name;\n const label = (refinement as NumericRefinement).operator\n ? `${getOperatorSymbol(\n (refinement as NumericRefinement).operator as SearchParameters.Operator\n )} ${refinement.name}`\n : refinement.name;\n\n const normalizedRefinement: CurrentRefinementsConnectorParamsRefinement = {\n attribute: refinement.attribute,\n type: refinement.type,\n value,\n label,\n };\n\n if ((refinement as NumericRefinement).operator !== undefined) {\n normalizedRefinement.operator = (refinement as NumericRefinement).operator;\n }\n if ((refinement as FacetRefinement).count !== undefined) {\n normalizedRefinement.count = (refinement as FacetRefinement).count;\n }\n if ((refinement as FacetRefinement).exhaustive !== undefined) {\n normalizedRefinement.exhaustive = (\n refinement as FacetRefinement\n ).exhaustive;\n }\n\n return normalizedRefinement;\n}\n\nexport default connectCurrentRefinements;\n","import type { SendEventForFacet } from '../../lib/utils';\nimport {\n checkRendering,\n warning,\n createDocumentationMessageGenerator,\n createSendEventForFacet,\n isEqual,\n noop,\n} from '../../lib/utils';\nimport type { SearchResults } from 'algoliasearch-helper';\nimport type {\n Connector,\n CreateURL,\n TransformItems,\n RenderOptions,\n Widget,\n SortBy,\n WidgetRenderState,\n} from '../../types';\n\nconst withUsage = createDocumentationMessageGenerator({\n name: 'hierarchical-menu',\n connector: true,\n});\n\nconst DEFAULT_SORT = ['name:asc'];\n\nexport type HierarchicalMenuItem = {\n /**\n * Value of the menu item.\n */\n value: string;\n /**\n * Human-readable value of the menu item.\n */\n label: string;\n /**\n * Number of matched results after refinement is applied.\n */\n count: number;\n /**\n * Indicates if the refinement is applied.\n */\n isRefined: boolean;\n /**\n * n+1 level of items, same structure HierarchicalMenuItem\n */\n data: HierarchicalMenuItem[] | null;\n};\n\nexport type HierarchicalMenuConnectorParams = {\n /**\n * Attributes to use to generate the hierarchy of the menu.\n */\n attributes: string[];\n /**\n * Separator used in the attributes to separate level values.\n */\n separator?: string;\n /**\n * Prefix path to use if the first level is not the root level.\n */\n rootPath?: string | null;\n /**\n * Show the siblings of the selected parent levels of the current refined value. This\n * does not impact the root level.\n */\n showParentLevel?: boolean;\n /**\n * Max number of values to display.\n */\n limit?: number;\n /**\n * Whether to display the \"show more\" button.\n */\n showMore?: boolean;\n /**\n * Max number of values to display when showing more.\n */\n showMoreLimit?: number;\n /**\n * How to sort refinements. Possible values: `count|isRefined|name:asc|name:desc`.\n * You can also use a sort function that behaves like the standard Javascript [compareFunction](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#Syntax).\n *\n * If a facetOrdering is set in the index settings, it is used when sortBy isn't passed\n */\n sortBy?: SortBy<HierarchicalMenuItem>;\n /**\n * Function to transform the items passed to the templates.\n */\n transformItems?: TransformItems<HierarchicalMenuItem>;\n};\n\nexport type HierarchicalMenuRenderState = {\n /**\n * Creates an url for the next state for a clicked item.\n */\n createURL: CreateURL<string>;\n /**\n * Values to be rendered.\n */\n items: HierarchicalMenuItem[];\n /**\n * Sets the path of the hierarchical filter and triggers a new search.\n */\n refine: (value: string) => void;\n /**\n * Indicates if search state can be refined.\n */\n canRefine: boolean;\n /**\n * True if the menu is displaying all the menu items.\n */\n isShowingMore: boolean;\n /**\n * Toggles the number of values displayed between `limit` and `showMoreLimit`.\n */\n toggleShowMore: () => void;\n /**\n * `true` if the toggleShowMore button can be activated (enough items to display more or\n * already displaying more than `limit` items)\n */\n canToggleShowMore: boolean;\n /**\n * Send event to insights middleware\n */\n sendEvent: SendEventForFacet;\n};\n\nexport type HierarchicalMenuWidgetDescription = {\n $$type: 'ais.hierarchicalMenu';\n renderState: HierarchicalMenuRenderState;\n indexRenderState: {\n hierarchicalMenu: {\n [rootAttribute: string]: WidgetRenderState<\n HierarchicalMenuRenderState,\n HierarchicalMenuConnectorParams\n >;\n };\n };\n indexUiState: {\n hierarchicalMenu: {\n [rootAttribute: string]: string[];\n };\n };\n};\n\nexport type HierarchicalMenuConnector = Connector<\n HierarchicalMenuWidgetDescription,\n HierarchicalMenuConnectorParams\n>;\n\n/**\n * **HierarchicalMenu** connector provides the logic to build a custom widget\n * that will give the user the ability to explore facets in a tree-like structure.\n *\n * This is commonly used for multi-level categorization of products on e-commerce\n * websites. From a UX point of view, we suggest not displaying more than two\n * levels deep.\n *\n * @type {Connector}\n * @param {function(HierarchicalMenuRenderingOptions, boolean)} renderFn Rendering function for the custom **HierarchicalMenu** widget.\n * @param {function} unmountFn Unmount function called when the widget is disposed.\n * @return {function(CustomHierarchicalMenuWidgetParams)} Re-usable widget factory for a custom **HierarchicalMenu** widget.\n */\nconst connectHierarchicalMenu: HierarchicalMenuConnector =\n function connectHierarchicalMenu(renderFn, unmountFn = noop) {\n checkRendering(renderFn, withUsage());\n\n return (widgetParams) => {\n const {\n attributes,\n separator = ' > ',\n rootPath = null,\n showParentLevel = true,\n limit = 10,\n showMore = false,\n showMoreLimit = 20,\n sortBy = DEFAULT_SORT,\n transformItems = ((items) =>\n items) as TransformItems<HierarchicalMenuItem>,\n } = widgetParams || {};\n\n if (\n !attributes ||\n !Array.isArray(attributes) ||\n attributes.length === 0\n ) {\n throw new Error(\n withUsage('The `attributes` option expects an array of strings.')\n );\n }\n\n if (showMore === true && showMoreLimit <= limit) {\n throw new Error(\n withUsage('The `showMoreLimit` option must be greater than `limit`.')\n );\n }\n\n type ThisWidget = Widget<\n HierarchicalMenuWidgetDescription & {\n widgetParams: typeof widgetParams;\n }\n >;\n\n // we need to provide a hierarchicalFacet name for the search state\n // so that we can always map $hierarchicalFacetName => real attributes\n // we use the first attribute name\n const [hierarchicalFacetName] = attributes;\n let sendEvent: HierarchicalMenuRenderState['sendEvent'];\n\n // Provide the same function to the `renderFn` so that way the user\n // has to only bind it once when `isFirstRendering` for instance\n let toggleShowMore = () => {};\n function cachedToggleShowMore() {\n toggleShowMore();\n }\n\n let _refine: HierarchicalMenuRenderState['refine'] | undefined;\n\n let isShowingMore = false;\n\n function createToggleShowMore(\n renderOptions: RenderOptions,\n widget: ThisWidget\n ) {\n return () => {\n isShowingMore = !isShowingMore;\n widget.render!(renderOptions);\n };\n }\n\n function getLimit() {\n return isShowingMore ? showMoreLimit : limit;\n }\n\n function _prepareFacetValues(\n facetValues: SearchResults.HierarchicalFacet[]\n ): HierarchicalMenuItem[] {\n return facetValues\n .slice(0, getLimit())\n .map(({ name: label, path: value, data, ...subValue }) => {\n const item: HierarchicalMenuItem = {\n ...subValue,\n label,\n value,\n data: null,\n };\n if (Array.isArray(data)) {\n item.data = _prepareFacetValues(data);\n }\n return item;\n });\n }\n\n return {\n $$type: 'ais.hierarchicalMenu',\n\n init(initOptions) {\n const { instantSearchInstance } = initOptions;\n\n renderFn(\n {\n ...this.getWidgetRenderState(initOptions),\n instantSearchInstance,\n },\n true\n );\n },\n\n render(renderOptions) {\n const { instantSearchInstance } = renderOptions;\n\n toggleShowMore = createToggleShowMore(renderOptions, this);\n\n renderFn(\n {\n ...this.getWidgetRenderState(renderOptions),\n instantSearchInstance,\n },\n false\n );\n },\n\n dispose({ state }) {\n unmountFn();\n\n return state\n .removeHierarchicalFacet(hierarchicalFacetName)\n .setQueryParameter('maxValuesPerFacet', undefined);\n },\n\n getRenderState(renderState, renderOptions) {\n return {\n ...renderState,\n hierarchicalMenu: {\n ...renderState.hierarchicalMenu,\n [hierarchicalFacetName]: this.getWidgetRenderState(renderOptions),\n },\n };\n },\n\n getWidgetRenderState({\n results,\n state,\n createURL,\n instantSearchInstance,\n helper,\n }) {\n let items: HierarchicalMenuRenderState['items'] = [];\n let canToggleShowMore = false;\n\n // Bind createURL to this specific attribute\n function _createURL(facetValue: string) {\n return createURL(\n state\n .resetPage()\n .toggleFacetRefinement(hierarchicalFacetName, facetValue)\n );\n }\n\n if (!sendEvent) {\n sendEvent = createSendEventForFacet({\n instantSearchInstance,\n helper,\n attribute: hierarchicalFacetName,\n widgetType: this.$$type,\n });\n }\n\n if (!_refine) {\n _refine = function (facetValue) {\n sendEvent('click', facetValue);\n helper\n .toggleFacetRefinement(hierarchicalFacetName, facetValue)\n .search();\n };\n }\n\n if (results) {\n const facetValues = results.getFacetValues(hierarchicalFacetName, {\n sortBy,\n facetOrdering: sortBy === DEFAULT_SORT,\n });\n const facetItems =\n facetValues && !Array.isArray(facetValues) && facetValues.data\n ? facetValues.data\n : [];\n\n // If the limit is the max number of facet retrieved it is impossible to know\n // if the facets are exhaustive. The only moment we are sure it is exhaustive\n // is when it is strictly under the number requested unless we know that another\n // widget has requested more values (maxValuesPerFacet > getLimit()).\n // Because this is used for making the search of facets unable or not, it is important\n // to be conservative here.\n const hasExhaustiveItems =\n (state.maxValuesPerFacet || 0) > getLimit()\n ? facetItems.length <= getLimit()\n : facetItems.length < getLimit();\n\n canToggleShowMore =\n showMore && (isShowingMore || !hasExhaustiveItems);\n\n items = transformItems(_prepareFacetValues(facetItems));\n }\n\n return {\n items,\n refine: _refine,\n canRefine: items.length > 0,\n createURL: _createURL,\n sendEvent,\n widgetParams,\n isShowingMore,\n toggleShowMore: cachedToggleShowMore,\n canToggleShowMore,\n };\n },\n\n getWidgetUiState(uiState, { searchParameters }) {\n const path = searchParameters.getHierarchicalFacetBreadcrumb(\n hierarchicalFacetName\n );\n\n if (!path.length) {\n return uiState;\n }\n\n return {\n ...uiState,\n hierarchicalMenu: {\n ...uiState.hierarchicalMenu,\n [hierarchicalFacetName]: path,\n },\n };\n },\n\n getWidgetSearchParameters(searchParameters, { uiState }) {\n const values =\n uiState.hierarchicalMenu &&\n uiState.hierarchicalMenu[hierarchicalFacetName];\n\n if (searchParameters.isHierarchicalFacet(hierarchicalFacetName)) {\n const facet = searchParameters.getHierarchicalFacetByName(\n hierarchicalFacetName\n );\n\n warning(\n isEqual(facet.attributes, attributes) &&\n facet.separator === separator &&\n facet.rootPath === rootPath,\n 'Using Breadcrumb and HierarchicalMenu on the same facet with different options overrides the configuration of the HierarchicalMenu.'\n );\n }\n\n const withFacetConfiguration = searchParameters\n .removeHierarchicalFacet(hierarchicalFacetName)\n .addHierarchicalFacet({\n name: hierarchicalFacetName,\n attributes,\n separator,\n rootPath,\n showParentLevel,\n });\n\n const currentMaxValuesPerFacet =\n withFacetConfiguration.maxValuesPerFacet || 0;\n\n const nextMaxValuesPerFacet = Math.max(\n currentMaxValuesPerFacet,\n showMore ? showMoreLimit : limit\n );\n\n const withMaxValuesPerFacet =\n withFacetConfiguration.setQueryParameter(\n 'maxValuesPerFacet',\n nextMaxValuesPerFacet\n );\n\n if (!values) {\n return withMaxValuesPerFacet.setQueryParameters({\n hierarchicalFacetsRefinements: {\n ...withMaxValuesPerFacet.hierarchicalFacetsRefinements,\n [hierarchicalFacetName]: [],\n },\n });\n }\n\n return withMaxValuesPerFacet.addHierarchicalFacetRefinement(\n hierarchicalFacetName,\n values.join(separator)\n );\n },\n };\n };\n };\n\nexport default connectHierarchicalMenu;\n","import type { SendEventForHits, BindEventForHits } from '../../lib/utils';\nimport {\n escapeHits,\n TAG_PLACEHOLDER,\n checkRendering,\n createDocumentationMessageGenerator,\n addAbsolutePosition,\n addQueryID,\n createSendEventForHits,\n createBindEventForHits,\n noop,\n} from '../../lib/utils';\nimport type {\n TransformItems,\n Connector,\n Hits,\n Hit,\n WidgetRenderState,\n} from '../../types';\nimport type { SearchResults } from 'algoliasearch-helper';\n\nconst withUsage = createDocumentationMessageGenerator({\n name: 'hits',\n connector: true,\n});\n\nexport type HitsRenderState = {\n /**\n * The matched hits from Algolia API.\n */\n hits: Hits;\n\n /**\n * The response from the Algolia API.\n */\n results?: SearchResults<Hit>;\n\n /**\n * Sends an event to the Insights middleware.\n */\n sendEvent: SendEventForHits;\n\n /**\n * Returns a string for the `data-insights-event` attribute for the Insights middleware\n */\n bindEvent: BindEventForHits;\n};\n\nexport type HitsConnectorParams = {\n /**\n * Whether to escape HTML tags from hits string values.\n *\n * @default true\n */\n escapeHTML?: boolean;\n\n /**\n * Function to transform the items passed to the templates.\n */\n transformItems?: TransformItems<Hit>;\n};\n\nexport type HitsWidgetDescription = {\n $$type: 'ais.hits';\n renderState: HitsRenderState;\n indexRenderState: {\n hits: WidgetRenderState<HitsRenderState, HitsConnectorParams>;\n };\n};\n\nexport type HitsConnector = Connector<\n HitsWidgetDescription,\n HitsConnectorParams\n>;\n\nconst connectHits: HitsConnector = function connectHits(\n renderFn,\n unmountFn = noop\n) {\n checkRendering(renderFn, withUsage());\n\n return (widgetParams) => {\n const {\n escapeHTML = true,\n transformItems = ((items) => items) as TransformItems<Hit>,\n } = widgetParams || {};\n let sendEvent: SendEventForHits;\n let bindEvent: BindEventForHits;\n\n return {\n $$type: 'ais.hits',\n\n init(initOptions) {\n renderFn(\n {\n ...this.getWidgetRenderState(initOptions),\n instantSearchInstance: initOptions.instantSearchInstance,\n },\n true\n );\n },\n\n render(renderOptions) {\n const renderState = this.getWidgetRenderState(renderOptions);\n renderState.sendEvent('view', renderState.hits);\n\n renderFn(\n {\n ...renderState,\n instantSearchInstance: renderOptions.instantSearchInstance,\n },\n false\n );\n },\n\n getRenderState(renderState, renderOptions) {\n return {\n ...renderState,\n hits: this.getWidgetRenderState(renderOptions),\n };\n },\n\n getWidgetRenderState({ results, helper, instantSearchInstance }) {\n if (!sendEvent) {\n sendEvent = createSendEventForHits({\n instantSearchInstance,\n index: helper.getIndex(),\n widgetType: this.$$type,\n });\n }\n\n if (!bindEvent) {\n bindEvent = createBindEventForHits({\n index: helper.getIndex(),\n widgetType: this.$$type,\n });\n }\n\n if (!results) {\n return {\n hits: [],\n results: undefined,\n sendEvent,\n bindEvent,\n widgetParams,\n };\n }\n\n if (escapeHTML && results.hits.length > 0) {\n results.hits = escapeHits(results.hits);\n }\n\n const hitsWithAbsolutePosition = addAbsolutePosition(\n results.hits,\n results.page,\n results.hitsPerPage\n );\n\n const hitsWithAbsolutePositionAndQueryID = addQueryID(\n hitsWithAbsolutePosition,\n results.queryID\n );\n\n const transformedHits = transformItems(\n hitsWithAbsolutePositionAndQueryID\n );\n\n return {\n hits: transformedHits,\n results,\n sendEvent,\n bindEvent,\n widgetParams,\n };\n },\n\n dispose({ state }) {\n unmountFn();\n\n if (!escapeHTML) {\n return state;\n }\n\n return state.setQueryParameters(\n Object.keys(TAG_PLACEHOLDER).reduce(\n (acc, key) => ({\n ...acc,\n [key]: undefined,\n }),\n {}\n )\n );\n },\n\n getWidgetSearchParameters(state) {\n if (!escapeHTML) {\n return state;\n }\n\n return state.setQueryParameters(TAG_PLACEHOLDER);\n },\n };\n };\n};\n\nexport default connectHits;\n","import type { SearchResults } from 'algoliasearch-helper';\nimport {\n uniq,\n find,\n createDocumentationMessageGenerator,\n warning,\n} from '../utils';\nimport type {\n Hits,\n InsightsClient,\n InsightsClientMethod,\n InsightsClientPayload,\n Connector,\n} from '../../types';\n\nconst getSelectedHits = (hits: Hits, selectedObjectIDs: string[]): Hits => {\n return selectedObjectIDs.map((objectID) => {\n const hit = find(hits, (h) => h.objectID === objectID);\n if (typeof hit === 'undefined') {\n throw new Error(\n `Could not find objectID \"${objectID}\" passed to \\`clickedObjectIDsAfterSearch\\` in the returned hits. This is necessary to infer the absolute position and the query ID.`\n );\n }\n return hit;\n });\n};\n\nconst getQueryID = (selectedHits: Hits): string => {\n const queryIDs = uniq(selectedHits.map((hit) => hit.__queryID));\n if (queryIDs.length > 1) {\n throw new Error(\n 'Insights currently allows a single `queryID`. The `objectIDs` provided map to multiple `queryID`s.'\n );\n }\n const queryID = queryIDs[0];\n if (typeof queryID !== 'string') {\n throw new Error(\n `Could not infer \\`queryID\\`. Ensure InstantSearch \\`clickAnalytics: true\\` was added with the Configure widget.\n\nSee: https://alg.li/lNiZZ7`\n );\n }\n return queryID;\n};\n\nconst getPositions = (selectedHits: Hits): number[] =>\n selectedHits.map((hit) => hit.__position);\n\nexport const inferPayload = ({\n method,\n results,\n hits,\n objectIDs,\n}: {\n method: InsightsClientMethod;\n results: SearchResults;\n hits: Hits;\n objectIDs: string[];\n}): Omit<InsightsClientPayload, 'eventName'> => {\n const { index } = results;\n const selectedHits = getSelectedHits(hits, objectIDs);\n const queryID = getQueryID(selectedHits);\n\n switch (method) {\n case 'clickedObjectIDsAfterSearch': {\n const positions = getPositions(selectedHits);\n return { index, queryID, objectIDs, positions };\n }\n\n case 'convertedObjectIDsAfterSearch':\n return { index, queryID, objectIDs };\n\n default:\n throw new Error(`Unsupported method passed to insights: \"${method}\".`);\n }\n};\n\nconst wrapInsightsClient =\n (\n aa: InsightsClient | null,\n results: SearchResults,\n hits: Hits\n ): InsightsClient =>\n (method, ...payloads) => {\n const [payload] = payloads;\n warning(\n false,\n `\\`insights\\` function has been deprecated. It is still supported in 4.x releases, but not further. It is replaced by the \\`insights\\` middleware.\n\nFor more information, visit https://www.algolia.com/doc/guides/getting-insights-and-analytics/search-analytics/click-through-and-conversions/how-to/send-click-and-conversion-events-with-instantsearch/js/`\n );\n if (!aa) {\n const withInstantSearchUsage = createDocumentationMessageGenerator({\n name: 'instantsearch',\n });\n throw new Error(\n withInstantSearchUsage(\n 'The `insightsClient` option has not been provided to `instantsearch`.'\n )\n );\n }\n if (!Array.isArray(payload.objectIDs)) {\n throw new TypeError('Expected `objectIDs` to be an array.');\n }\n const inferredPayload = inferPayload({\n method,\n results,\n hits,\n objectIDs: payload.objectIDs,\n });\n aa(method, { ...inferredPayload, ...payload });\n };\n\n/**\n * @deprecated This function will be still supported in 4.x releases, but not further. It is replaced by the `insights` middleware. For more information, visit https://www.algolia.com/doc/guides/getting-insights-and-analytics/search-analytics/click-through-and-conversions/how-to/send-click-and-conversion-events-with-instantsearch/js/\n * It passes `insights` to `HitsWithInsightsListener` and `InfiniteHitsWithInsightsListener`.\n */\nexport default function withInsights<TConnector extends Connector<any, any>>(\n connector: TConnector\n): TConnector {\n return ((renderFn, unmountFn) =>\n connector((renderOptions, isFirstRender) => {\n const { results, hits, instantSearchInstance } = renderOptions;\n if (results && hits && instantSearchInstance) {\n const insights = wrapInsightsClient(\n instantSearchInstance.insightsClient,\n results,\n hits\n );\n return renderFn({ ...renderOptions, insights }, isFirstRender);\n }\n return renderFn(renderOptions, isFirstRender);\n }, unmountFn)) as TConnector;\n}\n","var n,l,u,t,i,r,o,f={},e=[],c=/acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|^--/i;function s(n,l){for(var u in l)n[u]=l[u];return n}function a(n){var l=n.parentNode;l&&l.removeChild(n)}function h(n,l,u){var t,i,r,o,f=arguments;if(l=s({},l),arguments.length>3)for(u=[u],t=3;t<arguments.length;t++)u.push(f[t]);if(null!=u&&(l.children=u),null!=n&&null!=n.defaultProps)for(i in n.defaultProps)void 0===l[i]&&(l[i]=n.defaultProps[i]);return o=l.key,null!=(r=l.ref)&&delete l.ref,null!=o&&delete l.key,v(n,l,o,r)}function v(l,u,t,i){var r={type:l,props:u,key:t,ref:i,__k:null,__p:null,__b:0,__e:null,l:null,__c:null,constructor:void 0};return n.vnode&&n.vnode(r),r}function p(){return{}}function d(n){return n.children}function y(n){if(null==n||\"boolean\"==typeof n)return null;if(\"string\"==typeof n||\"number\"==typeof n)return v(null,n,null,null);if(null!=n.__e||null!=n.__c){var l=v(n.type,n.props,n.key,null);return l.__e=n.__e,l}return n}function m(n,l){this.props=n,this.context=l}function w(n,l){if(null==l)return n.__p?w(n.__p,n.__p.__k.indexOf(n)+1):null;for(var u;l<n.__k.length;l++)if(null!=(u=n.__k[l])&&null!=u.__e)return u.__e;return\"function\"==typeof n.type?w(n):null}function g(n){var l,u;if(null!=(n=n.__p)&&null!=n.__c){for(n.__e=n.__c.base=null,l=0;l<n.__k.length;l++)if(null!=(u=n.__k[l])&&null!=u.__e){n.__e=n.__c.base=u.__e;break}return g(n)}}function k(l){(!l.__d&&(l.__d=!0)&&1===u.push(l)||i!==n.debounceRendering)&&(i=n.debounceRendering,(n.debounceRendering||t)(_))}function _(){var n,l,t,i,r,o,f,e;for(u.sort(function(n,l){return l.__v.__b-n.__v.__b});n=u.pop();)n.__d&&(t=void 0,i=void 0,o=(r=(l=n).__v).__e,f=l.__P,e=l.u,l.u=!1,f&&(t=[],i=$(f,r,s({},r),l.__n,void 0!==f.ownerSVGElement,null,t,e,null==o?w(r):o),j(t,r),i!=o&&g(r)))}function b(n,l,u,t,i,r,o,c,s){var h,v,p,d,y,m,g,k=u&&u.__k||e,_=k.length;if(c==f&&(c=null!=r?r[0]:_?w(u,0):null),h=0,l.__k=x(l.__k,function(u){if(null!=u){if(u.__p=l,u.__b=l.__b+1,null===(p=k[h])||p&&u.key==p.key&&u.type===p.type)k[h]=void 0;else for(v=0;v<_;v++){if((p=k[v])&&u.key==p.key&&u.type===p.type){k[v]=void 0;break}p=null}if(d=$(n,u,p=p||f,t,i,r,o,null,c,s),(v=u.ref)&&p.ref!=v&&(g||(g=[])).push(v,u.__c||d,u),null!=d){if(null==m&&(m=d),null!=u.l)d=u.l,u.l=null;else if(r==p||d!=c||null==d.parentNode){n:if(null==c||c.parentNode!==n)n.appendChild(d);else{for(y=c,v=0;(y=y.nextSibling)&&v<_;v+=2)if(y==d)break n;n.insertBefore(d,c)}\"option\"==l.type&&(n.value=\"\")}c=d.nextSibling,\"function\"==typeof l.type&&(l.l=d)}}return h++,u}),l.__e=m,null!=r&&\"function\"!=typeof l.type)for(h=r.length;h--;)null!=r[h]&&a(r[h]);for(h=_;h--;)null!=k[h]&&D(k[h],k[h]);if(g)for(h=0;h<g.length;h++)A(g[h],g[++h],g[++h])}function x(n,l,u){if(null==u&&(u=[]),null==n||\"boolean\"==typeof n)l&&u.push(l(null));else if(Array.isArray(n))for(var t=0;t<n.length;t++)x(n[t],l,u);else u.push(l?l(y(n)):n);return u}function C(n,l,u,t,i){var r;for(r in u)r in l||N(n,r,null,u[r],t);for(r in l)i&&\"function\"!=typeof l[r]||\"value\"===r||\"checked\"===r||u[r]===l[r]||N(n,r,l[r],u[r],t)}function P(n,l,u){\"-\"===l[0]?n.setProperty(l,u):n[l]=\"number\"==typeof u&&!1===c.test(l)?u+\"px\":null==u?\"\":u}function N(n,l,u,t,i){var r,o,f,e,c;if(\"key\"===(l=i?\"className\"===l?\"class\":l:\"class\"===l?\"className\":l)||\"children\"===l);else if(\"style\"===l)if(r=n.style,\"string\"==typeof u)r.cssText=u;else{if(\"string\"==typeof t&&(r.cssText=\"\",t=null),t)for(o in t)u&&o in u||P(r,o,\"\");if(u)for(f in u)t&&u[f]===t[f]||P(r,f,u[f])}else\"o\"===l[0]&&\"n\"===l[1]?(e=l!==(l=l.replace(/Capture$/,\"\")),c=l.toLowerCase(),l=(c in n?c:l).slice(2),u?(t||n.addEventListener(l,T,e),(n.t||(n.t={}))[l]=u):n.removeEventListener(l,T,e)):\"list\"!==l&&\"tagName\"!==l&&\"form\"!==l&&!i&&l in n?n[l]=null==u?\"\":u:\"function\"!=typeof u&&\"dangerouslySetInnerHTML\"!==l&&(l!==(l=l.replace(/^xlink:?/,\"\"))?null==u||!1===u?n.removeAttributeNS(\"http://www.w3.org/1999/xlink\",l.toLowerCase()):n.setAttributeNS(\"http://www.w3.org/1999/xlink\",l.toLowerCase(),u):null==u||!1===u?n.removeAttribute(l):n.setAttribute(l,u))}function T(l){return this.t[l.type](n.event?n.event(l):l)}function $(l,u,t,i,r,o,f,e,c,a){var h,v,p,y,w,g,k,_,C,P,N=u.type;if(void 0!==u.constructor)return null;(h=n.__b)&&h(u);try{n:if(\"function\"==typeof N){if(_=u.props,C=(h=N.contextType)&&i[h.__c],P=h?C?C.props.value:h.__p:i,t.__c?k=(v=u.__c=t.__c).__p=v.__E:(\"prototype\"in N&&N.prototype.render?u.__c=v=new N(_,P):(u.__c=v=new m(_,P),v.constructor=N,v.render=H),C&&C.sub(v),v.props=_,v.state||(v.state={}),v.context=P,v.__n=i,p=v.__d=!0,v.__h=[]),null==v.__s&&(v.__s=v.state),null!=N.getDerivedStateFromProps&&s(v.__s==v.state?v.__s=s({},v.__s):v.__s,N.getDerivedStateFromProps(_,v.__s)),p)null==N.getDerivedStateFromProps&&null!=v.componentWillMount&&v.componentWillMount(),null!=v.componentDidMount&&f.push(v);else{if(null==N.getDerivedStateFromProps&&null==e&&null!=v.componentWillReceiveProps&&v.componentWillReceiveProps(_,P),!e&&null!=v.shouldComponentUpdate&&!1===v.shouldComponentUpdate(_,v.__s,P)){for(v.props=_,v.state=v.__s,v.__d=!1,v.__v=u,u.__e=null!=c?c!==t.__e?c:t.__e:null,u.__k=t.__k,h=0;h<u.__k.length;h++)u.__k[h]&&(u.__k[h].__p=u);break n}null!=v.componentWillUpdate&&v.componentWillUpdate(_,v.__s,P)}for(y=v.props,w=v.state,v.context=P,v.props=_,v.state=v.__s,(h=n.__r)&&h(u),v.__d=!1,v.__v=u,v.__P=l,h=v.render(v.props,v.state,v.context),u.__k=x(null!=h&&h.type==d&&null==h.key?h.props.children:h),null!=v.getChildContext&&(i=s(s({},i),v.getChildContext())),p||null==v.getSnapshotBeforeUpdate||(g=v.getSnapshotBeforeUpdate(y,w)),b(l,u,t,i,r,o,f,c,a),v.base=u.__e;h=v.__h.pop();)v.__s&&(v.state=v.__s),h.call(v);p||null==y||null==v.componentDidUpdate||v.componentDidUpdate(y,w,g),k&&(v.__E=v.__p=null)}else u.__e=z(t.__e,u,t,i,r,o,f,a);(h=n.diffed)&&h(u)}catch(l){n.__e(l,u,t)}return u.__e}function j(l,u){for(var t;t=l.pop();)try{t.componentDidMount()}catch(l){n.__e(l,t.__v)}n.__c&&n.__c(u)}function z(n,l,u,t,i,r,o,c){var s,a,h,v,p=u.props,d=l.props;if(i=\"svg\"===l.type||i,null==n&&null!=r)for(s=0;s<r.length;s++)if(null!=(a=r[s])&&(null===l.type?3===a.nodeType:a.localName===l.type)){n=a,r[s]=null;break}if(null==n){if(null===l.type)return document.createTextNode(d);n=i?document.createElementNS(\"http://www.w3.org/2000/svg\",l.type):document.createElement(l.type),r=null}return null===l.type?p!==d&&(null!=r&&(r[r.indexOf(n)]=null),n.data=d):l!==u&&(null!=r&&(r=e.slice.call(n.childNodes)),h=(p=u.props||f).dangerouslySetInnerHTML,v=d.dangerouslySetInnerHTML,c||(v||h)&&(v&&h&&v.__html==h.__html||(n.innerHTML=v&&v.__html||\"\")),C(n,d,p,i,c),l.__k=l.props.children,v||b(n,l,u,t,\"foreignObject\"!==l.type&&i,r,o,f,c),c||(\"value\"in d&&void 0!==d.value&&d.value!==n.value&&(n.value=null==d.value?\"\":d.value),\"checked\"in d&&void 0!==d.checked&&d.checked!==n.checked&&(n.checked=d.checked))),n}function A(l,u,t){try{\"function\"==typeof l?l(u):l.current=u}catch(l){n.__e(l,t)}}function D(l,u,t){var i,r,o;if(n.unmount&&n.unmount(l),(i=l.ref)&&A(i,null,u),t||\"function\"==typeof l.type||(t=null!=(r=l.__e)),l.__e=l.l=null,null!=(i=l.__c)){if(i.componentWillUnmount)try{i.componentWillUnmount()}catch(l){n.__e(l,u)}i.base=i.__P=null}if(i=l.__k)for(o=0;o<i.length;o++)i[o]&&D(i[o],u,t);null!=r&&a(r)}function H(n,l,u){return this.constructor(n,u)}function I(l,u,t){var i,o,c;n.__p&&n.__p(l,u),o=(i=t===r)?null:t&&t.__k||u.__k,l=h(d,null,[l]),c=[],$(u,i?u.__k=l:(t||u).__k=l,o||f,f,void 0!==u.ownerSVGElement,t&&!i?[t]:o?null:e.slice.call(u.childNodes),c,!1,t||f,i),j(c,l)}function L(n,l){I(n,l,r)}function M(n,l){return l=s(s({},n.props),l),arguments.length>2&&(l.children=e.slice.call(arguments,2)),v(n.type,l,l.key||n.key,l.ref||n.ref)}function O(n){var l={},u={__c:\"__cC\"+o++,__p:n,Consumer:function(n,l){return n.children(l)},Provider:function(n){var t,i=this;return this.getChildContext||(t=[],this.getChildContext=function(){return l[u.__c]=i,l},this.shouldComponentUpdate=function(i){n.value!==i.value&&(l[u.__c].props.value=i.value,t.some(function(n){n.__P&&(n.context=i.value,k(n))}))},this.sub=function(n){t.push(n);var l=n.componentWillUnmount;n.componentWillUnmount=function(){t.splice(t.indexOf(n),1),l&&l.call(n)}}),n.children}};return u.Consumer.contextType=u,u}n={},l=function(n){return null!=n&&void 0===n.constructor},m.prototype.setState=function(n,l){var u=this.__s!==this.state&&this.__s||(this.__s=s({},this.state));(\"function\"!=typeof n||(n=n(u,this.props)))&&s(u,n),null!=n&&this.__v&&(this.u=!1,l&&this.__h.push(l),k(this))},m.prototype.forceUpdate=function(n){this.__v&&(n&&this.__h.push(n),this.u=!0,k(this))},m.prototype.render=d,u=[],t=\"function\"==typeof Promise?Promise.prototype.then.bind(Promise.resolve()):setTimeout,i=n.debounceRendering,n.__e=function(n,l,u){for(var t;l=l.__p;)if((t=l.__c)&&!t.__p)try{if(t.constructor&&null!=t.constructor.getDerivedStateFromError)t.setState(t.constructor.getDerivedStateFromError(n));else{if(null==t.componentDidCatch)continue;t.componentDidCatch(n)}return k(t.__E=t)}catch(l){n=l}throw n},r=f,o=0;export{I as render,L as hydrate,h as createElement,h,d as Fragment,p as createRef,l as isValidElement,m as Component,M as cloneElement,O as createContext,x as toChildArray,D as _unmount,n as options};\n//# sourceMappingURL=preact.module.js.map\n","/** @jsx h */\n\nimport { h } from 'preact';\nimport { deserializePayload } from '../utils';\nimport { readDataAttributes, hasDataAttributes } from '../../helpers/insights';\nimport type { InsightsClient } from '../../types';\nimport type { InsightsEvent } from '../../middlewares/createInsightsMiddleware';\n\ntype WithInsightsListenerProps = {\n [key: string]: unknown;\n insights: InsightsClient;\n sendEvent?: (event: InsightsEvent) => void;\n};\n\nconst findInsightsTarget = (\n startElement: HTMLElement | null,\n endElement: HTMLElement | null,\n validator: (element: HTMLElement) => boolean\n): HTMLElement | null => {\n let element: HTMLElement | null = startElement;\n while (element && !validator(element)) {\n if (element === endElement) {\n return null;\n }\n element = element.parentElement;\n }\n return element;\n};\n\nconst parseInsightsEvent = (element: HTMLElement): InsightsEvent[] => {\n const serializedPayload = element.getAttribute('data-insights-event');\n\n if (typeof serializedPayload !== 'string') {\n throw new Error(\n 'The insights middleware expects `data-insights-event` to be a base64-encoded JSON string.'\n );\n }\n\n try {\n return deserializePayload(serializedPayload);\n } catch (error) {\n throw new Error(\n 'The insights middleware was unable to parse `data-insights-event`.'\n );\n }\n};\n\nconst insightsListener = (BaseComponent: any) => {\n function WithInsightsListener(props: WithInsightsListenerProps) {\n const handleClick = (event: MouseEvent): void => {\n if (props.sendEvent) {\n // new way with insights middleware\n const targetWithEvent = findInsightsTarget(\n event.target as HTMLElement | null,\n event.currentTarget as HTMLElement | null,\n (element) => element.hasAttribute('data-insights-event')\n );\n if (targetWithEvent) {\n const payload = parseInsightsEvent(targetWithEvent);\n\n payload.forEach((single) => props.sendEvent!(single));\n }\n }\n\n // old way, e.g. instantsearch.insights(\"clickedObjectIDsAfterSearch\", { .. })\n const insightsTarget = findInsightsTarget(\n event.target as HTMLElement | null,\n event.currentTarget as HTMLElement | null,\n (element) => hasDataAttributes(element)\n );\n if (insightsTarget) {\n const { method, payload } = readDataAttributes(insightsTarget);\n props.insights(method, payload);\n }\n };\n\n return (\n <div onClick={handleClick}>\n <BaseComponent {...props} />\n </div>\n );\n }\n\n return WithInsightsListener;\n};\n\nexport default insightsListener;\n","import {\n checkRendering,\n warning,\n createDocumentationMessageGenerator,\n noop,\n} from '../../lib/utils';\n\nimport type {\n AlgoliaSearchHelper,\n SearchParameters,\n} from 'algoliasearch-helper';\nimport type {\n Connector,\n TransformItems,\n CreateURL,\n InitOptions,\n RenderOptions,\n WidgetRenderState,\n} from '../../types';\n\nconst withUsage = createDocumentationMessageGenerator({\n name: 'hits-per-page',\n connector: true,\n});\n\nexport type HitsPerPageRenderStateItem = {\n /**\n * Label to display in the option.\n */\n label: string;\n\n /**\n * Number of hits to display per page.\n */\n value: number;\n\n /**\n * Indicates if it's the current refined value.\n */\n isRefined: boolean;\n};\n\nexport type HitsPerPageConnectorParamsItem = {\n /**\n * Label to display in the option.\n */\n label: string;\n\n /**\n * Number of hits to display per page.\n */\n value: number;\n\n /**\n * The default hits per page on first search.\n *\n * @default false\n */\n default?: boolean;\n};\n\nexport type HitsPerPageConnectorParams = {\n /**\n * Array of objects defining the different values and labels.\n */\n items: HitsPerPageConnectorParamsItem[];\n\n /**\n * Function to transform the items passed to the templates.\n */\n transformItems?: TransformItems<HitsPerPageRenderStateItem>;\n};\n\nexport type HitsPerPageRenderState = {\n /**\n * Array of objects defining the different values and labels.\n */\n items: HitsPerPageRenderStateItem[];\n\n /**\n * Creates the URL for a single item name in the list.\n *\n * @internal\n */\n createURL: CreateURL<HitsPerPageConnectorParamsItem['value']>;\n\n /**\n * Sets the number of hits per page and triggers a search.\n */\n refine: (value: number) => void;\n\n /**\n * Indicates whether or not the search has results.\n */\n hasNoResults: boolean;\n};\n\nexport type HitsPerPageWidgetDescription = {\n $$type: 'ais.hitsPerPage';\n renderState: HitsPerPageRenderState;\n indexRenderState: {\n hitsPerPage: WidgetRenderState<\n HitsPerPageRenderState,\n HitsPerPageConnectorParams\n >;\n };\n indexUiState: {\n hitsPerPage: number;\n };\n};\n\nexport type HitsPerPageConnector = Connector<\n HitsPerPageWidgetDescription,\n HitsPerPageConnectorParams\n>;\n\nconst connectHitsPerPage: HitsPerPageConnector = function connectHitsPerPage(\n renderFn,\n unmountFn = noop\n) {\n checkRendering(renderFn, withUsage());\n\n return (widgetParams) => {\n const {\n items: userItems,\n transformItems = ((items) =>\n items) as TransformItems<HitsPerPageRenderStateItem>,\n } = widgetParams || {};\n\n if (!Array.isArray(userItems)) {\n throw new Error(\n withUsage('The `items` option expects an array of objects.')\n );\n }\n\n let items = userItems;\n\n const defaultItems = items.filter((item) => item.default === true);\n\n if (defaultItems.length === 0) {\n throw new Error(\n withUsage(`A default value must be specified in \\`items\\`.`)\n );\n }\n\n if (defaultItems.length > 1) {\n throw new Error(\n withUsage('More than one default value is specified in `items`.')\n );\n }\n\n const defaultItem = defaultItems[0];\n\n const normalizeItems = ({ hitsPerPage }: SearchParameters) => {\n return items.map((item) => ({\n ...item,\n isRefined: Number(item.value) === Number(hitsPerPage),\n }));\n };\n\n type ConnectorState = {\n getRefine: (\n helper: AlgoliaSearchHelper\n ) => (value: HitsPerPageConnectorParamsItem['value']) => any;\n createURLFactory: (props: {\n state: SearchParameters;\n createURL: (InitOptions | RenderOptions)['createURL'];\n }) => HitsPerPageRenderState['createURL'];\n };\n\n const connectorState: ConnectorState = {\n getRefine: (helper) => (value) => {\n return !value && value !== 0\n ? helper.setQueryParameter('hitsPerPage', undefined).search()\n : helper.setQueryParameter('hitsPerPage', value).search();\n },\n createURLFactory:\n ({ state, createURL }) =>\n (value) =>\n createURL(\n state\n .resetPage()\n .setQueryParameter(\n 'hitsPerPage',\n !value && value !== 0 ? undefined : value\n )\n ),\n };\n\n return {\n $$type: 'ais.hitsPerPage',\n\n init(initOptions) {\n const { state, instantSearchInstance } = initOptions;\n\n const isCurrentInOptions = items.some(\n (item) => Number(state.hitsPerPage) === Number(item.value)\n );\n\n if (!isCurrentInOptions) {\n warning(\n state.hitsPerPage !== undefined,\n `\n\\`hitsPerPage\\` is not defined.\nThe option \\`hitsPerPage\\` needs to be set using the \\`configure\\` widget.\n\nLearn more: https://www.algolia.com/doc/api-reference/widgets/hits-per-page/js/\n `\n );\n\n warning(\n false,\n `\nThe \\`items\\` option of \\`hitsPerPage\\` does not contain the \"hits per page\" value coming from the state: ${state.hitsPerPage}.\n\nYou may want to add another entry to the \\`items\\` option with this value.`\n );\n\n items = [\n // The helper will convert the empty string to `undefined`.\n { value: '' as unknown as number, label: '' },\n ...items,\n ];\n }\n\n renderFn(\n {\n ...this.getWidgetRenderState(initOptions),\n instantSearchInstance,\n },\n true\n );\n },\n\n render(initOptions) {\n const { instantSearchInstance } = initOptions;\n\n renderFn(\n {\n ...this.getWidgetRenderState(initOptions),\n instantSearchInstance,\n },\n false\n );\n },\n\n dispose({ state }) {\n unmountFn();\n\n return state.setQueryParameter('hitsPerPage', undefined);\n },\n\n getRenderState(renderState, renderOptions) {\n return {\n ...renderState,\n hitsPerPage: this.getWidgetRenderState(renderOptions),\n };\n },\n\n getWidgetRenderState({ state, results, createURL, helper }) {\n return {\n items: transformItems(normalizeItems(state)),\n refine: connectorState.getRefine(helper),\n createURL: connectorState.createURLFactory({ state, createURL }),\n hasNoResults: results ? results.nbHits === 0 : true,\n widgetParams,\n };\n },\n\n getWidgetUiState(uiState, { searchParameters }) {\n const hitsPerPage = searchParameters.hitsPerPage;\n\n if (hitsPerPage === undefined || hitsPerPage === defaultItem.value) {\n return uiState;\n }\n\n return {\n ...uiState,\n hitsPerPage,\n };\n },\n\n getWidgetSearchParameters(searchParameters, { uiState }) {\n return searchParameters.setQueryParameters({\n hitsPerPage: uiState.hitsPerPage || defaultItem.value,\n });\n },\n };\n };\n};\n\nexport default connectHitsPerPage;\n","import { withInsights } from '../../lib/insights';\nimport type { HitsConnectorParams, HitsWidgetDescription } from './connectHits';\nimport connectHits from './connectHits';\nimport type { Connector } from '../../types';\n\n/**\n * Due to https://github.com/microsoft/web-build-tools/issues/1050, we need\n * Connector<...> imported in this file, even though it is only used implicitly.\n * This _uses_ Connector<...> so it is not accidentally removed by someone.\n */\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\ndeclare type ImportWorkaround = Connector<\n HitsWidgetDescription,\n HitsConnectorParams\n>;\n\nconst connectHitsWithInsights = withInsights(connectHits);\n\nexport default connectHitsWithInsights;\n","import type {\n AlgoliaSearchHelper as Helper,\n PlainSearchParameters,\n SearchParameters,\n SearchResults,\n} from 'algoliasearch-helper';\nimport type {\n Hits,\n Connector,\n TransformItems,\n Hit,\n WidgetRenderState,\n} from '../../types';\nimport type { SendEventForHits, BindEventForHits } from '../../lib/utils';\nimport {\n escapeHits,\n TAG_PLACEHOLDER,\n checkRendering,\n createDocumentationMessageGenerator,\n isEqual,\n addAbsolutePosition,\n addQueryID,\n noop,\n createSendEventForHits,\n createBindEventForHits,\n} from '../../lib/utils';\n\nexport type InfiniteHitsCachedHits = {\n [page: number]: Hits;\n};\n\ntype Read = ({\n state,\n}: {\n state: PlainSearchParameters;\n}) => InfiniteHitsCachedHits | null;\n\ntype Write = ({\n state,\n hits,\n}: {\n state: PlainSearchParameters;\n hits: InfiniteHitsCachedHits;\n}) => void;\n\nexport type InfiniteHitsCache = {\n read: Read;\n write: Write;\n};\n\nexport type InfiniteHitsConnectorParams = {\n /**\n * Escapes HTML entities from hits string values.\n *\n * @default `true`\n */\n escapeHTML?: boolean;\n\n /**\n * Enable the button to load previous results.\n *\n * @default `false`\n */\n showPrevious?: boolean;\n\n /**\n * Receives the items, and is called before displaying them.\n * Useful for mapping over the items to transform, and remove or reorder them.\n */\n transformItems?: TransformItems<Hit>;\n\n /**\n * Reads and writes hits from/to cache.\n * When user comes back to the search page after leaving for product page,\n * this helps restore InfiniteHits and its scroll position.\n */\n cache?: InfiniteHitsCache;\n};\n\nexport type InfiniteHitsRenderState = {\n /**\n * Loads the previous results.\n */\n showPrevious: () => void;\n\n /**\n * Loads the next page of hits.\n */\n showMore: () => void;\n\n /**\n * Indicates whether the first page of hits has been reached.\n */\n isFirstPage: boolean;\n\n /**\n * Indicates whether the last page of hits has been reached.\n */\n isLastPage: boolean;\n\n /**\n * Send event to insights middleware\n */\n sendEvent: SendEventForHits;\n\n /**\n * Returns a string of data-insights-event attribute for insights middleware\n */\n bindEvent: BindEventForHits;\n\n /**\n * Hits for the current page\n */\n currentPageHits: Hits;\n\n /**\n * Hits for current and cached pages\n */\n hits: Hits;\n\n /**\n * The response from the Algolia API.\n */\n results?: SearchResults<Hit>;\n};\n\nconst withUsage = createDocumentationMessageGenerator({\n name: 'infinite-hits',\n connector: true,\n});\n\nexport type InfiniteHitsWidgetDescription = {\n $$type: 'ais.infiniteHits';\n renderState: InfiniteHitsRenderState;\n indexRenderState: {\n infiniteHits: WidgetRenderState<\n InfiniteHitsRenderState,\n InfiniteHitsConnectorParams\n >;\n };\n indexUiState: {\n page: number;\n };\n};\n\nexport type InfiniteHitsConnector = Connector<\n InfiniteHitsWidgetDescription,\n InfiniteHitsConnectorParams\n>;\n\nfunction getStateWithoutPage(state: PlainSearchParameters) {\n const { page, ...rest } = state || {};\n return rest;\n}\n\nfunction getInMemoryCache(): InfiniteHitsCache {\n let cachedHits: InfiniteHitsCachedHits | null = null;\n let cachedState: PlainSearchParameters | null = null;\n return {\n read({ state }) {\n return isEqual(cachedState, getStateWithoutPage(state))\n ? cachedHits\n : null;\n },\n write({ state, hits }) {\n cachedState = getStateWithoutPage(state);\n cachedHits = hits;\n },\n };\n}\n\nfunction extractHitsFromCachedHits(cachedHits: InfiniteHitsCachedHits) {\n return Object.keys(cachedHits)\n .map(Number)\n .sort((a, b) => a - b)\n .reduce((acc: Hits, page) => {\n return acc.concat(cachedHits[page]);\n }, []);\n}\n\nconst connectInfiniteHits: InfiniteHitsConnector = function connectInfiniteHits(\n renderFn,\n unmountFn = noop\n) {\n checkRendering(renderFn, withUsage());\n\n return (widgetParams) => {\n const {\n escapeHTML = true,\n transformItems = ((items) => items) as TransformItems<Hit>,\n cache = getInMemoryCache(),\n } = widgetParams || {};\n let showPrevious: () => void;\n let showMore: () => void;\n let sendEvent: SendEventForHits;\n let bindEvent: BindEventForHits;\n const getFirstReceivedPage = (\n state: SearchParameters,\n cachedHits: InfiniteHitsCachedHits\n ) => {\n const { page = 0 } = state;\n const pages = Object.keys(cachedHits).map(Number);\n if (pages.length === 0) {\n return page;\n } else {\n return Math.min(page, ...pages);\n }\n };\n const getLastReceivedPage = (\n state: SearchParameters,\n cachedHits: InfiniteHitsCachedHits\n ) => {\n const { page = 0 } = state;\n const pages = Object.keys(cachedHits).map(Number);\n if (pages.length === 0) {\n return page;\n } else {\n return Math.max(page, ...pages);\n }\n };\n\n const getShowPrevious =\n (helper: Helper): (() => void) =>\n () => {\n // Using the helper's `overrideStateWithoutTriggeringChangeEvent` method\n // avoid updating the browser URL when the user displays the previous page.\n helper\n .overrideStateWithoutTriggeringChangeEvent({\n ...helper.state,\n page:\n getFirstReceivedPage(\n helper.state,\n cache.read({ state: helper.state }) || {}\n ) - 1,\n })\n .searchWithoutTriggeringOnStateChange();\n };\n\n const getShowMore =\n (helper: Helper): (() => void) =>\n () => {\n helper\n .setPage(\n getLastReceivedPage(\n helper.state,\n cache.read({ state: helper.state }) || {}\n ) + 1\n )\n .search();\n };\n\n return {\n $$type: 'ais.infiniteHits',\n\n init(initOptions) {\n renderFn(\n {\n ...this.getWidgetRenderState(initOptions),\n instantSearchInstance: initOptions.instantSearchInstance,\n },\n true\n );\n },\n\n render(renderOptions) {\n const { instantSearchInstance } = renderOptions;\n\n const widgetRenderState = this.getWidgetRenderState(renderOptions);\n\n sendEvent('view', widgetRenderState.currentPageHits);\n\n renderFn(\n {\n ...widgetRenderState,\n instantSearchInstance,\n },\n false\n );\n },\n\n getRenderState(renderState, renderOptions) {\n return {\n ...renderState,\n infiniteHits: this.getWidgetRenderState(renderOptions),\n };\n },\n\n getWidgetRenderState({ results, helper, state, instantSearchInstance }) {\n let isFirstPage: boolean;\n let currentPageHits: Hits = [];\n const cachedHits = cache.read({ state }) || {};\n\n if (!results) {\n showPrevious = getShowPrevious(helper);\n showMore = getShowMore(helper);\n sendEvent = createSendEventForHits({\n instantSearchInstance,\n index: helper.getIndex(),\n widgetType: this.$$type,\n });\n bindEvent = createBindEventForHits({\n index: helper.getIndex(),\n widgetType: this.$$type,\n });\n isFirstPage =\n state.page === undefined ||\n getFirstReceivedPage(state, cachedHits) === 0;\n } else {\n const { page = 0 } = state;\n\n if (escapeHTML && results.hits.length > 0) {\n results.hits = escapeHits(results.hits);\n }\n\n const hitsWithAbsolutePosition = addAbsolutePosition(\n results.hits,\n results.page,\n results.hitsPerPage\n );\n\n const hitsWithAbsolutePositionAndQueryID = addQueryID(\n hitsWithAbsolutePosition,\n results.queryID\n );\n\n const transformedHits = transformItems(\n hitsWithAbsolutePositionAndQueryID\n );\n\n if (cachedHits[page] === undefined) {\n cachedHits[page] = transformedHits;\n cache.write({ state, hits: cachedHits });\n }\n currentPageHits = transformedHits;\n\n isFirstPage = getFirstReceivedPage(state, cachedHits) === 0;\n }\n\n const hits = extractHitsFromCachedHits(cachedHits);\n const isLastPage = results\n ? results.nbPages <= getLastReceivedPage(state, cachedHits) + 1\n : true;\n\n return {\n hits,\n currentPageHits,\n sendEvent,\n bindEvent,\n results,\n showPrevious,\n showMore,\n isFirstPage,\n isLastPage,\n widgetParams,\n };\n },\n\n dispose({ state }) {\n unmountFn();\n\n const stateWithoutPage = state.setQueryParameter('page', undefined);\n\n if (!escapeHTML) {\n return stateWithoutPage;\n }\n\n return stateWithoutPage.setQueryParameters(\n Object.keys(TAG_PLACEHOLDER).reduce(\n (acc, key) => ({\n ...acc,\n [key]: undefined,\n }),\n {}\n )\n );\n },\n\n getWidgetUiState(uiState, { searchParameters }) {\n const page = searchParameters.page || 0;\n\n if (!page) {\n // return without adding `page` to uiState\n // because we don't want `page=1` in the URL\n return uiState;\n }\n\n return {\n ...uiState,\n // The page in the UI state is incremented by one\n // to expose the user value (not `0`).\n page: page + 1,\n };\n },\n\n getWidgetSearchParameters(searchParameters, { uiState }) {\n let widgetSearchParameters = searchParameters;\n\n if (escapeHTML) {\n widgetSearchParameters =\n searchParameters.setQueryParameters(TAG_PLACEHOLDER);\n }\n\n // The page in the search parameters is decremented by one\n // to get to the actual parameter value from the UI state.\n const page = uiState.page ? uiState.page - 1 : 0;\n\n return widgetSearchParameters.setQueryParameter('page', page);\n },\n };\n };\n};\n\nexport default connectInfiniteHits;\n","import type { SendEventForFacet } from '../../lib/utils';\nimport {\n checkRendering,\n createDocumentationMessageGenerator,\n createSendEventForFacet,\n noop,\n} from '../../lib/utils';\nimport type {\n Connector,\n CreateURL,\n RenderOptions,\n SortBy,\n TransformItems,\n Widget,\n WidgetRenderState,\n} from '../../types';\n\nconst withUsage = createDocumentationMessageGenerator({\n name: 'menu',\n connector: true,\n});\n\nconst DEFAULT_SORT = ['isRefined', 'name:asc'];\n\nexport type MenuItem = {\n /**\n * The value of the menu item.\n */\n value: string;\n /**\n * Human-readable value of the menu item.\n */\n label: string;\n /**\n * Number of results matched after refinement is applied.\n */\n count: number;\n /**\n * Indicates if the refinement is applied.\n */\n isRefined: boolean;\n};\n\nexport type MenuConnectorParams = {\n /**\n * Name of the attribute for faceting (eg. \"free_shipping\").\n */\n attribute: string;\n /**\n * How many facets values to retrieve.\n */\n limit?: number;\n /**\n * Whether to display a button that expands the number of items.\n */\n showMore?: boolean;\n /**\n * How many facets values to retrieve when `toggleShowMore` is called, this value is meant to be greater than `limit` option.\n */\n showMoreLimit?: number;\n /**\n * How to sort refinements. Possible values: `count|isRefined|name:asc|name:desc`.\n *\n * You can also use a sort function that behaves like the standard Javascript [compareFunction](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#Syntax).\n *\n * If a facetOrdering is set in the index settings, it is used when sortBy isn't passed\n */\n sortBy?: SortBy<MenuItem>;\n /**\n * Function to transform the items passed to the templates.\n */\n transformItems?: TransformItems<MenuItem>;\n};\n\nexport type MenuRenderState = {\n /**\n * The elements that can be refined for the current search results.\n */\n items: MenuItem[];\n /**\n * Creates the URL for a single item name in the list.\n */\n createURL: CreateURL<string>;\n /**\n * Filter the search to item value.\n */\n refine(value: string): void;\n /**\n * True if refinement can be applied.\n */\n canRefine: boolean;\n /**\n * True if the menu is displaying all the menu items.\n */\n isShowingMore: boolean;\n /**\n * Toggles the number of values displayed between `limit` and `showMore.limit`.\n */\n toggleShowMore(): void;\n /**\n * `true` if the toggleShowMore button can be activated (enough items to display more or\n * already displaying more than `limit` items)\n */\n canToggleShowMore: boolean;\n /**\n * Send event to insights middleware\n */\n sendEvent: SendEventForFacet;\n};\n\nexport type MenuWidgetDescription = {\n $$type: 'ais.menu';\n renderState: MenuRenderState;\n indexRenderState: {\n menu: {\n [attribute: string]: WidgetRenderState<\n MenuRenderState,\n MenuConnectorParams\n >;\n };\n };\n indexUiState: {\n menu: {\n [attribute: string]: string;\n };\n };\n};\n\nexport type MenuConnector = Connector<\n MenuWidgetDescription,\n MenuConnectorParams\n>;\n\n/**\n * **Menu** connector provides the logic to build a widget that will give the user the ability to choose a single value for a specific facet. The typical usage of menu is for navigation in categories.\n *\n * This connector provides a `toggleShowMore()` function to display more or less items and a `refine()`\n * function to select an item. While selecting a new element, the `refine` will also unselect the\n * one that is currently selected.\n *\n * **Requirement:** the attribute passed as `attribute` must be present in \"attributes for faceting\" on the Algolia dashboard or configured as attributesForFaceting via a set settings call to the Algolia API.\n */\nconst connectMenu: MenuConnector = function connectMenu(\n renderFn,\n unmountFn = noop\n) {\n checkRendering(renderFn, withUsage());\n\n return (widgetParams) => {\n const {\n attribute,\n limit = 10,\n showMore = false,\n showMoreLimit = 20,\n sortBy = DEFAULT_SORT,\n transformItems = ((items) => items) as TransformItems<MenuItem>,\n } = widgetParams || {};\n\n if (!attribute) {\n throw new Error(withUsage('The `attribute` option is required.'));\n }\n\n if (showMore === true && showMoreLimit <= limit) {\n throw new Error(\n withUsage('The `showMoreLimit` option must be greater than `limit`.')\n );\n }\n\n type ThisWidget = Widget<\n MenuWidgetDescription & { widgetParams: typeof widgetParams }\n >;\n\n let sendEvent: MenuRenderState['sendEvent'] | undefined;\n let _createURL: MenuRenderState['createURL'] | undefined;\n let _refine: MenuRenderState['refine'] | undefined;\n\n // Provide the same function to the `renderFn` so that way the user\n // has to only bind it once when `isFirstRendering` for instance\n let isShowingMore = false;\n let toggleShowMore = () => {};\n function createToggleShowMore(\n renderOptions: RenderOptions,\n widget: ThisWidget\n ) {\n return () => {\n isShowingMore = !isShowingMore;\n widget.render!(renderOptions);\n };\n }\n function cachedToggleShowMore() {\n toggleShowMore();\n }\n\n function getLimit() {\n return isShowingMore ? showMoreLimit : limit;\n }\n\n return {\n $$type: 'ais.menu' as const,\n\n init(initOptions) {\n const { instantSearchInstance } = initOptions;\n\n renderFn(\n {\n ...this.getWidgetRenderState(initOptions),\n instantSearchInstance,\n },\n true\n );\n },\n\n render(renderOptions) {\n const { instantSearchInstance } = renderOptions;\n\n renderFn(\n {\n ...this.getWidgetRenderState(renderOptions),\n instantSearchInstance,\n },\n false\n );\n },\n\n dispose({ state }) {\n unmountFn();\n\n return state\n .removeHierarchicalFacet(attribute)\n .setQueryParameter('maxValuesPerFacet', undefined);\n },\n\n getRenderState(renderState, renderOptions) {\n return {\n ...renderState,\n menu: {\n ...renderState.menu,\n [attribute]: this.getWidgetRenderState(renderOptions),\n },\n };\n },\n\n getWidgetRenderState(renderOptions) {\n const { results, createURL, instantSearchInstance, helper } =\n renderOptions;\n\n let items: MenuRenderState['items'] = [];\n let canToggleShowMore = false;\n\n if (!sendEvent) {\n sendEvent = createSendEventForFacet({\n instantSearchInstance,\n helper,\n attribute,\n widgetType: this.$$type,\n });\n }\n\n if (!_createURL) {\n _createURL = (facetValue: string) =>\n createURL(\n helper.state\n .resetPage()\n .toggleFacetRefinement(attribute, facetValue)\n );\n }\n\n if (!_refine) {\n _refine = function (facetValue: string) {\n const [refinedItem] =\n helper.getHierarchicalFacetBreadcrumb(attribute);\n sendEvent!('click', facetValue ? facetValue : refinedItem);\n helper\n .toggleFacetRefinement(\n attribute,\n facetValue ? facetValue : refinedItem\n )\n .search();\n };\n }\n\n if (renderOptions.results) {\n toggleShowMore = createToggleShowMore(renderOptions, this);\n }\n\n if (results) {\n const facetValues = results.getFacetValues(attribute, {\n sortBy,\n facetOrdering: sortBy === DEFAULT_SORT,\n });\n const facetItems =\n facetValues && !Array.isArray(facetValues) && facetValues.data\n ? facetValues.data\n : [];\n\n canToggleShowMore =\n showMore && (isShowingMore || facetItems.length > getLimit());\n\n items = transformItems(\n facetItems\n .slice(0, getLimit())\n .map(({ name: label, path: value, ...item }) => ({\n ...item,\n label,\n value,\n }))\n );\n }\n\n return {\n items,\n createURL: _createURL,\n refine: _refine,\n sendEvent,\n canRefine: items.length > 0,\n widgetParams,\n isShowingMore,\n toggleShowMore: cachedToggleShowMore,\n canToggleShowMore,\n };\n },\n\n getWidgetUiState(uiState, { searchParameters }) {\n const [value] =\n searchParameters.getHierarchicalFacetBreadcrumb(attribute);\n\n if (!value) {\n return uiState;\n }\n\n return {\n ...uiState,\n menu: {\n ...uiState.menu,\n [attribute]: value,\n },\n };\n },\n\n getWidgetSearchParameters(searchParameters, { uiState }) {\n const value = uiState.menu && uiState.menu[attribute];\n\n const withFacetConfiguration = searchParameters\n .removeHierarchicalFacet(attribute)\n .addHierarchicalFacet({\n name: attribute,\n attributes: [attribute],\n });\n\n const currentMaxValuesPerFacet =\n withFacetConfiguration.maxValuesPerFacet || 0;\n\n const nextMaxValuesPerFacet = Math.max(\n currentMaxValuesPerFacet,\n showMore ? showMoreLimit : limit\n );\n\n const withMaxValuesPerFacet = withFacetConfiguration.setQueryParameter(\n 'maxValuesPerFacet',\n nextMaxValuesPerFacet\n );\n\n if (!value) {\n return withMaxValuesPerFacet.setQueryParameters({\n hierarchicalFacetsRefinements: {\n ...withMaxValuesPerFacet.hierarchicalFacetsRefinements,\n [attribute]: [],\n },\n });\n }\n\n return withMaxValuesPerFacet.addHierarchicalFacetRefinement(\n attribute,\n value\n );\n },\n };\n };\n};\n\nexport default connectMenu;\n","import type { SendEventForFacet } from '../../lib/utils';\nimport {\n checkRendering,\n createDocumentationMessageGenerator,\n isFiniteNumber,\n convertNumericRefinementsToFilters,\n noop,\n} from '../../lib/utils';\nimport type {\n Connector,\n CreateURL,\n InstantSearch,\n TransformItems,\n WidgetRenderState,\n} from '../../types';\nimport type {\n AlgoliaSearchHelper,\n SearchParameters,\n} from 'algoliasearch-helper';\nimport type { InsightsEvent } from '../../middlewares';\n\nconst withUsage = createDocumentationMessageGenerator({\n name: 'numeric-menu',\n connector: true,\n});\n\nexport type NumericMenuConnectorParamsItem = {\n /**\n * Name of the option\n */\n label: string;\n\n /**\n * Higher bound of the option (<=)\n */\n start?: number;\n\n /**\n * Lower bound of the option (>=)\n */\n end?: number;\n};\n\nexport type NumericMenuRenderStateItem = {\n /**\n * Name of the option.\n */\n label: string;\n\n /**\n * URL encoded of the bounds object with the form `{start, end}`.\n * This value can be used verbatim in the webpage and can be read by `refine`\n * directly. If you want to inspect the value, you can do:\n * `JSON.parse(decodeURI(value))` to get the object.\n */\n value: string;\n\n /**\n * True if the value is selected\n */\n isRefined: boolean;\n};\n\nexport type NumericMenuConnectorParams = {\n /**\n * Name of the attribute for filtering\n */\n attribute: string;\n\n /**\n * List of all the items\n */\n items: NumericMenuConnectorParamsItem[];\n\n /**\n * Function to transform the items passed to the templates\n */\n transformItems?: TransformItems<NumericMenuRenderStateItem>;\n};\n\nexport type NumericMenuRenderState = {\n /**\n * The list of available choices\n */\n items: NumericMenuRenderStateItem[];\n\n /**\n * Creates URLs for the next state, the string is the name of the selected option\n */\n createURL: CreateURL<NumericMenuRenderStateItem['value']>;\n\n /**\n * `true` if the last search contains no result\n */\n hasNoResults: boolean;\n\n /**\n * Sets the selected value and trigger a new search\n */\n refine: (facetValue: string) => void;\n\n /**\n * Send event to insights middleware\n */\n sendEvent: SendEventForFacet;\n};\n\nexport type NumericMenuWidgetDescription = {\n $$type: 'ais.numericMenu';\n renderState: NumericMenuRenderState;\n indexRenderState: {\n numericMenu: {\n [attribute: string]: WidgetRenderState<\n NumericMenuRenderState,\n NumericMenuConnectorParams\n >;\n };\n };\n indexUiState: {\n numericMenu: {\n // @TODO: this could possibly become `${number}:${number}` later\n [attribute: string]: string;\n };\n };\n};\n\nexport type NumericMenuConnector = Connector<\n NumericMenuWidgetDescription,\n NumericMenuConnectorParams\n>;\n\nconst $$type = 'ais.numericMenu';\n\nconst createSendEvent =\n ({\n instantSearchInstance,\n helper,\n attribute,\n }: {\n instantSearchInstance: InstantSearch;\n helper: AlgoliaSearchHelper;\n attribute: string;\n }) =>\n (...args: [InsightsEvent] | [string, string, string?]) => {\n if (args.length === 1) {\n instantSearchInstance.sendEventToInsights(args[0]);\n return;\n }\n\n const [eventType, facetValue, eventName = 'Filter Applied'] = args;\n if (eventType !== 'click') {\n return;\n }\n // facetValue === \"%7B%22start%22:5,%22end%22:10%7D\"\n const filters = convertNumericRefinementsToFilters(\n getRefinedState(helper.state, attribute, facetValue),\n attribute\n );\n if (filters && filters.length > 0) {\n /*\n filters === [\"price<=10\", \"price>=5\"]\n */\n instantSearchInstance.sendEventToInsights({\n insightsMethod: 'clickedFilters',\n widgetType: $$type,\n eventType,\n payload: {\n eventName,\n index: helper.getIndex(),\n filters,\n },\n attribute,\n });\n }\n };\n\nconst connectNumericMenu: NumericMenuConnector = function connectNumericMenu(\n renderFn,\n unmountFn = noop\n) {\n checkRendering(renderFn, withUsage());\n\n return (widgetParams) => {\n const {\n attribute = '',\n items = [],\n transformItems = ((x) => x) as TransformItems<NumericMenuRenderStateItem>,\n } = widgetParams || {};\n\n if (attribute === '') {\n throw new Error(withUsage('The `attribute` option is required.'));\n }\n\n if (!items || items.length === 0) {\n throw new Error(\n withUsage('The `items` option expects an array of objects.')\n );\n }\n\n type ConnectorState = {\n refine?(facetValue: string): void;\n createURL?(state: SearchParameters): (facetValue: string) => string;\n sendEvent?: SendEventForFacet;\n };\n\n const prepareItems = (state: SearchParameters) =>\n items.map(({ start, end, label }) => ({\n label,\n value: encodeURI(JSON.stringify({ start, end })),\n isRefined: isRefined(state, attribute, { start, end, label }),\n }));\n\n const connectorState: ConnectorState = {};\n\n return {\n $$type,\n\n init(initOptions) {\n const { instantSearchInstance } = initOptions;\n\n renderFn(\n {\n ...this.getWidgetRenderState(initOptions),\n instantSearchInstance,\n },\n true\n );\n },\n\n render(renderOptions) {\n const { instantSearchInstance } = renderOptions;\n renderFn(\n {\n ...this.getWidgetRenderState(renderOptions),\n instantSearchInstance,\n },\n false\n );\n },\n\n dispose({ state }) {\n unmountFn();\n return state.clearRefinements(attribute);\n },\n\n getWidgetUiState(uiState, { searchParameters }) {\n const values = searchParameters.getNumericRefinements(attribute);\n\n const equal = values['='] && values['='][0];\n\n if (equal || equal === 0) {\n return {\n ...uiState,\n numericMenu: {\n ...uiState.numericMenu,\n [attribute]: `${values['=']}`,\n },\n };\n }\n\n const min = (values['>='] && values['>='][0]) || '';\n const max = (values['<='] && values['<='][0]) || '';\n\n if (min === '' && max === '') {\n return uiState;\n }\n\n return {\n ...uiState,\n numericMenu: {\n ...uiState.numericMenu,\n [attribute]: `${min}:${max}`,\n },\n };\n },\n\n getWidgetSearchParameters(searchParameters, { uiState }) {\n const value = uiState.numericMenu && uiState.numericMenu[attribute];\n\n const withoutRefinements = searchParameters.clearRefinements(attribute);\n\n if (!value) {\n return withoutRefinements.setQueryParameters({\n numericRefinements: {\n ...withoutRefinements.numericRefinements,\n [attribute]: {},\n },\n });\n }\n\n const isExact = value.indexOf(':') === -1;\n\n if (isExact) {\n return withoutRefinements.addNumericRefinement(\n attribute,\n '=',\n Number(value)\n );\n }\n\n const [min, max] = value.split(':').map(parseFloat);\n\n const withMinRefinement = isFiniteNumber(min)\n ? withoutRefinements.addNumericRefinement(attribute, '>=', min)\n : withoutRefinements;\n\n const withMaxRefinement = isFiniteNumber(max)\n ? withMinRefinement.addNumericRefinement(attribute, '<=', max)\n : withMinRefinement;\n\n return withMaxRefinement;\n },\n\n getRenderState(renderState, renderOptions) {\n return {\n ...renderState,\n numericMenu: {\n ...renderState.numericMenu,\n [attribute]: this.getWidgetRenderState(renderOptions),\n },\n };\n },\n\n getWidgetRenderState({\n results,\n state,\n instantSearchInstance,\n helper,\n createURL,\n }) {\n if (!connectorState.refine) {\n connectorState.refine = (facetValue) => {\n const refinedState = getRefinedState(\n helper.state,\n attribute,\n facetValue\n );\n connectorState.sendEvent!('click', facetValue);\n helper.setState(refinedState).search();\n };\n }\n\n if (!connectorState.createURL) {\n connectorState.createURL = (newState) => (facetValue) =>\n createURL(getRefinedState(newState, attribute, facetValue));\n }\n\n if (!connectorState.sendEvent) {\n connectorState.sendEvent = createSendEvent({\n instantSearchInstance,\n helper,\n attribute,\n });\n }\n\n return {\n createURL: connectorState.createURL(state),\n items: transformItems(prepareItems(state)),\n hasNoResults: results ? results.nbHits === 0 : true,\n refine: connectorState.refine,\n sendEvent: connectorState.sendEvent,\n widgetParams,\n };\n },\n };\n };\n};\n\nfunction isRefined(\n state: SearchParameters,\n attribute: string,\n option: NumericMenuConnectorParamsItem\n) {\n // @TODO: same as another spot, why is this mixing arrays & elements?\n const currentRefinements = state.getNumericRefinements(attribute);\n\n if (option.start !== undefined && option.end !== undefined) {\n if (option.start === option.end) {\n return hasNumericRefinement(currentRefinements, '=', option.start);\n } else {\n return (\n hasNumericRefinement(currentRefinements, '>=', option.start) &&\n hasNumericRefinement(currentRefinements, '<=', option.end)\n );\n }\n }\n\n if (option.start !== undefined) {\n return hasNumericRefinement(currentRefinements, '>=', option.start);\n }\n\n if (option.end !== undefined) {\n return hasNumericRefinement(currentRefinements, '<=', option.end);\n }\n\n if (option.start === undefined && option.end === undefined) {\n return (\n Object.keys(currentRefinements) as SearchParameters.Operator[]\n ).every((operator) => (currentRefinements[operator] || []).length === 0);\n }\n\n return false;\n}\n\nfunction getRefinedState(\n state: SearchParameters,\n attribute: string,\n facetValue: string\n) {\n let resolvedState = state;\n\n const refinedOption = JSON.parse(decodeURI(facetValue));\n\n // @TODO: why is array / element mixed here & hasRefinements; seems wrong?\n const currentRefinements = resolvedState.getNumericRefinements(attribute);\n\n if (refinedOption.start === undefined && refinedOption.end === undefined) {\n return resolvedState.removeNumericRefinement(attribute);\n }\n\n if (!isRefined(resolvedState, attribute, refinedOption)) {\n resolvedState = resolvedState.removeNumericRefinement(attribute);\n }\n\n if (refinedOption.start !== undefined && refinedOption.end !== undefined) {\n if (refinedOption.start > refinedOption.end) {\n throw new Error('option.start should be > to option.end');\n }\n\n if (refinedOption.start === refinedOption.end) {\n if (hasNumericRefinement(currentRefinements, '=', refinedOption.start)) {\n resolvedState = resolvedState.removeNumericRefinement(\n attribute,\n '=',\n refinedOption.start\n );\n } else {\n resolvedState = resolvedState.addNumericRefinement(\n attribute,\n '=',\n refinedOption.start\n );\n }\n return resolvedState;\n }\n }\n\n if (refinedOption.start !== undefined) {\n if (hasNumericRefinement(currentRefinements, '>=', refinedOption.start)) {\n resolvedState = resolvedState.removeNumericRefinement(\n attribute,\n '>=',\n refinedOption.start\n );\n }\n resolvedState = resolvedState.addNumericRefinement(\n attribute,\n '>=',\n refinedOption.start\n );\n }\n\n if (refinedOption.end !== undefined) {\n if (hasNumericRefinement(currentRefinements, '<=', refinedOption.end)) {\n resolvedState = resolvedState.removeNumericRefinement(\n attribute,\n '<=',\n refinedOption.end\n );\n }\n resolvedState = resolvedState.addNumericRefinement(\n attribute,\n '<=',\n refinedOption.end\n );\n }\n\n if (typeof resolvedState.page === 'number') {\n resolvedState.page = 0;\n }\n\n return resolvedState;\n}\n\nfunction hasNumericRefinement(\n currentRefinements: SearchParameters.OperatorList,\n operator: SearchParameters.Operator,\n value: number\n) {\n return (\n currentRefinements[operator] !== undefined &&\n currentRefinements[operator]!.includes(value)\n );\n}\n\nexport default connectNumericMenu;\n","import { withInsights } from '../../lib/insights';\nimport type {\n InfiniteHitsWidgetDescription,\n InfiniteHitsConnectorParams,\n} from './connectInfiniteHits';\nimport connectInfiniteHits from './connectInfiniteHits';\nimport type { Connector } from '../../types';\n\n/**\n * Due to https://github.com/microsoft/web-build-tools/issues/1050, we need\n * Connector<...> imported in this file, even though it is only used implicitly.\n * This _uses_ Connector<...> so it is not accidentally removed by someone.\n */\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\ndeclare type ImportWorkaround = Connector<\n InfiniteHitsWidgetDescription,\n InfiniteHitsConnectorParams\n>;\n\nconst connectInfiniteHitsWithInsights = withInsights(connectInfiniteHits);\n\nexport default connectInfiniteHitsWithInsights;\n","import {\n checkRendering,\n createDocumentationMessageGenerator,\n noop,\n} from '../../lib/utils';\nimport Paginator from './Paginator';\nimport type { Connector, CreateURL, WidgetRenderState } from '../../types';\nimport type { SearchParameters } from 'algoliasearch-helper';\n\nconst withUsage = createDocumentationMessageGenerator({\n name: 'pagination',\n connector: true,\n});\n\nexport type PaginationConnectorParams = {\n /**\n * The total number of pages to browse.\n */\n totalPages?: number;\n\n /**\n * The padding of pages to show around the current page\n * @default 3\n */\n padding?: number;\n};\n\nexport type PaginationRenderState = {\n /** Creates URLs for the next state, the number is the page to generate the URL for. */\n createURL: CreateURL<number>;\n\n /** Sets the current page and triggers a search. */\n refine(page: number): void;\n\n /** true if this search returned more than one page */\n canRefine: boolean;\n\n /** The number of the page currently displayed. */\n currentRefinement: number;\n\n /** The number of hits computed for the last query (can be approximated). */\n nbHits: number;\n\n /** The number of pages for the result set. */\n nbPages: number;\n\n /** The actual pages relevant to the current situation and padding. */\n pages: number[];\n\n /** true if the current page is also the first page. */\n isFirstPage: boolean;\n\n /** true if the current page is also the last page. */\n isLastPage: boolean;\n};\n\nexport type PaginationWidgetDescription = {\n $$type: 'ais.pagination';\n renderState: PaginationRenderState;\n indexRenderState: {\n pagination: WidgetRenderState<\n PaginationRenderState,\n PaginationConnectorParams\n >;\n };\n indexUiState: {\n page: number;\n };\n};\n\nexport type PaginationConnector = Connector<\n PaginationWidgetDescription,\n PaginationConnectorParams\n>;\n\n/**\n * **Pagination** connector provides the logic to build a widget that will let the user\n * choose the current page of the results.\n *\n * When using the pagination with Algolia, you should be aware that the engine won't provide you pages\n * beyond the 1000th hits by default. You can find more information on the [Algolia documentation](https://www.algolia.com/doc/guides/searching/pagination/#pagination-limitations).\n */\nconst connectPagination: PaginationConnector = function connectPagination(\n renderFn,\n unmountFn = noop\n) {\n checkRendering(renderFn, withUsage());\n\n return (widgetParams) => {\n const { totalPages, padding = 3 } = widgetParams || {};\n\n const pager = new Paginator({\n currentPage: 0,\n total: 0,\n padding,\n });\n\n type ConnectorState = {\n refine?(page: number): void;\n createURL?(state: SearchParameters): (page: number) => string;\n };\n\n const connectorState: ConnectorState = {};\n\n function getMaxPage({ nbPages }: { nbPages: number }) {\n return totalPages !== undefined ? Math.min(totalPages, nbPages) : nbPages;\n }\n\n return {\n $$type: 'ais.pagination',\n\n init(initOptions) {\n const { instantSearchInstance } = initOptions;\n\n renderFn(\n {\n ...this.getWidgetRenderState(initOptions),\n instantSearchInstance,\n },\n true\n );\n },\n\n render(renderOptions) {\n const { instantSearchInstance } = renderOptions;\n\n renderFn(\n {\n ...this.getWidgetRenderState(renderOptions),\n instantSearchInstance,\n },\n false\n );\n },\n\n dispose({ state }) {\n unmountFn();\n\n return state.setQueryParameter('page', undefined);\n },\n\n getWidgetUiState(uiState, { searchParameters }) {\n const page = searchParameters.page || 0;\n\n if (!page) {\n return uiState;\n }\n\n return {\n ...uiState,\n page: page + 1,\n };\n },\n\n getWidgetSearchParameters(searchParameters, { uiState }) {\n const page = uiState.page ? uiState.page - 1 : 0;\n\n return searchParameters.setQueryParameter('page', page);\n },\n\n getWidgetRenderState({ results, helper, state, createURL }) {\n if (!connectorState.refine) {\n connectorState.refine = (page) => {\n helper.setPage(page);\n helper.search();\n };\n }\n\n if (!connectorState.createURL) {\n connectorState.createURL = (helperState) => (page) =>\n createURL(helperState.setPage(page));\n }\n\n const page = state.page || 0;\n const nbPages = getMaxPage(results || { nbPages: 0 });\n pager.currentPage = page;\n pager.total = nbPages;\n\n return {\n createURL: connectorState.createURL(state),\n refine: connectorState.refine,\n canRefine: nbPages > 1,\n currentRefinement: page,\n nbHits: results?.nbHits || 0,\n nbPages,\n pages: results ? pager.pages() : [],\n isFirstPage: pager.isFirstPage(),\n isLastPage: pager.isLastPage(),\n widgetParams,\n };\n },\n\n getRenderState(renderState, renderOptions) {\n return {\n ...renderState,\n pagination: this.getWidgetRenderState(renderOptions),\n };\n },\n };\n };\n};\n\nexport default connectPagination;\n","import { range } from '../../lib/utils';\n\nclass Paginator {\n public currentPage: number;\n public total: number;\n public padding: number;\n\n public constructor(params: {\n currentPage: number;\n total: number;\n padding: number;\n }) {\n this.currentPage = params.currentPage;\n this.total = params.total;\n this.padding = params.padding;\n }\n\n public pages() {\n const { total, currentPage, padding } = this;\n\n if (total === 0) return [0];\n\n const totalDisplayedPages = this.nbPagesDisplayed(padding, total);\n if (totalDisplayedPages === total) {\n return range({ end: total });\n }\n\n const paddingLeft = this.calculatePaddingLeft(\n currentPage,\n padding,\n total,\n totalDisplayedPages\n );\n const paddingRight = totalDisplayedPages - paddingLeft;\n\n const first = currentPage - paddingLeft;\n const last = currentPage + paddingRight;\n\n return range({ start: first, end: last });\n }\n\n public nbPagesDisplayed(padding: number, total: number) {\n return Math.min(2 * padding + 1, total);\n }\n\n public calculatePaddingLeft(\n current: number,\n padding: number,\n total: number,\n totalDisplayedPages: number\n ) {\n if (current <= padding) {\n return current;\n }\n\n if (current >= total - padding) {\n return totalDisplayedPages - (total - current);\n }\n\n return padding;\n }\n\n public isLastPage() {\n return this.currentPage === this.total - 1 || this.total === 0;\n }\n\n public isFirstPage() {\n return this.currentPage === 0;\n }\n}\n\nexport default Paginator;\n","import type {\n AlgoliaSearchHelper,\n SearchParameters,\n SearchResults,\n} from 'algoliasearch-helper';\nimport type { SendEventForFacet } from '../../lib/utils';\nimport {\n checkRendering,\n createDocumentationMessageGenerator,\n convertNumericRefinementsToFilters,\n isFiniteNumber,\n find,\n noop,\n} from '../../lib/utils';\nimport type { InsightsEvent } from '../../middlewares';\nimport type { Connector, InstantSearch, WidgetRenderState } from '../../types';\n\nconst withUsage = createDocumentationMessageGenerator(\n { name: 'range-input', connector: true },\n { name: 'range-slider', connector: true }\n);\n\nconst $$type = 'ais.range';\n\nexport type RangeMin = number | undefined;\nexport type RangeMax = number | undefined;\n\n// @MAJOR: potentially we should consolidate these types\nexport type RangeBoundaries = [RangeMin, RangeMax];\nexport type Range = {\n min: RangeMin;\n max: RangeMax;\n};\n\nexport type RangeRenderState = {\n /**\n * Sets a range to filter the results on. Both values\n * are optional, and will default to the higher and lower bounds. You can use `undefined` to remove a\n * previously set bound or to set an infinite bound.\n * @param rangeValue tuple of [min, max] bounds\n */\n refine(rangeValue: RangeBoundaries): void;\n\n /**\n * Indicates whether this widget can be refined\n */\n canRefine: boolean;\n\n /**\n * Send an event to the insights middleware\n */\n sendEvent: SendEventForFacet;\n\n /**\n * Maximum range possible for this search\n */\n range: Range;\n\n /**\n * Current refinement of the search\n */\n start: RangeBoundaries;\n\n /**\n * Transform for the rendering `from` and/or `to` values.\n * Both functions take a `number` as input and should output a `string`.\n */\n format: {\n from(fromValue: number): string;\n to(toValue: number): string;\n };\n};\n\nexport type RangeConnectorParams = {\n /**\n * Name of the attribute for faceting.\n */\n attribute: string;\n\n /**\n * Minimal range value, default to automatically computed from the result set.\n */\n min?: number;\n\n /**\n * Maximal range value, default to automatically computed from the result set.\n */\n max?: number;\n\n /**\n * Number of digits after decimal point to use.\n */\n precision?: number;\n};\n\nexport type RangeWidgetDescription = {\n $$type: 'ais.range';\n renderState: RangeRenderState;\n indexRenderState: {\n range: {\n [attribute: string]: WidgetRenderState<\n RangeRenderState,\n RangeConnectorParams\n >;\n };\n };\n indexUiState: {\n range: {\n // @TODO: this could possibly become `${number}:${number}` later\n [attribute: string]: string;\n };\n };\n};\n\nexport type RangeConnector = Connector<\n RangeWidgetDescription,\n RangeConnectorParams\n>;\n\nfunction toPrecision({\n min,\n max,\n precision,\n}: {\n min?: number;\n max?: number;\n precision: number;\n}) {\n const pow = Math.pow(10, precision);\n\n return {\n min: min ? Math.floor(min * pow) / pow : min,\n max: max ? Math.ceil(max * pow) / pow : max,\n };\n}\n\n/**\n * **Range** connector provides the logic to create custom widget that will let\n * the user refine results using a numeric range.\n *\n * This connectors provides a `refine()` function that accepts bounds. It will also provide\n * information about the min and max bounds for the current result set.\n */\nconst connectRange: RangeConnector = function connectRange(\n renderFn,\n unmountFn = noop\n) {\n checkRendering(renderFn, withUsage());\n\n return (widgetParams) => {\n const {\n attribute = '',\n min: minBound,\n max: maxBound,\n precision = 0,\n } = widgetParams || {};\n\n if (!attribute) {\n throw new Error(withUsage('The `attribute` option is required.'));\n }\n\n if (\n isFiniteNumber(minBound) &&\n isFiniteNumber(maxBound) &&\n minBound > maxBound\n ) {\n throw new Error(withUsage(\"The `max` option can't be lower than `min`.\"));\n }\n\n const formatToNumber = (v: string | number) =>\n Number(Number(v).toFixed(precision));\n\n const rangeFormatter = {\n from: (v: number) => v.toLocaleString(),\n to: (v: number) => formatToNumber(v).toLocaleString(),\n };\n\n // eslint-disable-next-line complexity\n const getRefinedState = (\n helper: AlgoliaSearchHelper,\n currentRange: Range,\n nextMin: RangeMin | string,\n nextMax: RangeMax | string\n ) => {\n let resolvedState = helper.state;\n const { min: currentRangeMin, max: currentRangeMax } = currentRange;\n\n const [min] = resolvedState.getNumericRefinement(attribute, '>=') || [];\n const [max] = resolvedState.getNumericRefinement(attribute, '<=') || [];\n\n const isResetMin = nextMin === undefined || nextMin === '';\n const isResetMax = nextMax === undefined || nextMax === '';\n\n const { min: nextMinAsNumber, max: nextMaxAsNumber } = toPrecision({\n min: !isResetMin ? parseFloat(nextMin as string) : undefined,\n max: !isResetMax ? parseFloat(nextMax as string) : undefined,\n precision,\n });\n\n let newNextMin: RangeMin;\n if (!isFiniteNumber(minBound) && currentRangeMin === nextMinAsNumber) {\n newNextMin = undefined;\n } else if (isFiniteNumber(minBound) && isResetMin) {\n newNextMin = minBound;\n } else {\n newNextMin = nextMinAsNumber;\n }\n\n let newNextMax: RangeMax;\n if (!isFiniteNumber(maxBound) && currentRangeMax === nextMaxAsNumber) {\n newNextMax = undefined;\n } else if (isFiniteNumber(maxBound) && isResetMax) {\n newNextMax = maxBound;\n } else {\n newNextMax = nextMaxAsNumber;\n }\n\n const isResetNewNextMin = newNextMin === undefined;\n\n const isGreaterThanCurrentRange =\n isFiniteNumber(currentRangeMin) && currentRangeMin <= newNextMin!;\n const isMinValid =\n isResetNewNextMin ||\n (isFiniteNumber(newNextMin) &&\n (!isFiniteNumber(currentRangeMin) || isGreaterThanCurrentRange));\n\n const isResetNewNextMax = newNextMax === undefined;\n const isLowerThanRange =\n isFiniteNumber(newNextMax) && currentRangeMax! >= newNextMax;\n const isMaxValid =\n isResetNewNextMax ||\n (isFiniteNumber(newNextMax) &&\n (!isFiniteNumber(currentRangeMax) || isLowerThanRange));\n\n const hasMinChange = min !== newNextMin;\n const hasMaxChange = max !== newNextMax;\n\n if ((hasMinChange || hasMaxChange) && isMinValid && isMaxValid) {\n resolvedState = resolvedState.removeNumericRefinement(attribute);\n\n if (isFiniteNumber(newNextMin)) {\n resolvedState = resolvedState.addNumericRefinement(\n attribute,\n '>=',\n newNextMin\n );\n }\n\n if (isFiniteNumber(newNextMax)) {\n resolvedState = resolvedState.addNumericRefinement(\n attribute,\n '<=',\n newNextMax\n );\n }\n\n return resolvedState.resetPage();\n }\n\n return null;\n };\n\n const sendEventWithRefinedState = (\n refinedState: SearchParameters | null,\n instantSearchInstance: InstantSearch,\n helper: AlgoliaSearchHelper,\n eventName = 'Filter Applied'\n ) => {\n const filters = convertNumericRefinementsToFilters(\n refinedState,\n attribute\n );\n if (filters && filters.length > 0) {\n instantSearchInstance.sendEventToInsights({\n insightsMethod: 'clickedFilters',\n widgetType: $$type,\n eventType: 'click',\n payload: {\n eventName,\n index: helper.getIndex(),\n filters,\n },\n attribute,\n });\n }\n };\n\n const createSendEvent =\n (\n instantSearchInstance: InstantSearch,\n helper: AlgoliaSearchHelper,\n currentRange: Range\n ) =>\n (...args: [InsightsEvent] | [string, string, string?]) => {\n if (args.length === 1) {\n instantSearchInstance.sendEventToInsights(args[0]);\n return;\n }\n\n const [eventType, facetValue, eventName] = args;\n if (eventType !== 'click') {\n return;\n }\n const [nextMin, nextMax] = facetValue;\n const refinedState = getRefinedState(\n helper,\n currentRange,\n nextMin,\n nextMax\n );\n sendEventWithRefinedState(\n refinedState,\n instantSearchInstance,\n helper,\n eventName\n );\n };\n\n function _getCurrentRange(\n stats: Partial<NonNullable<SearchResults.Facet['stats']>>\n ) {\n let min: number;\n if (isFiniteNumber(minBound)) {\n min = minBound;\n } else if (isFiniteNumber(stats.min)) {\n min = stats.min;\n } else {\n min = 0;\n }\n\n let max: number;\n if (isFiniteNumber(maxBound)) {\n max = maxBound;\n } else if (isFiniteNumber(stats.max)) {\n max = stats.max;\n } else {\n max = 0;\n }\n\n return toPrecision({ min, max, precision });\n }\n\n function _getCurrentRefinement(\n helper: AlgoliaSearchHelper\n ): RangeBoundaries {\n const [minValue] = helper.getNumericRefinement(attribute, '>=') || [];\n\n const [maxValue] = helper.getNumericRefinement(attribute, '<=') || [];\n\n const min = isFiniteNumber(minValue) ? minValue : -Infinity;\n const max = isFiniteNumber(maxValue) ? maxValue : Infinity;\n\n return [min, max];\n }\n\n function _refine(\n instantSearchInstance: InstantSearch,\n helper: AlgoliaSearchHelper,\n currentRange: Range\n ) {\n return ([nextMin, nextMax]: RangeBoundaries = [undefined, undefined]) => {\n const refinedState = getRefinedState(\n helper,\n currentRange,\n nextMin,\n nextMax\n );\n if (refinedState) {\n sendEventWithRefinedState(\n refinedState,\n instantSearchInstance,\n helper\n );\n helper.setState(refinedState).search();\n }\n };\n }\n\n return {\n $$type,\n\n init(initOptions) {\n renderFn(\n {\n ...this.getWidgetRenderState(initOptions),\n instantSearchInstance: initOptions.instantSearchInstance,\n },\n true\n );\n },\n\n render(renderOptions) {\n renderFn(\n {\n ...this.getWidgetRenderState(renderOptions),\n instantSearchInstance: renderOptions.instantSearchInstance,\n },\n false\n );\n },\n\n getRenderState(renderState, renderOptions) {\n return {\n ...renderState,\n range: {\n ...renderState.range,\n [attribute]: this.getWidgetRenderState(renderOptions),\n },\n };\n },\n\n getWidgetRenderState({ results, helper, instantSearchInstance }) {\n const facetsFromResults = (results && results.disjunctiveFacets) || [];\n const facet = find(\n facetsFromResults,\n (facetResult) => facetResult.name === attribute\n );\n const stats = (facet && facet.stats) || {\n min: undefined,\n max: undefined,\n };\n\n const currentRange = _getCurrentRange(stats);\n const start = _getCurrentRefinement(helper);\n\n let refine: ReturnType<typeof _refine>;\n\n if (!results) {\n // On first render pass an empty range\n // to be able to bypass the validation\n // related to it\n refine = _refine(instantSearchInstance, helper, {\n min: undefined,\n max: undefined,\n });\n } else {\n refine = _refine(instantSearchInstance, helper, currentRange);\n }\n\n return {\n refine,\n canRefine: currentRange.min !== currentRange.max,\n format: rangeFormatter,\n range: currentRange,\n sendEvent: createSendEvent(\n instantSearchInstance,\n helper,\n currentRange\n ),\n widgetParams: {\n ...widgetParams,\n precision,\n },\n start,\n };\n },\n\n dispose({ state }) {\n unmountFn();\n\n return state\n .removeDisjunctiveFacet(attribute)\n .removeNumericRefinement(attribute);\n },\n\n getWidgetUiState(uiState, { searchParameters }) {\n const { '>=': min = [], '<=': max = [] } =\n searchParameters.getNumericRefinements(attribute);\n\n if (min.length === 0 && max.length === 0) {\n return uiState;\n }\n\n return {\n ...uiState,\n range: {\n ...uiState.range,\n [attribute]: `${min}:${max}`,\n },\n };\n },\n\n getWidgetSearchParameters(searchParameters, { uiState }) {\n let widgetSearchParameters = searchParameters\n .addDisjunctiveFacet(attribute)\n .setQueryParameters({\n numericRefinements: {\n ...searchParameters.numericRefinements,\n [attribute]: {},\n },\n });\n\n if (isFiniteNumber(minBound)) {\n widgetSearchParameters = widgetSearchParameters.addNumericRefinement(\n attribute,\n '>=',\n minBound\n );\n }\n\n if (isFiniteNumber(maxBound)) {\n widgetSearchParameters = widgetSearchParameters.addNumericRefinement(\n attribute,\n '<=',\n maxBound\n );\n }\n\n const value = uiState.range && uiState.range[attribute];\n\n if (!value || value.indexOf(':') === -1) {\n return widgetSearchParameters;\n }\n\n const [lowerBound, upperBound] = value.split(':').map(parseFloat);\n\n if (\n isFiniteNumber(lowerBound) &&\n (!isFiniteNumber(minBound) || minBound < lowerBound)\n ) {\n widgetSearchParameters =\n widgetSearchParameters.removeNumericRefinement(attribute, '>=');\n widgetSearchParameters = widgetSearchParameters.addNumericRefinement(\n attribute,\n '>=',\n lowerBound\n );\n }\n\n if (\n isFiniteNumber(upperBound) &&\n (!isFiniteNumber(maxBound) || upperBound < maxBound)\n ) {\n widgetSearchParameters =\n widgetSearchParameters.removeNumericRefinement(attribute, '<=');\n widgetSearchParameters = widgetSearchParameters.addNumericRefinement(\n attribute,\n '<=',\n upperBound\n );\n }\n\n return widgetSearchParameters;\n },\n };\n };\n};\n\nexport default connectRange;\n","import type { AlgoliaSearchHelper, SearchResults } from 'algoliasearch-helper';\nimport type { SendEventForFacet } from '../../lib/utils';\nimport {\n escapeFacets,\n TAG_PLACEHOLDER,\n TAG_REPLACEMENT,\n checkRendering,\n createDocumentationMessageGenerator,\n createSendEventForFacet,\n noop,\n} from '../../lib/utils';\nimport type {\n Connector,\n TransformItems,\n SortBy,\n RenderOptions,\n Widget,\n InitOptions,\n FacetHit,\n CreateURL,\n WidgetRenderState,\n} from '../../types';\n\nconst withUsage = createDocumentationMessageGenerator({\n name: 'refinement-list',\n connector: true,\n});\n\nconst DEFAULT_SORT = ['isRefined', 'count:desc', 'name:asc'];\n\nexport type RefinementListItem = {\n /**\n * The value of the refinement list item.\n */\n value: string;\n /**\n * Human-readable value of the refinement list item.\n */\n label: string;\n /**\n * Human-readable value of the searched refinement list item.\n */\n highlighted?: string;\n /**\n * Number of matched results after refinement is applied.\n */\n count: number;\n /**\n * Indicates if the list item is refined.\n */\n isRefined: boolean;\n};\n\nexport type RefinementListConnectorParams = {\n /**\n * The name of the attribute in the records.\n */\n attribute: string;\n /**\n * How the filters are combined together.\n */\n operator?: 'and' | 'or';\n /**\n * The max number of items to display when\n * `showMoreLimit` is not set or if the widget is showing less value.\n */\n limit?: number;\n /**\n * Whether to display a button that expands the number of items.\n */\n showMore?: boolean;\n /**\n * The max number of items to display if the widget\n * is showing more items.\n */\n showMoreLimit?: number;\n /**\n * How to sort refinements. Possible values: `count|isRefined|name:asc|name:desc`.\n *\n * You can also use a sort function that behaves like the standard Javascript [compareFunction](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#Syntax).\n *\n * If a facetOrdering is set in the index settings, it is used when sortBy isn't passed\n */\n sortBy?: SortBy<RefinementListItem>;\n /**\n * Escapes the content of the facet values.\n */\n escapeFacetValues?: boolean;\n /**\n * Function to transform the items passed to the templates.\n */\n transformItems?: TransformItems<RefinementListItem>;\n};\n\nexport type RefinementListRenderState = {\n /**\n * The list of filtering values returned from Algolia API.\n */\n items: RefinementListItem[];\n /**\n * indicates whether the results are exhaustive (complete)\n */\n hasExhaustiveItems: boolean;\n /**\n * Creates the next state url for a selected refinement.\n */\n createURL: CreateURL<string>;\n /**\n * Action to apply selected refinements.\n */\n refine(value: string): void;\n /**\n * Send event to insights middleware\n */\n sendEvent: SendEventForFacet;\n /**\n * Searches for values inside the list.\n */\n searchForItems(query: string): void;\n /**\n * `true` if the values are from an index search.\n */\n isFromSearch: boolean;\n /**\n * `true` if a refinement can be applied.\n */\n canRefine: boolean;\n /**\n * `true` if the toggleShowMore button can be activated (enough items to display more or\n * already displaying more than `limit` items)\n */\n canToggleShowMore: boolean;\n /**\n * True if the menu is displaying all the menu items.\n */\n isShowingMore: boolean;\n /**\n * Toggles the number of values displayed between `limit` and `showMoreLimit`.\n */\n toggleShowMore(): void;\n};\n\nexport type RefinementListWidgetDescription = {\n $$type: 'ais.refinementList';\n renderState: RefinementListRenderState;\n indexRenderState: {\n refinementList: {\n [attribute: string]: WidgetRenderState<\n RefinementListRenderState,\n RefinementListConnectorParams\n >;\n };\n };\n indexUiState: {\n refinementList: {\n [attribute: string]: string[];\n };\n };\n};\n\nexport type RefinementListConnector = Connector<\n RefinementListWidgetDescription,\n RefinementListConnectorParams\n>;\n\n/**\n * **RefinementList** connector provides the logic to build a custom widget that\n * will let the user filter the results based on the values of a specific facet.\n *\n * **Requirement:** the attribute passed as `attribute` must be present in\n * attributesForFaceting of the searched index.\n *\n * This connector provides:\n * - a `refine()` function to select an item.\n * - a `toggleShowMore()` function to display more or less items\n * - a `searchForItems()` function to search within the items.\n */\nconst connectRefinementList: RefinementListConnector =\n function connectRefinementList(renderFn, unmountFn = noop) {\n checkRendering(renderFn, withUsage());\n\n return (widgetParams) => {\n const {\n attribute,\n operator = 'or',\n limit = 10,\n showMore = false,\n showMoreLimit = 20,\n sortBy = DEFAULT_SORT,\n escapeFacetValues = true,\n transformItems = ((items) =>\n items) as TransformItems<RefinementListItem>,\n } = widgetParams || {};\n\n type ThisWidget = Widget<\n RefinementListWidgetDescription & { widgetParams: typeof widgetParams }\n >;\n\n if (!attribute) {\n throw new Error(withUsage('The `attribute` option is required.'));\n }\n\n if (!/^(and|or)$/.test(operator)) {\n throw new Error(\n withUsage(\n `The \\`operator\\` must one of: \\`\"and\"\\`, \\`\"or\"\\` (got \"${operator}\").`\n )\n );\n }\n\n if (showMore === true && showMoreLimit <= limit) {\n throw new Error(\n withUsage('`showMoreLimit` should be greater than `limit`.')\n );\n }\n\n const formatItems = ({\n name: label,\n ...item\n }: SearchResults.FacetValue): RefinementListItem => ({\n ...item,\n label,\n value: label,\n highlighted: label,\n });\n\n let lastResultsFromMainSearch: SearchResults;\n let lastItemsFromMainSearch: RefinementListItem[] = [];\n let hasExhaustiveItems = true;\n let triggerRefine: RefinementListRenderState['refine'] | undefined;\n let sendEvent: RefinementListRenderState['sendEvent'] | undefined;\n\n let isShowingMore = false;\n // Provide the same function to the `renderFn` so that way the user\n // has to only bind it once when `isFirstRendering` for instance\n let toggleShowMore = () => {};\n function cachedToggleShowMore() {\n toggleShowMore();\n }\n\n function createToggleShowMore(\n renderOptions: RenderOptions,\n widget: ThisWidget\n ) {\n return () => {\n isShowingMore = !isShowingMore;\n widget.render!(renderOptions);\n };\n }\n\n function getLimit() {\n return isShowingMore ? showMoreLimit : limit;\n }\n\n let searchForFacetValues: (\n renderOptions: RenderOptions | InitOptions\n ) => RefinementListRenderState['searchForItems'] = () => () => {};\n\n const createSearchForFacetValues = function (\n helper: AlgoliaSearchHelper,\n widget: ThisWidget\n ) {\n return (renderOptions: RenderOptions | InitOptions) =>\n (query: string) => {\n const { instantSearchInstance } = renderOptions;\n if (query === '' && lastItemsFromMainSearch) {\n // render with previous data from the helper.\n renderFn(\n {\n ...widget.getWidgetRenderState({\n ...renderOptions,\n results: lastResultsFromMainSearch,\n }),\n instantSearchInstance,\n },\n false\n );\n } else {\n const tags = {\n highlightPreTag: escapeFacetValues\n ? TAG_PLACEHOLDER.highlightPreTag\n : TAG_REPLACEMENT.highlightPreTag,\n highlightPostTag: escapeFacetValues\n ? TAG_PLACEHOLDER.highlightPostTag\n : TAG_REPLACEMENT.highlightPostTag,\n };\n\n helper\n .searchForFacetValues(\n attribute,\n query,\n // We cap the `maxFacetHits` value to 100 because the Algolia API\n // doesn't support a greater number.\n // See https://www.algolia.com/doc/api-reference/api-parameters/maxFacetHits/\n Math.min(getLimit(), 100),\n tags\n )\n .then((results) => {\n const facetValues = escapeFacetValues\n ? escapeFacets(results.facetHits)\n : results.facetHits;\n\n const normalizedFacetValues = transformItems(\n facetValues.map(({ value, ...item }) => ({\n ...item,\n value,\n label: value,\n }))\n );\n\n renderFn(\n {\n ...widget.getWidgetRenderState({\n ...renderOptions,\n results: lastResultsFromMainSearch,\n }),\n items: normalizedFacetValues,\n canToggleShowMore: false,\n canRefine: true,\n isFromSearch: true,\n instantSearchInstance,\n },\n false\n );\n });\n }\n };\n };\n\n return {\n $$type: 'ais.refinementList' as const,\n\n init(initOptions) {\n renderFn(\n {\n ...this.getWidgetRenderState(initOptions),\n instantSearchInstance: initOptions.instantSearchInstance,\n },\n true\n );\n },\n\n render(renderOptions) {\n renderFn(\n {\n ...this.getWidgetRenderState(renderOptions),\n instantSearchInstance: renderOptions.instantSearchInstance,\n },\n false\n );\n },\n\n getRenderState(renderState, renderOptions) {\n return {\n ...renderState,\n refinementList: {\n ...renderState.refinementList,\n [attribute]: this.getWidgetRenderState(renderOptions),\n },\n };\n },\n\n getWidgetRenderState(renderOptions) {\n const { results, state, createURL, instantSearchInstance, helper } =\n renderOptions;\n let items: RefinementListItem[] = [];\n let facetValues: SearchResults.FacetValue[] | FacetHit[] = [];\n\n if (!sendEvent || !triggerRefine || !searchForFacetValues) {\n sendEvent = createSendEventForFacet({\n instantSearchInstance,\n helper,\n attribute,\n widgetType: this.$$type,\n });\n\n triggerRefine = (facetValue) => {\n sendEvent!('click', facetValue);\n helper.toggleFacetRefinement(attribute, facetValue).search();\n };\n\n searchForFacetValues = createSearchForFacetValues(helper, this);\n }\n\n if (results) {\n const values = results.getFacetValues(attribute, {\n sortBy,\n facetOrdering: sortBy === DEFAULT_SORT,\n });\n facetValues = values && Array.isArray(values) ? values : [];\n items = transformItems(\n facetValues.slice(0, getLimit()).map(formatItems)\n );\n\n const maxValuesPerFacetConfig = state.maxValuesPerFacet;\n const currentLimit = getLimit();\n // If the limit is the max number of facet retrieved it is impossible to know\n // if the facets are exhaustive. The only moment we are sure it is exhaustive\n // is when it is strictly under the number requested unless we know that another\n // widget has requested more values (maxValuesPerFacet > getLimit()).\n // Because this is used for making the search of facets unable or not, it is important\n // to be conservative here.\n hasExhaustiveItems =\n maxValuesPerFacetConfig! > currentLimit\n ? facetValues.length <= currentLimit\n : facetValues.length < currentLimit;\n\n lastResultsFromMainSearch = results;\n lastItemsFromMainSearch = items;\n\n if (renderOptions.results) {\n toggleShowMore = createToggleShowMore(renderOptions, this);\n }\n }\n\n // Do not mistake searchForFacetValues and searchFacetValues which is the actual search\n // function\n const searchFacetValues =\n searchForFacetValues && searchForFacetValues(renderOptions);\n\n const canShowLess =\n isShowingMore && lastItemsFromMainSearch.length > limit;\n const canShowMore = showMore && !hasExhaustiveItems;\n\n const canToggleShowMore = canShowLess || canShowMore;\n\n return {\n createURL: (facetValue) =>\n createURL(\n state.resetPage().toggleFacetRefinement(attribute, facetValue)\n ),\n items,\n refine: triggerRefine,\n searchForItems: searchFacetValues,\n isFromSearch: false,\n canRefine: items.length > 0,\n widgetParams,\n isShowingMore,\n canToggleShowMore,\n toggleShowMore: cachedToggleShowMore,\n sendEvent,\n hasExhaustiveItems,\n };\n },\n\n dispose({ state }) {\n unmountFn();\n\n const withoutMaxValuesPerFacet = state.setQueryParameter(\n 'maxValuesPerFacet',\n undefined\n );\n if (operator === 'and') {\n return withoutMaxValuesPerFacet.removeFacet(attribute);\n }\n return withoutMaxValuesPerFacet.removeDisjunctiveFacet(attribute);\n },\n\n getWidgetUiState(uiState, { searchParameters }) {\n const values =\n operator === 'or'\n ? searchParameters.getDisjunctiveRefinements(attribute)\n : searchParameters.getConjunctiveRefinements(attribute);\n\n if (!values.length) {\n return uiState;\n }\n\n return {\n ...uiState,\n refinementList: {\n ...uiState.refinementList,\n [attribute]: values,\n },\n };\n },\n\n getWidgetSearchParameters(searchParameters, { uiState }) {\n const isDisjunctive = operator === 'or';\n const values =\n uiState.refinementList && uiState.refinementList[attribute];\n\n const withoutRefinements =\n searchParameters.clearRefinements(attribute);\n const withFacetConfiguration = isDisjunctive\n ? withoutRefinements.addDisjunctiveFacet(attribute)\n : withoutRefinements.addFacet(attribute);\n\n const currentMaxValuesPerFacet =\n withFacetConfiguration.maxValuesPerFacet || 0;\n\n const nextMaxValuesPerFacet = Math.max(\n currentMaxValuesPerFacet,\n showMore ? showMoreLimit : limit\n );\n\n const withMaxValuesPerFacet =\n withFacetConfiguration.setQueryParameter(\n 'maxValuesPerFacet',\n nextMaxValuesPerFacet\n );\n\n if (!values) {\n const key = isDisjunctive\n ? 'disjunctiveFacetsRefinements'\n : 'facetsRefinements';\n\n return withMaxValuesPerFacet.setQueryParameters({\n [key]: {\n ...withMaxValuesPerFacet[key],\n [attribute]: [],\n },\n });\n }\n\n return values.reduce(\n (parameters, value) =>\n isDisjunctive\n ? parameters.addDisjunctiveFacetRefinement(attribute, value)\n : parameters.addFacetRefinement(attribute, value),\n withMaxValuesPerFacet\n );\n },\n };\n };\n };\n\nexport default connectRefinementList;\n","import type { AlgoliaSearchHelper } from 'algoliasearch-helper';\nimport {\n checkRendering,\n createDocumentationMessageGenerator,\n noop,\n} from '../../lib/utils';\nimport type { Connector, WidgetRenderState } from '../../types';\n\nconst withUsage = createDocumentationMessageGenerator({\n name: 'search-box',\n connector: true,\n});\n\nexport type SearchBoxConnectorParams = {\n /**\n * A function that will be called every time\n * a new value for the query is set. The first parameter is the query and the second is a\n * function to actually trigger the search. The function takes the query as the parameter.\n *\n * This queryHook can be used to debounce the number of searches done from the searchBox.\n */\n queryHook?: (query: string, hook: (value: string) => void) => void;\n};\n\n/**\n * @typedef {Object} CustomSearchBoxWidgetParams\n * @property {function(string, function(string))} [queryHook = undefined] A function that will be called every time\n * a new value for the query is set. The first parameter is the query and the second is a\n * function to actually trigger the search. The function takes the query as the parameter.\n *\n * This queryHook can be used to debounce the number of searches done from the searchBox.\n */\n\nexport type SearchBoxRenderState = {\n /**\n * The query from the last search.\n */\n query: string;\n /**\n * Sets a new query and searches.\n */\n refine: (value: string) => void;\n /**\n * Remove the query and perform search.\n */\n clear: () => void;\n /**\n * `true` if the search results takes more than a certain time to come back\n * from Algolia servers. This can be configured on the InstantSearch constructor with the attribute\n * `stalledSearchDelay` which is 200ms, by default.\n */\n isSearchStalled: boolean;\n};\n\nexport type SearchBoxWidgetDescription = {\n $$type: 'ais.searchBox';\n renderState: SearchBoxRenderState;\n indexRenderState: {\n searchBox: WidgetRenderState<\n SearchBoxRenderState,\n SearchBoxConnectorParams\n >;\n };\n indexUiState: {\n query: string;\n };\n};\n\nexport type SearchBoxConnector = Connector<\n SearchBoxWidgetDescription,\n SearchBoxConnectorParams\n>;\n\n/**\n * **SearchBox** connector provides the logic to build a widget that will let the user search for a query.\n *\n * The connector provides to the rendering: `refine()` to set the query. The behaviour of this function\n * may be impacted by the `queryHook` widget parameter.\n */\nconst connectSearchBox: SearchBoxConnector = function connectSearchBox(\n renderFn,\n unmountFn = noop\n) {\n checkRendering(renderFn, withUsage());\n\n return (widgetParams) => {\n const { queryHook } = widgetParams || {};\n\n function clear(helper: AlgoliaSearchHelper) {\n return function () {\n helper.setQuery('').search();\n };\n }\n\n let _refine: SearchBoxRenderState['refine'];\n let _clear = () => {};\n function _cachedClear() {\n _clear();\n }\n\n return {\n $$type: 'ais.searchBox',\n\n init(initOptions) {\n const { instantSearchInstance } = initOptions;\n\n renderFn(\n {\n ...this.getWidgetRenderState(initOptions),\n instantSearchInstance,\n },\n true\n );\n },\n\n render(renderOptions) {\n const { instantSearchInstance } = renderOptions;\n\n renderFn(\n {\n ...this.getWidgetRenderState(renderOptions),\n instantSearchInstance,\n },\n false\n );\n },\n\n dispose({ state }) {\n unmountFn();\n\n return state.setQueryParameter('query', undefined);\n },\n\n getRenderState(renderState, renderOptions) {\n return {\n ...renderState,\n searchBox: this.getWidgetRenderState(renderOptions),\n };\n },\n\n getWidgetRenderState({ helper, searchMetadata, state }) {\n if (!_refine) {\n const setQueryAndSearch = (query: string) => {\n if (query !== state.query) {\n helper.setQuery(query).search();\n }\n };\n\n _refine = (query) => {\n if (queryHook) {\n queryHook(query, setQueryAndSearch);\n return;\n }\n\n setQueryAndSearch(query);\n };\n }\n\n _clear = clear(helper);\n\n return {\n query: state.query || '',\n refine: _refine,\n clear: _cachedClear,\n widgetParams,\n isSearchStalled: searchMetadata.isSearchStalled,\n };\n },\n\n getWidgetUiState(uiState, { searchParameters }) {\n const query = searchParameters.query || '';\n\n if (query === '' || (uiState && uiState.query === query)) {\n return uiState;\n }\n\n return {\n ...uiState,\n query,\n };\n },\n\n getWidgetSearchParameters(searchParameters, { uiState }) {\n return searchParameters.setQueryParameter('query', uiState.query || '');\n },\n };\n };\n};\n\nexport default connectSearchBox;\n","import {\n checkRendering,\n createDocumentationMessageGenerator,\n find,\n warning,\n noop,\n} from '../../lib/utils';\nimport type { Connector, TransformItems, WidgetRenderState } from '../../types';\n\nconst withUsage = createDocumentationMessageGenerator({\n name: 'sort-by',\n connector: true,\n});\n\n/**\n * The **SortBy** connector provides the logic to build a custom widget that will display a\n * list of indices. With Algolia, this is most commonly used for changing ranking strategy. This allows\n * a user to change how the hits are being sorted.\n */\n\nexport type SortByItem = {\n /**\n * The name of the index to target.\n */\n value: string;\n /**\n * The label of the index to display.\n */\n label: string;\n};\n\nexport type SortByConnectorParams = {\n /**\n * Array of objects defining the different indices to choose from.\n */\n items: SortByItem[];\n /**\n * Function to transform the items passed to the templates.\n */\n transformItems?: TransformItems<SortByItem>;\n};\n\nexport type SortByRenderState = {\n /**\n * The initially selected index.\n */\n initialIndex?: string;\n /**\n * The currently selected index.\n */\n currentRefinement: string;\n /**\n * All the available indices\n */\n options: SortByItem[];\n /**\n * Switches indices and triggers a new search.\n */\n refine: (value: string) => void;\n /**\n * `true` if the last search contains no result.\n */\n hasNoResults: boolean;\n};\n\nexport type SortByWidgetDescription = {\n $$type: 'ais.sortBy';\n renderState: SortByRenderState;\n indexRenderState: {\n sortBy: WidgetRenderState<SortByRenderState, SortByConnectorParams>;\n };\n indexUiState: {\n sortBy: string;\n };\n};\n\nexport type SortByConnector = Connector<\n SortByWidgetDescription,\n SortByConnectorParams\n>;\n\nconst connectSortBy: SortByConnector = function connectSortBy(\n renderFn,\n unmountFn = noop\n) {\n checkRendering(renderFn, withUsage());\n\n const connectorState: ConnectorState = {};\n\n type ConnectorState = {\n setIndex?(indexName: string): void;\n initialIndex?: string;\n };\n\n return (widgetParams) => {\n const { items, transformItems = ((x) => x) as TransformItems<SortByItem> } =\n widgetParams || {};\n\n if (!Array.isArray(items)) {\n throw new Error(\n withUsage('The `items` option expects an array of objects.')\n );\n }\n\n return {\n $$type: 'ais.sortBy',\n\n init(initOptions) {\n const { instantSearchInstance } = initOptions;\n\n const widgetRenderState = this.getWidgetRenderState(initOptions);\n const currentIndex = widgetRenderState.currentRefinement;\n const isCurrentIndexInItems = find(\n items,\n (item) => item.value === currentIndex\n );\n\n warning(\n isCurrentIndexInItems !== undefined,\n `The index named \"${currentIndex}\" is not listed in the \\`items\\` of \\`sortBy\\`.`\n );\n\n renderFn(\n {\n ...widgetRenderState,\n instantSearchInstance,\n },\n true\n );\n },\n\n render(renderOptions) {\n const { instantSearchInstance } = renderOptions;\n renderFn(\n {\n ...this.getWidgetRenderState(renderOptions),\n instantSearchInstance,\n },\n false\n );\n },\n\n dispose({ state }) {\n unmountFn();\n\n return connectorState.initialIndex\n ? state.setIndex(connectorState.initialIndex)\n : state;\n },\n\n getRenderState(renderState, renderOptions) {\n return {\n ...renderState,\n sortBy: this.getWidgetRenderState(renderOptions),\n };\n },\n\n getWidgetRenderState({ results, helper, state, parent }) {\n if (!connectorState.initialIndex && parent) {\n connectorState.initialIndex = parent.getIndexName();\n }\n if (!connectorState.setIndex) {\n connectorState.setIndex = (indexName) => {\n helper.setIndex(indexName).search();\n };\n }\n\n return {\n currentRefinement: state.index,\n options: transformItems(items),\n refine: connectorState.setIndex,\n hasNoResults: results ? results.nbHits === 0 : true,\n widgetParams,\n };\n },\n\n getWidgetUiState(uiState, { searchParameters }) {\n const currentIndex = searchParameters.index;\n\n return {\n ...uiState,\n sortBy:\n currentIndex !== connectorState.initialIndex\n ? currentIndex\n : undefined,\n };\n },\n\n getWidgetSearchParameters(searchParameters, { uiState }) {\n return searchParameters.setQueryParameter(\n 'index',\n uiState.sortBy ||\n connectorState.initialIndex ||\n searchParameters.index\n );\n },\n };\n };\n};\n\nexport default connectSortBy;\n","import type {\n AlgoliaSearchHelper,\n SearchParameters,\n SearchResults,\n} from 'algoliasearch-helper';\nimport {\n checkRendering,\n createDocumentationLink,\n createDocumentationMessageGenerator,\n noop,\n warning,\n} from '../../lib/utils';\nimport type {\n Connector,\n InstantSearch,\n CreateURL,\n WidgetRenderState,\n} from '../../types';\nimport type { InsightsEvent } from '../../middlewares';\n\nconst withUsage = createDocumentationMessageGenerator({\n name: 'rating-menu',\n connector: true,\n});\n\nconst $$type = 'ais.ratingMenu';\n\nconst MAX_VALUES_PER_FACET_API_LIMIT = 1000;\nconst STEP = 1;\n\ntype SendEvent = (...args: [InsightsEvent] | [string, string, string?]) => void;\n\ntype CreateSendEvent = (createSendEventArgs: {\n instantSearchInstance: InstantSearch;\n helper: AlgoliaSearchHelper;\n getRefinedStar: () => number | number[] | undefined;\n attribute: string;\n}) => SendEvent;\n\nconst createSendEvent: CreateSendEvent =\n ({ instantSearchInstance, helper, getRefinedStar, attribute }) =>\n (...args) => {\n if (args.length === 1) {\n instantSearchInstance.sendEventToInsights(args[0]);\n return;\n }\n const [eventType, facetValue, eventName = 'Filter Applied'] = args;\n if (eventType !== 'click') {\n return;\n }\n const isRefined = getRefinedStar() === Number(facetValue);\n if (!isRefined) {\n instantSearchInstance.sendEventToInsights({\n insightsMethod: 'clickedFilters',\n widgetType: $$type,\n eventType,\n payload: {\n eventName,\n index: helper.getIndex(),\n filters: [`${attribute}>=${facetValue}`],\n },\n attribute,\n });\n }\n };\n\ntype StarRatingItems = {\n /**\n * Name corresponding to the number of stars.\n */\n name: string;\n /**\n * Human-readable name corresponding to the number of stars.\n */\n label: string;\n /**\n * Number of stars as string.\n */\n value: string;\n /**\n * Count of matched results corresponding to the number of stars.\n */\n count: number;\n /**\n * Array of length of maximum rating value with stars to display or not.\n */\n stars: boolean[];\n /**\n * Indicates if star rating refinement is applied.\n */\n isRefined: boolean;\n};\n\nexport type RatingMenuConnectorParams = {\n /**\n * Name of the attribute for faceting (eg. \"free_shipping\").\n */\n attribute: string;\n\n /**\n * The maximum rating value.\n */\n max?: number;\n};\n\nexport type RatingMenuRenderState = {\n /**\n * Possible star ratings the user can apply.\n */\n items: StarRatingItems[];\n\n /**\n * Creates an URL for the next state (takes the item value as parameter). Takes the value of an item as parameter.\n */\n createURL: CreateURL<string>;\n\n /**\n * Indicates if search state can be refined.\n */\n canRefine: boolean;\n\n /**\n * Selects a rating to filter the results (takes the filter value as parameter). Takes the value of an item as parameter.\n */\n refine: (value: string) => void;\n\n /**\n * `true` if the last search contains no result.\n */\n hasNoResults: boolean;\n\n /**\n * Send event to insights middleware\n */\n sendEvent: SendEvent;\n};\n\nexport type RatingMenuWidgetDescription = {\n $$type: 'ais.ratingMenu';\n renderState: RatingMenuRenderState;\n indexRenderState: {\n ratingMenu: {\n [attribute: string]: WidgetRenderState<\n RatingMenuRenderState,\n RatingMenuConnectorParams\n >;\n };\n };\n indexUiState: {\n ratingMenu: {\n [attribute: string]: number;\n };\n };\n};\n\nexport type RatingMenuConnector = Connector<\n RatingMenuWidgetDescription,\n RatingMenuConnectorParams\n>;\n\n/**\n * **StarRating** connector provides the logic to build a custom widget that will let\n * the user refine search results based on ratings.\n *\n * The connector provides to the rendering: `refine()` to select a value and\n * `items` that are the values that can be selected. `refine` should be used\n * with `items.value`.\n */\nconst connectRatingMenu: RatingMenuConnector = function connectRatingMenu(\n renderFn,\n unmountFn = noop\n) {\n checkRendering(renderFn, withUsage());\n\n return (widgetParams) => {\n const { attribute, max = 5 } = widgetParams || {};\n let sendEvent: SendEvent;\n\n if (!attribute) {\n throw new Error(withUsage('The `attribute` option is required.'));\n }\n\n const getRefinedStar = (state: SearchParameters) => {\n const values = state.getNumericRefinements(attribute);\n\n if (!values['>=']?.length) {\n return undefined;\n }\n\n return values['>='][0];\n };\n\n const getFacetsMaxDecimalPlaces = (\n facetResults: SearchResults.FacetValue[]\n ) => {\n let maxDecimalPlaces = 0;\n facetResults.forEach((facetResult) => {\n const [, decimal = ''] = facetResult.name.split('.');\n maxDecimalPlaces = Math.max(maxDecimalPlaces, decimal.length);\n });\n return maxDecimalPlaces;\n };\n\n const getFacetValuesWarningMessage = ({\n maxDecimalPlaces,\n maxFacets,\n maxValuesPerFacet,\n }: {\n maxDecimalPlaces: number;\n maxFacets: number;\n maxValuesPerFacet: number;\n }) => {\n const maxDecimalPlacesInRange = Math.max(\n 0,\n Math.floor(Math.log10(MAX_VALUES_PER_FACET_API_LIMIT / max))\n );\n const maxFacetsInRange = Math.min(\n MAX_VALUES_PER_FACET_API_LIMIT,\n Math.pow(10, maxDecimalPlacesInRange) * max\n );\n\n const solutions: string[] = [];\n\n if (maxFacets > MAX_VALUES_PER_FACET_API_LIMIT) {\n solutions.push(\n `- Update your records to lower the precision of the values in the \"${attribute}\" attribute (for example: ${(5.123456789).toPrecision(\n maxDecimalPlaces + 1\n )} to ${(5.123456789).toPrecision(maxDecimalPlacesInRange + 1)})`\n );\n }\n if (maxValuesPerFacet < maxFacetsInRange) {\n solutions.push(\n `- Increase the maximum number of facet values to ${maxFacetsInRange} using the \"configure\" widget ${createDocumentationLink(\n { name: 'configure' }\n )} and the \"maxValuesPerFacet\" parameter https://www.algolia.com/doc/api-reference/api-parameters/maxValuesPerFacet/`\n );\n }\n\n return `The ${attribute} attribute can have ${maxFacets} different values (0 to ${max} with a maximum of ${maxDecimalPlaces} decimals = ${maxFacets}) but you retrieved only ${maxValuesPerFacet} facet values. Therefore the number of results that match the refinements can be incorrect.\n ${\n solutions.length\n ? `To resolve this problem you can:\\n${solutions.join('\\n')}`\n : ``\n }`;\n };\n\n function getRefinedState(state: SearchParameters, facetValue: string) {\n const isRefined = getRefinedStar(state) === Number(facetValue);\n\n const emptyState = state.resetPage().removeNumericRefinement(attribute);\n\n if (!isRefined) {\n return emptyState\n .addNumericRefinement(attribute, '<=', max)\n .addNumericRefinement(attribute, '>=', Number(facetValue));\n }\n return emptyState;\n }\n\n const toggleRefinement = (\n helper: AlgoliaSearchHelper,\n facetValue: string\n ) => {\n sendEvent('click', facetValue);\n helper.setState(getRefinedState(helper.state, facetValue)).search();\n };\n\n type ConnectorState = {\n toggleRefinementFactory: (\n helper: AlgoliaSearchHelper\n ) => (facetValue: string) => void;\n createURLFactory: ({\n state,\n createURL,\n }: {\n state: SearchParameters;\n createURL: (createURLState: SearchParameters) => string;\n }) => (value: string) => string;\n };\n\n const connectorState: ConnectorState = {\n toggleRefinementFactory: (helper) => toggleRefinement.bind(null, helper),\n createURLFactory:\n ({ state, createURL }) =>\n (value) =>\n createURL(getRefinedState(state, value)),\n };\n\n return {\n $$type,\n\n init(initOptions) {\n const { instantSearchInstance } = initOptions;\n\n renderFn(\n {\n ...this.getWidgetRenderState(initOptions),\n instantSearchInstance,\n },\n true\n );\n },\n\n render(renderOptions) {\n const { instantSearchInstance } = renderOptions;\n\n renderFn(\n {\n ...this.getWidgetRenderState(renderOptions),\n instantSearchInstance,\n },\n false\n );\n },\n\n getRenderState(renderState, renderOptions) {\n return {\n ...renderState,\n ratingMenu: {\n ...renderState.ratingMenu,\n [attribute]: this.getWidgetRenderState(renderOptions),\n },\n };\n },\n\n getWidgetRenderState({\n helper,\n results,\n state,\n instantSearchInstance,\n createURL,\n }) {\n let facetValues: StarRatingItems[] = [];\n\n if (!sendEvent) {\n sendEvent = createSendEvent({\n instantSearchInstance,\n helper,\n getRefinedStar: () => getRefinedStar(helper.state),\n attribute,\n });\n }\n\n if (results) {\n const facetResults = results.getFacetValues(\n attribute,\n {}\n ) as SearchResults.FacetValue[];\n const maxValuesPerFacet = facetResults.length;\n\n const maxDecimalPlaces = getFacetsMaxDecimalPlaces(facetResults);\n const maxFacets = Math.pow(10, maxDecimalPlaces) * max;\n\n warning(\n maxFacets <= maxValuesPerFacet,\n getFacetValuesWarningMessage({\n maxDecimalPlaces,\n maxFacets,\n maxValuesPerFacet,\n })\n );\n\n const refinedStar = getRefinedStar(state);\n\n for (let star = STEP; star < max; star += STEP) {\n const isRefined = refinedStar === star;\n\n const count = facetResults\n .filter((f) => Number(f.name) >= star && Number(f.name) <= max)\n .map((f) => f.count)\n .reduce((sum, current) => sum + current, 0);\n\n if (refinedStar && !isRefined && count === 0) {\n // skip count==0 when at least 1 refinement is enabled\n // eslint-disable-next-line no-continue\n continue;\n }\n\n const stars = [...new Array(Math.floor(max / STEP))].map(\n (_v, i) => i * STEP < star\n );\n\n facetValues.push({\n stars,\n name: String(star),\n label: String(star),\n value: String(star),\n count,\n isRefined,\n });\n }\n }\n facetValues = facetValues.reverse();\n\n return {\n items: facetValues,\n hasNoResults: results ? results.nbHits === 0 : true,\n canRefine: facetValues.length > 0,\n refine: connectorState.toggleRefinementFactory(helper),\n sendEvent,\n createURL: connectorState.createURLFactory({ state, createURL }),\n widgetParams,\n };\n },\n\n dispose({ state }) {\n unmountFn();\n\n return state.removeNumericRefinement(attribute);\n },\n\n getWidgetUiState(uiState, { searchParameters }) {\n const value = getRefinedStar(searchParameters);\n\n if (typeof value !== 'number') {\n return uiState;\n }\n\n return {\n ...uiState,\n ratingMenu: {\n ...uiState.ratingMenu,\n [attribute]: value,\n },\n };\n },\n\n getWidgetSearchParameters(searchParameters, { uiState }) {\n const value = uiState.ratingMenu && uiState.ratingMenu[attribute];\n\n const withoutRefinements = searchParameters.clearRefinements(attribute);\n const withDisjunctiveFacet =\n withoutRefinements.addDisjunctiveFacet(attribute);\n\n if (!value) {\n return withDisjunctiveFacet.setQueryParameters({\n numericRefinements: {\n ...withDisjunctiveFacet.numericRefinements,\n [attribute]: {},\n },\n });\n }\n\n return withDisjunctiveFacet\n .addNumericRefinement(attribute, '<=', max)\n .addNumericRefinement(attribute, '>=', value);\n },\n };\n };\n};\n\nexport default connectRatingMenu;\n","import {\n checkRendering,\n createDocumentationMessageGenerator,\n noop,\n} from '../../lib/utils';\nimport type { Connector, WidgetRenderState } from '../../types';\n\nconst withUsage = createDocumentationMessageGenerator({\n name: 'stats',\n connector: true,\n});\n\n/**\n * **Stats** connector provides the logic to build a custom widget that will displays\n * search statistics (hits number and processing time).\n */\n\nexport type StatsRenderState = {\n /**\n * The maximum number of hits per page returned by Algolia.\n */\n hitsPerPage?: number;\n /**\n * The number of hits in the result set.\n */\n nbHits: number;\n /**\n * The number of sorted hits in the result set (when using Relevant sort).\n */\n nbSortedHits?: number;\n /**\n * Indicates whether the index is currently using Relevant sort and is displaying only sorted hits.\n */\n areHitsSorted: boolean;\n /**\n * The number of pages computed for the result set.\n */\n nbPages: number;\n /**\n * The current page.\n */\n page: number;\n /**\n * The time taken to compute the results inside the Algolia engine.\n */\n processingTimeMS: number;\n /**\n * The query used for the current search.\n */\n query: string;\n};\n\nexport type StatsConnectorParams = Record<string, unknown>;\n\nexport type StatsWidgetDescription = {\n $$type: 'ais.stats';\n renderState: StatsRenderState;\n indexRenderState: {\n stats: WidgetRenderState<StatsRenderState, StatsConnectorParams>;\n };\n};\n\nexport type StatsConnector = Connector<\n StatsWidgetDescription,\n StatsConnectorParams\n>;\n\nconst connectStats: StatsConnector = function connectStats(\n renderFn,\n unmountFn = noop\n) {\n checkRendering(renderFn, withUsage());\n\n return (widgetParams) => ({\n $$type: 'ais.stats',\n\n init(initOptions) {\n const { instantSearchInstance } = initOptions;\n\n renderFn(\n {\n ...this.getWidgetRenderState(initOptions),\n instantSearchInstance,\n },\n true\n );\n },\n\n render(renderOptions) {\n const { instantSearchInstance } = renderOptions;\n\n renderFn(\n {\n ...this.getWidgetRenderState(renderOptions),\n instantSearchInstance,\n },\n false\n );\n },\n\n dispose() {\n unmountFn();\n },\n\n getRenderState(renderState, renderOptions) {\n return {\n ...renderState,\n stats: this.getWidgetRenderState(renderOptions),\n };\n },\n\n getWidgetRenderState({ results, state }) {\n if (!results) {\n return {\n hitsPerPage: state.hitsPerPage,\n nbHits: 0,\n nbSortedHits: undefined,\n areHitsSorted: false,\n nbPages: 0,\n page: state.page || 0,\n processingTimeMS: -1,\n query: state.query || '',\n widgetParams,\n };\n }\n\n return {\n hitsPerPage: results.hitsPerPage,\n nbHits: results.nbHits,\n nbSortedHits: results.nbSortedHits,\n areHitsSorted:\n typeof results.appliedRelevancyStrictness !== 'undefined' &&\n results.appliedRelevancyStrictness > 0 &&\n results.nbSortedHits !== results.nbHits,\n nbPages: results.nbPages,\n page: results.page,\n processingTimeMS: results.processingTimeMS,\n query: results.query,\n widgetParams,\n };\n },\n });\n};\n\nexport default connectStats;\n","import type {\n AlgoliaSearchHelper,\n SearchParameters,\n SearchResults,\n} from 'algoliasearch-helper';\nimport {\n checkRendering,\n escapeRefinement,\n unescapeRefinement,\n createDocumentationMessageGenerator,\n find,\n noop,\n toArray,\n} from '../../lib/utils';\nimport type {\n Connector,\n CreateURL,\n InstantSearch,\n WidgetRenderState,\n} from '../../types';\n\nconst withUsage = createDocumentationMessageGenerator({\n name: 'toggle-refinement',\n connector: true,\n});\n\nconst $$type = 'ais.toggleRefinement';\n\ntype BuiltInSendEventForToggle = (\n eventType: string,\n isRefined: boolean,\n eventName?: string\n) => void;\ntype CustomSendEventForToggle = (customPayload: any) => void;\n\nexport type SendEventForToggle = BuiltInSendEventForToggle &\n CustomSendEventForToggle;\n\nconst createSendEvent = ({\n instantSearchInstance,\n helper,\n attribute,\n on,\n}: {\n instantSearchInstance: InstantSearch;\n helper: AlgoliaSearchHelper;\n attribute: string;\n on: string[] | undefined;\n}) => {\n const sendEventForToggle: SendEventForToggle = (...args: any[]) => {\n if (args.length === 1) {\n instantSearchInstance.sendEventToInsights(args[0]);\n return;\n }\n const [eventType, isRefined, eventName = 'Filter Applied'] = args;\n if (eventType !== 'click' || on === undefined) {\n return;\n }\n\n // only send an event when the refinement gets applied,\n // not when it gets removed\n if (!isRefined) {\n instantSearchInstance.sendEventToInsights({\n insightsMethod: 'clickedFilters',\n widgetType: $$type,\n eventType,\n payload: {\n eventName,\n index: helper.getIndex(),\n filters: on.map((value) => `${attribute}:${value}`),\n },\n attribute,\n });\n }\n };\n return sendEventForToggle;\n};\n\nexport type ToggleRefinementValue = {\n /** whether this option is enabled */\n isRefined: boolean;\n /** number of result if this option is enabled */\n count: number | null;\n};\n\nexport type ToggleRefinementConnectorParams = {\n /** Name of the attribute for faceting (eg. \"free_shipping\"). */\n attribute: string;\n /**\n * Value to filter on when toggled.\n * @default \"true\"\n */\n on?: string | string[] | boolean | boolean[] | number | number[];\n /**\n * Value to filter on when not toggled.\n */\n off?: string | string[] | boolean | boolean[] | number | number[];\n};\n\nexport type ToggleRefinementRenderState = {\n /** The current toggle value */\n value: {\n name: string;\n isRefined: boolean;\n count: number | null;\n onFacetValue: ToggleRefinementValue;\n offFacetValue: ToggleRefinementValue;\n };\n /** Creates an URL for the next state. */\n createURL: CreateURL<string>;\n /** send a \"facet clicked\" insights event */\n sendEvent: SendEventForToggle;\n /** Indicates if search state can be refined. */\n canRefine: boolean;\n /** Updates to the next state by applying the toggle refinement. */\n refine: (value?: { isRefined: boolean }) => void;\n};\n\nexport type ToggleRefinementWidgetDescription = {\n $$type: 'ais.toggleRefinement';\n renderState: ToggleRefinementRenderState;\n indexRenderState: {\n toggleRefinement: {\n [attribute: string]: WidgetRenderState<\n ToggleRefinementRenderState,\n ToggleRefinementConnectorParams\n >;\n };\n };\n indexUiState: {\n toggle: {\n [attribute: string]: boolean;\n };\n };\n};\n\nexport type ToggleRefinementConnector = Connector<\n ToggleRefinementWidgetDescription,\n ToggleRefinementConnectorParams\n>;\n\n/**\n * **Toggle** connector provides the logic to build a custom widget that will provide\n * an on/off filtering feature based on an attribute value or values.\n *\n * Two modes are implemented in the custom widget:\n * - with or without the value filtered\n * - switch between two values.\n */\nconst connectToggleRefinement: ToggleRefinementConnector =\n function connectToggleRefinement(renderFn, unmountFn = noop) {\n checkRendering(renderFn, withUsage());\n\n return (widgetParams) => {\n const { attribute, on: userOn = true, off: userOff } = widgetParams || {};\n\n if (!attribute) {\n throw new Error(withUsage('The `attribute` option is required.'));\n }\n\n const hasAnOffValue = userOff !== undefined;\n const on = toArray(userOn).map(escapeRefinement);\n const off = hasAnOffValue\n ? toArray(userOff).map(escapeRefinement)\n : undefined;\n\n let sendEvent: SendEventForToggle;\n\n const toggleRefinementFactory =\n (helper: AlgoliaSearchHelper) =>\n (\n {\n isRefined,\n }: {\n isRefined: boolean;\n } = { isRefined: false }\n ) => {\n if (!isRefined) {\n sendEvent('click', isRefined);\n if (hasAnOffValue) {\n off!.forEach((v) =>\n helper.removeDisjunctiveFacetRefinement(attribute, v)\n );\n }\n\n on.forEach((v) =>\n helper.addDisjunctiveFacetRefinement(attribute, v)\n );\n } else {\n on.forEach((v) =>\n helper.removeDisjunctiveFacetRefinement(attribute, v)\n );\n\n if (hasAnOffValue) {\n off!.forEach((v) =>\n helper.addDisjunctiveFacetRefinement(attribute, v)\n );\n }\n }\n\n helper.search();\n };\n\n const connectorState = {\n createURLFactory:\n (\n isRefined: boolean,\n {\n state,\n createURL,\n }: {\n state: SearchParameters;\n createURL(parameters: SearchParameters): string;\n }\n ) =>\n () => {\n state = state.resetPage();\n\n const valuesToRemove = isRefined ? on : off;\n if (valuesToRemove) {\n valuesToRemove.forEach((v) => {\n state = state.removeDisjunctiveFacetRefinement(attribute, v);\n });\n }\n\n const valuesToAdd = isRefined ? off : on;\n if (valuesToAdd) {\n valuesToAdd.forEach((v) => {\n state = state.addDisjunctiveFacetRefinement(attribute, v);\n });\n }\n\n return createURL(state);\n },\n };\n\n return {\n $$type,\n\n init(initOptions) {\n const { instantSearchInstance } = initOptions;\n\n renderFn(\n {\n ...this.getWidgetRenderState(initOptions),\n instantSearchInstance,\n },\n true\n );\n },\n\n render(renderOptions) {\n const { instantSearchInstance } = renderOptions;\n\n renderFn(\n {\n ...this.getWidgetRenderState(renderOptions),\n instantSearchInstance,\n },\n false\n );\n },\n\n dispose({ state }) {\n unmountFn();\n\n return state.removeDisjunctiveFacet(attribute);\n },\n\n getRenderState(renderState, renderOptions) {\n return {\n ...renderState,\n toggleRefinement: {\n ...renderState.toggleRefinement,\n [attribute]: this.getWidgetRenderState(renderOptions),\n },\n };\n },\n\n getWidgetRenderState({\n state,\n helper,\n results,\n createURL,\n instantSearchInstance,\n }) {\n const isRefined = results\n ? on.every((v) => state.isDisjunctiveFacetRefined(attribute, v))\n : on.every((v) => state.isDisjunctiveFacetRefined(attribute, v));\n\n let onFacetValue: ToggleRefinementValue = {\n isRefined,\n count: 0,\n };\n\n let offFacetValue: ToggleRefinementValue = {\n isRefined: hasAnOffValue && !isRefined,\n count: 0,\n };\n\n if (results) {\n const offValue = toArray(off || false);\n const allFacetValues = (results.getFacetValues(attribute, {}) ||\n []) as SearchResults.FacetValue[];\n\n const onData = on\n .map((v) =>\n find(\n allFacetValues,\n ({ name }) => name === unescapeRefinement(v)\n )\n )\n .filter((v): v is SearchResults.FacetValue => v !== undefined);\n\n const offData = hasAnOffValue\n ? offValue\n .map((v) =>\n find(\n allFacetValues,\n ({ name }) => name === unescapeRefinement(v)\n )\n )\n .filter((v): v is SearchResults.FacetValue => v !== undefined)\n : [];\n\n onFacetValue = {\n isRefined: onData.length\n ? onData.every((v) => v.isRefined)\n : false,\n count: onData.reduce((acc, v) => acc + v.count, 0) || null,\n };\n\n offFacetValue = {\n isRefined: offData.length\n ? offData.every((v) => v.isRefined)\n : false,\n count:\n offData.reduce((acc, v) => acc + v.count, 0) ||\n allFacetValues.reduce((total, { count }) => total + count, 0),\n };\n }\n\n if (!sendEvent) {\n sendEvent = createSendEvent({\n instantSearchInstance,\n attribute,\n on,\n helper,\n });\n }\n const nextRefinement = isRefined ? offFacetValue : onFacetValue;\n\n return {\n value: {\n name: attribute,\n isRefined,\n count: results ? nextRefinement.count : null,\n onFacetValue,\n offFacetValue,\n },\n createURL: connectorState.createURLFactory(isRefined, {\n state,\n createURL,\n }),\n sendEvent,\n canRefine: Boolean(results ? nextRefinement.count : null),\n refine: toggleRefinementFactory(helper),\n widgetParams,\n };\n },\n\n getWidgetUiState(uiState, { searchParameters }) {\n const isRefined =\n on &&\n on.every((v) =>\n searchParameters.isDisjunctiveFacetRefined(attribute, v)\n );\n\n if (!isRefined) {\n return uiState;\n }\n\n return {\n ...uiState,\n toggle: {\n ...uiState.toggle,\n [attribute]: isRefined,\n },\n };\n },\n\n getWidgetSearchParameters(searchParameters, { uiState }) {\n let withFacetConfiguration = searchParameters\n .clearRefinements(attribute)\n .addDisjunctiveFacet(attribute);\n\n const isRefined = Boolean(\n uiState.toggle && uiState.toggle[attribute]\n );\n\n if (isRefined) {\n if (on) {\n on.forEach((v) => {\n withFacetConfiguration =\n withFacetConfiguration.addDisjunctiveFacetRefinement(\n attribute,\n v\n );\n });\n }\n\n return withFacetConfiguration;\n }\n\n // It's not refined with an `off` value\n if (hasAnOffValue) {\n if (off) {\n off.forEach((v) => {\n withFacetConfiguration =\n withFacetConfiguration.addDisjunctiveFacetRefinement(\n attribute,\n v\n );\n });\n }\n return withFacetConfiguration;\n }\n\n // It's not refined without an `off` value\n return withFacetConfiguration.setQueryParameters({\n disjunctiveFacetsRefinements: {\n ...searchParameters.disjunctiveFacetsRefinements,\n [attribute]: [],\n },\n });\n },\n };\n };\n };\n\nexport default connectToggleRefinement;\n","import {\n checkRendering,\n warning,\n createDocumentationMessageGenerator,\n isEqual,\n noop,\n} from '../../lib/utils';\nimport type { SearchParameters, SearchResults } from 'algoliasearch-helper';\nimport type {\n Connector,\n TransformItems,\n CreateURL,\n WidgetRenderState,\n} from '../../types';\n\nconst withUsage = createDocumentationMessageGenerator({\n name: 'breadcrumb',\n connector: true,\n});\n\nexport type BreadcrumbConnectorParamsItem = {\n /**\n * Label of the category or subcategory.\n */\n label: string;\n\n /**\n * Value of breadcrumb item.\n */\n value: string | null;\n};\n\nexport type BreadcrumbConnectorParams = {\n /**\n * Attributes to use to generate the hierarchy of the breadcrumb.\n */\n attributes: string[];\n\n /**\n * Prefix path to use if the first level is not the root level.\n */\n rootPath?: string;\n\n /**\n * Function to transform the items passed to the templates.\n */\n transformItems?: TransformItems<BreadcrumbConnectorParamsItem>;\n\n /**\n * The level separator used in the records.\n *\n * @default '>'\n */\n separator?: string;\n};\n\nexport type BreadcrumbRenderState = {\n /**\n * Creates the URL for a single item name in the list.\n */\n createURL: CreateURL<BreadcrumbConnectorParamsItem['value']>;\n\n /**\n * Array of objects defining the different values and labels.\n */\n items: BreadcrumbConnectorParamsItem[];\n\n /**\n * Sets the path of the hierarchical filter and triggers a new search.\n */\n refine: (value: BreadcrumbConnectorParamsItem['value']) => void;\n\n /**\n * True if refinement can be applied.\n */\n canRefine: boolean;\n};\n\nexport type BreadcrumbWidgetDescription = {\n $$type: 'ais.breadcrumb';\n renderState: BreadcrumbRenderState;\n indexRenderState: {\n breadcrumb: {\n [rootAttribute: string]: WidgetRenderState<\n BreadcrumbRenderState,\n BreadcrumbConnectorParams\n >;\n };\n };\n};\n\nexport type BreadcrumbConnector = Connector<\n BreadcrumbWidgetDescription,\n BreadcrumbConnectorParams\n>;\n\nconst connectBreadcrumb: BreadcrumbConnector = function connectBreadcrumb(\n renderFn,\n unmountFn = noop\n) {\n checkRendering(renderFn, withUsage());\n\n type ConnectorState = {\n refine?: BreadcrumbRenderState['refine'];\n createURL?: BreadcrumbRenderState['createURL'];\n };\n\n const connectorState: ConnectorState = {};\n\n return (widgetParams) => {\n const {\n attributes,\n separator = ' > ',\n rootPath = null,\n transformItems = ((items) =>\n items) as TransformItems<BreadcrumbConnectorParamsItem>,\n } = widgetParams || {};\n\n if (!attributes || !Array.isArray(attributes) || attributes.length === 0) {\n throw new Error(\n withUsage('The `attributes` option expects an array of strings.')\n );\n }\n\n const [hierarchicalFacetName] = attributes;\n\n function getRefinedState(\n state: SearchParameters,\n facetValue: string | null\n ) {\n if (!facetValue) {\n const breadcrumb = state.getHierarchicalFacetBreadcrumb(\n hierarchicalFacetName\n );\n if (breadcrumb.length > 0) {\n return state\n .resetPage()\n .toggleFacetRefinement(hierarchicalFacetName, breadcrumb[0]);\n }\n }\n return state\n .resetPage()\n .toggleFacetRefinement(hierarchicalFacetName, facetValue);\n }\n\n return {\n $$type: 'ais.breadcrumb',\n\n init(initOptions) {\n renderFn(\n {\n ...this.getWidgetRenderState(initOptions),\n instantSearchInstance: initOptions.instantSearchInstance,\n },\n true\n );\n },\n\n render(renderOptions) {\n renderFn(\n {\n ...this.getWidgetRenderState(renderOptions),\n instantSearchInstance: renderOptions.instantSearchInstance,\n },\n false\n );\n },\n\n dispose() {\n unmountFn();\n },\n\n getRenderState(renderState, renderOptions) {\n return {\n ...renderState,\n breadcrumb: {\n ...renderState.breadcrumb,\n [hierarchicalFacetName]: this.getWidgetRenderState(renderOptions),\n },\n };\n },\n\n getWidgetRenderState({ helper, createURL, results, state }) {\n function getItems() {\n if (!results) {\n return [];\n }\n\n const [{ name: facetName }] = state.hierarchicalFacets;\n\n const facetValues = results.getFacetValues(\n facetName,\n {}\n ) as SearchResults.HierarchicalFacet;\n const data = Array.isArray(facetValues.data) ? facetValues.data : [];\n const items = transformItems(shiftItemsValues(prepareItems(data)));\n\n return items;\n }\n\n const items = getItems();\n\n if (!connectorState.createURL) {\n connectorState.createURL = (facetValue) => {\n return createURL(getRefinedState(helper.state, facetValue));\n };\n }\n\n if (!connectorState.refine) {\n connectorState.refine = (facetValue) => {\n helper.setState(getRefinedState(helper.state, facetValue)).search();\n };\n }\n\n return {\n canRefine: items.length > 0,\n createURL: connectorState.createURL,\n items,\n refine: connectorState.refine,\n widgetParams,\n };\n },\n\n getWidgetSearchParameters(searchParameters) {\n if (searchParameters.isHierarchicalFacet(hierarchicalFacetName)) {\n const facet = searchParameters.getHierarchicalFacetByName(\n hierarchicalFacetName\n );\n\n warning(\n isEqual(facet.attributes, attributes) &&\n facet.separator === separator &&\n facet.rootPath === rootPath,\n 'Using Breadcrumb and HierarchicalMenu on the same facet with different options overrides the configuration of the HierarchicalMenu.'\n );\n\n return searchParameters;\n }\n\n return searchParameters.addHierarchicalFacet({\n name: hierarchicalFacetName,\n attributes,\n separator,\n rootPath,\n });\n },\n };\n };\n};\n\nfunction prepareItems(data: SearchResults.HierarchicalFacet[]) {\n return data.reduce<BreadcrumbConnectorParamsItem[]>((result, currentItem) => {\n if (currentItem.isRefined) {\n result.push({\n label: currentItem.name,\n value: currentItem.path,\n });\n if (Array.isArray(currentItem.data)) {\n result = result.concat(prepareItems(currentItem.data));\n }\n }\n return result;\n }, []);\n}\n\nfunction shiftItemsValues(array: BreadcrumbConnectorParamsItem[]) {\n return array.map((x, idx) => ({\n label: x.label,\n value: idx + 1 === array.length ? null : array[idx + 1].value,\n }));\n}\n\nexport default connectBreadcrumb;\n","import type {\n AlgoliaSearchHelper,\n SearchParameters,\n} from 'algoliasearch-helper';\nimport type { SendEventForHits } from '../../lib/utils';\nimport {\n checkRendering,\n aroundLatLngToPosition,\n insideBoundingBoxToBoundingBox,\n createDocumentationMessageGenerator,\n createSendEventForHits,\n noop,\n} from '../../lib/utils';\nimport type {\n Connector,\n GeoLoc,\n Hit,\n InitOptions,\n RenderOptions,\n TransformItems,\n WidgetRenderState,\n} from '../../types';\n\nconst withUsage = createDocumentationMessageGenerator({\n name: 'geo-search',\n connector: true,\n});\n\n// in this connector, we assume insideBoundingBox is only a string,\n// even though in the helper it's defined as number[][] alone.\n// This can be done, since the connector assumes \"control\" of the parameter\nfunction getBoundingBoxAsString(state: SearchParameters) {\n return (state.insideBoundingBox as unknown as string) || '';\n}\nfunction setBoundingBoxAsString(state: SearchParameters, value: string) {\n return state.setQueryParameter(\n 'insideBoundingBox',\n value as unknown as number[][]\n );\n}\n\nexport type GeoHit = Hit & Required<Pick<Hit, '_geoLoc'>>;\n\ntype Bounds = {\n /**\n * The top right corner of the map view.\n */\n northEast: GeoLoc;\n /**\n * The bottom left corner of the map view.\n */\n southWest: GeoLoc;\n};\n\nexport type GeoSearchRenderState = {\n /**\n * Reset the current bounding box refinement.\n */\n clearMapRefinement(): void;\n /**\n * The current bounding box of the search.\n */\n currentRefinement?: Bounds;\n /**\n * Return true if the map has move since the last refinement.\n */\n hasMapMoveSinceLastRefine(): boolean;\n /**\n * Return true if the current refinement is set with the map bounds.\n */\n isRefinedWithMap(): boolean;\n /**\n * Return true if the user is able to refine on map move.\n */\n isRefineOnMapMove(): boolean;\n /**\n * The matched hits from Algolia API.\n */\n items: GeoHit[];\n /**\n * The current position of the search.\n */\n position?: GeoLoc;\n /**\n * Sets a bounding box to filter the results from the given map bounds.\n */\n refine(bounds: Bounds): void;\n /**\n * Send event to insights middleware\n */\n sendEvent: SendEventForHits;\n /**\n * Set the fact that the map has moved since the last refinement, should be\n * called on each map move. The call to the function triggers a new rendering\n * only when the value change.\n */\n setMapMoveSinceLastRefine(): void;\n /**\n * Toggle the fact that the user is able to refine on map move.\n */\n toggleRefineOnMapMove(): void;\n};\n\nexport type GeoSearchConnectorParams = {\n /**\n * If true, refine will be triggered as you move the map.\n * @default true\n */\n enableRefineOnMapMove?: boolean;\n /**\n * Function to transform the items passed to the templates.\n * @default items => items\n */\n transformItems?: TransformItems<GeoHit>;\n};\n\nconst $$type = 'ais.geoSearch';\n\nexport type GeoSearchWidgetDescription = {\n $$type: 'ais.geoSearch';\n renderState: GeoSearchRenderState;\n indexRenderState: {\n geoSearch: WidgetRenderState<\n GeoSearchRenderState,\n GeoSearchConnectorParams\n >;\n };\n indexUiState: {\n geoSearch: {\n /**\n * The rectangular area in geo coordinates.\n * The rectangle is defined by two diagonally opposite points,\n * hence by 4 floats separated by commas.\n *\n * @example '47.3165,4.9665,47.3424,5.0201'\n */\n boundingBox: string;\n };\n };\n};\n\nexport type GeoSearchConnector = Connector<\n GeoSearchWidgetDescription,\n GeoSearchConnectorParams\n>;\n\n/**\n * The **GeoSearch** connector provides the logic to build a widget that will display the results on a map. It also provides a way to search for results based on their position. The connector provides functions to manage the search experience (search on map interaction or control the interaction for example).\n *\n * @requirements\n *\n * Note that the GeoSearch connector uses the [geosearch](https://www.algolia.com/doc/guides/searching/geo-search) capabilities of Algolia. Your hits **must** have a `_geoloc` attribute in order to be passed to the rendering function.\n *\n * Currently, the feature is not compatible with multiple values in the _geoloc attribute.\n */\nconst connectGeoSearch: GeoSearchConnector = (renderFn, unmountFn = noop) => {\n checkRendering(renderFn, withUsage());\n\n return (widgetParams) => {\n const {\n enableRefineOnMapMove = true,\n transformItems = ((items) => items) as TransformItems<GeoHit>,\n } = widgetParams || {};\n\n const widgetState = {\n isRefineOnMapMove: enableRefineOnMapMove,\n // @MAJOR hasMapMoveSinceLastRefine -> hasMapMovedSinceLastRefine\n hasMapMoveSinceLastRefine: false,\n lastRefinePosition: '',\n lastRefineBoundingBox: '',\n internalToggleRefineOnMapMove: noop,\n internalSetMapMoveSinceLastRefine: noop,\n };\n\n const getPositionFromState = (state: SearchParameters) =>\n state.aroundLatLng\n ? aroundLatLngToPosition(state.aroundLatLng)\n : undefined;\n\n const getCurrentRefinementFromState = (state: SearchParameters) =>\n state.insideBoundingBox &&\n insideBoundingBoxToBoundingBox(state.insideBoundingBox);\n\n const refine =\n (helper: AlgoliaSearchHelper) =>\n ({ northEast: ne, southWest: sw }: Bounds) => {\n const boundingBox = [ne.lat, ne.lng, sw.lat, sw.lng].join();\n\n helper\n .setState(\n setBoundingBoxAsString(helper.state, boundingBox).resetPage()\n )\n .search();\n\n widgetState.hasMapMoveSinceLastRefine = false;\n widgetState.lastRefineBoundingBox = boundingBox;\n };\n\n const clearMapRefinement = (helper: AlgoliaSearchHelper) => () => {\n helper.setQueryParameter('insideBoundingBox', undefined).search();\n };\n\n const isRefinedWithMap = (state: SearchParameters) => () =>\n Boolean(state.insideBoundingBox);\n\n const toggleRefineOnMapMove = () =>\n widgetState.internalToggleRefineOnMapMove();\n const createInternalToggleRefinementOnMapMove =\n <TRenderOptions extends RenderOptions | InitOptions>(\n renderOptions: TRenderOptions,\n // false positive eslint because of generics\n // eslint-disable-next-line no-shadow\n render: (renderOptions: TRenderOptions) => void\n ) =>\n () => {\n widgetState.isRefineOnMapMove = !widgetState.isRefineOnMapMove;\n\n render(renderOptions);\n };\n\n const isRefineOnMapMove = () => widgetState.isRefineOnMapMove;\n\n const setMapMoveSinceLastRefine = () =>\n widgetState.internalSetMapMoveSinceLastRefine();\n const createInternalSetMapMoveSinceLastRefine =\n <TRenderOptions extends RenderOptions | InitOptions>(\n renderOptions: TRenderOptions,\n // false positive eslint because of generics\n // eslint-disable-next-line no-shadow\n render: (renderOptions: TRenderOptions) => void\n ) =>\n () => {\n const shouldTriggerRender =\n widgetState.hasMapMoveSinceLastRefine !== true;\n\n widgetState.hasMapMoveSinceLastRefine = true;\n\n if (shouldTriggerRender) {\n render(renderOptions);\n }\n };\n\n const hasMapMoveSinceLastRefine = () =>\n widgetState.hasMapMoveSinceLastRefine;\n\n let sendEvent: SendEventForHits;\n\n return {\n $$type,\n\n init(initArgs) {\n const { instantSearchInstance } = initArgs;\n const isFirstRendering = true;\n\n widgetState.internalToggleRefineOnMapMove =\n createInternalToggleRefinementOnMapMove(initArgs, noop);\n\n widgetState.internalSetMapMoveSinceLastRefine =\n createInternalSetMapMoveSinceLastRefine(initArgs, noop);\n\n renderFn(\n {\n ...this.getWidgetRenderState(initArgs),\n instantSearchInstance,\n },\n isFirstRendering\n );\n },\n\n render(renderArgs) {\n const { helper, instantSearchInstance } = renderArgs;\n const isFirstRendering = false;\n // We don't use the state provided by the render function because we need\n // to be sure that the state is the latest one for the following condition\n const state = helper.state;\n\n const positionChangedSinceLastRefine =\n Boolean(state.aroundLatLng) &&\n Boolean(widgetState.lastRefinePosition) &&\n state.aroundLatLng !== widgetState.lastRefinePosition;\n\n const boundingBoxChangedSinceLastRefine =\n !state.insideBoundingBox &&\n Boolean(widgetState.lastRefineBoundingBox) &&\n state.insideBoundingBox !== widgetState.lastRefineBoundingBox;\n\n if (\n positionChangedSinceLastRefine ||\n boundingBoxChangedSinceLastRefine\n ) {\n widgetState.hasMapMoveSinceLastRefine = false;\n }\n\n widgetState.lastRefinePosition = state.aroundLatLng || '';\n\n widgetState.lastRefineBoundingBox = getBoundingBoxAsString(state);\n\n widgetState.internalToggleRefineOnMapMove =\n createInternalToggleRefinementOnMapMove(\n renderArgs,\n this.render!.bind(this)\n );\n\n widgetState.internalSetMapMoveSinceLastRefine =\n createInternalSetMapMoveSinceLastRefine(\n renderArgs,\n this.render!.bind(this)\n );\n\n const widgetRenderState = this.getWidgetRenderState(renderArgs);\n\n sendEvent('view', widgetRenderState.items);\n\n renderFn(\n {\n ...widgetRenderState,\n instantSearchInstance,\n },\n isFirstRendering\n );\n },\n\n getWidgetRenderState(renderOptions) {\n const { helper, results, instantSearchInstance } = renderOptions;\n const state = helper.state;\n\n const items = results\n ? transformItems(results.hits.filter((hit) => hit._geoloc))\n : [];\n\n if (!sendEvent) {\n sendEvent = createSendEventForHits({\n instantSearchInstance,\n index: helper.getIndex(),\n widgetType: $$type,\n });\n }\n\n return {\n items,\n position: getPositionFromState(state),\n currentRefinement: getCurrentRefinementFromState(state),\n refine: refine(helper),\n sendEvent,\n clearMapRefinement: clearMapRefinement(helper),\n isRefinedWithMap: isRefinedWithMap(state),\n toggleRefineOnMapMove,\n isRefineOnMapMove,\n setMapMoveSinceLastRefine,\n hasMapMoveSinceLastRefine,\n widgetParams,\n };\n },\n\n getRenderState(renderState, renderOptions) {\n return {\n ...renderState,\n geoSearch: this.getWidgetRenderState(renderOptions),\n };\n },\n\n dispose({ state }) {\n unmountFn();\n\n return state.setQueryParameter('insideBoundingBox', undefined);\n },\n\n getWidgetUiState(uiState, { searchParameters }) {\n const boundingBox = getBoundingBoxAsString(searchParameters);\n\n if (\n !boundingBox ||\n (uiState &&\n uiState.geoSearch &&\n uiState.geoSearch.boundingBox === boundingBox)\n ) {\n return uiState;\n }\n\n return {\n ...uiState,\n geoSearch: {\n boundingBox,\n },\n };\n },\n\n getWidgetSearchParameters(searchParameters, { uiState }) {\n if (!uiState || !uiState.geoSearch) {\n return searchParameters.setQueryParameter(\n 'insideBoundingBox',\n undefined\n );\n }\n return setBoundingBoxAsString(\n searchParameters,\n uiState.geoSearch.boundingBox\n );\n },\n };\n };\n};\n\nexport default connectGeoSearch;\n","import {\n safelyRunOnBrowser,\n checkRendering,\n createDocumentationMessageGenerator,\n noop,\n} from '../../lib/utils';\n\nimport type { Connector, WidgetRenderState } from '../../types';\n\nconst withUsage = createDocumentationMessageGenerator({\n name: 'powered-by',\n connector: true,\n});\n\nexport type PoweredByRenderState = {\n /** the url to redirect to on click */\n url: string;\n};\n\nexport type PoweredByConnectorParams = {\n /** the url to redirect to on click */\n url?: string;\n};\n\nexport type PoweredByWidgetDescription = {\n $$type: 'ais.poweredBy';\n renderState: PoweredByRenderState;\n indexRenderState: {\n poweredBy: WidgetRenderState<\n PoweredByRenderState,\n PoweredByConnectorParams\n >;\n };\n};\n\nexport type PoweredByConnector = Connector<\n PoweredByWidgetDescription,\n PoweredByConnectorParams\n>;\n\n/**\n * **PoweredBy** connector provides the logic to build a custom widget that will displays\n * the logo to redirect to Algolia.\n */\nconst connectPoweredBy: PoweredByConnector = function connectPoweredBy(\n renderFn,\n unmountFn = noop\n) {\n checkRendering(renderFn, withUsage());\n\n const defaultUrl =\n 'https://www.algolia.com/?' +\n 'utm_source=instantsearch.js&' +\n 'utm_medium=website&' +\n `utm_content=${safelyRunOnBrowser<string>(\n ({ window }) => window.location?.hostname || '',\n { fallback: () => '' }\n )}&` +\n 'utm_campaign=poweredby';\n\n return (widgetParams) => {\n const { url = defaultUrl } = widgetParams || {};\n\n return {\n $$type: 'ais.poweredBy',\n\n init(initOptions) {\n const { instantSearchInstance } = initOptions;\n renderFn(\n {\n ...this.getWidgetRenderState(initOptions),\n instantSearchInstance,\n },\n true\n );\n },\n\n render(renderOptions) {\n const { instantSearchInstance } = renderOptions;\n\n renderFn(\n {\n ...this.getWidgetRenderState(renderOptions),\n instantSearchInstance,\n },\n false\n );\n },\n\n getRenderState(renderState, renderOptions) {\n return {\n ...renderState,\n poweredBy: this.getWidgetRenderState(renderOptions),\n };\n },\n\n getWidgetRenderState() {\n return {\n url,\n widgetParams,\n };\n },\n\n dispose() {\n unmountFn();\n },\n };\n };\n};\n\nexport default connectPoweredBy;\n","import type {\n SearchParameters,\n PlainSearchParameters,\n AlgoliaSearchHelper,\n} from 'algoliasearch-helper';\nimport algoliasearchHelper from 'algoliasearch-helper';\nimport type { Connector, WidgetRenderState } from '../../types';\nimport {\n createDocumentationMessageGenerator,\n isPlainObject,\n mergeSearchParameters,\n noop,\n} from '../../lib/utils';\n\n/**\n * Refine the given search parameters.\n */\ntype Refine = (searchParameters: PlainSearchParameters) => void;\n\nexport type ConfigureConnectorParams = {\n /**\n * A list of [search parameters](https://www.algolia.com/doc/api-reference/search-api-parameters/)\n * to enable when the widget mounts.\n */\n searchParameters: PlainSearchParameters;\n};\n\nexport type ConfigureRenderState = {\n /**\n * Refine the given search parameters.\n */\n refine: Refine;\n};\n\nconst withUsage = createDocumentationMessageGenerator({\n name: 'configure',\n connector: true,\n});\n\nfunction getInitialSearchParameters(\n state: SearchParameters,\n widgetParams: ConfigureConnectorParams\n): SearchParameters {\n // We leverage the helper internals to remove the `widgetParams` from\n // the state. The function `setQueryParameters` omits the values that\n // are `undefined` on the next state.\n return state.setQueryParameters(\n Object.keys(widgetParams.searchParameters).reduce(\n (acc, key) => ({\n ...acc,\n [key]: undefined,\n }),\n {}\n )\n );\n}\n\nexport type ConfigureWidgetDescription = {\n $$type: 'ais.configure';\n renderState: ConfigureRenderState;\n indexRenderState: {\n configure: WidgetRenderState<\n ConfigureRenderState,\n ConfigureConnectorParams\n >;\n };\n indexUiState: {\n configure: PlainSearchParameters;\n };\n};\n\nexport type ConfigureConnector = Connector<\n ConfigureWidgetDescription,\n ConfigureConnectorParams\n>;\n\nconst connectConfigure: ConfigureConnector = function connectConfigure(\n renderFn = noop,\n unmountFn = noop\n) {\n return (widgetParams) => {\n if (!widgetParams || !isPlainObject(widgetParams.searchParameters)) {\n throw new Error(\n withUsage('The `searchParameters` option expects an object.')\n );\n }\n\n type ConnectorState = {\n refine?: Refine;\n };\n\n const connectorState: ConnectorState = {};\n\n function refine(helper: AlgoliaSearchHelper): Refine {\n return (searchParameters: PlainSearchParameters) => {\n // Merge new `searchParameters` with the ones set from other widgets\n const actualState = getInitialSearchParameters(\n helper.state,\n widgetParams\n );\n const nextSearchParameters = mergeSearchParameters(\n actualState,\n new algoliasearchHelper.SearchParameters(searchParameters)\n );\n\n // Update original `widgetParams.searchParameters` to the new refined one\n widgetParams.searchParameters = searchParameters;\n\n // Trigger a search with the resolved search parameters\n helper.setState(nextSearchParameters).search();\n };\n }\n\n return {\n $$type: 'ais.configure',\n\n init(initOptions) {\n const { instantSearchInstance } = initOptions;\n renderFn(\n {\n ...this.getWidgetRenderState(initOptions),\n instantSearchInstance,\n },\n true\n );\n },\n\n render(renderOptions) {\n const { instantSearchInstance } = renderOptions;\n\n renderFn(\n {\n ...this.getWidgetRenderState(renderOptions),\n instantSearchInstance,\n },\n false\n );\n },\n\n dispose({ state }) {\n unmountFn();\n\n return getInitialSearchParameters(state, widgetParams);\n },\n\n getRenderState(renderState, renderOptions) {\n const widgetRenderState = this.getWidgetRenderState(renderOptions);\n return {\n ...renderState,\n configure: {\n ...widgetRenderState,\n widgetParams: {\n ...widgetRenderState.widgetParams,\n searchParameters: mergeSearchParameters(\n new algoliasearchHelper.SearchParameters(\n renderState.configure?.widgetParams.searchParameters\n ),\n new algoliasearchHelper.SearchParameters(\n widgetRenderState.widgetParams.searchParameters\n )\n ).getQueryParams(),\n },\n },\n };\n },\n\n getWidgetRenderState({ helper }) {\n if (!connectorState.refine) {\n connectorState.refine = refine(helper);\n }\n\n return {\n refine: connectorState.refine,\n widgetParams,\n };\n },\n\n getWidgetSearchParameters(state, { uiState }) {\n return mergeSearchParameters(\n state,\n new algoliasearchHelper.SearchParameters({\n ...uiState.configure,\n ...widgetParams.searchParameters,\n })\n );\n },\n\n getWidgetUiState(uiState) {\n return {\n ...uiState,\n configure: {\n ...uiState.configure,\n ...widgetParams.searchParameters,\n },\n };\n },\n };\n };\n};\n\nexport default connectConfigure;\n","import type {\n SearchParameters,\n PlainSearchParameters,\n} from 'algoliasearch-helper';\nimport algoliasearchHelper from 'algoliasearch-helper';\nimport type { AlgoliaHit, Connector } from '../../types';\nimport {\n createDocumentationMessageGenerator,\n getObjectType,\n warning,\n getPropertyByPath,\n} from '../../lib/utils';\nimport type { ConfigureWidgetDescription } from '../configure/connectConfigure';\nimport connectConfigure from '../configure/connectConfigure';\n\nexport type MatchingPatterns = {\n [attribute: string]: {\n /**\n * The score of the optional filter.\n *\n * @see https://www.algolia.com/doc/guides/managing-results/rules/merchandising-and-promoting/in-depth/optional-filters/\n */\n score: number;\n };\n};\n\nexport type TransformSearchParameters = (\n searchParameters: SearchParameters\n) => PlainSearchParameters;\n\nexport type ConfigureRelatedItemsConnectorParams = {\n /**\n * The reference hit to extract the filters from.\n */\n hit: AlgoliaHit;\n /**\n * The schema to create the optional filters.\n * Each key represents an attribute from the hit.\n */\n matchingPatterns: MatchingPatterns;\n /**\n * Function to transform the generated search parameters.\n */\n transformSearchParameters?: TransformSearchParameters;\n};\n\nconst withUsage = createDocumentationMessageGenerator({\n name: 'configure-related-items',\n connector: true,\n});\n\nfunction createOptionalFilter({\n attributeName,\n attributeValue,\n attributeScore,\n}: {\n attributeName: string;\n attributeValue: string;\n attributeScore: number;\n}) {\n return `${attributeName}:${attributeValue}<score=${attributeScore || 1}>`;\n}\n\nexport type ConfigureRelatedItemsWidgetDescription = {\n $$type: 'ais.configureRelatedItems';\n} & Omit<ConfigureWidgetDescription, '$$type'>;\n\nexport type ConfigureRelatedItemsConnector = Connector<\n ConfigureRelatedItemsWidgetDescription,\n ConfigureRelatedItemsConnectorParams\n>;\n\nconst connectConfigureRelatedItems: ConfigureRelatedItemsConnector =\n function connectConfigureRelatedItems(renderFn, unmountFn) {\n return (widgetParams) => {\n const {\n hit,\n matchingPatterns,\n transformSearchParameters = ((x) => x) as TransformSearchParameters,\n } = widgetParams || {};\n\n if (!hit) {\n throw new Error(withUsage('The `hit` option is required.'));\n }\n\n if (!matchingPatterns) {\n throw new Error(\n withUsage('The `matchingPatterns` option is required.')\n );\n }\n\n const optionalFilters = Object.keys(matchingPatterns).reduce<\n Array<string | string[]>\n >((acc, attributeName) => {\n const attribute = matchingPatterns[attributeName];\n const attributeValue = getPropertyByPath(hit, attributeName);\n const attributeScore = attribute.score;\n\n if (Array.isArray(attributeValue)) {\n return [\n ...acc,\n attributeValue.map((attributeSubValue) => {\n return createOptionalFilter({\n attributeName,\n attributeValue: attributeSubValue,\n attributeScore,\n });\n }),\n ];\n }\n\n if (typeof attributeValue === 'string') {\n return [\n ...acc,\n createOptionalFilter({\n attributeName,\n attributeValue,\n attributeScore,\n }),\n ];\n }\n\n warning(\n false,\n `\nThe \\`matchingPatterns\\` option returned a value of type ${getObjectType(\n attributeValue\n )} for the \"${attributeName}\" key. This value was not sent to Algolia because \\`optionalFilters\\` only supports strings and array of strings.\n\nYou can remove the \"${attributeName}\" key from the \\`matchingPatterns\\` option.\n\nSee https://www.algolia.com/doc/api-reference/api-parameters/optionalFilters/\n `\n );\n\n return acc;\n }, []);\n\n const searchParameters: PlainSearchParameters = {\n ...transformSearchParameters(\n new algoliasearchHelper.SearchParameters({\n sumOrFiltersScores: true,\n facetFilters: [`objectID:-${hit.objectID}`],\n optionalFilters,\n })\n ),\n };\n\n const makeWidget = connectConfigure(renderFn, unmountFn);\n\n return {\n // required, since widget parameters differ between these connectors\n // and we don't want to have the parameters of configure here\n ...makeWidget({ searchParameters } as any),\n $$type: 'ais.configureRelatedItems',\n };\n };\n };\n\nexport default connectConfigureRelatedItems;\n","import type { SearchResults } from 'algoliasearch-helper';\nimport type { SendEventForHits } from '../../lib/utils';\nimport {\n escapeHits,\n TAG_PLACEHOLDER,\n checkRendering,\n createDocumentationMessageGenerator,\n createSendEventForHits,\n noop,\n warning,\n} from '../../lib/utils';\nimport type { Hits, Connector, WidgetRenderState } from '../../types';\n\nconst withUsage = createDocumentationMessageGenerator({\n name: 'autocomplete',\n connector: true,\n});\n\nexport type AutocompleteConnectorParams = {\n /**\n * Escapes HTML entities from hits string values.\n *\n * @default `true`\n */\n escapeHTML?: boolean;\n};\n\nexport type AutocompleteRenderState = {\n /**\n * The current value of the query.\n */\n currentRefinement: string;\n\n /**\n * The indices this widget has access to.\n */\n indices: Array<{\n /**\n * The name of the index\n */\n indexName: string;\n\n /**\n * The resolved hits from the index matching the query.\n */\n hits: Hits;\n\n /**\n * The full results object from the Algolia API.\n */\n results: SearchResults;\n\n /**\n * Send event to insights middleware\n */\n sendEvent: SendEventForHits;\n }>;\n\n /**\n * Searches into the indices with the provided query.\n */\n refine: (query: string) => void;\n};\n\nexport type AutocompleteWidgetDescription = {\n $$type: 'ais.autocomplete';\n renderState: AutocompleteRenderState;\n indexRenderState: {\n autocomplete: WidgetRenderState<\n AutocompleteRenderState,\n AutocompleteConnectorParams\n >;\n };\n indexUiState: { query: string };\n};\n\nexport type AutocompleteConnector = Connector<\n AutocompleteWidgetDescription,\n AutocompleteConnectorParams\n>;\n\nconst connectAutocomplete: AutocompleteConnector = function connectAutocomplete(\n renderFn,\n unmountFn = noop\n) {\n checkRendering(renderFn, withUsage());\n\n return (widgetParams) => {\n const { escapeHTML = true } = widgetParams || {};\n\n warning(\n !(widgetParams as any).indices,\n `\nThe option \\`indices\\` has been removed from the Autocomplete connector.\n\nThe indices to target are now inferred from the widgets tree.\n${\n Array.isArray((widgetParams as any).indices)\n ? `\nAn alternative would be:\n\nconst autocomplete = connectAutocomplete(renderer);\n\nsearch.addWidgets([\n ${(widgetParams as any).indices\n .map(({ value }: { value: string }) => `index({ indexName: '${value}' }),`)\n .join('\\n ')}\n autocomplete()\n]);\n`\n : ''\n}\n `\n );\n\n type ConnectorState = {\n refine?(query: string): void;\n };\n\n const connectorState: ConnectorState = {};\n\n return {\n $$type: 'ais.autocomplete',\n\n init(initOptions) {\n const { instantSearchInstance } = initOptions;\n\n renderFn(\n {\n ...this.getWidgetRenderState(initOptions),\n instantSearchInstance,\n },\n true\n );\n },\n\n render(renderOptions) {\n const { instantSearchInstance } = renderOptions;\n\n const renderState = this.getWidgetRenderState(renderOptions);\n\n renderState.indices.forEach(({ sendEvent, hits }) => {\n sendEvent('view', hits);\n });\n\n renderFn(\n {\n ...renderState,\n instantSearchInstance,\n },\n false\n );\n },\n\n getRenderState(renderState, renderOptions) {\n return {\n ...renderState,\n autocomplete: this.getWidgetRenderState(renderOptions),\n };\n },\n\n getWidgetRenderState({\n helper,\n state,\n scopedResults,\n instantSearchInstance,\n }) {\n if (!connectorState.refine) {\n connectorState.refine = (query: string) => {\n helper.setQuery(query).search();\n };\n }\n\n const indices = scopedResults.map((scopedResult) => {\n // We need to escape the hits because highlighting\n // exposes HTML tags to the end-user.\n scopedResult.results.hits = escapeHTML\n ? escapeHits(scopedResult.results.hits)\n : scopedResult.results.hits;\n\n const sendEvent = createSendEventForHits({\n instantSearchInstance,\n index: scopedResult.results.index,\n widgetType: this.$$type,\n });\n\n return {\n indexId: scopedResult.indexId,\n indexName: scopedResult.results.index,\n hits: scopedResult.results.hits,\n results: scopedResult.results,\n sendEvent,\n };\n });\n\n return {\n currentRefinement: state.query || '',\n indices,\n refine: connectorState.refine,\n widgetParams,\n };\n },\n\n getWidgetUiState(uiState, { searchParameters }) {\n const query = searchParameters.query || '';\n\n if (query === '' || (uiState && uiState.query === query)) {\n return uiState;\n }\n\n return {\n ...uiState,\n query,\n };\n },\n\n getWidgetSearchParameters(searchParameters, { uiState }) {\n const parameters = {\n query: uiState.query || '',\n };\n\n if (!escapeHTML) {\n return searchParameters.setQueryParameters(parameters);\n }\n\n return searchParameters.setQueryParameters({\n ...parameters,\n ...TAG_PLACEHOLDER,\n });\n },\n\n dispose({ state }) {\n unmountFn();\n\n const stateWithoutQuery = state.setQueryParameter('query', undefined);\n\n if (!escapeHTML) {\n return stateWithoutQuery;\n }\n\n return stateWithoutQuery.setQueryParameters(\n Object.keys(TAG_PLACEHOLDER).reduce(\n (acc, key) => ({\n ...acc,\n [key]: undefined,\n }),\n {}\n )\n );\n },\n };\n };\n};\n\nexport default connectAutocomplete;\n","import type {\n AlgoliaSearchHelper as Helper,\n SearchParameters,\n} from 'algoliasearch-helper';\nimport type { Connector, TransformItems, WidgetRenderState } from '../../types';\nimport {\n checkRendering,\n createDocumentationMessageGenerator,\n warning,\n getRefinements,\n isEqual,\n noop,\n} from '../../lib/utils';\nimport type {\n Refinement as InternalRefinement,\n NumericRefinement as InternalNumericRefinement,\n} from '../../lib/utils/getRefinements';\n\ntype TrackedFilterRefinement = string | number | boolean;\n\nexport type ParamTrackedFilters = {\n [facetName: string]: (\n facetValues: TrackedFilterRefinement[]\n ) => TrackedFilterRefinement[];\n};\nexport type ParamTransformRuleContexts = (ruleContexts: string[]) => string[];\ntype ParamTransformItems = TransformItems<any>;\n\nexport type QueryRulesConnectorParams = {\n trackedFilters?: ParamTrackedFilters;\n transformRuleContexts?: ParamTransformRuleContexts;\n transformItems?: ParamTransformItems;\n};\n\nexport type QueryRulesRenderState = {\n items: any[];\n};\n\nconst withUsage = createDocumentationMessageGenerator({\n name: 'query-rules',\n connector: true,\n});\n\nfunction hasStateRefinements(state: SearchParameters): boolean {\n return [\n state.disjunctiveFacetsRefinements,\n state.facetsRefinements,\n state.hierarchicalFacetsRefinements,\n state.numericRefinements,\n ].some((refinement) =>\n Boolean(refinement && Object.keys(refinement).length > 0)\n );\n}\n\n// A context rule must consist only of alphanumeric characters, hyphens, and underscores.\n// See https://www.algolia.com/doc/guides/managing-results/refine-results/merchandising-and-promoting/in-depth/implementing-query-rules/#context\nfunction escapeRuleContext(ruleName: string): string {\n return ruleName.replace(/[^a-z0-9-_]+/gi, '_');\n}\n\nfunction getRuleContextsFromTrackedFilters({\n helper,\n sharedHelperState,\n trackedFilters,\n}: {\n helper: Helper;\n sharedHelperState: SearchParameters;\n trackedFilters: ParamTrackedFilters;\n}): string[] {\n const ruleContexts = Object.keys(trackedFilters).reduce<string[]>(\n (facets, facetName) => {\n const facetRefinements: TrackedFilterRefinement[] = getRefinements(\n helper.lastResults || {},\n sharedHelperState,\n true\n )\n .filter(\n (refinement: InternalRefinement) => refinement.attribute === facetName\n )\n .map(\n (refinement: InternalRefinement) =>\n (refinement as InternalNumericRefinement).numericValue ||\n refinement.name\n );\n\n const getTrackedFacetValues = trackedFilters[facetName];\n const trackedFacetValues = getTrackedFacetValues(facetRefinements);\n\n return [\n ...facets,\n ...facetRefinements\n .filter((facetRefinement) =>\n trackedFacetValues.includes(facetRefinement)\n )\n .map((facetValue) =>\n escapeRuleContext(`ais-${facetName}-${facetValue}`)\n ),\n ];\n },\n []\n );\n\n return ruleContexts;\n}\n\nfunction applyRuleContexts(\n this: {\n helper: Helper;\n initialRuleContexts: string[];\n trackedFilters: ParamTrackedFilters;\n transformRuleContexts: ParamTransformRuleContexts;\n },\n event: { state: SearchParameters }\n): void {\n const { helper, initialRuleContexts, trackedFilters, transformRuleContexts } =\n this;\n\n const sharedHelperState = event.state;\n const previousRuleContexts: string[] = sharedHelperState.ruleContexts || [];\n const newRuleContexts = getRuleContextsFromTrackedFilters({\n helper,\n sharedHelperState,\n trackedFilters,\n });\n const nextRuleContexts = [...initialRuleContexts, ...newRuleContexts];\n\n warning(\n nextRuleContexts.length <= 10,\n `\nThe maximum number of \\`ruleContexts\\` is 10. They have been sliced to that limit.\nConsider using \\`transformRuleContexts\\` to minimize the number of rules sent to Algolia.\n`\n );\n\n const ruleContexts = transformRuleContexts(nextRuleContexts).slice(0, 10);\n\n if (!isEqual(previousRuleContexts, ruleContexts)) {\n helper.overrideStateWithoutTriggeringChangeEvent({\n ...sharedHelperState,\n ruleContexts,\n });\n }\n}\n\nexport type QueryRulesWidgetDescription = {\n $$type: 'ais.queryRules';\n renderState: QueryRulesRenderState;\n indexRenderState: {\n queryRules: WidgetRenderState<\n QueryRulesRenderState,\n QueryRulesConnectorParams\n >;\n };\n};\n\nexport type QueryRulesConnector = Connector<\n QueryRulesWidgetDescription,\n QueryRulesConnectorParams\n>;\n\nconst connectQueryRules: QueryRulesConnector = function connectQueryRules(\n render,\n unmount = noop\n) {\n checkRendering(render, withUsage());\n\n return (widgetParams) => {\n const {\n trackedFilters = {} as ParamTrackedFilters,\n transformRuleContexts = ((rules) => rules) as ParamTransformRuleContexts,\n transformItems = ((items) => items) as ParamTransformItems,\n } = widgetParams || {};\n\n Object.keys(trackedFilters).forEach((facetName) => {\n if (typeof trackedFilters[facetName] !== 'function') {\n throw new Error(\n withUsage(\n `'The \"${facetName}\" filter value in the \\`trackedFilters\\` option expects a function.`\n )\n );\n }\n });\n\n const hasTrackedFilters = Object.keys(trackedFilters).length > 0;\n\n // We store the initial rule contexts applied before creating the widget\n // so that we do not override them with the rules created from `trackedFilters`.\n let initialRuleContexts: string[] = [];\n let onHelperChange: (event: { state: SearchParameters }) => void;\n\n return {\n $$type: 'ais.queryRules',\n\n init(initOptions) {\n const { helper, state, instantSearchInstance } = initOptions;\n\n initialRuleContexts = state.ruleContexts || [];\n onHelperChange = applyRuleContexts.bind({\n helper,\n initialRuleContexts,\n trackedFilters,\n transformRuleContexts,\n });\n\n if (hasTrackedFilters) {\n // We need to apply the `ruleContexts` based on the `trackedFilters`\n // before the helper changes state in some cases:\n // - Some filters are applied on the first load (e.g. using `configure`)\n // - The `transformRuleContexts` option sets initial `ruleContexts`.\n if (\n hasStateRefinements(state) ||\n Boolean(widgetParams.transformRuleContexts)\n ) {\n onHelperChange({ state });\n }\n\n // We track every change in the helper to override its state and add\n // any `ruleContexts` needed based on the `trackedFilters`.\n helper.on('change', onHelperChange);\n }\n\n render(\n {\n ...this.getWidgetRenderState(initOptions),\n instantSearchInstance,\n },\n true\n );\n },\n\n render(renderOptions) {\n const { instantSearchInstance } = renderOptions;\n\n render(\n {\n ...this.getWidgetRenderState(renderOptions),\n instantSearchInstance,\n },\n false\n );\n },\n\n getWidgetRenderState({ results }) {\n const { userData = [] } = results || {};\n const items = transformItems(userData);\n\n return {\n items,\n widgetParams,\n };\n },\n\n getRenderState(renderState, renderOptions) {\n return {\n ...renderState,\n queryRules: this.getWidgetRenderState(renderOptions),\n };\n },\n\n dispose({ helper, state }) {\n unmount();\n\n if (hasTrackedFilters) {\n helper.removeListener('change', onHelperChange);\n\n return state.setQueryParameter('ruleContexts', initialRuleContexts);\n }\n\n return state;\n },\n };\n };\n};\n\nexport default connectQueryRules;\n","// `SpeechRecognition` is an API used on the browser so we can safely disable\n// the `window` check.\n/* eslint-disable no-restricted-globals */\n/* global SpeechRecognition SpeechRecognitionEvent */\nimport type {\n CreateVoiceSearchHelper,\n Status,\n VoiceListeningState,\n} from './types';\n\nconst createVoiceSearchHelper: CreateVoiceSearchHelper =\n function createVoiceSearchHelper({\n searchAsYouSpeak,\n language,\n onQueryChange,\n onStateChange,\n }) {\n const SpeechRecognitionAPI: new () => SpeechRecognition =\n (window as any).webkitSpeechRecognition ||\n (window as any).SpeechRecognition;\n const getDefaultState = (status: Status): VoiceListeningState => ({\n status,\n transcript: '',\n isSpeechFinal: false,\n errorCode: undefined,\n });\n let state: VoiceListeningState = getDefaultState('initial');\n let recognition: SpeechRecognition | undefined;\n\n const isBrowserSupported = (): boolean => Boolean(SpeechRecognitionAPI);\n\n const isListening = (): boolean =>\n state.status === 'askingPermission' ||\n state.status === 'waiting' ||\n state.status === 'recognizing';\n\n const setState = (newState: Partial<VoiceListeningState> = {}): void => {\n state = { ...state, ...newState };\n onStateChange();\n };\n\n const getState = (): VoiceListeningState => state;\n\n const resetState = (status: Status = 'initial'): void => {\n setState(getDefaultState(status));\n };\n\n const onStart = (): void => {\n setState({\n status: 'waiting',\n });\n };\n\n const onError = (event: Event): void => {\n setState({ status: 'error', errorCode: (event as any).error });\n };\n\n const onResult = (event: SpeechRecognitionEvent): void => {\n setState({\n status: 'recognizing',\n transcript:\n (event.results[0] &&\n event.results[0][0] &&\n event.results[0][0].transcript) ||\n '',\n isSpeechFinal: event.results[0] && event.results[0].isFinal,\n });\n if (searchAsYouSpeak && state.transcript) {\n onQueryChange(state.transcript);\n }\n };\n\n const onEnd = (): void => {\n if (!state.errorCode && state.transcript && !searchAsYouSpeak) {\n onQueryChange(state.transcript);\n }\n if (state.status !== 'error') {\n setState({ status: 'finished' });\n }\n };\n\n const startListening = (): void => {\n recognition = new SpeechRecognitionAPI();\n if (!recognition) {\n return;\n }\n resetState('askingPermission');\n recognition.interimResults = true;\n\n if (language) {\n recognition.lang = language;\n }\n\n recognition.addEventListener('start', onStart);\n recognition.addEventListener('error', onError);\n recognition.addEventListener('result', onResult);\n recognition.addEventListener('end', onEnd);\n recognition.start();\n };\n\n const dispose = (): void => {\n if (!recognition) {\n return;\n }\n recognition.stop();\n recognition.removeEventListener('start', onStart);\n recognition.removeEventListener('error', onError);\n recognition.removeEventListener('result', onResult);\n recognition.removeEventListener('end', onEnd);\n recognition = undefined;\n };\n\n const stopListening = (): void => {\n dispose();\n // Because `dispose` removes event listeners, `end` listener is not called.\n // So we're setting the `status` as `finished` here.\n // If we don't do it, it will be still `waiting` or `recognizing`.\n resetState('finished');\n };\n\n return {\n getState,\n isBrowserSupported,\n isListening,\n startListening,\n stopListening,\n dispose,\n };\n };\n\nexport default createVoiceSearchHelper;\n","import type { PlainSearchParameters } from 'algoliasearch-helper';\nimport {\n checkRendering,\n createDocumentationMessageGenerator,\n noop,\n} from '../../lib/utils';\nimport type { Connector, WidgetRenderState } from '../../types';\nimport builtInCreateVoiceSearchHelper from '../../lib/voiceSearchHelper';\nimport type {\n CreateVoiceSearchHelper,\n VoiceListeningState,\n} from '../../lib/voiceSearchHelper/types';\n\nconst withUsage = createDocumentationMessageGenerator({\n name: 'voice-search',\n connector: true,\n});\n\nexport type VoiceSearchConnectorParams = {\n searchAsYouSpeak?: boolean;\n language?: string;\n additionalQueryParameters?: (params: {\n query: string;\n }) => PlainSearchParameters | void;\n createVoiceSearchHelper?: CreateVoiceSearchHelper;\n};\n\nexport type VoiceSearchRenderState = {\n isBrowserSupported: boolean;\n isListening: boolean;\n toggleListening: () => void;\n voiceListeningState: VoiceListeningState;\n};\n\nexport type VoiceSearchWidgetDescription = {\n $$type: 'ais.voiceSearch';\n renderState: VoiceSearchRenderState;\n indexRenderState: {\n voiceSearch: WidgetRenderState<\n VoiceSearchRenderState,\n VoiceSearchConnectorParams\n >;\n };\n indexUiState: {\n query: string;\n };\n};\n\nexport type VoiceSearchConnector = Connector<\n VoiceSearchWidgetDescription,\n VoiceSearchConnectorParams\n>;\n\nconst connectVoiceSearch: VoiceSearchConnector = function connectVoiceSearch(\n renderFn,\n unmountFn = noop\n) {\n checkRendering(renderFn, withUsage());\n\n return (widgetParams) => {\n const {\n searchAsYouSpeak = false,\n language,\n additionalQueryParameters,\n createVoiceSearchHelper = builtInCreateVoiceSearchHelper,\n } = widgetParams;\n\n return {\n $$type: 'ais.voiceSearch',\n\n init(initOptions) {\n const { instantSearchInstance } = initOptions;\n renderFn(\n {\n ...this.getWidgetRenderState(initOptions),\n instantSearchInstance,\n },\n true\n );\n },\n\n render(renderOptions) {\n const { instantSearchInstance } = renderOptions;\n renderFn(\n {\n ...this.getWidgetRenderState(renderOptions),\n instantSearchInstance,\n },\n false\n );\n },\n\n getRenderState(renderState, renderOptions) {\n return {\n ...renderState,\n voiceSearch: this.getWidgetRenderState(renderOptions),\n };\n },\n\n getWidgetRenderState(renderOptions) {\n const { helper, instantSearchInstance } = renderOptions;\n if (!(this as any)._refine) {\n (this as any)._refine = (query: string): void => {\n if (query !== helper.state.query) {\n const queryLanguages = language\n ? [language.split('-')[0]]\n : undefined;\n helper.setQueryParameter('queryLanguages', queryLanguages);\n\n if (typeof additionalQueryParameters === 'function') {\n helper.setState(\n helper.state.setQueryParameters({\n ignorePlurals: true,\n removeStopWords: true,\n // @ts-ignore (optionalWords only allows array in v3, while string is also valid)\n optionalWords: query,\n ...additionalQueryParameters({ query }),\n })\n );\n }\n\n helper.setQuery(query).search();\n }\n };\n }\n\n if (!(this as any)._voiceSearchHelper) {\n (this as any)._voiceSearchHelper = createVoiceSearchHelper({\n searchAsYouSpeak,\n language,\n onQueryChange: (query) => (this as any)._refine(query),\n onStateChange: () => {\n renderFn(\n {\n ...this.getWidgetRenderState(renderOptions),\n instantSearchInstance,\n },\n false\n );\n },\n });\n }\n\n const {\n isBrowserSupported,\n isListening,\n startListening,\n stopListening,\n getState,\n } = (this as any)._voiceSearchHelper;\n\n return {\n isBrowserSupported: isBrowserSupported(),\n isListening: isListening(),\n toggleListening() {\n if (!isBrowserSupported()) {\n return;\n }\n if (isListening()) {\n stopListening();\n } else {\n startListening();\n }\n },\n voiceListeningState: getState(),\n widgetParams,\n };\n },\n\n dispose({ state }) {\n (this as any)._voiceSearchHelper.dispose();\n\n unmountFn();\n\n let newState = state;\n if (typeof additionalQueryParameters === 'function') {\n const additional = additionalQueryParameters({ query: '' });\n const toReset = additional\n ? (\n Object.keys(additional) as Array<keyof PlainSearchParameters>\n ).reduce<PlainSearchParameters>((acc, current) => {\n // @ts-ignore search parameters is typed as readonly in v4\n acc[current] = undefined;\n return acc;\n }, {})\n : {};\n newState = state.setQueryParameters({\n // @ts-ignore (queryLanguages is not added to algoliasearch v3)\n queryLanguages: undefined,\n ignorePlurals: undefined,\n removeStopWords: undefined,\n optionalWords: undefined,\n ...toReset,\n });\n }\n\n return newState.setQueryParameter('query', undefined);\n },\n\n getWidgetUiState(uiState, { searchParameters }) {\n const query = searchParameters.query || '';\n\n if (!query) {\n return uiState;\n }\n\n return {\n ...uiState,\n query,\n };\n },\n\n getWidgetSearchParameters(searchParameters, { uiState }) {\n return searchParameters.setQueryParameter('query', uiState.query || '');\n },\n };\n };\n};\n\nexport default connectVoiceSearch;\n","import {\n checkRendering,\n createDocumentationMessageGenerator,\n createConcurrentSafePromise,\n addQueryID,\n debounce,\n addAbsolutePosition,\n noop,\n escapeHits,\n} from '../../lib/utils';\nimport type { DebouncedFunction } from '../../lib/utils/debounce';\nimport type {\n Connector,\n Hits,\n Hit,\n FindAnswersOptions,\n FindAnswersParameters,\n FindAnswersResponse,\n WidgetRenderState,\n} from '../../types';\n\ntype IndexWithAnswers = {\n readonly findAnswers: any;\n};\n\nfunction hasFindAnswersMethod(\n answersIndex: IndexWithAnswers | any\n): answersIndex is IndexWithAnswers {\n return typeof (answersIndex as IndexWithAnswers).findAnswers === 'function';\n}\n\nconst withUsage = createDocumentationMessageGenerator({\n name: 'answers',\n connector: true,\n});\n\nexport type AnswersRenderState = {\n /**\n * The matched hits from Algolia API.\n */\n hits: Hits;\n\n /**\n * Whether it's still loading the results from the Answers API.\n */\n isLoading: boolean;\n};\n\nexport type AnswersConnectorParams = {\n /**\n * Attributes to use for predictions.\n * If empty, we use all `searchableAttributes` to find answers.\n * All your `attributesForPrediction` must be part of your `searchableAttributes`.\n */\n attributesForPrediction?: string[];\n\n /**\n * The languages in the query. Currently only supports `en`.\n */\n queryLanguages: ['en'];\n\n /**\n * Maximum number of answers to retrieve from the Answers Engine.\n * Cannot be greater than 1000.\n * @default 1\n */\n nbHits?: number;\n\n /**\n * Debounce time in milliseconds to debounce render\n * @default 100\n */\n renderDebounceTime?: number;\n\n /**\n * Debounce time in milliseconds to debounce search\n * @default 100\n */\n searchDebounceTime?: number;\n\n /**\n * Whether to escape HTML tags from hits string values.\n *\n * @default true\n */\n escapeHTML?: boolean;\n\n /**\n * Extra parameters to pass to findAnswers method.\n * @default {}\n */\n extraParameters?: FindAnswersOptions;\n};\n\nexport type AnswersWidgetDescription = {\n $$type: 'ais.answers';\n renderState: AnswersRenderState;\n indexRenderState: {\n answers: WidgetRenderState<AnswersRenderState, AnswersConnectorParams>;\n };\n};\n\nexport type AnswersConnector = Connector<\n AnswersWidgetDescription,\n AnswersConnectorParams\n>;\n\nconst connectAnswers: AnswersConnector = function connectAnswers(\n renderFn,\n unmountFn = noop\n) {\n checkRendering(renderFn, withUsage());\n\n return (widgetParams) => {\n const {\n queryLanguages,\n attributesForPrediction,\n nbHits = 1,\n renderDebounceTime = 100,\n searchDebounceTime = 100,\n escapeHTML = true,\n extraParameters = {},\n } = widgetParams || {};\n\n // @ts-expect-error checking for the wrong value\n if (!queryLanguages || queryLanguages.length === 0) {\n throw new Error(\n withUsage('The `queryLanguages` expects an array of strings.')\n );\n }\n\n const runConcurrentSafePromise =\n createConcurrentSafePromise<FindAnswersResponse<Hit>>();\n\n let lastHits: FindAnswersResponse<Hit>['hits'] = [];\n let isLoading = false;\n const debouncedRender = debounce(renderFn, renderDebounceTime);\n\n // this does not directly use DebouncedFunction<findAnswers>, since then the generic will disappear\n let debouncedRefine: DebouncedFunction<\n (...params: FindAnswersParameters) => Promise<FindAnswersResponse<Hit>>\n >;\n\n return {\n $$type: 'ais.answers',\n\n init(initOptions) {\n const { state, instantSearchInstance } = initOptions;\n const answersIndex = instantSearchInstance.client.initIndex!(\n state.index\n );\n if (!hasFindAnswersMethod(answersIndex)) {\n throw new Error(withUsage('`algoliasearch` >= 4.8.0 required.'));\n }\n debouncedRefine = debounce(\n answersIndex.findAnswers,\n searchDebounceTime\n );\n\n renderFn(\n {\n ...this.getWidgetRenderState(initOptions),\n instantSearchInstance: initOptions.instantSearchInstance,\n },\n true\n );\n },\n\n render(renderOptions) {\n const query = renderOptions.state.query;\n if (!query) {\n // renders nothing with empty query\n lastHits = [];\n isLoading = false;\n renderFn(\n {\n ...this.getWidgetRenderState(renderOptions),\n instantSearchInstance: renderOptions.instantSearchInstance,\n },\n false\n );\n return;\n }\n\n // render the loader\n lastHits = [];\n isLoading = true;\n renderFn(\n {\n ...this.getWidgetRenderState(renderOptions),\n instantSearchInstance: renderOptions.instantSearchInstance,\n },\n false\n );\n\n // call /answers API\n runConcurrentSafePromise(\n debouncedRefine(query, queryLanguages, {\n ...extraParameters,\n nbHits,\n attributesForPrediction,\n })\n ).then((result) => {\n if (!result) {\n // It's undefined when it's debounced.\n return;\n }\n\n if (escapeHTML && result.hits.length > 0) {\n result.hits = escapeHits(result.hits);\n }\n\n const hitsWithAbsolutePosition = addAbsolutePosition(\n result.hits,\n 0,\n nbHits\n );\n\n const hitsWithAbsolutePositionAndQueryID = addQueryID(\n hitsWithAbsolutePosition,\n result.queryID\n );\n\n lastHits = hitsWithAbsolutePositionAndQueryID;\n isLoading = false;\n debouncedRender(\n {\n ...this.getWidgetRenderState(renderOptions),\n instantSearchInstance: renderOptions.instantSearchInstance,\n },\n false\n );\n });\n },\n\n getRenderState(renderState, renderOptions) {\n return {\n ...renderState,\n answers: this.getWidgetRenderState(renderOptions),\n };\n },\n\n getWidgetRenderState() {\n return {\n hits: lastHits,\n isLoading,\n widgetParams,\n };\n },\n\n dispose({ state }) {\n unmountFn();\n return state;\n },\n\n getWidgetSearchParameters(state) {\n return state;\n },\n };\n };\n};\n\nexport default connectAnswers;\n","export type MaybePromise<TResolution> =\n | Readonly<Promise<TResolution>>\n | Promise<TResolution>\n | TResolution;\n\n// copied from\n// https://github.com/algolia/autocomplete.js/blob/307a7acc4283e10a19cb7d067f04f1bea79dc56f/packages/autocomplete-core/src/utils/createConcurrentSafePromise.ts#L1:L1\n/**\n * Creates a runner that executes promises in a concurrent-safe way.\n *\n * This is useful to prevent older promises to resolve after a newer promise,\n * otherwise resulting in stale resolved values.\n */\nexport function createConcurrentSafePromise<TValue>() {\n let basePromiseId = -1;\n let latestResolvedId = -1;\n let latestResolvedValue: TValue | undefined = undefined;\n\n return function runConcurrentSafePromise(promise: MaybePromise<TValue>) {\n const currentPromiseId = ++basePromiseId;\n\n return Promise.resolve(promise).then((x) => {\n // The promise might take too long to resolve and get outdated. This would\n // result in resolving stale values.\n // When this happens, we ignore the promise value and return the one\n // coming from the latest resolved value.\n //\n // +----------------------------------+\n // | 100ms |\n // | run(1) +---> R1 |\n // | 300ms |\n // | run(2) +-------------> R2 (SKIP) |\n // | 200ms |\n // | run(3) +--------> R3 |\n // +----------------------------------+\n if (latestResolvedValue && currentPromiseId < latestResolvedId) {\n return latestResolvedValue;\n }\n\n latestResolvedId = currentPromiseId;\n latestResolvedValue = x;\n\n return x;\n });\n };\n}\n","import type { Connector, WidgetRenderState } from '../../types';\nimport { noop } from '../../lib/utils';\n\nexport type RelevantSortConnectorParams = Record<string, unknown>;\n\ntype Refine = (relevancyStrictness: number) => void;\n\nexport type RelevantSortRenderState = {\n /**\n * Indicates if it has appliedRelevancyStrictness greater than zero\n */\n isRelevantSorted: boolean;\n\n /**\n * Indicates if the results come from a virtual replica\n */\n isVirtualReplica: boolean;\n\n /**\n * Indicates if search state can be refined\n */\n canRefine: boolean;\n\n /**\n * Sets the value as relevancyStrictness and trigger a new search\n */\n refine: Refine;\n};\n\nexport type RelevantSortWidgetDescription = {\n $$type: 'ais.relevantSort';\n renderState: RelevantSortRenderState;\n indexRenderState: {\n relevantSort: WidgetRenderState<\n RelevantSortRenderState,\n RelevantSortConnectorParams\n >;\n };\n indexUiState: {\n relevantSort: number;\n };\n};\n\nexport type RelevantSortConnector = Connector<\n RelevantSortWidgetDescription,\n RelevantSortConnectorParams\n>;\n\nconst connectRelevantSort: RelevantSortConnector = function connectRelevantSort(\n renderFn = noop,\n unmountFn = noop\n) {\n return (widgetParams) => {\n type ConnectorState = {\n refine?: Refine;\n };\n\n const connectorState: ConnectorState = {};\n\n return {\n $$type: 'ais.relevantSort',\n\n init(initOptions) {\n const { instantSearchInstance } = initOptions;\n renderFn(\n {\n ...this.getWidgetRenderState(initOptions),\n instantSearchInstance,\n },\n true\n );\n },\n\n render(renderOptions) {\n const { instantSearchInstance } = renderOptions;\n\n renderFn(\n {\n ...this.getWidgetRenderState(renderOptions),\n instantSearchInstance,\n },\n false\n );\n },\n\n dispose({ state }) {\n unmountFn();\n\n return state.setQueryParameter('relevancyStrictness', undefined);\n },\n\n getRenderState(renderState, renderOptions) {\n return {\n ...renderState,\n relevantSort: this.getWidgetRenderState(renderOptions),\n };\n },\n\n getWidgetRenderState({ results, helper }) {\n if (!connectorState.refine) {\n connectorState.refine = (relevancyStrictness: number | undefined) => {\n helper\n .setQueryParameter('relevancyStrictness', relevancyStrictness)\n .search();\n };\n }\n\n const { appliedRelevancyStrictness } = results || {};\n\n const isVirtualReplica = appliedRelevancyStrictness !== undefined;\n\n return {\n isRelevantSorted:\n typeof appliedRelevancyStrictness !== 'undefined' &&\n appliedRelevancyStrictness > 0,\n isVirtualReplica,\n canRefine: isVirtualReplica,\n refine: connectorState.refine,\n widgetParams,\n };\n },\n\n getWidgetSearchParameters(state, { uiState }) {\n return state.setQueryParameter(\n 'relevancyStrictness',\n uiState.relevantSort ?? state.relevancyStrictness\n );\n },\n\n getWidgetUiState(uiState, { searchParameters }) {\n return {\n ...uiState,\n relevantSort:\n searchParameters.relevancyStrictness || uiState.relevantSort,\n };\n },\n };\n };\n};\n\nexport default connectRelevantSort;\n","import type { SearchResults } from 'algoliasearch-helper';\nimport {\n checkRendering,\n createDocumentationMessageGenerator,\n getWidgetAttribute,\n noop,\n warning,\n} from '../../lib/utils';\nimport type { Connector, Widget } from '../../types';\n\nconst withUsage = createDocumentationMessageGenerator({\n name: 'dynamic-widgets',\n connector: true,\n});\n\nexport type DynamicWidgetsRenderState = {\n attributesToRender: string[];\n};\n\nexport type DynamicWidgetsConnectorParams = {\n /**\n * An array of widgets, displayed in the order defined by `facetOrdering`.\n */\n widgets: Widget[];\n\n /**\n * Function to return a fallback widget when an attribute isn't found in\n * `widgets`.\n */\n fallbackWidget?(args: {\n /** The attribute name to create a widget for. */\n attribute: string;\n }): Widget;\n\n /**\n * Function to transform the items to render.\n * The function also exposes the full search response.\n */\n transformItems?(\n items: string[],\n metadata: { results: SearchResults }\n ): string[];\n\n /**\n * To prevent unneeded extra network requests when widgets mount or unmount,\n * we request all facet values.\n *\n * @default ['*']\n */\n facets?: ['*'] | never[];\n\n /**\n * If you have more than 20 facet values pinned, you need to increase the\n * maxValuesPerFacet to at least that value.\n *\n * @default 20\n */\n maxValuesPerFacet?: number;\n};\n\nexport type DynamicWidgetsWidgetDescription = {\n $$type: 'ais.dynamicWidgets';\n renderState: DynamicWidgetsRenderState;\n indexRenderState: {\n dynamicWidgets: DynamicWidgetsRenderState;\n };\n};\n\nexport type DynamicWidgetsConnector = Connector<\n DynamicWidgetsWidgetDescription,\n DynamicWidgetsConnectorParams\n>;\n\nconst MAX_WILDCARD_FACETS = 20;\n\nconst connectDynamicWidgets: DynamicWidgetsConnector =\n function connectDynamicWidgets(renderFn, unmountFn = noop) {\n checkRendering(renderFn, withUsage());\n\n return (widgetParams) => {\n const {\n widgets,\n maxValuesPerFacet = 20,\n facets = ['*'],\n transformItems = (items) => items,\n fallbackWidget,\n } = widgetParams;\n\n if (\n !(\n widgets &&\n Array.isArray(widgets) &&\n widgets.every((widget) => typeof widget === 'object')\n )\n ) {\n throw new Error(\n withUsage('The `widgets` option expects an array of widgets.')\n );\n }\n\n if (\n !(\n Array.isArray(facets) &&\n facets.length <= 1 &&\n (facets[0] === '*' || facets[0] === undefined)\n )\n ) {\n throw new Error(\n withUsage(\n `The \\`facets\\` option only accepts [] or [\"*\"], you passed ${JSON.stringify(\n facets\n )}`\n )\n );\n }\n\n const localWidgets: Map<string, { widget: Widget; isMounted: boolean }> =\n new Map();\n\n return {\n $$type: 'ais.dynamicWidgets',\n init(initOptions) {\n widgets.forEach((widget) => {\n const attribute = getWidgetAttribute(widget, initOptions);\n localWidgets.set(attribute, { widget, isMounted: false });\n });\n\n renderFn(\n {\n ...this.getWidgetRenderState(initOptions),\n instantSearchInstance: initOptions.instantSearchInstance,\n },\n true\n );\n },\n render(renderOptions) {\n const { parent } = renderOptions;\n const renderState = this.getWidgetRenderState(renderOptions);\n\n const widgetsToUnmount: Widget[] = [];\n const widgetsToMount: Widget[] = [];\n\n if (fallbackWidget) {\n renderState.attributesToRender.forEach((attribute) => {\n if (!localWidgets.has(attribute)) {\n const widget = fallbackWidget({ attribute });\n localWidgets.set(attribute, { widget, isMounted: false });\n }\n });\n }\n\n localWidgets.forEach(({ widget, isMounted }, attribute) => {\n const shouldMount =\n renderState.attributesToRender.indexOf(attribute) > -1;\n\n if (!isMounted && shouldMount) {\n widgetsToMount.push(widget);\n localWidgets.set(attribute, {\n widget,\n isMounted: true,\n });\n } else if (isMounted && !shouldMount) {\n widgetsToUnmount.push(widget);\n localWidgets.set(attribute, {\n widget,\n isMounted: false,\n });\n }\n });\n\n parent!.addWidgets(widgetsToMount);\n // make sure this only happens after the regular render, otherwise it\n // happens too quick, since render is \"deferred\" for the next microtask,\n // so this needs to be a whole task later\n setTimeout(() => parent!.removeWidgets(widgetsToUnmount), 0);\n\n renderFn(\n {\n ...renderState,\n instantSearchInstance: renderOptions.instantSearchInstance,\n },\n false\n );\n },\n dispose({ parent }) {\n const toRemove: Widget[] = [];\n localWidgets.forEach(({ widget, isMounted }) => {\n if (isMounted) {\n toRemove.push(widget);\n }\n });\n parent.removeWidgets(toRemove);\n\n unmountFn();\n },\n getWidgetSearchParameters(state) {\n // broadening the scope of facets to avoid conflict between never and *\n return (facets as string[]).reduce(\n (acc, curr) => acc.addFacet(curr),\n state.setQueryParameters({\n maxValuesPerFacet: Math.max(\n maxValuesPerFacet || 0,\n state.maxValuesPerFacet || 0\n ),\n })\n );\n },\n getRenderState(renderState, renderOptions) {\n return {\n ...renderState,\n dynamicWidgets: this.getWidgetRenderState(renderOptions),\n };\n },\n getWidgetRenderState({ results, state }) {\n if (!results) {\n return { attributesToRender: [], widgetParams };\n }\n\n const attributesToRender = transformItems(\n results.renderingContent?.facetOrdering?.facets?.order ?? [],\n { results }\n );\n\n if (!Array.isArray(attributesToRender)) {\n throw new Error(\n withUsage(\n 'The `transformItems` option expects a function that returns an Array.'\n )\n );\n }\n\n warning(\n maxValuesPerFacet >= (state.maxValuesPerFacet || 0),\n `The maxValuesPerFacet set by dynamic widgets (${maxValuesPerFacet}) is smaller than one of the limits set by a widget (${state.maxValuesPerFacet}). This causes a mismatch in query parameters and thus an extra network request when that widget is mounted.`\n );\n\n warning(\n attributesToRender.length <= MAX_WILDCARD_FACETS ||\n widgetParams.facets !== undefined,\n `More than ${MAX_WILDCARD_FACETS} facets are requested to be displayed without explicitly setting which facets to retrieve. This could have a performance impact. Set \"facets\" to [] to do two smaller network requests, or explicitly to ['*'] to avoid this warning.`\n );\n\n return {\n attributesToRender,\n widgetParams,\n };\n },\n };\n };\n };\n\nexport default connectDynamicWidgets;\n","export { default as connectClearRefinements } from './clear-refinements/connectClearRefinements';\nexport { default as connectCurrentRefinements } from './current-refinements/connectCurrentRefinements';\nexport { default as connectHierarchicalMenu } from './hierarchical-menu/connectHierarchicalMenu';\nexport { default as connectHits } from './hits/connectHits';\nexport { default as connectHitsWithInsights } from './hits/connectHitsWithInsights';\nexport { default as connectHitsPerPage } from './hits-per-page/connectHitsPerPage';\nexport { default as connectInfiniteHits } from './infinite-hits/connectInfiniteHits';\nexport { default as connectInfiniteHitsWithInsights } from './infinite-hits/connectInfiniteHitsWithInsights';\nexport { default as connectMenu } from './menu/connectMenu';\nexport { default as connectNumericMenu } from './numeric-menu/connectNumericMenu';\nexport { default as connectPagination } from './pagination/connectPagination';\nexport { default as connectRange } from './range/connectRange';\nexport { default as connectRefinementList } from './refinement-list/connectRefinementList';\nexport { default as connectSearchBox } from './search-box/connectSearchBox';\nexport { default as connectSortBy } from './sort-by/connectSortBy';\nexport { default as connectRatingMenu } from './rating-menu/connectRatingMenu';\nexport { default as connectStats } from './stats/connectStats';\nexport { default as connectToggleRefinement } from './toggle-refinement/connectToggleRefinement';\nexport { default as connectBreadcrumb } from './breadcrumb/connectBreadcrumb';\nexport { default as connectGeoSearch } from './geo-search/connectGeoSearch';\nexport { default as connectPoweredBy } from './powered-by/connectPoweredBy';\nexport { default as connectConfigure } from './configure/connectConfigure';\nexport { default as EXPERIMENTAL_connectConfigureRelatedItems } from './configure-related-items/connectConfigureRelatedItems';\nexport { default as connectAutocomplete } from './autocomplete/connectAutocomplete';\nexport { default as connectQueryRules } from './query-rules/connectQueryRules';\nexport { default as connectVoiceSearch } from './voice-search/connectVoiceSearch';\nexport { default as EXPERIMENTAL_connectAnswers } from './answers/connectAnswers';\nexport { default as connectRelevantSort } from './relevant-sort/connectRelevantSort';\n\nimport connectDynamicWidgets from './dynamic-widgets/connectDynamicWidgets';\nexport { connectDynamicWidgets };\nimport { deprecate } from '../lib/utils';\n/** @deprecated use connectDynamicWidgets */\nexport const EXPERIMENTAL_connectDynamicWidgets = deprecate(\n connectDynamicWidgets,\n 'use connectDynamicWidgets'\n);\n","import type { SearchParameters, SearchResults } from 'algoliasearch-helper';\nimport { createDocumentationMessageGenerator, warning } from '../../lib/utils';\nimport type { WidgetFactory, WidgetRenderState } from '../../types';\n\nexport type AnalyticsWidgetParamsPushFunction = (\n /**\n * Contains the search parameters, serialized as a query string.\n */\n formattedParameters: string,\n\n /**\n * Contains the whole search state.\n */\n state: SearchParameters,\n\n /**\n * The last received results.\n */\n results: SearchResults\n) => void;\n\nexport type AnalyticsWidgetParams = {\n /**\n * A function that is called every time the query or refinements changes. You\n * need to add the logic to push the data to your analytics platform.\n */\n pushFunction: AnalyticsWidgetParamsPushFunction;\n\n /**\n * The number of milliseconds between the last search keystroke and calling `pushFunction`.\n *\n * @default 3000\n */\n delay?: number;\n\n /**\n * Triggers `pushFunction` after click on page or redirecting the page. This is useful if\n * you want the pushFunction to be called for the last actions before the user leaves the\n * current page, even if the delay wasn’t reached.\n *\n * @default false\n */\n triggerOnUIInteraction?: boolean;\n\n /**\n * Triggers `pushFunction` when InstantSearch is initialized. This means\n * the `pushFunction` might be called even though the user didn’t perfom\n * any search-related action.\n *\n * @default true\n */\n pushInitialSearch?: boolean;\n\n /**\n * Triggers `pushFunction` when the page changes, either through the UI or programmatically.\n *\n * @default false\n */\n pushPagination?: boolean;\n};\n\nconst withUsage = createDocumentationMessageGenerator({ name: 'analytics' });\n\nexport type AnalyticsWidgetDescription = {\n $$type: 'ais.analytics';\n $$widgetType: 'ais.analytics';\n renderState: Record<string, unknown>;\n indexRenderState: {\n analytics: WidgetRenderState<\n Record<string, unknown>,\n AnalyticsWidgetParams\n >;\n };\n};\n\nexport type AnalyticsWidget = WidgetFactory<\n AnalyticsWidgetDescription,\n AnalyticsWidgetParams,\n AnalyticsWidgetParams\n>;\n\n// @major this widget will be removed from the next major version.\nconst analytics: AnalyticsWidget = function analytics(widgetParams) {\n const {\n pushFunction,\n delay = 3000,\n triggerOnUIInteraction = false,\n pushInitialSearch = true,\n pushPagination = false,\n } = widgetParams || {};\n\n if (!pushFunction) {\n throw new Error(withUsage('The `pushFunction` option is required.'));\n }\n\n warning(\n false,\n `\\`analytics\\` widget has been deprecated. It is still supported in 4.x releases, but not further. It is replaced by the \\`insights\\` middleware.\n\nFor the migration, visit https://www.algolia.com/doc/guides/building-search-ui/upgrade-guides/js/#analytics-widget`\n );\n\n type AnalyticsState = {\n results: SearchResults;\n state: SearchParameters;\n } | null;\n\n let cachedState: AnalyticsState = null;\n\n type RefinementParameters = {\n [key: string]: string[];\n };\n\n const serializeRefinements = function (\n parameters: RefinementParameters\n ): string {\n const refinements: string[] = [];\n\n for (const parameter in parameters) {\n if (parameters.hasOwnProperty(parameter)) {\n const values = parameters[parameter].join('+');\n\n refinements.push(\n `${encodeURIComponent(parameter)}=${encodeURIComponent(\n parameter\n )}_${encodeURIComponent(values)}`\n );\n }\n }\n\n return refinements.join('&');\n };\n\n const serializeNumericRefinements = function (\n numericRefinements: SearchParameters['numericRefinements']\n ): string {\n const refinements: string[] = [];\n\n for (const attribute in numericRefinements) {\n if (numericRefinements.hasOwnProperty(attribute)) {\n const filter = numericRefinements[attribute];\n\n if (filter.hasOwnProperty('>=') && filter.hasOwnProperty('<=')) {\n if (\n filter['>='] &&\n filter['>='][0] === filter['<='] &&\n filter['<='][0]\n ) {\n refinements.push(`${attribute}=${attribute}_${filter['>=']}`);\n } else {\n refinements.push(\n `${attribute}=${attribute}_${filter['>=']}to${filter['<=']}`\n );\n }\n } else if (filter.hasOwnProperty('>=')) {\n refinements.push(`${attribute}=${attribute}_from${filter['>=']}`);\n } else if (filter.hasOwnProperty('<=')) {\n refinements.push(`${attribute}=${attribute}_to${filter['<=']}`);\n } else if (filter.hasOwnProperty('=')) {\n const equals: string[] = [];\n\n for (const equal in filter['=']) {\n // eslint-disable-next-line max-depth\n if (filter['='].hasOwnProperty(equal)) {\n // @ts-ignore somehow 'equal' is a string, even though it's a number?\n equals.push(filter['='][equal]);\n }\n }\n\n refinements.push(`${attribute}=${attribute}_${equals.join('-')}`);\n }\n }\n }\n\n return refinements.join('&');\n };\n\n let lastSentData = '';\n\n const sendAnalytics = function (analyticsState: AnalyticsState | null): void {\n if (analyticsState === null) {\n return;\n }\n\n const serializedParams: string[] = [];\n\n const serializedRefinements = serializeRefinements({\n ...analyticsState.state.disjunctiveFacetsRefinements,\n ...analyticsState.state.facetsRefinements,\n ...analyticsState.state.hierarchicalFacetsRefinements,\n });\n\n const serializedNumericRefinements = serializeNumericRefinements(\n analyticsState.state.numericRefinements\n );\n\n if (serializedRefinements !== '') {\n serializedParams.push(serializedRefinements);\n }\n\n if (serializedNumericRefinements !== '') {\n serializedParams.push(serializedNumericRefinements);\n }\n\n const stringifiedParams = serializedParams.join('&');\n\n let dataToSend = `Query: ${\n analyticsState.state.query || ''\n }, ${stringifiedParams}`;\n if (pushPagination === true) {\n dataToSend += `, Page: ${analyticsState.state.page || 0}`;\n }\n\n if (lastSentData !== dataToSend) {\n pushFunction(\n stringifiedParams,\n analyticsState.state,\n analyticsState.results\n );\n\n lastSentData = dataToSend;\n }\n };\n\n let pushTimeout: number;\n let isInitialSearch = true;\n\n if (pushInitialSearch === true) {\n isInitialSearch = false;\n }\n\n const onClick = (): void => {\n sendAnalytics(cachedState);\n };\n\n const onUnload = (): void => {\n sendAnalytics(cachedState);\n };\n\n return {\n $$type: 'ais.analytics',\n $$widgetType: 'ais.analytics',\n\n init() {\n if (triggerOnUIInteraction === true) {\n document.addEventListener('click', onClick);\n window.addEventListener('beforeunload', onUnload);\n }\n },\n\n render({ results, state }) {\n if (isInitialSearch === true) {\n isInitialSearch = false;\n\n return;\n }\n\n cachedState = { results, state };\n\n if (pushTimeout) {\n clearTimeout(pushTimeout);\n }\n\n pushTimeout = window.setTimeout(() => sendAnalytics(cachedState), delay);\n },\n\n dispose() {\n if (triggerOnUIInteraction === true) {\n document.removeEventListener('click', onClick);\n window.removeEventListener('beforeunload', onUnload);\n }\n },\n\n getRenderState(renderState, renderOptions) {\n return {\n ...renderState,\n analytics: this.getWidgetRenderState(renderOptions),\n };\n },\n\n getWidgetRenderState() {\n return {\n widgetParams,\n };\n },\n };\n};\n\nexport default analytics;\n","/*!\n Copyright (c) 2017 Jed Watson.\n Licensed under the MIT License (MIT), see\n http://jedwatson.github.io/classnames\n*/\n/* global define */\n\n(function () {\n\t'use strict';\n\n\tvar hasOwn = {}.hasOwnProperty;\n\n\tfunction classNames () {\n\t\tvar classes = [];\n\n\t\tfor (var i = 0; i < arguments.length; i++) {\n\t\t\tvar arg = arguments[i];\n\t\t\tif (!arg) continue;\n\n\t\t\tvar argType = typeof arg;\n\n\t\t\tif (argType === 'string' || argType === 'number') {\n\t\t\t\tclasses.push(arg);\n\t\t\t} else if (Array.isArray(arg) && arg.length) {\n\t\t\t\tvar inner = classNames.apply(null, arg);\n\t\t\t\tif (inner) {\n\t\t\t\t\tclasses.push(inner);\n\t\t\t\t}\n\t\t\t} else if (argType === 'object') {\n\t\t\t\tfor (var key in arg) {\n\t\t\t\t\tif (hasOwn.call(arg, key) && arg[key]) {\n\t\t\t\t\t\tclasses.push(key);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn classes.join(' ');\n\t}\n\n\tif (typeof module !== 'undefined' && module.exports) {\n\t\tclassNames.default = classNames;\n\t\tmodule.exports = classNames;\n\t} else if (typeof define === 'function' && typeof define.amd === 'object' && define.amd) {\n\t\t// register as 'classnames', consistent with npm package name\n\t\tdefine('classnames', [], function () {\n\t\t\treturn classNames;\n\t\t});\n\t} else {\n\t\twindow.classNames = classNames;\n\t}\n}());\n","/** @jsx h */\n\nimport type { JSX } from 'preact';\nimport { h, Component } from 'preact';\nimport { renderTemplate, isEqual } from '../../lib/utils';\nimport type { PreparedTemplateProps } from '../../lib/utils/prepareTemplateProps';\nimport type { Templates } from '../../types';\n\nconst defaultProps = {\n data: {},\n rootTagName: 'div',\n useCustomCompileOptions: {},\n templates: {},\n templatesConfig: {},\n};\n\ntype TemplateProps = {\n data?: Record<string, any>;\n rootProps?: Record<string, any>;\n rootTagName?: keyof JSX.IntrinsicElements;\n templateKey: string;\n bindEvent?: (...args: any[]) => string;\n} & PreparedTemplateProps<Templates> &\n Readonly<typeof defaultProps>;\n\n// @TODO: Template should be a generic and receive TData to pass to Templates (to avoid TTemplateData to be set as `any`)\nclass Template extends Component<TemplateProps> {\n public static readonly defaultProps = defaultProps;\n\n public shouldComponentUpdate(nextProps: TemplateProps) {\n return (\n !isEqual(this.props.data, nextProps.data) ||\n this.props.templateKey !== nextProps.templateKey ||\n !isEqual(this.props.rootProps, nextProps.rootProps)\n );\n }\n\n public render() {\n const RootTagName = this.props.rootTagName;\n\n const useCustomCompileOptions =\n this.props.useCustomCompileOptions[this.props.templateKey];\n const compileOptions = useCustomCompileOptions\n ? this.props.templatesConfig.compileOptions\n : {};\n\n const content = renderTemplate({\n templates: this.props.templates,\n templateKey: this.props.templateKey,\n compileOptions,\n helpers: this.props.templatesConfig.helpers,\n data: this.props.data,\n bindEvent: this.props.bindEvent,\n });\n\n if (content === null) {\n // Adds a noscript to the DOM but virtual DOM is null\n // See http://facebook.github.io/react/docs/component-specs.html#render\n return null;\n }\n\n return (\n <RootTagName\n {...this.props.rootProps}\n dangerouslySetInnerHTML={{ __html: content }}\n />\n );\n }\n}\n\nexport default Template;\n","/** @jsx h */\n\nimport { h } from 'preact';\nimport cx from 'classnames';\nimport Template from '../Template/Template';\nimport type {\n BreadcrumbCSSClasses,\n BreadcrumbTemplates,\n} from '../../widgets/breadcrumb/breadcrumb';\nimport type { ComponentCSSClasses } from '../../types';\nimport type { PreparedTemplateProps } from '../../lib/utils/prepareTemplateProps';\nimport type { BreadcrumbConnectorParamsItem } from '../../connectors/breadcrumb/connectBreadcrumb';\n\nexport type BreadcrumbComponentCSSClasses =\n ComponentCSSClasses<BreadcrumbCSSClasses>;\n\nexport type BreadcrumbComponentTemplates = Required<BreadcrumbTemplates>;\n\nexport type BreadcrumbProps = {\n items: BreadcrumbConnectorParamsItem[];\n cssClasses: BreadcrumbComponentCSSClasses;\n templateProps: PreparedTemplateProps<BreadcrumbComponentTemplates>;\n createURL(value?: string | null): string;\n refine(value?: string | null): void;\n canRefine?: boolean;\n};\n\nconst Breadcrumb = ({\n items,\n cssClasses,\n templateProps,\n createURL,\n refine,\n}: BreadcrumbProps) => (\n <div\n className={cx(cssClasses.root, {\n [cssClasses.noRefinementRoot]: items.length === 0,\n })}\n >\n <ul className={cssClasses.list}>\n <li\n className={cx(cssClasses.item, {\n [cssClasses.selectedItem]: items.length === 0,\n })}\n >\n <Template\n {...templateProps}\n templateKey=\"home\"\n rootTagName=\"a\"\n rootProps={{\n className: cssClasses.link,\n href: createURL(undefined),\n onClick: (event: MouseEvent) => {\n event.preventDefault();\n refine(undefined);\n },\n }}\n />\n </li>\n\n {items.map((item, idx) => {\n const isLast = idx === items.length - 1;\n\n return (\n <li\n key={item.label + idx}\n className={cx(cssClasses.item, {\n [cssClasses.selectedItem]: isLast,\n })}\n >\n <Template\n {...templateProps}\n templateKey=\"separator\"\n rootTagName=\"span\"\n rootProps={{\n className: cssClasses.separator,\n 'aria-hidden': true,\n }}\n />\n {isLast ? (\n item.label\n ) : (\n <a\n className={cssClasses.link}\n href={createURL(item.value)}\n onClick={(event) => {\n event.preventDefault();\n refine(item.value);\n }}\n >\n {item.label}\n </a>\n )}\n </li>\n );\n })}\n </ul>\n </div>\n);\n\nexport default Breadcrumb;\n","/** @jsx h */\n\nimport { h } from 'preact';\nimport cx from 'classnames';\nimport Template from '../Template/Template';\nimport type { ClearRefinementsRenderState } from '../../connectors/clear-refinements/connectClearRefinements';\nimport type {\n ClearRefinementsCSSClasses,\n ClearRefinementsTemplates,\n} from '../../widgets/clear-refinements/clear-refinements';\nimport type { ComponentCSSClasses } from '../../types';\nimport type { PreparedTemplateProps } from '../../lib/utils/prepareTemplateProps';\n\nexport type ClearRefinementsComponentCSSClasses =\n ComponentCSSClasses<ClearRefinementsCSSClasses>;\n\nexport type ClearRefinementsComponentTemplates =\n Required<ClearRefinementsTemplates>;\n\nexport type ClearRefinementsProps = {\n refine: ClearRefinementsRenderState['refine'];\n cssClasses: ClearRefinementsComponentCSSClasses;\n hasRefinements: ClearRefinementsRenderState['hasRefinements'];\n templateProps: PreparedTemplateProps<ClearRefinementsComponentTemplates>;\n};\n\nconst ClearRefinements = ({\n hasRefinements,\n refine,\n cssClasses,\n templateProps,\n}: ClearRefinementsProps) => (\n <div className={cssClasses.root}>\n <Template\n {...templateProps}\n templateKey=\"resetLabel\"\n rootTagName=\"button\"\n rootProps={{\n className: cx(cssClasses.button, {\n [cssClasses.disabledButton]: !hasRefinements,\n }),\n onClick: refine,\n disabled: !hasRefinements,\n }}\n data={{ hasRefinements }}\n />\n </div>\n);\n\nexport default ClearRefinements;\n","/** @jsx h */\n\nimport { h } from 'preact';\nimport { isSpecialClick, capitalize } from '../../lib/utils';\nimport type {\n CurrentRefinementsConnectorParamsItem,\n CurrentRefinementsConnectorParamsRefinement,\n} from '../../connectors/current-refinements/connectCurrentRefinements';\nimport type { CurrentRefinementsCSSClasses } from '../../widgets/current-refinements/current-refinements';\nimport type { ComponentCSSClasses } from '../../types';\n\nexport type CurrentRefinementsComponentCSSClasses =\n ComponentCSSClasses<CurrentRefinementsCSSClasses>;\n\nexport type CurrentRefinementsProps = {\n items: CurrentRefinementsConnectorParamsItem[];\n cssClasses: CurrentRefinementsComponentCSSClasses;\n};\n\nconst createItemKey = ({\n attribute,\n value,\n type,\n operator,\n}: CurrentRefinementsConnectorParamsRefinement): string =>\n [attribute, type, value, operator]\n .map((key) => key)\n .filter(Boolean)\n .join(':');\n\nconst handleClick = (callback: () => void) => (event: any) => {\n if (isSpecialClick(event)) {\n return;\n }\n\n event.preventDefault();\n callback();\n};\n\nconst CurrentRefinements = ({ items, cssClasses }: CurrentRefinementsProps) => (\n <div className={cssClasses.root}>\n <ul className={cssClasses.list}>\n {items.map((item, index) => (\n <li\n key={`${item.indexName}-${item.attribute}-${index}`}\n className={cssClasses.item}\n >\n <span className={cssClasses.label}>{capitalize(item.label)}:</span>\n\n {item.refinements.map((refinement) => (\n <span\n key={createItemKey(refinement)}\n className={cssClasses.category}\n >\n <span className={cssClasses.categoryLabel}>\n {refinement.attribute === 'query' ? (\n <q>{refinement.label}</q>\n ) : (\n refinement.label\n )}\n </span>\n\n <button\n className={cssClasses.delete}\n onClick={handleClick(item.refine.bind(null, refinement))}\n >\n ✕\n </button>\n </span>\n ))}\n </li>\n ))}\n </ul>\n </div>\n);\n\nexport default CurrentRefinements;\n","function capitalize(text: string): string {\n return text.toString().charAt(0).toUpperCase() + text.toString().slice(1);\n}\n\nexport default capitalize;\n","/** @jsx h */\n\nimport { h, render } from 'preact';\nimport cx from 'classnames';\nimport CurrentRefinements from '../../components/CurrentRefinements/CurrentRefinements';\nimport type {\n CurrentRefinementsConnectorParams,\n CurrentRefinementsRenderState,\n CurrentRefinementsWidgetDescription,\n} from '../../connectors/current-refinements/connectCurrentRefinements';\nimport connectCurrentRefinements from '../../connectors/current-refinements/connectCurrentRefinements';\nimport {\n getContainerNode,\n createDocumentationMessageGenerator,\n} from '../../lib/utils';\nimport { component } from '../../lib/suit';\nimport type { ComponentCSSClasses, Renderer, WidgetFactory } from '../../types';\n\nexport type CurrentRefinementsCSSClasses = Partial<{\n /**\n * CSS class to add to the root element.\n */\n root: string | string[];\n\n /**\n * CSS class to add to the list element.\n */\n list: string | string[];\n\n /**\n * CSS class to add to the each item element.\n */\n item: string | string[];\n\n /**\n * CSS class to add to the label element.\n */\n label: string | string[];\n\n /**\n * CSS class to add to the category element.\n */\n category: string | string[];\n\n /**\n * CSS class to add to the categoryLabel element.\n */\n categoryLabel: string | string[];\n\n /**\n * CSS class to add to the delete element.\n */\n delete: string | string[];\n}>;\n\nexport type CurrentRefinementsWidgetParams = {\n /**\n * The CSS Selector or `HTMLElement` to insert the widget into.\n */\n container: string | HTMLElement;\n\n /**\n * The CSS classes to override.\n */\n cssClasses?: CurrentRefinementsCSSClasses;\n};\n\nconst withUsage = createDocumentationMessageGenerator({\n name: 'current-refinements',\n});\nconst suit = component('CurrentRefinements');\n\nconst renderer: Renderer<\n CurrentRefinementsRenderState,\n Partial<CurrentRefinementsWidgetParams>\n> = ({ items, widgetParams }, isFirstRender) => {\n if (isFirstRender) {\n return;\n }\n\n const { container, cssClasses } = widgetParams as {\n container: HTMLElement;\n cssClasses: ComponentCSSClasses<CurrentRefinementsCSSClasses>;\n };\n\n render(\n <CurrentRefinements cssClasses={cssClasses} items={items} />,\n container\n );\n};\n\nexport type CurrentRefinementsWidget = WidgetFactory<\n CurrentRefinementsWidgetDescription & {\n $$widgetType: 'ais.currentRefinements';\n },\n CurrentRefinementsConnectorParams,\n CurrentRefinementsWidgetParams\n>;\n\nconst currentRefinements: CurrentRefinementsWidget =\n function currentRefinements(widgetParams) {\n const {\n container,\n includedAttributes,\n excludedAttributes,\n cssClasses: userCssClasses = {},\n transformItems,\n } = widgetParams || {};\n\n if (!container) {\n throw new Error(withUsage('The `container` option is required.'));\n }\n\n const containerNode = getContainerNode(container);\n const cssClasses = {\n root: cx(suit(), userCssClasses.root),\n list: cx(suit({ descendantName: 'list' }), userCssClasses.list),\n item: cx(suit({ descendantName: 'item' }), userCssClasses.item),\n label: cx(suit({ descendantName: 'label' }), userCssClasses.label),\n category: cx(\n suit({ descendantName: 'category' }),\n userCssClasses.category\n ),\n categoryLabel: cx(\n suit({ descendantName: 'categoryLabel' }),\n userCssClasses.categoryLabel\n ),\n delete: cx(suit({ descendantName: 'delete' }), userCssClasses.delete),\n };\n\n const makeWidget =\n connectCurrentRefinements<CurrentRefinementsWidgetParams>(renderer, () =>\n render(null, containerNode)\n );\n\n return {\n ...makeWidget({\n container: containerNode,\n cssClasses,\n includedAttributes,\n excludedAttributes,\n transformItems,\n }),\n $$widgetType: 'ais.currentRefinements',\n };\n };\n\nexport default currentRefinements;\n","/** @jsx h */\n\nimport { h } from 'preact';\nimport cx from 'classnames';\nimport Template from '../Template/Template';\nimport type {\n AnswersCSSClasses,\n AnswersTemplates,\n} from '../../widgets/answers/answers';\nimport type { ComponentCSSClasses, Hits } from '../../types';\n\nexport type AnswersComponentCSSClasses = ComponentCSSClasses<AnswersCSSClasses>;\n\nexport type AnswersComponentTemplates = Required<AnswersTemplates>;\n\nexport type AnswersProps = {\n hits: Hits;\n isLoading: boolean;\n cssClasses: AnswersComponentCSSClasses;\n templateProps: {\n [key: string]: any;\n templates: AnswersComponentTemplates;\n };\n};\n\nconst Answers = ({\n hits,\n isLoading,\n cssClasses,\n templateProps,\n}: AnswersProps) => (\n <div\n className={cx(cssClasses.root, {\n [cssClasses.emptyRoot]: hits.length === 0,\n })}\n >\n <Template\n {...templateProps}\n templateKey=\"header\"\n rootProps={{ className: cssClasses.header }}\n data={{\n hits,\n isLoading,\n }}\n />\n {isLoading ? (\n <Template\n {...templateProps}\n templateKey=\"loader\"\n rootProps={{ className: cssClasses.loader }}\n />\n ) : (\n <ul className={cssClasses.list}>\n {hits.map((hit, position) => (\n <Template\n {...templateProps}\n templateKey=\"item\"\n rootTagName=\"li\"\n rootProps={{ className: cssClasses.item }}\n key={hit.objectID}\n data={{\n ...hit,\n __hitIndex: position,\n }}\n />\n ))}\n </ul>\n )}\n </div>\n);\n\nexport default Answers;\n","import type { BreadcrumbComponentTemplates } from '../../components/Breadcrumb/Breadcrumb';\n\nconst defaultTemplates: BreadcrumbComponentTemplates = {\n home: 'Home',\n separator: '>',\n};\n\nexport default defaultTemplates;\n","/** @jsx h */\n\nimport { h, render } from 'preact';\nimport cx from 'classnames';\nimport type {\n BreadcrumbComponentCSSClasses,\n BreadcrumbComponentTemplates,\n} from '../../components/Breadcrumb/Breadcrumb';\nimport Breadcrumb from '../../components/Breadcrumb/Breadcrumb';\nimport type {\n BreadcrumbWidgetDescription,\n BreadcrumbConnectorParams,\n BreadcrumbRenderState,\n} from '../../connectors/breadcrumb/connectBreadcrumb';\nimport connectBreadcrumb from '../../connectors/breadcrumb/connectBreadcrumb';\nimport defaultTemplates from './defaultTemplates';\nimport {\n getContainerNode,\n prepareTemplateProps,\n createDocumentationMessageGenerator,\n} from '../../lib/utils';\nimport { component } from '../../lib/suit';\nimport type { WidgetFactory, Template, Renderer } from '../../types';\nimport type { PreparedTemplateProps } from '../../lib/utils/prepareTemplateProps';\n\nconst withUsage = createDocumentationMessageGenerator({ name: 'breadcrumb' });\nconst suit = component('Breadcrumb');\n\nconst renderer =\n ({\n containerNode,\n cssClasses,\n renderState,\n templates,\n }: {\n containerNode: HTMLElement;\n cssClasses: BreadcrumbComponentCSSClasses;\n renderState: {\n templateProps?: PreparedTemplateProps<BreadcrumbComponentTemplates>;\n };\n templates: BreadcrumbTemplates;\n }): Renderer<BreadcrumbRenderState, Partial<BreadcrumbWidgetParams>> =>\n (\n { canRefine, createURL, instantSearchInstance, items, refine },\n isFirstRendering\n ) => {\n if (isFirstRendering) {\n renderState.templateProps = prepareTemplateProps({\n defaultTemplates,\n templatesConfig: instantSearchInstance.templatesConfig,\n templates,\n });\n\n return;\n }\n\n render(\n <Breadcrumb\n canRefine={canRefine}\n cssClasses={cssClasses}\n createURL={createURL}\n items={items}\n refine={refine}\n templateProps={renderState.templateProps!}\n />,\n containerNode\n );\n };\n\nexport type BreadcrumbCSSClasses = Partial<{\n /**\n * CSS class to add to the root element of the widget.\n */\n root: string | string[];\n\n /**\n * CSS class to add to the root element of the widget if there are no refinements.\n */\n noRefinementRoot: string | string[];\n\n /**\n * CSS class to add to the list element.\n */\n list: string | string[];\n\n /**\n * CSS class to add to the items of the list. The items contains the link and the separator.\n */\n item: string | string[];\n\n /**\n * CSS class to add to the selected item in the list: the last one or the home if there are no refinements.\n */\n selectedItem: string | string[];\n\n /**\n * CSS class to add to the separator.\n */\n separator: string | string[];\n\n /**\n * CSS class to add to the links in the items.\n */\n link: string | string[];\n}>;\n\nexport type BreadcrumbTemplates = Partial<{\n /**\n * Label of the breadcrumb's first element.\n */\n home: Template;\n\n /**\n * Symbol used to separate the elements of the breadcrumb.\n */\n separator: Template;\n}>;\n\nexport type BreadcrumbWidgetParams = {\n /**\n * CSS Selector or HTMLElement to insert the widget.\n */\n container: string | HTMLElement;\n\n /**\n * Templates to use for the widget.\n */\n templates?: BreadcrumbTemplates;\n\n /**\n * CSS classes to add to the wrapping elements.\n */\n cssClasses?: BreadcrumbCSSClasses;\n};\n\nexport type BreadcrumbWidget = WidgetFactory<\n BreadcrumbWidgetDescription & { $$widgetType: 'ais.breadcrumb' },\n BreadcrumbConnectorParams,\n BreadcrumbWidgetParams\n>;\n\nconst breadcrumb: BreadcrumbWidget = function breadcrumb(widgetParams) {\n const {\n container,\n attributes,\n separator,\n rootPath,\n transformItems,\n templates = {},\n cssClasses: userCssClasses = {},\n } = widgetParams || {};\n\n if (!container) {\n throw new Error(withUsage('The `container` option is required.'));\n }\n\n const containerNode = getContainerNode(container);\n\n const cssClasses = {\n root: cx(suit(), userCssClasses.root),\n noRefinementRoot: cx(\n suit({ modifierName: 'noRefinement' }),\n userCssClasses.noRefinementRoot\n ),\n list: cx(suit({ descendantName: 'list' }), userCssClasses.list),\n item: cx(suit({ descendantName: 'item' }), userCssClasses.item),\n selectedItem: cx(\n suit({ descendantName: 'item', modifierName: 'selected' }),\n userCssClasses.selectedItem\n ),\n separator: cx(\n suit({ descendantName: 'separator' }),\n userCssClasses.separator\n ),\n link: cx(suit({ descendantName: 'link' }), userCssClasses.link),\n };\n\n const specializedRenderer = renderer({\n containerNode,\n cssClasses,\n renderState: {},\n templates,\n });\n\n const makeWidget = connectBreadcrumb(specializedRenderer, () =>\n render(null, containerNode)\n );\n\n return {\n ...makeWidget({ attributes, separator, rootPath, transformItems }),\n $$widgetType: 'ais.breadcrumb',\n };\n};\n\nexport default breadcrumb;\n","import type { ClearRefinementsComponentTemplates } from '../../components/ClearRefinements/ClearRefinements';\n\nconst defaultTemplates: ClearRefinementsComponentTemplates = {\n resetLabel: 'Clear refinements',\n};\n\nexport default defaultTemplates;\n","/** @jsx h */\n\nimport { h, render } from 'preact';\nimport type {\n ClearRefinementsComponentCSSClasses,\n ClearRefinementsComponentTemplates,\n} from '../../components/ClearRefinements/ClearRefinements';\nimport ClearRefinements from '../../components/ClearRefinements/ClearRefinements';\nimport cx from 'classnames';\nimport type {\n ClearRefinementsConnectorParams,\n ClearRefinementsRenderState,\n ClearRefinementsWidgetDescription,\n} from '../../connectors/clear-refinements/connectClearRefinements';\nimport connectClearRefinements from '../../connectors/clear-refinements/connectClearRefinements';\nimport defaultTemplates from './defaultTemplates';\nimport {\n getContainerNode,\n prepareTemplateProps,\n createDocumentationMessageGenerator,\n} from '../../lib/utils';\nimport { component } from '../../lib/suit';\nimport type { WidgetFactory, Template, Renderer } from '../../types';\nimport type { PreparedTemplateProps } from '../../lib/utils/prepareTemplateProps';\n\nconst withUsage = createDocumentationMessageGenerator({\n name: 'clear-refinements',\n});\nconst suit = component('ClearRefinements');\n\nconst renderer =\n ({\n containerNode,\n cssClasses,\n renderState,\n templates,\n }: {\n containerNode: HTMLElement;\n cssClasses: ClearRefinementsComponentCSSClasses;\n renderState: {\n templateProps?: PreparedTemplateProps<ClearRefinementsComponentTemplates>;\n };\n templates: ClearRefinementsTemplates;\n }): Renderer<\n ClearRefinementsRenderState,\n Partial<ClearRefinementsWidgetParams>\n > =>\n ({ refine, hasRefinements, instantSearchInstance }, isFirstRendering) => {\n if (isFirstRendering) {\n renderState.templateProps = prepareTemplateProps({\n defaultTemplates,\n templatesConfig: instantSearchInstance.templatesConfig,\n templates,\n });\n return;\n }\n\n render(\n <ClearRefinements\n refine={refine}\n cssClasses={cssClasses}\n hasRefinements={hasRefinements}\n templateProps={renderState.templateProps!}\n />,\n containerNode\n );\n };\n\nexport type ClearRefinementsCSSClasses = Partial<{\n /**\n * CSS class to add to the wrapper element.\n */\n root: string | string[];\n\n /**\n * CSS class to add to the button of the widget.\n */\n button: string | string[];\n\n /**\n * CSS class to add to the button when there are no refinements.\n */\n disabledButton: string | string[];\n}>;\n\nexport type ClearRefinementsTemplates = Partial<{\n /**\n * Template for the content of the button\n */\n resetLabel: Template;\n}>;\n\nexport type ClearRefinementsWidgetParams = {\n /**\n * CSS Selector or HTMLElement to insert the widget.\n */\n container: string | HTMLElement;\n\n /**\n * Templates to use for the widget.\n */\n templates?: ClearRefinementsTemplates;\n\n /**\n * CSS classes to be added.\n */\n cssClasses?: ClearRefinementsCSSClasses;\n};\n\nexport type ClearRefinementsWidget = WidgetFactory<\n ClearRefinementsWidgetDescription & { $$widgetType: 'ais.clearRefinements' },\n ClearRefinementsConnectorParams,\n ClearRefinementsWidgetParams\n>;\n\nconst clearRefinements: ClearRefinementsWidget = (widgetParams) => {\n const {\n container,\n templates = {},\n includedAttributes,\n excludedAttributes,\n transformItems,\n cssClasses: userCssClasses = {},\n } = widgetParams || {};\n\n if (!container) {\n throw new Error(withUsage('The `container` option is required.'));\n }\n\n const containerNode = getContainerNode(container);\n\n const cssClasses = {\n root: cx(suit(), userCssClasses.root),\n button: cx(suit({ descendantName: 'button' }), userCssClasses.button),\n disabledButton: cx(\n suit({ descendantName: 'button', modifierName: 'disabled' }),\n userCssClasses.disabledButton\n ),\n };\n\n const specializedRenderer = renderer({\n containerNode,\n cssClasses,\n renderState: {},\n templates,\n });\n\n const makeWidget = connectClearRefinements(specializedRenderer, () =>\n render(null, containerNode)\n );\n\n return {\n ...makeWidget({\n includedAttributes,\n excludedAttributes,\n transformItems,\n }),\n $$widgetType: 'ais.clearRefinements',\n };\n};\n\nexport default clearRefinements;\n","import type { AnswersComponentTemplates } from '../../components/Answers/Answers';\n\nconst defaultTemplates: AnswersComponentTemplates = {\n header: '',\n loader: '',\n item: (item) => JSON.stringify(item),\n};\n\nexport default defaultTemplates;\n","/** @jsx h */\n\nimport { h, render } from 'preact';\nimport cx from 'classnames';\nimport type { WidgetFactory, Template, Hit, Renderer } from '../../types';\nimport defaultTemplates from './defaultTemplates';\nimport {\n createDocumentationMessageGenerator,\n getContainerNode,\n prepareTemplateProps,\n} from '../../lib/utils';\nimport { component } from '../../lib/suit';\nimport type {\n AnswersComponentCSSClasses,\n AnswersComponentTemplates,\n} from '../../components/Answers/Answers';\nimport Answers from '../../components/Answers/Answers';\nimport type {\n AnswersRenderState,\n AnswersConnectorParams,\n AnswersWidgetDescription,\n} from '../../connectors/answers/connectAnswers';\nimport connectAnswers from '../../connectors/answers/connectAnswers';\nimport type { PreparedTemplateProps } from '../../lib/utils/prepareTemplateProps';\n\nconst withUsage = createDocumentationMessageGenerator({ name: 'answers' });\nconst suit = component('Answers');\n\nconst renderer =\n ({\n containerNode,\n cssClasses,\n renderState,\n templates,\n }: {\n containerNode: HTMLElement;\n cssClasses: AnswersComponentCSSClasses;\n renderState: {\n templateProps?: PreparedTemplateProps<AnswersComponentTemplates>;\n };\n templates: AnswersTemplates;\n }): Renderer<AnswersRenderState, Partial<AnswersWidgetParams>> =>\n ({ hits, isLoading, instantSearchInstance }, isFirstRendering) => {\n if (isFirstRendering) {\n renderState.templateProps = prepareTemplateProps({\n defaultTemplates,\n templatesConfig: instantSearchInstance.templatesConfig,\n templates,\n });\n return;\n }\n\n render(\n <Answers\n cssClasses={cssClasses}\n hits={hits}\n isLoading={isLoading}\n templateProps={renderState.templateProps!}\n />,\n containerNode\n );\n };\n\nexport type AnswersTemplates = Partial<{\n /**\n * Template to use for the header. This template will receive an object containing `hits` and `isLoading`.\n */\n header: Template<{\n hits: Hit[];\n isLoading: boolean;\n }>;\n\n /**\n * Template to use for the loader.\n */\n loader: Template;\n\n /**\n * Template to use for each result. This template will receive an object containing a single record.\n */\n item: Template<Hit>;\n}>;\n\nexport type AnswersCSSClasses = Partial<{\n /**\n * CSS class to add to the root element of the widget.\n */\n root: string | string[];\n\n /**\n * CSS class to add to the wrapping element when no results.\n */\n emptyRoot: string | string[];\n\n /**\n * CSS classes to add to the header.\n */\n header: string | string[];\n\n /**\n * CSS classes to add to the loader.\n */\n loader: string | string[];\n\n /**\n * CSS class to add to the list of results.\n */\n list: string | string[];\n\n /**\n * CSS class to add to each result.\n */\n item: string | string[];\n}>;\n\nexport type AnswersWidgetParams = {\n /**\n * CSS Selector or HTMLElement to insert the widget.\n */\n container: string | HTMLElement;\n\n /**\n * The templates to use for the widget.\n */\n templates?: AnswersTemplates;\n\n /**\n * The CSS classes to override.\n */\n cssClasses?: AnswersCSSClasses;\n};\n\nexport type AnswersWidget = WidgetFactory<\n AnswersWidgetDescription & { $$widgetType: 'ais.answers' },\n AnswersConnectorParams,\n AnswersWidgetParams\n>;\n\nconst answersWidget: AnswersWidget = (widgetParams) => {\n const {\n container,\n attributesForPrediction,\n queryLanguages,\n nbHits,\n searchDebounceTime,\n renderDebounceTime,\n escapeHTML,\n extraParameters,\n templates = {},\n cssClasses: userCssClasses = {},\n } = widgetParams || {};\n\n if (!container) {\n throw new Error(withUsage('The `container` option is required.'));\n }\n\n const containerNode = getContainerNode(container);\n const cssClasses = {\n root: cx(suit(), userCssClasses.root),\n emptyRoot: cx(suit({ modifierName: 'empty' }), userCssClasses.emptyRoot),\n header: cx(suit({ descendantName: 'header' }), userCssClasses.header),\n loader: cx(suit({ descendantName: 'loader' }), userCssClasses.loader),\n list: cx(suit({ descendantName: 'list' }), userCssClasses.list),\n item: cx(suit({ descendantName: 'item' }), userCssClasses.item),\n };\n\n const specializedRenderer = renderer({\n containerNode,\n cssClasses,\n templates,\n renderState: {},\n });\n\n const makeWidget = connectAnswers(specializedRenderer, () =>\n render(null, containerNode)\n );\n\n return {\n ...makeWidget({\n attributesForPrediction,\n queryLanguages,\n nbHits,\n searchDebounceTime,\n renderDebounceTime,\n escapeHTML,\n extraParameters,\n }),\n $$widgetType: 'ais.answers',\n };\n};\n\nexport default answersWidget;\n","import type {\n DynamicWidgetsConnectorParams,\n DynamicWidgetsWidgetDescription,\n} from '../../connectors/dynamic-widgets/connectDynamicWidgets';\nimport connectDynamicWidgets from '../../connectors/dynamic-widgets/connectDynamicWidgets';\nimport { component } from '../../lib/suit';\nimport {\n createDocumentationMessageGenerator,\n getContainerNode,\n getWidgetAttribute,\n} from '../../lib/utils';\nimport type { Widget, WidgetFactory } from '../../types';\n\nconst withUsage = createDocumentationMessageGenerator({\n name: 'dynamic-widgets',\n});\nconst suit = component('DynamicWidgets');\n\nexport type DynamicWidgetsWidgetParams = {\n /**\n * CSS Selector or HTMLElement to insert the widget.\n */\n container: string | HTMLElement;\n\n /**\n * An array of widget creator functions, displayed in the order defined by\n * `facetOrdering`.\n */\n widgets: Array<(container: HTMLElement) => Widget>;\n\n /**\n * Function to return a fallback widget when an attribute isn't found in\n * `widgets`.\n */\n fallbackWidget?(args: {\n /** The attribute name to create a widget for. */\n attribute: string;\n /** CSS Selector or HTMLElement to insert the widget */\n container: HTMLElement;\n }): Widget;\n};\n\nexport type DynamicWidgetsWidget = WidgetFactory<\n DynamicWidgetsWidgetDescription & { $$widgetType: 'ais.dynamicWidgets' },\n Omit<DynamicWidgetsConnectorParams, 'widgets' | 'fallbackWidget'>,\n DynamicWidgetsWidgetParams\n>;\n\nfunction createContainer(rootContainer: HTMLElement) {\n const container = document.createElement('div');\n container.className = suit({ descendantName: 'widget' });\n\n rootContainer.appendChild(container);\n\n return container;\n}\n\nconst dynamicWidgets: DynamicWidgetsWidget = function dynamicWidgets(\n widgetParams\n) {\n const {\n container: containerSelector,\n widgets,\n fallbackWidget,\n ...otherWidgetParams\n } = widgetParams || {};\n\n if (!containerSelector) {\n throw new Error(withUsage('The `container` option is required.'));\n }\n\n if (\n !(\n widgets &&\n Array.isArray(widgets) &&\n widgets.every((widget) => typeof widget === 'function')\n )\n ) {\n throw new Error(\n withUsage('The `widgets` option expects an array of callbacks.')\n );\n }\n\n const userContainer = getContainerNode(containerSelector);\n const rootContainer = document.createElement('div');\n rootContainer.className = suit();\n\n const containers = new Map<string, HTMLElement>();\n const connectorWidgets: Widget[] = [];\n\n const makeWidget = connectDynamicWidgets(\n ({ attributesToRender }, isFirstRender) => {\n if (isFirstRender) {\n userContainer.appendChild(rootContainer);\n }\n\n attributesToRender.forEach((attribute) => {\n if (!containers.has(attribute)) {\n return;\n }\n const container = containers.get(attribute)!;\n rootContainer.appendChild(container);\n });\n },\n () => {\n userContainer.removeChild(rootContainer);\n }\n );\n\n const widget = makeWidget({\n ...otherWidgetParams,\n widgets: connectorWidgets,\n fallbackWidget:\n typeof fallbackWidget === 'function'\n ? ({ attribute }) => {\n const container = createContainer(rootContainer);\n containers.set(attribute, container);\n return fallbackWidget({ attribute, container });\n }\n : undefined,\n });\n\n return {\n ...widget,\n init(initOptions) {\n widgets.forEach((cb) => {\n const container = createContainer(rootContainer);\n\n const childWidget = cb(container);\n const attribute = getWidgetAttribute(childWidget, initOptions);\n\n containers.set(attribute, container);\n connectorWidgets.push(childWidget);\n });\n\n widget.init!(initOptions);\n },\n $$widgetType: 'ais.dynamicWidgets',\n };\n};\nexport default dynamicWidgets;\n","/** @jsx h */\n\nimport type { ComponentChildren } from 'preact';\nimport { h } from 'preact';\n\ntype Props = {\n className: string;\n onClick(event: MouseEvent): void;\n children: ComponentChildren;\n disabled?: boolean;\n};\n\nconst GeoSearchButton = ({\n className,\n disabled = false,\n onClick,\n children,\n}: Props) => (\n <button className={className} onClick={onClick} disabled={disabled}>\n {children}\n </button>\n);\n\nexport default GeoSearchButton;\n","/** @jsx h */\n\nimport type { ComponentChildren } from 'preact';\nimport { h } from 'preact';\n\ntype Props = {\n classNameLabel: string;\n classNameInput: string;\n checked: boolean;\n onToggle(event: Event): void;\n children: ComponentChildren;\n};\n\nconst GeoSearchToggle = ({\n classNameLabel,\n classNameInput,\n checked,\n onToggle,\n children,\n}: Props) => (\n <label className={classNameLabel}>\n <input\n className={classNameInput}\n type=\"checkbox\"\n checked={checked}\n onChange={onToggle}\n />\n {children}\n </label>\n);\n\nexport default GeoSearchToggle;\n","/** @jsx h */\n\nimport { h, Fragment } from 'preact';\nimport cx from 'classnames';\nimport Template from '../Template/Template';\nimport GeoSearchButton from './GeoSearchButton';\nimport GeoSearchToggle from './GeoSearchToggle';\nimport type {\n GeoSearchCSSClasses,\n GeoSearchTemplates,\n} from '../../widgets/geo-search/geo-search';\nimport type { ComponentCSSClasses } from '../../types';\nimport type { PreparedTemplateProps } from '../../lib/utils/prepareTemplateProps';\n\ntype Props = {\n cssClasses: ComponentCSSClasses<GeoSearchCSSClasses>;\n enableRefine: boolean;\n enableRefineControl: boolean;\n enableClearMapRefinement: boolean;\n isRefineOnMapMove: boolean;\n isRefinedWithMap: boolean;\n hasMapMoveSinceLastRefine: boolean;\n onRefineToggle(event: Event): void;\n onRefineClick(event: MouseEvent): void;\n onClearClick(event: MouseEvent): void;\n templateProps: PreparedTemplateProps<GeoSearchTemplates>;\n};\n\nconst GeoSearchControls = ({\n cssClasses,\n enableRefine,\n enableRefineControl,\n enableClearMapRefinement,\n isRefineOnMapMove,\n isRefinedWithMap,\n hasMapMoveSinceLastRefine,\n onRefineToggle,\n onRefineClick,\n onClearClick,\n templateProps,\n}: Props) => (\n <Fragment>\n {enableRefine && (\n <div>\n {enableRefineControl && (\n <div className={cssClasses.control}>\n {isRefineOnMapMove || !hasMapMoveSinceLastRefine ? (\n <GeoSearchToggle\n classNameLabel={cx(cssClasses.label, {\n [cssClasses.selectedLabel]: isRefineOnMapMove,\n })}\n classNameInput={cssClasses.input}\n checked={isRefineOnMapMove}\n onToggle={onRefineToggle}\n >\n <Template\n {...templateProps}\n templateKey=\"toggle\"\n rootTagName=\"span\"\n />\n </GeoSearchToggle>\n ) : (\n <GeoSearchButton\n className={cssClasses.redo}\n disabled={!hasMapMoveSinceLastRefine}\n onClick={onRefineClick}\n >\n <Template\n {...templateProps}\n templateKey=\"redo\"\n rootTagName=\"span\"\n />\n </GeoSearchButton>\n )}\n </div>\n )}\n\n {!enableRefineControl && !isRefineOnMapMove && (\n <div className={cssClasses.control}>\n <GeoSearchButton\n className={cx(cssClasses.redo, {\n [cssClasses.disabledRedo]: !hasMapMoveSinceLastRefine,\n })}\n disabled={!hasMapMoveSinceLastRefine}\n onClick={onRefineClick}\n >\n <Template\n {...templateProps}\n templateKey=\"redo\"\n rootTagName=\"span\"\n />\n </GeoSearchButton>\n </div>\n )}\n\n {enableClearMapRefinement && isRefinedWithMap && (\n <GeoSearchButton className={cssClasses.reset} onClick={onClearClick}>\n <Template\n {...templateProps}\n templateKey=\"reset\"\n rootTagName=\"span\"\n />\n </GeoSearchButton>\n )}\n </div>\n )}\n </Fragment>\n);\n\nexport default GeoSearchControls;\n","/** @jsx h */\n\nimport { h, render } from 'preact';\nimport { prepareTemplateProps } from '../../lib/utils';\nimport GeoSearchControls from '../../components/GeoSearchControls/GeoSearchControls';\n\nconst refineWithMap = ({ refine, mapInstance }) =>\n refine({\n northEast: mapInstance.getBounds().getNorthEast().toJSON(),\n southWest: mapInstance.getBounds().getSouthWest().toJSON(),\n });\n\nconst collectMarkersForNextRender = (markers, nextIds) =>\n markers.reduce(\n ([update, exit], marker) => {\n const persist = nextIds.includes(marker.__id);\n\n return persist\n ? [update.concat(marker), exit]\n : [update, exit.concat(marker)];\n },\n [[], []]\n );\n\nconst createBoundingBoxFromMarkers = (google, markers) => {\n const latLngBounds = markers.reduce(\n (acc, marker) => acc.extend(marker.getPosition()),\n new google.maps.LatLngBounds()\n );\n\n return {\n northEast: latLngBounds.getNorthEast().toJSON(),\n southWest: latLngBounds.getSouthWest().toJSON(),\n };\n};\n\nconst lockUserInteraction = (renderState, functionThatAltersTheMapPosition) => {\n renderState.isUserInteraction = false;\n functionThatAltersTheMapPosition();\n renderState.isUserInteraction = true;\n};\n\nconst renderer = (\n {\n items,\n position,\n currentRefinement,\n refine,\n clearMapRefinement,\n toggleRefineOnMapMove,\n isRefineOnMapMove,\n setMapMoveSinceLastRefine,\n hasMapMoveSinceLastRefine,\n isRefinedWithMap,\n widgetParams,\n instantSearchInstance,\n },\n isFirstRendering\n) => {\n const {\n container,\n googleReference,\n cssClasses,\n templates,\n initialZoom,\n initialPosition,\n enableRefine,\n enableClearMapRefinement,\n enableRefineControl,\n mapOptions,\n createMarker,\n markerOptions,\n renderState,\n } = widgetParams;\n\n if (isFirstRendering) {\n renderState.isUserInteraction = true;\n renderState.isPendingRefine = false;\n renderState.markers = [];\n\n const rootElement = document.createElement('div');\n rootElement.className = cssClasses.root;\n container.appendChild(rootElement);\n\n const mapElement = document.createElement('div');\n mapElement.className = cssClasses.map;\n rootElement.appendChild(mapElement);\n\n const treeElement = document.createElement('div');\n treeElement.className = cssClasses.tree;\n rootElement.appendChild(treeElement);\n\n renderState.mapInstance = new googleReference.maps.Map(mapElement, {\n mapTypeControl: false,\n fullscreenControl: false,\n streetViewControl: false,\n clickableIcons: false,\n zoomControlOptions: {\n position: googleReference.maps.ControlPosition.LEFT_TOP,\n },\n ...mapOptions,\n });\n\n const setupListenersWhenMapIsReady = () => {\n const onChange = () => {\n if (renderState.isUserInteraction && enableRefine) {\n setMapMoveSinceLastRefine();\n\n if (isRefineOnMapMove()) {\n renderState.isPendingRefine = true;\n }\n }\n };\n\n renderState.mapInstance.addListener('center_changed', onChange);\n renderState.mapInstance.addListener('zoom_changed', onChange);\n renderState.mapInstance.addListener('dragstart', onChange);\n\n renderState.mapInstance.addListener('idle', () => {\n if (renderState.isUserInteraction && renderState.isPendingRefine) {\n renderState.isPendingRefine = false;\n\n refineWithMap({\n mapInstance: renderState.mapInstance,\n refine,\n });\n }\n });\n };\n\n googleReference.maps.event.addListenerOnce(\n renderState.mapInstance,\n 'idle',\n setupListenersWhenMapIsReady\n );\n\n renderState.templateProps = prepareTemplateProps({\n templatesConfig: instantSearchInstance.templatesConfig,\n templates,\n });\n\n return;\n }\n\n // Collect markers that need to be updated or removed\n const nextItemsIds = items.map((_) => _.objectID);\n const [updateMarkers, exitMarkers] = collectMarkersForNextRender(\n renderState.markers,\n nextItemsIds\n );\n\n // Collect items that will be added\n const updateMarkerIds = updateMarkers.map((_) => _.__id);\n const nextPendingItems = items.filter(\n (item) => !updateMarkerIds.includes(item.objectID)\n );\n\n // Remove all markers that need to be removed\n exitMarkers.forEach((marker) => marker.setMap(null));\n\n // Create the markers from the items\n renderState.markers = updateMarkers.concat(\n nextPendingItems.map((item) => {\n const marker = createMarker({\n map: renderState.mapInstance,\n item,\n });\n\n Object.keys(markerOptions.events).forEach((eventName) => {\n marker.addListener(eventName, (event) => {\n markerOptions.events[eventName]({\n map: renderState.mapInstance,\n event,\n item,\n marker,\n });\n });\n });\n\n return marker;\n })\n );\n\n const shouldUpdate = !hasMapMoveSinceLastRefine();\n\n // We use this value for differentiate the padding to apply during\n // fitBounds. When we don't have a currenRefinement (boundingBox)\n // we let Google Maps compute the automatic padding. But when we\n // provide the currentRefinement we explicitly set the padding\n // to `0` otherwise the map will decrease the zoom on each refine.\n const boundingBoxPadding = currentRefinement ? 0 : null;\n const boundingBox =\n !currentRefinement && Boolean(renderState.markers.length)\n ? createBoundingBoxFromMarkers(googleReference, renderState.markers)\n : currentRefinement;\n\n if (boundingBox && shouldUpdate) {\n lockUserInteraction(renderState, () => {\n renderState.mapInstance.fitBounds(\n new googleReference.maps.LatLngBounds(\n boundingBox.southWest,\n boundingBox.northEast\n ),\n boundingBoxPadding\n );\n });\n } else if (shouldUpdate) {\n lockUserInteraction(renderState, () => {\n renderState.mapInstance.setCenter(position || initialPosition);\n renderState.mapInstance.setZoom(initialZoom);\n });\n }\n\n render(\n <GeoSearchControls\n cssClasses={cssClasses}\n enableRefine={enableRefine}\n enableRefineControl={enableRefineControl}\n enableClearMapRefinement={enableClearMapRefinement}\n isRefineOnMapMove={isRefineOnMapMove()}\n isRefinedWithMap={isRefinedWithMap()}\n hasMapMoveSinceLastRefine={hasMapMoveSinceLastRefine()}\n onRefineToggle={toggleRefineOnMapMove}\n onRefineClick={() =>\n refineWithMap({\n mapInstance: renderState.mapInstance,\n refine,\n })\n }\n onClearClick={clearMapRefinement}\n templateProps={renderState.templateProps}\n />,\n container.querySelector(`.${cssClasses.tree}`)\n );\n};\n\nexport default renderer;\n","import type { GeoSearchComponentTemplates } from './geo-search';\n\nconst defaultTemplates: GeoSearchComponentTemplates = {\n HTMLMarker: '<p>Your custom HTML Marker</p>',\n reset: 'Clear the map refinement',\n toggle: 'Search as I move the map',\n redo: 'Redo search here',\n};\n\nexport default defaultTemplates;\n","// global for TypeScript alone\n/* global google */\nimport cx from 'classnames';\nimport { render } from 'preact';\nimport {\n getContainerNode,\n renderTemplate,\n createDocumentationMessageGenerator,\n} from '../../lib/utils';\nimport { component } from '../../lib/suit';\nimport type {\n GeoSearchConnectorParams,\n GeoSearchWidgetDescription,\n GeoHit,\n} from '../../connectors/geo-search/connectGeoSearch';\nimport connectGeoSearch from '../../connectors/geo-search/connectGeoSearch';\nimport renderer from './GeoSearchRenderer';\nimport defaultTemplates from './defaultTemplates';\nimport type { HTMLMarkerArguments } from './createHTMLMarker';\nimport createHTMLMarker from './createHTMLMarker';\nimport type { GeoLoc, Template, WidgetFactory } from '../../types';\n\nexport type CreateMarker = (args: {\n item: GeoHit;\n map: google.maps.Map;\n}) => google.maps.OverlayView | google.maps.Marker;\n\nconst withUsage = createDocumentationMessageGenerator({ name: 'geo-search' });\nconst suit = component('GeoSearch');\n\nexport type GeoSearchTemplates = Partial<{\n /** Template to use for the marker. */\n HTMLMarker: Template<GeoHit>;\n /** Template for the reset button. */\n reset: Template;\n /** Template for the toggle label. */\n toggle: Template;\n /** Template for the redo button. */\n redo: Template;\n}>;\n\nexport type GeoSearchComponentTemplates = Required<GeoSearchTemplates>;\n\nexport type GeoSearchCSSClasses = Partial<{\n /** The root div of the widget. */\n root: string | string[];\n /** The map container of the widget. */\n map: string | string[];\n /** The control element of the widget. */\n control: string | string[];\n /** The label of the control element. */\n label: string | string[];\n /** The selected label of the control element. */\n selectedLabel: string | string[];\n /** The input of the control element. */\n input: string | string[];\n /** The redo search button. */\n redo: string | string[];\n /** The disabled redo search button. */\n disabledRedo: string | string[];\n /** The reset refinement button. */\n reset: string | string[];\n}>;\n\nexport type GeoSearchMarker<TOptions> = {\n /**\n * Function used to create the options passed to the Google Maps marker.\n * See the documentation for more information:\n * https://developers.google.com/maps/documentation/javascript/reference/3/#MarkerOptions\n */\n createOptions?(item: GeoHit): TOptions;\n /**\n * Object that takes an event type (ex: `click`, `mouseover`) as key and a\n * listener as value. The listener is provided with an object that contains:\n * `event`, `item`, `marker`, `map`.\n */\n events: {\n [key: string]: (event: {\n item: any;\n marker: any;\n map: any;\n event: any;\n }) => void;\n };\n};\n\nexport type GeoSearchWidgetParams = {\n /**\n * By default the map will set the zoom accordingly to the markers displayed on it.\n * When we refine it may happen that the results are empty. For those situations we\n * need to provide a zoom to render the map.\n * @default 1\n */\n initialZoom?: number;\n /**\n * By default the map will set the position accordingly to the markers displayed on it.\n * When we refine it may happen that the results are empty. For those situations we need\n * to provide a position to render the map. This option is ignored when the `position`\n * is provided.\n * @default { lat: 0, lng: 0 }\n */\n initialPosition?: GeoLoc;\n /** Templates to use for the widget. */\n templates?: GeoSearchTemplates;\n /** CSS classes to add to the wrapping elements. */\n cssClasses?: GeoSearchCSSClasses;\n /**\n * Options for customize the built-in Google Maps marker. This option is\n * ignored when the `customHTMLMarker` is provided.\n */\n builtInMarker?: Partial<GeoSearchMarker<google.maps.MarkerOptions>>;\n /**\n * Options to customize the HTML marker. We provide an alternative to the\n * built-in Google Maps marker in order to have a full control of the marker\n * rendering. You can use plain HTML to build your marker.\n */\n customHTMLMarker?:\n | Partial<GeoSearchMarker<Partial<HTMLMarkerArguments>>>\n | boolean;\n /**\n * If true, the map is used to search - otherwise it's for display purposes only.\n * @default true\n */\n enableRefine?: boolean;\n /**\n * If true, a button is displayed on the map when the refinement is coming from\n * the map in order to remove it.\n * @default true\n */\n enableClearMapRefinement?: boolean;\n /**\n * If true, the user can toggle the option `enableRefineOnMapMove` directly from the map.\n * @default true\n */\n enableRefineControl?: boolean;\n /**\n * Option forwarded to the Google Maps constructor.\n * See the documentation for more information:\n * https://developers.google.com/maps/documentation/javascript/reference/3/#MapOptions\n */\n mapOptions?: google.maps.MapOptions;\n /**\n * CSS Selector or HTMLElement to insert the widget.\n */\n container: string | HTMLElement;\n /**\n * Reference to the global `window.google` object.\n * See [the documentation](https://developers.google.com/maps/documentation/javascript/tutorial) for more information.\n */\n googleReference: typeof window['google'];\n};\n\nexport type GeoSearchWidget = WidgetFactory<\n GeoSearchWidgetDescription & { $$widgetType: 'ais.geoSearch' },\n GeoSearchConnectorParams,\n GeoSearchWidgetParams\n>;\n\n/**\n * The **GeoSearch** widget displays the list of results from the search on a Google Maps. It also provides a way to search for results based on their position. The widget also provide some of the common GeoSearch patterns like search on map interaction.\n *\n * @requirements\n *\n * Note that the GeoSearch widget uses the [geosearch](https://www.algolia.com/doc/guides/searching/geo-search) capabilities of Algolia. Your hits **must** have a `_geoloc` attribute in order to be displayed on the map.\n *\n * Currently, the feature is not compatible with multiple values in the _geoloc attribute.\n *\n * You are also responsible for loading the Google Maps library, it's not shipped with InstantSearch. You need to load the Google Maps library and pass a reference to the widget. You can find more information about how to install the library in [the Google Maps documentation](https://developers.google.com/maps/documentation/javascript/tutorial).\n *\n * Don't forget to explicitly set the `height` of the map container (default class `.ais-geo-search--map`), otherwise it won't be shown (it's a requirement of Google Maps).\n */\nconst geoSearch: GeoSearchWidget = (widgetParams) => {\n const {\n initialZoom = 1,\n initialPosition = { lat: 0, lng: 0 },\n templates: userTemplates = {},\n cssClasses: userCssClasses = {},\n builtInMarker: userBuiltInMarker = {},\n customHTMLMarker: userCustomHTMLMarker,\n enableRefine = true,\n enableClearMapRefinement = true,\n enableRefineControl = true,\n container,\n googleReference,\n ...otherWidgetParams\n } = widgetParams || {};\n\n const defaultBuiltInMarker: GeoSearchMarker<google.maps.MarkerOptions> = {\n createOptions: () => ({}),\n events: {},\n };\n\n const defaultCustomHTMLMarker: GeoSearchMarker<Partial<HTMLMarkerArguments>> =\n {\n createOptions: () => ({}),\n events: {},\n };\n\n if (!container) {\n throw new Error(withUsage('The `container` option is required.'));\n }\n\n if (!googleReference) {\n throw new Error(withUsage('The `googleReference` option is required.'));\n }\n\n const containerNode = getContainerNode(container);\n\n const cssClasses = {\n root: cx(suit(), userCssClasses.root),\n // Required only to mount / unmount the Preact tree\n tree: suit({ descendantName: 'tree' }),\n map: cx(suit({ descendantName: 'map' }), userCssClasses.map),\n control: cx(suit({ descendantName: 'control' }), userCssClasses.control),\n label: cx(suit({ descendantName: 'label' }), userCssClasses.label),\n selectedLabel: cx(\n suit({ descendantName: 'label', modifierName: 'selected' }),\n userCssClasses.selectedLabel\n ),\n input: cx(suit({ descendantName: 'input' }), userCssClasses.input),\n redo: cx(suit({ descendantName: 'redo' }), userCssClasses.redo),\n disabledRedo: cx(\n suit({ descendantName: 'redo', modifierName: 'disabled' }),\n userCssClasses.disabledRedo\n ),\n reset: cx(suit({ descendantName: 'reset' }), userCssClasses.reset),\n };\n\n const templates = {\n ...defaultTemplates,\n ...userTemplates,\n };\n\n const builtInMarker = {\n ...defaultBuiltInMarker,\n ...userBuiltInMarker,\n };\n\n const isCustomHTMLMarker =\n Boolean(userCustomHTMLMarker) || Boolean(userTemplates.HTMLMarker);\n\n const customHTMLMarker = isCustomHTMLMarker && {\n ...defaultCustomHTMLMarker,\n ...(userCustomHTMLMarker as Partial<\n GeoSearchMarker<Partial<HTMLMarkerArguments>>\n >),\n };\n\n const createBuiltInMarker: CreateMarker = ({ item, ...rest }) =>\n new googleReference.maps.Marker({\n ...builtInMarker.createOptions!(item),\n ...rest,\n // @ts-expect-error @types/googlemaps doesn't document this\n __id: item.objectID,\n position: item._geoloc,\n });\n\n const HTMLMarker = createHTMLMarker(googleReference);\n const createCustomHTMLMarker: CreateMarker = ({ item, ...rest }) =>\n new HTMLMarker({\n // this is only called when customHTMLMarker is defined\n ...(customHTMLMarker as GeoSearchMarker<Partial<HTMLMarkerArguments>>)\n .createOptions!(item),\n ...rest,\n __id: item.objectID,\n position: item._geoloc,\n className: cx(suit({ descendantName: 'marker' })),\n template: renderTemplate({\n templateKey: 'HTMLMarker',\n templates,\n data: item,\n }),\n });\n\n const createMarker = !customHTMLMarker\n ? createBuiltInMarker\n : createCustomHTMLMarker;\n\n const markerOptions = !customHTMLMarker ? builtInMarker : customHTMLMarker;\n\n const makeWidget = connectGeoSearch(renderer, () =>\n render(null, containerNode)\n );\n\n return {\n ...makeWidget({\n ...otherWidgetParams,\n renderState: {},\n container: containerNode,\n googleReference,\n initialZoom,\n initialPosition,\n templates,\n cssClasses,\n createMarker,\n markerOptions,\n enableRefine,\n enableClearMapRefinement,\n enableRefineControl,\n }),\n $$widgetType: 'ais.geoSearch',\n };\n};\n\nexport default geoSearch;\n","/** @jsx h */\n\nimport type { JSX } from 'preact';\nimport { h } from 'preact';\nimport Template from '../Template/Template';\n\nexport type RefinementListItemProps = {\n facetValueToRefine: string;\n handleClick: (args: {\n facetValueToRefine: string;\n isRefined: boolean;\n originalEvent: MouseEvent;\n }) => void;\n isRefined: boolean;\n subItems?: JSX.Element;\n templateData: Record<string, any>;\n templateKey: string;\n templateProps?: Record<string, any>;\n className: string;\n};\n\nfunction RefinementListItem({\n className,\n handleClick,\n facetValueToRefine,\n isRefined,\n templateProps,\n templateKey,\n templateData,\n subItems,\n}: RefinementListItemProps) {\n return (\n <li\n className={className}\n onClick={(originalEvent) => {\n handleClick({\n facetValueToRefine,\n isRefined,\n originalEvent,\n });\n }}\n >\n <Template\n {...templateProps}\n templateKey={templateKey}\n data={templateData}\n />\n {subItems}\n </li>\n );\n}\n\nexport default RefinementListItem;\n","/** @jsx h */\n\nimport { h, createRef, Component } from 'preact';\nimport { noop } from '../../lib/utils';\nimport Template from '../Template/Template';\nimport type {\n SearchBoxCSSClasses,\n SearchBoxTemplates,\n} from '../../widgets/search-box/search-box';\nimport type { ComponentCSSClasses } from '../../types';\n\nexport type SearchBoxComponentCSSClasses =\n ComponentCSSClasses<SearchBoxCSSClasses>;\n\nexport type SearchBoxComponentTemplates = Required<SearchBoxTemplates>;\n\ntype SearchBoxProps = {\n placeholder?: string;\n cssClasses: SearchBoxComponentCSSClasses;\n templates: SearchBoxComponentTemplates;\n query?: string;\n showSubmit?: boolean;\n showReset?: boolean;\n showLoadingIndicator?: boolean;\n refine?: (value: string) => void;\n autofocus?: boolean;\n searchAsYouType?: boolean;\n isSearchStalled?: boolean;\n disabled?: boolean;\n onChange?: (event: Event) => void;\n onSubmit?: (event: Event) => void;\n onReset?: (event: Event) => void;\n};\n\nconst defaultProps = {\n query: '',\n showSubmit: true,\n showReset: true,\n showLoadingIndicator: true,\n autofocus: false,\n searchAsYouType: true,\n isSearchStalled: false,\n disabled: false,\n onChange: noop,\n onSubmit: noop,\n onReset: noop,\n refine: noop,\n};\n\ntype SearchBoxPropsWithDefaultProps = SearchBoxProps &\n Readonly<typeof defaultProps>;\n\ntype SearchBoxState = {\n query: string;\n focused: boolean;\n};\n\nclass SearchBox extends Component<\n SearchBoxPropsWithDefaultProps,\n SearchBoxState\n> {\n public static defaultProps = defaultProps;\n\n public state = {\n query: this.props.query,\n focused: false,\n };\n\n private input = createRef<HTMLInputElement>();\n\n /**\n * This public method is used in the RefinementList SFFV search box\n * to reset the input state when an item is selected.\n *\n * @see RefinementList#componentWillReceiveProps\n * @return {undefined}\n */\n public resetInput() {\n this.setState({ query: '' });\n }\n\n private onInput = (event: Event) => {\n const { searchAsYouType, refine, onChange } = this.props;\n const query = (event.target as HTMLInputElement).value;\n\n if (searchAsYouType) {\n refine(query);\n }\n this.setState({ query });\n\n onChange(event);\n };\n\n public componentWillReceiveProps(nextProps: SearchBoxPropsWithDefaultProps) {\n /**\n * when the user is typing, we don't want to replace the query typed\n * by the user (state.query) with the query exposed by the connector (props.query)\n * see: https://github.com/algolia/instantsearch.js/issues/4141\n */\n if (!this.state.focused && nextProps.query !== this.state.query) {\n this.setState({ query: nextProps.query });\n }\n }\n\n private onSubmit = (event: Event) => {\n const { searchAsYouType, refine, onSubmit } = this.props;\n\n event.preventDefault();\n event.stopPropagation();\n if (this.input.current) {\n this.input.current.blur();\n }\n\n if (!searchAsYouType) {\n refine(this.state.query);\n }\n\n onSubmit(event);\n\n return false;\n };\n\n private onReset = (event: Event) => {\n const { refine, onReset } = this.props;\n const query = '';\n\n if (this.input.current) {\n this.input.current.focus();\n }\n\n refine(query);\n this.setState({ query });\n\n onReset(event);\n };\n\n private onBlur = () => {\n this.setState({ focused: false });\n };\n\n private onFocus = () => {\n this.setState({ focused: true });\n };\n\n public render() {\n const {\n cssClasses,\n placeholder,\n autofocus,\n showSubmit,\n showReset,\n showLoadingIndicator,\n templates,\n isSearchStalled,\n } = this.props;\n\n return (\n <div className={cssClasses.root}>\n <form\n action=\"\"\n role=\"search\"\n className={cssClasses.form}\n noValidate\n onSubmit={this.onSubmit}\n // @ts-expect-error `onReset` attibute is missing in preact 10.0.0 JSX types\n onReset={this.onReset}\n >\n <input\n ref={this.input}\n value={this.state.query}\n disabled={this.props.disabled}\n className={cssClasses.input}\n type=\"search\"\n placeholder={placeholder}\n autoFocus={autofocus}\n autoComplete=\"off\"\n autoCorrect=\"off\"\n // @ts-expect-error `autoCapitalize` attibute is missing in preact 10.0.0 JSX types\n autoCapitalize=\"off\"\n spellCheck=\"false\"\n maxLength={512}\n onInput={this.onInput}\n onBlur={this.onBlur}\n onFocus={this.onFocus}\n />\n\n <Template\n templateKey=\"submit\"\n rootTagName=\"button\"\n rootProps={{\n className: cssClasses.submit,\n type: 'submit',\n title: 'Submit the search query.',\n hidden: !showSubmit,\n }}\n templates={templates}\n data={{ cssClasses }}\n />\n\n <Template\n templateKey=\"reset\"\n rootTagName=\"button\"\n rootProps={{\n className: cssClasses.reset,\n type: 'reset',\n title: 'Clear the search query.',\n hidden: !(\n showReset &&\n this.state.query.trim() &&\n !isSearchStalled\n ),\n }}\n templates={templates}\n data={{ cssClasses }}\n />\n\n {showLoadingIndicator && (\n <Template\n templateKey=\"loadingIndicator\"\n rootTagName=\"span\"\n rootProps={{\n className: cssClasses.loadingIndicator,\n hidden: !isSearchStalled,\n }}\n templates={templates}\n data={{ cssClasses }}\n />\n )}\n </form>\n </div>\n );\n }\n}\n\nexport default SearchBox;\n","/** @jsx h */\n\nimport type { JSX } from 'preact';\nimport { h, createRef, Component } from 'preact';\nimport cx from 'classnames';\nimport { isSpecialClick, isEqual } from '../../lib/utils';\nimport type { PreparedTemplateProps } from '../../lib/utils/prepareTemplateProps';\nimport Template from '../Template/Template';\nimport RefinementListItem from './RefinementListItem';\nimport type {\n SearchBoxComponentCSSClasses,\n SearchBoxComponentTemplates,\n} from '../SearchBox/SearchBox';\nimport SearchBox from '../SearchBox/SearchBox';\nimport type { HierarchicalMenuItem } from '../../connectors/hierarchical-menu/connectHierarchicalMenu';\nimport type { ComponentCSSClasses, CreateURL, Templates } from '../../types';\nimport type { RefinementListOwnCSSClasses } from '../../widgets/refinement-list/refinement-list';\nimport type { RatingMenuComponentCSSClasses } from '../../widgets/rating-menu/rating-menu';\nimport type { HierarchicalMenuComponentCSSClasses } from '../../widgets/hierarchical-menu/hierarchical-menu';\n\n// CSS types\ntype RefinementListOptionalClasses =\n | 'noResults'\n | 'checkbox'\n | 'labelText'\n | 'showMore'\n | 'disabledShowMore'\n | 'searchBox'\n | 'count';\n\ntype RefinementListWidgetCSSClasses =\n ComponentCSSClasses<RefinementListOwnCSSClasses>;\n\ntype RefinementListRequiredCSSClasses = Omit<\n RefinementListWidgetCSSClasses,\n RefinementListOptionalClasses\n> &\n Partial<Pick<RefinementListWidgetCSSClasses, RefinementListOptionalClasses>>;\n\nexport type RefinementListComponentCSSClasses =\n RefinementListRequiredCSSClasses & {\n searchable?: SearchBoxComponentCSSClasses;\n } & Partial<Pick<RatingMenuComponentCSSClasses, 'disabledItem'>> &\n Partial<\n Pick<HierarchicalMenuComponentCSSClasses, 'childList' | 'parentItem'>\n >;\n\ntype FacetValue = {\n value: string;\n label: string;\n highlighted?: string;\n count?: number;\n isRefined: boolean;\n data?: HierarchicalMenuItem[] | null;\n};\n\nexport type RefinementListProps<TTemplates extends Templates> = {\n createURL: CreateURL<string>;\n cssClasses: RefinementListComponentCSSClasses;\n depth?: number;\n facetValues?: FacetValue[];\n attribute?: string;\n templateProps: PreparedTemplateProps<TTemplates>;\n toggleRefinement: (value: string) => void;\n showMore?: boolean;\n toggleShowMore?: () => void;\n isShowingMore?: boolean;\n hasExhaustiveItems?: boolean;\n canToggleShowMore?: boolean;\n className?: string;\n children?: JSX.Element;\n\n // searchable props are optional, but will definitely be present in a searchable context\n isFromSearch?: boolean;\n searchIsAlwaysActive?: boolean;\n searchFacetValues?: (query: string) => void;\n searchPlaceholder?: string;\n searchBoxTemplateProps?: PreparedTemplateProps<SearchBoxComponentTemplates>;\n};\n\nconst defaultProps = {\n cssClasses: {},\n depth: 0,\n};\n\ntype RefinementListPropsWithDefaultProps<TTemplates extends Templates> =\n RefinementListProps<TTemplates> & Readonly<typeof defaultProps>;\n\ntype RefinementListItemTemplateData<TTemplates extends Templates> =\n FacetValue & {\n url: string;\n } & Pick<\n RefinementListProps<TTemplates>,\n 'attribute' | 'cssClasses' | 'isFromSearch'\n >;\n\nfunction isHierarchicalMenuItem(\n facetValue: FacetValue\n): facetValue is HierarchicalMenuItem {\n return (facetValue as HierarchicalMenuItem).data !== undefined;\n}\n\nclass RefinementList<TTemplates extends Templates> extends Component<\n RefinementListPropsWithDefaultProps<TTemplates>\n> {\n public static defaultProps = defaultProps;\n\n private searchBox = createRef<SearchBox>();\n\n public constructor(props: RefinementListPropsWithDefaultProps<TTemplates>) {\n super(props);\n this.handleItemClick = this.handleItemClick.bind(this);\n }\n\n public shouldComponentUpdate(\n nextProps: RefinementListPropsWithDefaultProps<TTemplates>\n ) {\n const areFacetValuesDifferent = !isEqual(\n this.props.facetValues,\n nextProps.facetValues\n );\n\n return areFacetValuesDifferent;\n }\n\n private refine(facetValueToRefine: string) {\n this.props.toggleRefinement(facetValueToRefine);\n }\n\n private _generateFacetItem(facetValue: FacetValue) {\n let subItems;\n if (\n isHierarchicalMenuItem(facetValue) &&\n Array.isArray(facetValue.data) &&\n facetValue.data.length > 0\n ) {\n const { root, ...cssClasses } = this.props.cssClasses;\n\n subItems = (\n <RefinementList\n {...this.props}\n // We want to keep `root` required for external usage but not for the\n // sub items.\n cssClasses={cssClasses as RefinementListComponentCSSClasses}\n depth={this.props.depth + 1}\n facetValues={facetValue.data}\n showMore={false}\n className={this.props.cssClasses.childList}\n />\n );\n }\n\n const url = this.props.createURL(facetValue.value);\n const templateData: RefinementListItemTemplateData<TTemplates> = {\n ...facetValue,\n url,\n attribute: this.props.attribute,\n cssClasses: this.props.cssClasses,\n isFromSearch: this.props.isFromSearch,\n };\n\n let { value: key } = facetValue;\n if (facetValue.isRefined !== undefined) {\n key += `/${facetValue.isRefined}`;\n }\n\n if (facetValue.count !== undefined) {\n key += `/${facetValue.count}`;\n }\n\n const refinementListItemClassName = cx(this.props.cssClasses.item, {\n [this.props.cssClasses.selectedItem]: facetValue.isRefined,\n // cx allows `undefined` as a key but typescript doesn't\n [this.props.cssClasses.disabledItem!]: !facetValue.count,\n [this.props.cssClasses.parentItem!]:\n isHierarchicalMenuItem(facetValue) &&\n Array.isArray(facetValue.data) &&\n facetValue.data.length > 0,\n });\n\n return (\n <RefinementListItem\n templateKey=\"item\"\n key={key}\n facetValueToRefine={facetValue.value}\n handleClick={this.handleItemClick}\n isRefined={facetValue.isRefined}\n className={refinementListItemClassName}\n subItems={subItems}\n templateData={templateData}\n templateProps={this.props.templateProps}\n />\n );\n }\n\n // Click events on DOM tree like LABEL > INPUT will result in two click events\n // instead of one.\n // No matter the framework, see https://www.google.com/search?q=click+label+twice\n //\n // Thus making it hard to distinguish activation from deactivation because both click events\n // are very close. Debounce is a solution but hacky.\n //\n // So the code here checks if the click was done on or in a LABEL. If this LABEL\n // has a checkbox inside, we ignore the first click event because we will get another one.\n //\n // We also check if the click was done inside a link and then e.preventDefault() because we already\n // handle the url\n //\n // Finally, we always stop propagation of the event to avoid multiple levels RefinementLists to fail: click\n // on child would click on parent also\n private handleItemClick({\n facetValueToRefine,\n isRefined,\n originalEvent,\n }: {\n facetValueToRefine: string;\n isRefined: boolean;\n originalEvent: MouseEvent;\n }) {\n if (isSpecialClick(originalEvent)) {\n // do not alter the default browser behavior\n // if one special key is down\n return;\n }\n\n if (\n !(originalEvent.target instanceof HTMLElement) ||\n !(originalEvent.target.parentNode instanceof HTMLElement)\n ) {\n return;\n }\n\n if (\n isRefined &&\n originalEvent.target.parentNode.querySelector(\n 'input[type=\"radio\"]:checked'\n )\n ) {\n // Prevent refinement for being reset if the user clicks on an already checked radio button\n return;\n }\n\n if (originalEvent.target.tagName === 'INPUT') {\n this.refine(facetValueToRefine);\n return;\n }\n\n let parent = originalEvent.target;\n\n while (parent !== originalEvent.currentTarget) {\n if (\n parent.tagName === 'LABEL' &&\n (parent.querySelector('input[type=\"checkbox\"]') ||\n parent.querySelector('input[type=\"radio\"]'))\n ) {\n return;\n }\n\n if (parent.tagName === 'A' && (parent as HTMLAnchorElement).href) {\n originalEvent.preventDefault();\n }\n\n parent = parent.parentNode as HTMLElement;\n }\n\n originalEvent.stopPropagation();\n\n this.refine(facetValueToRefine);\n }\n\n public componentWillReceiveProps(\n nextProps: RefinementListPropsWithDefaultProps<TTemplates>\n ) {\n if (this.searchBox.current && !nextProps.isFromSearch) {\n this.searchBox.current.resetInput();\n }\n }\n\n private refineFirstValue() {\n const firstValue = this.props.facetValues && this.props.facetValues[0];\n if (firstValue) {\n const actualValue = firstValue.value;\n this.props.toggleRefinement(actualValue);\n }\n }\n\n public render() {\n const showMoreButtonClassName = cx(this.props.cssClasses.showMore, {\n [this.props.cssClasses.disabledShowMore!]: !(\n this.props.showMore === true && this.props.canToggleShowMore\n ),\n });\n\n const showMoreButton = this.props.showMore === true && (\n <Template\n {...this.props.templateProps}\n templateKey=\"showMoreText\"\n rootTagName=\"button\"\n rootProps={{\n className: showMoreButtonClassName,\n disabled: !this.props.canToggleShowMore,\n onClick: this.props.toggleShowMore,\n }}\n data={{\n isShowingMore: this.props.isShowingMore,\n }}\n />\n );\n\n const shouldDisableSearchBox =\n this.props.searchIsAlwaysActive !== true &&\n !(this.props.isFromSearch || !this.props.hasExhaustiveItems);\n\n const searchBox = this.props.searchFacetValues && (\n <div className={this.props.cssClasses.searchBox}>\n <SearchBox\n ref={this.searchBox}\n placeholder={this.props.searchPlaceholder}\n disabled={shouldDisableSearchBox}\n cssClasses={this.props.cssClasses.searchable!}\n templates={this.props.searchBoxTemplateProps!.templates}\n onChange={(event: Event) =>\n this.props.searchFacetValues!(\n (event.target as HTMLInputElement).value\n )\n }\n onReset={() => this.props.searchFacetValues!('')}\n onSubmit={() => this.refineFirstValue()}\n // This sets the search box to a controlled state because\n // we don't rely on the `refine` prop but on `onChange`.\n searchAsYouType={false}\n />\n </div>\n );\n\n const facetValues = this.props.facetValues &&\n this.props.facetValues.length > 0 && (\n <ul className={this.props.cssClasses.list}>\n {this.props.facetValues.map(this._generateFacetItem, this)}\n </ul>\n );\n\n const noResults = this.props.searchFacetValues &&\n this.props.isFromSearch &&\n (!this.props.facetValues || this.props.facetValues.length === 0) && (\n <Template\n {...this.props.templateProps}\n templateKey=\"searchableNoResults\"\n rootProps={{ className: this.props.cssClasses.noResults }}\n />\n );\n\n const rootClassName = cx(\n this.props.cssClasses.root,\n {\n [this.props.cssClasses.noRefinementRoot]:\n !this.props.facetValues || this.props.facetValues.length === 0,\n },\n this.props.className\n );\n\n return (\n <div className={rootClassName}>\n {this.props.children}\n {searchBox}\n {facetValues}\n {noResults}\n {showMoreButton}\n </div>\n );\n }\n}\n\nexport default RefinementList;\n","/** @jsx h */\n\nimport { h } from 'preact';\nimport cx from 'classnames';\nimport Template from '../Template/Template';\nimport type { SearchResults } from 'algoliasearch-helper';\nimport type { BindEventForHits, SendEventForHits } from '../../lib/utils';\nimport type { ComponentCSSClasses, Hits as HitsArray } from '../../types';\nimport type { HitsCSSClasses, HitsTemplates } from '../../widgets/hits/hits';\nimport type { PreparedTemplateProps } from '../../lib/utils/prepareTemplateProps';\n\nexport type HitsComponentCSSClasses = ComponentCSSClasses<HitsCSSClasses>;\nexport type HitsComponentTemplates = Required<HitsTemplates>;\n\nexport type HitsProps = {\n results: SearchResults;\n hits: HitsArray;\n sendEvent?: SendEventForHits;\n bindEvent?: BindEventForHits;\n cssClasses: HitsComponentCSSClasses;\n templateProps: PreparedTemplateProps<HitsComponentTemplates>;\n};\n\nconst Hits = ({\n results,\n hits,\n bindEvent,\n cssClasses,\n templateProps,\n}: HitsProps) => {\n if (results.hits.length === 0) {\n return (\n <Template\n {...templateProps}\n templateKey=\"empty\"\n rootProps={{\n className: cx(cssClasses.root, cssClasses.emptyRoot),\n }}\n data={results}\n />\n );\n }\n\n return (\n <div className={cssClasses.root}>\n <ol className={cssClasses.list}>\n {hits.map((hit, index) => (\n <Template\n {...templateProps}\n templateKey=\"item\"\n rootTagName=\"li\"\n rootProps={{ className: cssClasses.item }}\n key={hit.objectID}\n data={{\n ...hit,\n __hitIndex: index,\n }}\n bindEvent={bindEvent}\n />\n ))}\n </ol>\n </div>\n );\n};\n\nHits.defaultProps = {\n results: { hits: [] },\n hits: [],\n};\n\nexport default Hits;\n","import type { HierarchicalMenuComponentTemplates } from './hierarchical-menu';\nconst defaultTemplates: HierarchicalMenuComponentTemplates = {\n item:\n '<a class=\"{{cssClasses.link}}\" href=\"{{url}}\">' +\n '<span class=\"{{cssClasses.label}}\">{{label}}</span>' +\n '<span class=\"{{cssClasses.count}}\">{{#helpers.formatNumber}}{{count}}{{/helpers.formatNumber}}</span>' +\n '</a>',\n showMoreText: `\n {{#isShowingMore}}\n Show less\n {{/isShowingMore}}\n {{^isShowingMore}}\n Show more\n {{/isShowingMore}}\n `,\n};\n\nexport default defaultTemplates;\n","/** @jsx h */\n\nimport { h, render } from 'preact';\nimport cx from 'classnames';\nimport RefinementList from '../../components/RefinementList/RefinementList';\nimport type {\n HierarchicalMenuItem,\n HierarchicalMenuConnectorParams,\n HierarchicalMenuRenderState,\n HierarchicalMenuWidgetDescription,\n} from '../../connectors/hierarchical-menu/connectHierarchicalMenu';\nimport connectHierarchicalMenu from '../../connectors/hierarchical-menu/connectHierarchicalMenu';\nimport defaultTemplates from './defaultTemplates';\nimport type { PreparedTemplateProps } from '../../lib/utils/prepareTemplateProps';\nimport {\n prepareTemplateProps,\n getContainerNode,\n createDocumentationMessageGenerator,\n} from '../../lib/utils';\nimport type {\n TransformItems,\n Template,\n WidgetFactory,\n RendererOptions,\n SortBy,\n ComponentCSSClasses,\n} from '../../types';\nimport { component } from '../../lib/suit';\n\nconst withUsage = createDocumentationMessageGenerator({\n name: 'hierarchical-menu',\n});\nconst suit = component('HierarchicalMenu');\n\ntype HierarchicalMenuTemplates = Partial<{\n /**\n * Item template, provided with `name`, `count`, `isRefined`, `url` data properties.\n */\n item: Template<{\n name: string;\n count: number;\n isRefined: boolean;\n url: string;\n }>;\n /**\n * Template used for the show more text, provided with `isShowingMore` data property.\n */\n showMoreText: Template<{ isShowingMore: boolean }>;\n}>;\n\nexport type HierarchicalMenuCSSClasses = Partial<{\n /**\n * CSS class to add to the root element.\n */\n root: string | string[];\n /**\n * CSS class to add to the root element when no refinements.\n */\n noRefinementRoot: string | string[];\n /**\n * CSS class to add to the list element.\n */\n list: string | string[];\n /**\n * CSS class to add to the child list element.\n */\n childList: string | string[];\n /**\n * CSS class to add to each item element.\n */\n item: string | string[];\n /**\n * CSS class to add to each selected item element.\n */\n selectedItem: string | string[];\n /**\n * CSS class to add to each parent item element.\n */\n parentItem: string | string[];\n /**\n * CSS class to add to each link (when using the default template).\n */\n link: string | string[];\n /**\n * CSS class to add to each label (when using the default template).\n */\n label: string | string[];\n /**\n * CSS class to add to each count element (when using the default template).\n */\n count: string | string[];\n /**\n * CSS class to add to the show more element.\n */\n showMore: string | string[];\n /**\n * CSS class to add to the disabled show more element.\n */\n disabledShowMore: string | string[];\n}>;\n\nexport type HierarchicalMenuComponentCSSClasses =\n ComponentCSSClasses<HierarchicalMenuCSSClasses>;\n\nexport type HierarchicalMenuComponentTemplates =\n Required<HierarchicalMenuTemplates>;\n\nexport type HierarchicalMenuWidgetParams = {\n /**\n * CSS Selector or HTMLElement to insert the widget.\n */\n container: string | HTMLElement;\n /**\n * Array of attributes to use to generate the hierarchy of the menu.\n */\n attributes: string[];\n /**\n * Separator used in the attributes to separate level values.\n */\n separator?: string;\n /**\n * Prefix path to use if the first level is not the root level.\n */\n rootPath?: string;\n /**\n * Show the siblings of the selected parent level of the current refined value.\n *\n * With `showParentLevel` set to `true` (default):\n * - Parent lvl0\n * - **lvl1**\n * - **lvl2**\n * - lvl2\n * - lvl2\n * - lvl 1\n * - lvl 1\n * - Parent lvl0\n * - Parent lvl0\n *\n * With `showParentLevel` set to `false`:\n * - Parent lvl0\n * - **lvl1**\n * - **lvl2**\n * - Parent lvl0\n * - Parent lvl0\n */\n showParentLevel?: boolean;\n /**\n * Max number of values to display.\n */\n limit?: number;\n /**\n * Whether to display the \"show more\" button.\n */\n showMore?: boolean;\n /**\n * Max number of values to display when showing more.\n * does not impact the root level.\n */\n showMoreLimit?: number;\n /**\n * How to sort refinements. Possible values: `count|isRefined|name:asc|name:desc`.\n * You can also use a sort function that behaves like the standard Javascript [compareFunction](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#Syntax).\n */\n sortBy?: SortBy<HierarchicalMenuItem>;\n /**\n * Function to transform the items passed to the templates.\n */\n transformItems?: TransformItems<HierarchicalMenuItem>;\n /**\n * Templates to use for the widget.\n */\n templates?: HierarchicalMenuTemplates;\n /**\n * CSS classes to add to the wrapping elements.\n */\n cssClasses?: HierarchicalMenuCSSClasses;\n};\n\nconst renderer =\n ({\n cssClasses,\n containerNode,\n showMore,\n templates,\n renderState,\n }: {\n cssClasses: HierarchicalMenuComponentCSSClasses;\n containerNode: HTMLElement;\n showMore: boolean;\n templates: HierarchicalMenuTemplates;\n renderState: {\n templateProps?: PreparedTemplateProps<HierarchicalMenuComponentTemplates>;\n };\n }) =>\n (\n {\n createURL,\n items,\n refine,\n instantSearchInstance,\n isShowingMore,\n toggleShowMore,\n canToggleShowMore,\n }: HierarchicalMenuRenderState &\n RendererOptions<HierarchicalMenuConnectorParams>,\n isFirstRendering: boolean\n ) => {\n if (isFirstRendering) {\n renderState.templateProps = prepareTemplateProps({\n defaultTemplates,\n templatesConfig: instantSearchInstance.templatesConfig,\n templates,\n });\n return;\n }\n\n render(\n <RefinementList\n createURL={createURL}\n cssClasses={cssClasses}\n facetValues={items}\n templateProps={renderState.templateProps!}\n toggleRefinement={refine}\n showMore={showMore}\n toggleShowMore={toggleShowMore}\n isShowingMore={isShowingMore}\n canToggleShowMore={canToggleShowMore}\n />,\n containerNode\n );\n };\n\n/**\n * The hierarchical menu widget is used to create a navigation based on a hierarchy of facet attributes.\n *\n * It is commonly used for categories with subcategories.\n *\n * All attributes (lvl0, lvl1 here) must be declared as [attributes for faceting](https://www.algolia.com/doc/guides/searching/faceting/#declaring-attributes-for-faceting) in your\n * Algolia settings.\n *\n * By default, the separator we expect is ` > ` (with spaces) but you can use\n * a different one by using the `separator` option.\n * @requirements\n * Your objects must be formatted in a specific way to be\n * able to display hierarchical menus. Here's an example:\n *\n * ```javascript\n * {\n * \"objectID\": \"123\",\n * \"name\": \"orange\",\n * \"categories\": {\n * \"lvl0\": \"fruits\",\n * \"lvl1\": \"fruits > citrus\"\n * }\n * }\n * ```\n *\n * Every level must be specified entirely.\n * It's also possible to have multiple values per level, for example:\n *\n * ```javascript\n * {\n * \"objectID\": \"123\",\n * \"name\": \"orange\",\n * \"categories\": {\n * \"lvl0\": [\"fruits\", \"vitamins\"],\n * \"lvl1\": [\"fruits > citrus\", \"vitamins > C\"]\n * }\n * }\n * ```\n * @type {WidgetFactory}\n * @devNovel HierarchicalMenu\n * @category filter\n * @param {HierarchicalMenuWidgetParams} widgetParams The HierarchicalMenu widget options.\n * @return {Widget} A new HierarchicalMenu widget instance.\n * @example\n * search.addWidgets([\n * instantsearch.widgets.hierarchicalMenu({\n * container: '#hierarchical-categories',\n * attributes: ['hierarchicalCategories.lvl0', 'hierarchicalCategories.lvl1', 'hierarchicalCategories.lvl2'],\n * })\n * ]);\n */\nexport type HierarchicalMenuWidget = WidgetFactory<\n HierarchicalMenuWidgetDescription & { $$widgetType: 'ais.hierarchicalMenu' },\n HierarchicalMenuConnectorParams,\n HierarchicalMenuWidgetParams\n>;\n\nconst hierarchicalMenu: HierarchicalMenuWidget = function hierarchicalMenu(\n widgetParams\n) {\n const {\n container,\n attributes,\n separator,\n rootPath,\n showParentLevel,\n limit,\n showMore = false,\n showMoreLimit,\n sortBy,\n transformItems,\n templates = {},\n cssClasses: userCssClasses = {},\n } = widgetParams || {};\n\n if (!container) {\n throw new Error(withUsage('The `container` option is required.'));\n }\n\n const containerNode = getContainerNode(container);\n\n const cssClasses = {\n root: cx(suit(), userCssClasses.root),\n noRefinementRoot: cx(\n suit({ modifierName: 'noRefinement' }),\n userCssClasses.noRefinementRoot\n ),\n list: cx(suit({ descendantName: 'list' }), userCssClasses.list),\n childList: cx(\n suit({ descendantName: 'list', modifierName: 'child' }),\n userCssClasses.childList\n ),\n item: cx(suit({ descendantName: 'item' }), userCssClasses.item),\n selectedItem: cx(\n suit({ descendantName: 'item', modifierName: 'selected' }),\n userCssClasses.selectedItem\n ),\n parentItem: cx(\n suit({ descendantName: 'item', modifierName: 'parent' }),\n userCssClasses.parentItem\n ),\n link: cx(suit({ descendantName: 'link' }), userCssClasses.link),\n label: cx(suit({ descendantName: 'label' }), userCssClasses.label),\n count: cx(suit({ descendantName: 'count' }), userCssClasses.count),\n showMore: cx(suit({ descendantName: 'showMore' }), userCssClasses.showMore),\n disabledShowMore: cx(\n suit({ descendantName: 'showMore', modifierName: 'disabled' }),\n userCssClasses.disabledShowMore\n ),\n };\n\n const specializedRenderer = renderer({\n cssClasses,\n containerNode,\n templates,\n showMore,\n renderState: {},\n });\n\n const makeWidget = connectHierarchicalMenu(specializedRenderer, () =>\n render(null, containerNode)\n );\n\n return {\n ...makeWidget({\n attributes,\n separator,\n rootPath,\n showParentLevel,\n limit,\n showMore,\n showMoreLimit,\n sortBy,\n transformItems,\n }),\n $$widgetType: 'ais.hierarchicalMenu',\n };\n};\n\nexport default hierarchicalMenu;\n","import type { HitsComponentTemplates } from '../../components/Hits/Hits';\n\nconst defaultTemplates: HitsComponentTemplates = {\n empty: 'No results',\n item(data) {\n return JSON.stringify(data, null, 2);\n },\n};\n\nexport default defaultTemplates;\n","/** @jsx h */\n\nimport { h, render } from 'preact';\nimport cx from 'classnames';\nimport type {\n HitsConnectorParams,\n HitsRenderState,\n HitsWidgetDescription,\n} from '../../connectors/hits/connectHits';\nimport connectHits from '../../connectors/hits/connectHits';\nimport type {\n HitsComponentCSSClasses,\n HitsComponentTemplates,\n} from '../../components/Hits/Hits';\nimport Hits from '../../components/Hits/Hits';\nimport defaultTemplates from './defaultTemplates';\nimport {\n prepareTemplateProps,\n getContainerNode,\n createDocumentationMessageGenerator,\n} from '../../lib/utils';\nimport { component } from '../../lib/suit';\nimport { withInsights, withInsightsListener } from '../../lib/insights';\nimport type {\n Template,\n TemplateWithBindEvent,\n Hit,\n WidgetFactory,\n Renderer,\n InsightsClient,\n} from '../../types';\nimport type { InsightsEvent } from '../../middlewares/createInsightsMiddleware';\nimport type { PreparedTemplateProps } from '../../lib/utils/prepareTemplateProps';\n\nconst withUsage = createDocumentationMessageGenerator({ name: 'hits' });\nconst suit = component('Hits');\nconst HitsWithInsightsListener = withInsightsListener(Hits);\n\nconst renderer =\n ({\n renderState,\n cssClasses,\n containerNode,\n templates,\n }: {\n containerNode: HTMLElement;\n cssClasses: HitsComponentCSSClasses;\n renderState: {\n templateProps?: PreparedTemplateProps<HitsComponentTemplates>;\n };\n templates: HitsTemplates;\n }): Renderer<HitsRenderState, Partial<HitsWidgetParams>> =>\n (\n { hits: receivedHits, results, instantSearchInstance, insights, bindEvent },\n isFirstRendering\n ) => {\n if (isFirstRendering) {\n renderState.templateProps = prepareTemplateProps({\n defaultTemplates,\n templatesConfig: instantSearchInstance.templatesConfig,\n templates,\n });\n return;\n }\n\n render(\n <HitsWithInsightsListener\n cssClasses={cssClasses}\n hits={receivedHits}\n results={results}\n templateProps={renderState.templateProps}\n insights={insights as InsightsClient}\n sendEvent={(event: InsightsEvent) => {\n instantSearchInstance.sendEventToInsights(event);\n }}\n bindEvent={bindEvent}\n />,\n containerNode\n );\n };\n\nexport type HitsCSSClasses = Partial<{\n /**\n * CSS class to add to the wrapping element.\n */\n root: string | string[];\n\n /**\n * CSS class to add to the wrapping element when no results.\n */\n emptyRoot: string | string[];\n\n /**\n * CSS class to add to the list of results.\n */\n list: string | string[];\n\n /**\n * CSS class to add to each result.\n */\n item: string | string[];\n}>;\n\nexport type HitsTemplates = Partial<{\n /**\n * Template to use when there are no results.\n *\n * @default 'No Results'\n */\n empty: Template;\n\n /**\n * Template to use for each result. This template will receive an object containing a single record.\n *\n * @default ''\n */\n item: TemplateWithBindEvent<\n Hit & {\n // @deprecated the index in the hits array, use __position instead, which is the absolute position\n __hitIndex: number;\n }\n >;\n}>;\n\nexport type HitsWidgetParams = {\n /**\n * CSS Selector or HTMLElement to insert the widget.\n */\n container: string | HTMLElement;\n\n /**\n * Templates to use for the widget.\n */\n templates?: HitsTemplates;\n\n /**\n * CSS classes to add.\n */\n cssClasses?: HitsCSSClasses;\n};\n\nexport type HitsWidget = WidgetFactory<\n HitsWidgetDescription & { $$widgetType: 'ais.hits' },\n HitsConnectorParams,\n HitsWidgetParams\n>;\n\nconst hits: HitsWidget = function hits(widgetParams) {\n const {\n container,\n escapeHTML,\n transformItems,\n templates = {},\n cssClasses: userCssClasses = {},\n } = widgetParams || {};\n\n if (!container) {\n throw new Error(withUsage('The `container` option is required.'));\n }\n\n const containerNode = getContainerNode(container);\n const cssClasses = {\n root: cx(suit(), userCssClasses.root),\n emptyRoot: cx(suit({ modifierName: 'empty' }), userCssClasses.emptyRoot),\n list: cx(suit({ descendantName: 'list' }), userCssClasses.list),\n item: cx(suit({ descendantName: 'item' }), userCssClasses.item),\n };\n\n const specializedRenderer = renderer({\n containerNode,\n cssClasses,\n renderState: {},\n templates,\n });\n\n const makeWidget = withInsights(connectHits)(specializedRenderer, () =>\n render(null, containerNode)\n );\n\n return {\n ...makeWidget({ escapeHTML, transformItems }),\n $$widgetType: 'ais.hits',\n };\n};\n\nexport default hits;\n","/** @jsx h */\n\nimport { h } from 'preact';\nimport cx from 'classnames';\n\nexport type SelectorOption = {\n value?: string | number;\n label: string;\n};\n\nexport type SelectorComponentCSSClasses = {\n root: string;\n select: string;\n option: string;\n};\n\nexport type SelectorProps = {\n cssClasses: SelectorComponentCSSClasses;\n currentValue?: string | number;\n options: SelectorOption[];\n setValue(value: SelectorOption['value']): void;\n};\n\nfunction Selector({\n currentValue,\n options,\n cssClasses,\n setValue,\n}: SelectorProps) {\n return (\n <select\n className={cx(cssClasses.select)}\n onChange={(event) => setValue((event.target as HTMLSelectElement).value)}\n value={`${currentValue}`}\n >\n {options.map((option) => (\n <option\n className={cx(cssClasses.option)}\n key={option.label + option.value}\n value={`${option.value}`}\n >\n {option.label}\n </option>\n ))}\n </select>\n );\n}\n\nexport default Selector;\n","/** @jsx h */\n\nimport { h, render } from 'preact';\nimport cx from 'classnames';\nimport Selector from '../../components/Selector/Selector';\nimport type {\n HitsPerPageConnectorParams,\n HitsPerPageRenderState,\n HitsPerPageWidgetDescription,\n} from '../../connectors/hits-per-page/connectHitsPerPage';\nimport connectHitsPerPage from '../../connectors/hits-per-page/connectHitsPerPage';\nimport {\n getContainerNode,\n createDocumentationMessageGenerator,\n find,\n} from '../../lib/utils';\nimport { component } from '../../lib/suit';\nimport type { ComponentCSSClasses, WidgetFactory } from '../../types';\n\nconst withUsage = createDocumentationMessageGenerator({\n name: 'hits-per-page',\n});\nconst suit = component('HitsPerPage');\n\nconst renderer =\n ({\n containerNode,\n cssClasses,\n }: {\n containerNode: HTMLElement;\n cssClasses: ComponentCSSClasses<HitsPerPageCSSClasses>;\n }) =>\n ({ items, refine }: HitsPerPageRenderState, isFirstRendering: boolean) => {\n if (isFirstRendering) return;\n\n const { value: currentValue } =\n find(items, ({ isRefined }) => isRefined) || {};\n\n render(\n <div className={cssClasses.root}>\n <Selector\n cssClasses={cssClasses}\n currentValue={currentValue}\n options={items}\n setValue={refine}\n />\n </div>,\n containerNode\n );\n };\n\nexport type HitsPerPageCSSClasses = Partial<{\n /**\n * CSS classes added to the outer `<div>`.\n */\n root: string | string[];\n\n /**\n * CSS classes added to the parent `<select>`.\n */\n select: string | string[];\n\n /**\n * CSS classes added to each `<option>`.\n */\n option: string | string[];\n}>;\n\nexport type HitsPerPageWidgetParams = {\n /**\n * CSS Selector or HTMLElement to insert the widget.\n */\n container: string | HTMLElement;\n\n /**\n * CSS classes to be added.\n */\n cssClasses?: HitsPerPageCSSClasses;\n};\n\nexport type HitsPerPageWidget = WidgetFactory<\n HitsPerPageWidgetDescription & { $$widgetType: 'ais.hitsPerPage' },\n HitsPerPageConnectorParams,\n HitsPerPageWidgetParams\n>;\n\nconst hitsPerPage: HitsPerPageWidget = function hitsPerPage(widgetParams) {\n const {\n container,\n items,\n cssClasses: userCssClasses = {},\n transformItems,\n } = widgetParams || {};\n\n if (!container) {\n throw new Error(withUsage('The `container` option is required.'));\n }\n\n const containerNode = getContainerNode(container);\n\n const cssClasses = {\n root: cx(suit(), userCssClasses.root),\n select: cx(suit({ descendantName: 'select' }), userCssClasses.select),\n option: cx(suit({ descendantName: 'option' }), userCssClasses.option),\n };\n\n const specializedRenderer = renderer({\n containerNode,\n cssClasses,\n });\n\n const makeWidget = connectHitsPerPage(specializedRenderer, () =>\n render(null, containerNode)\n );\n\n return {\n ...makeWidget({ items, transformItems }),\n $$widgetType: 'ais.hitsPerPage',\n };\n};\n\nexport default hitsPerPage;\n","import type { InfiniteHitsComponentTemplates } from '../../components/InfiniteHits/InfiniteHits';\n\nconst defaultTemplates: InfiniteHitsComponentTemplates = {\n empty: 'No results',\n showPreviousText: 'Show previous results',\n showMoreText: 'Show more results',\n item(data) {\n return JSON.stringify(data, null, 2);\n },\n};\n\nexport default defaultTemplates;\n","/** @jsx h */\n\nimport { h, render } from 'preact';\nimport cx from 'classnames';\nimport type { SearchResults } from 'algoliasearch-helper';\nimport type {\n InfiniteHitsComponentCSSClasses,\n InfiniteHitsComponentTemplates,\n} from '../../components/InfiniteHits/InfiniteHits';\nimport InfiniteHits from '../../components/InfiniteHits/InfiniteHits';\nimport type {\n InfiniteHitsConnectorParams,\n InfiniteHitsRenderState,\n InfiniteHitsCache,\n InfiniteHitsWidgetDescription,\n} from '../../connectors/infinite-hits/connectInfiniteHits';\nimport connectInfiniteHits from '../../connectors/infinite-hits/connectInfiniteHits';\nimport {\n prepareTemplateProps,\n getContainerNode,\n createDocumentationMessageGenerator,\n} from '../../lib/utils';\nimport { component } from '../../lib/suit';\nimport { withInsights, withInsightsListener } from '../../lib/insights';\nimport type {\n WidgetFactory,\n Template,\n TemplateWithBindEvent,\n Hit,\n InsightsClient,\n Renderer,\n} from '../../types';\nimport defaultTemplates from './defaultTemplates';\nimport type { InsightsEvent } from '../../middlewares/createInsightsMiddleware';\nimport type { PreparedTemplateProps } from '../../lib/utils/prepareTemplateProps';\n\nconst withUsage = createDocumentationMessageGenerator({\n name: 'infinite-hits',\n});\nconst suit = component('InfiniteHits');\nconst InfiniteHitsWithInsightsListener = withInsightsListener(InfiniteHits);\n\nexport type InfiniteHitsCSSClasses = Partial<{\n /**\n * The root element of the widget.\n */\n root: string | string[];\n\n /**\n * The root container without results.\n */\n emptyRoot: string | string[];\n\n /**\n * The list of results.\n */\n list: string | string[];\n\n /**\n * The list item.\n */\n item: string | string[];\n\n /**\n * The “Show previous” button.\n */\n loadPrevious: string | string[];\n\n /**\n * The disabled “Show previous” button.\n */\n disabledLoadPrevious: string | string[];\n\n /**\n * The “Show more” button.\n */\n loadMore: string | string[];\n\n /**\n * The disabled “Show more” button.\n */\n disabledLoadMore: string | string[];\n}>;\n\nexport type InfiniteHitsTemplates = Partial<{\n /**\n * The template to use when there are no results.\n */\n empty: Template<{ results: SearchResults }>;\n\n /**\n * The template to use for the “Show previous” label.\n */\n showPreviousText: Template;\n\n /**\n * The template to use for the “Show more” label.\n */\n showMoreText: Template;\n\n /**\n * The template to use for each result.\n */\n item: TemplateWithBindEvent<\n Hit & {\n // @deprecated the index in the hits array, use __position instead, which is the absolute position\n __hitIndex: number;\n }\n >;\n}>;\n\nexport type InfiniteHitsWidgetParams = {\n /**\n * The CSS Selector or `HTMLElement` to insert the widget into.\n */\n container: string | HTMLElement;\n\n /**\n * The CSS classes to override.\n */\n cssClasses?: InfiniteHitsCSSClasses;\n\n /**\n * The templates to use for the widget.\n */\n templates?: InfiniteHitsTemplates;\n\n /**\n * Reads and writes hits from/to cache.\n * When user comes back to the search page after leaving for product page,\n * this helps restore InfiniteHits and its scroll position.\n */\n cache?: InfiniteHitsCache;\n};\n\nexport type InfiniteHitsWidget = WidgetFactory<\n InfiniteHitsWidgetDescription & { $$widgetType: 'ais.infiniteHits' },\n InfiniteHitsConnectorParams,\n InfiniteHitsWidgetParams\n>;\n\nconst renderer =\n ({\n containerNode,\n cssClasses,\n renderState,\n templates,\n showPrevious: hasShowPrevious,\n }: {\n containerNode: HTMLElement;\n cssClasses: InfiniteHitsComponentCSSClasses;\n renderState: {\n templateProps?: PreparedTemplateProps<InfiniteHitsComponentTemplates>;\n };\n templates: InfiniteHitsTemplates;\n showPrevious?: boolean;\n }): Renderer<InfiniteHitsRenderState, Partial<InfiniteHitsWidgetParams>> =>\n (\n {\n hits,\n results,\n showMore,\n showPrevious,\n isFirstPage,\n isLastPage,\n instantSearchInstance,\n insights,\n bindEvent,\n },\n isFirstRendering\n ) => {\n if (isFirstRendering) {\n renderState.templateProps = prepareTemplateProps({\n defaultTemplates,\n templatesConfig: instantSearchInstance.templatesConfig,\n templates,\n });\n return;\n }\n\n render(\n <InfiniteHitsWithInsightsListener\n cssClasses={cssClasses}\n hits={hits}\n results={results}\n hasShowPrevious={hasShowPrevious}\n showPrevious={showPrevious}\n showMore={showMore}\n templateProps={renderState.templateProps!}\n isFirstPage={isFirstPage}\n isLastPage={isLastPage}\n insights={insights as InsightsClient}\n sendEvent={(event: InsightsEvent) => {\n instantSearchInstance.sendEventToInsights(event);\n }}\n bindEvent={bindEvent}\n />,\n containerNode\n );\n };\n\nconst infiniteHits: InfiniteHitsWidget = (widgetParams) => {\n const {\n container,\n escapeHTML,\n transformItems,\n templates = {},\n cssClasses: userCssClasses = {},\n showPrevious,\n cache,\n } = widgetParams || {};\n\n if (!container) {\n throw new Error(withUsage('The `container` option is required.'));\n }\n\n const containerNode = getContainerNode(container);\n const cssClasses = {\n root: cx(suit(), userCssClasses.root),\n emptyRoot: cx(suit({ modifierName: 'empty' }), userCssClasses.emptyRoot),\n item: cx(suit({ descendantName: 'item' }), userCssClasses.item),\n list: cx(suit({ descendantName: 'list' }), userCssClasses.list),\n loadPrevious: cx(\n suit({ descendantName: 'loadPrevious' }),\n userCssClasses.loadPrevious\n ),\n disabledLoadPrevious: cx(\n suit({ descendantName: 'loadPrevious', modifierName: 'disabled' }),\n userCssClasses.disabledLoadPrevious\n ),\n loadMore: cx(suit({ descendantName: 'loadMore' }), userCssClasses.loadMore),\n disabledLoadMore: cx(\n suit({ descendantName: 'loadMore', modifierName: 'disabled' }),\n userCssClasses.disabledLoadMore\n ),\n };\n\n const specializedRenderer = renderer({\n containerNode,\n cssClasses,\n templates,\n showPrevious,\n renderState: {},\n });\n\n const makeWidget = withInsights(connectInfiniteHits)(\n specializedRenderer,\n () => render(null, containerNode)\n );\n\n return {\n ...makeWidget({\n escapeHTML,\n transformItems,\n showPrevious,\n cache,\n }),\n $$widgetType: 'ais.infiniteHits',\n };\n};\n\nexport default infiniteHits;\n","/** @jsx h */\n\nimport { h } from 'preact';\nimport cx from 'classnames';\nimport Template from '../Template/Template';\nimport type { SearchResults } from 'algoliasearch-helper';\nimport type { ComponentCSSClasses, Hits } from '../../types';\nimport type {\n InfiniteHitsCSSClasses,\n InfiniteHitsTemplates,\n} from '../../widgets/infinite-hits/infinite-hits';\nimport type { SendEventForHits, BindEventForHits } from '../../lib/utils';\n\nexport type InfiniteHitsComponentCSSClasses =\n ComponentCSSClasses<InfiniteHitsCSSClasses>;\nexport type InfiniteHitsComponentTemplates = Required<InfiniteHitsTemplates>;\n\nexport type InfiniteHitsProps = {\n cssClasses: InfiniteHitsComponentCSSClasses;\n hits: Hits;\n results: SearchResults;\n hasShowPrevious: boolean;\n showPrevious: () => void;\n showMore: () => void;\n templateProps: {\n [key: string]: any;\n templates: InfiniteHitsComponentTemplates;\n };\n isFirstPage: boolean;\n isLastPage: boolean;\n sendEvent: SendEventForHits;\n bindEvent: BindEventForHits;\n};\n\nconst InfiniteHits = ({\n results,\n hits,\n bindEvent,\n hasShowPrevious,\n showPrevious,\n showMore,\n isFirstPage,\n isLastPage,\n cssClasses,\n templateProps,\n}: InfiniteHitsProps) => {\n if (results.hits.length === 0) {\n return (\n <Template\n {...templateProps}\n templateKey=\"empty\"\n rootProps={{\n className: cx(cssClasses.root, cssClasses.emptyRoot),\n }}\n data={results}\n />\n );\n }\n\n return (\n <div className={cssClasses.root}>\n {hasShowPrevious && (\n <Template\n {...templateProps}\n templateKey=\"showPreviousText\"\n rootTagName=\"button\"\n rootProps={{\n className: cx(cssClasses.loadPrevious, {\n [cssClasses.disabledLoadPrevious]: isFirstPage,\n }),\n disabled: isFirstPage,\n onClick: showPrevious,\n }}\n />\n )}\n\n <ol className={cssClasses.list}>\n {hits.map((hit, position) => (\n <Template\n {...templateProps}\n templateKey=\"item\"\n rootTagName=\"li\"\n rootProps={{ className: cssClasses.item }}\n key={hit.objectID}\n data={{\n ...hit,\n __hitIndex: position,\n }}\n bindEvent={bindEvent}\n />\n ))}\n </ol>\n\n <Template\n {...templateProps}\n templateKey=\"showMoreText\"\n rootTagName=\"button\"\n rootProps={{\n className: cx(cssClasses.loadMore, {\n [cssClasses.disabledLoadMore]: isLastPage,\n }),\n disabled: isLastPage,\n onClick: showMore,\n }}\n />\n </div>\n );\n};\n\nexport default InfiniteHits;\n","import type { MenuComponentTemplates } from './menu';\n\nconst defaultTemplates: MenuComponentTemplates = {\n item:\n '<a class=\"{{cssClasses.link}}\" href=\"{{url}}\">' +\n '<span class=\"{{cssClasses.label}}\">{{label}}</span>' +\n '<span class=\"{{cssClasses.count}}\">{{#helpers.formatNumber}}{{count}}{{/helpers.formatNumber}}</span>' +\n '</a>',\n showMoreText: `\n {{#isShowingMore}}\n Show less\n {{/isShowingMore}}\n {{^isShowingMore}}\n Show more\n {{/isShowingMore}}\n `,\n};\n\nexport default defaultTemplates;\n","/** @jsx h */\n\nimport { h, render } from 'preact';\nimport cx from 'classnames';\nimport RefinementList from '../../components/RefinementList/RefinementList';\nimport type {\n MenuConnectorParams,\n MenuRenderState,\n MenuWidgetDescription,\n} from '../../connectors/menu/connectMenu';\nimport connectMenu from '../../connectors/menu/connectMenu';\nimport defaultTemplates from './defaultTemplates';\nimport {\n prepareTemplateProps,\n getContainerNode,\n createDocumentationMessageGenerator,\n} from '../../lib/utils';\nimport { component } from '../../lib/suit';\nimport type {\n ComponentCSSClasses,\n RendererOptions,\n Template,\n WidgetFactory,\n} from '../../types';\nimport type { PreparedTemplateProps } from '../../lib/utils/prepareTemplateProps';\n\nconst withUsage = createDocumentationMessageGenerator({ name: 'menu' });\nconst suit = component('Menu');\n\nexport type MenuCSSClasses = Partial<{\n /**\n * CSS class to add to the root element.\n */\n root: string | string[];\n /**\n * CSS class to add to the root element when no refinements.\n */\n noRefinementRoot: string | string[];\n /**\n * CSS class to add to the list element.\n */\n list: string | string[];\n /**\n * CSS class to add to each item element.\n */\n item: string | string[];\n /**\n * CSS class to add to each selected item element.\n */\n selectedItem: string | string[];\n /**\n * CSS class to add to each link (when using the default template).\n */\n link: string | string[];\n /**\n * CSS class to add to each label (when using the default template).\n */\n label: string | string[];\n /**\n * CSS class to add to each count element (when using the default template).\n */\n count: string | string[];\n /**\n * CSS class to add to the show more button.\n */\n showMore: string | string[];\n /**\n * CSS class to add to the disabled show more button.\n */\n disabledShowMore: string | string[];\n}>;\n\nexport type MenuTemplates = Partial<{\n /**\n * Item template. The string template gets the same values as the function.\n */\n item: Template<{\n count: number;\n cssClasses: MenuCSSClasses;\n isRefined: boolean;\n label: string;\n url: string;\n value: string;\n }>;\n /**\n * Template used for the show more text, provided with `isShowingMore` data property.\n */\n showMoreText: Template<{\n isShowingMore: boolean;\n }>;\n}>;\n\nexport type MenuComponentCSSClasses = ComponentCSSClasses<MenuCSSClasses>;\n\nexport type MenuComponentTemplates = Required<MenuTemplates>;\n\nexport type MenuWidgetParams = {\n /**\n * CSS Selector or HTMLElement to insert the widget.\n */\n container: string | HTMLElement;\n /**\n * Customize the output through templating.\n */\n templates?: MenuTemplates;\n /**\n * CSS classes to add to the wrapping elements.\n */\n cssClasses?: MenuCSSClasses;\n};\n\nconst renderer =\n ({\n containerNode,\n cssClasses,\n renderState,\n templates,\n showMore,\n }: {\n containerNode: HTMLElement;\n cssClasses: MenuComponentCSSClasses;\n renderState: {\n templateProps?: PreparedTemplateProps<MenuComponentTemplates>;\n };\n templates: MenuTemplates;\n showMore?: boolean;\n }) =>\n (\n {\n refine,\n items,\n createURL,\n instantSearchInstance,\n isShowingMore,\n toggleShowMore,\n canToggleShowMore,\n }: MenuRenderState & RendererOptions<MenuConnectorParams>,\n isFirstRendering: boolean\n ) => {\n if (isFirstRendering) {\n renderState.templateProps = prepareTemplateProps({\n defaultTemplates,\n templatesConfig: instantSearchInstance.templatesConfig,\n templates,\n });\n return;\n }\n\n const facetValues = items.map((facetValue) => ({\n ...facetValue,\n url: createURL(facetValue.value),\n }));\n\n render(\n <RefinementList\n createURL={createURL}\n cssClasses={cssClasses}\n facetValues={facetValues}\n showMore={showMore}\n templateProps={renderState.templateProps!}\n toggleRefinement={refine}\n toggleShowMore={toggleShowMore}\n isShowingMore={isShowingMore}\n canToggleShowMore={canToggleShowMore}\n />,\n containerNode\n );\n };\n\nexport type MenuWidget = WidgetFactory<\n MenuWidgetDescription & { $$widgetType: 'ais.menu' },\n MenuConnectorParams,\n MenuWidgetParams\n>;\n\nconst menu: MenuWidget = function menu(widgetParams) {\n const {\n container,\n attribute,\n sortBy,\n limit,\n showMore,\n showMoreLimit,\n cssClasses: userCssClasses = {},\n templates = {},\n transformItems,\n } = widgetParams || {};\n\n if (!container) {\n throw new Error(withUsage('The `container` option is required.'));\n }\n\n const containerNode = getContainerNode(container);\n\n const cssClasses = {\n root: cx(suit(), userCssClasses.root),\n noRefinementRoot: cx(\n suit({ modifierName: 'noRefinement' }),\n userCssClasses.noRefinementRoot\n ),\n list: cx(suit({ descendantName: 'list' }), userCssClasses.list),\n item: cx(suit({ descendantName: 'item' }), userCssClasses.item),\n selectedItem: cx(\n suit({ descendantName: 'item', modifierName: 'selected' }),\n userCssClasses.selectedItem\n ),\n link: cx(suit({ descendantName: 'link' }), userCssClasses.link),\n label: cx(suit({ descendantName: 'label' }), userCssClasses.label),\n count: cx(suit({ descendantName: 'count' }), userCssClasses.count),\n showMore: cx(suit({ descendantName: 'showMore' }), userCssClasses.showMore),\n disabledShowMore: cx(\n suit({ descendantName: 'showMore', modifierName: 'disabled' }),\n userCssClasses.disabledShowMore\n ),\n };\n\n const specializedRenderer = renderer({\n containerNode,\n cssClasses,\n renderState: {},\n templates,\n showMore,\n });\n\n const makeWidget = connectMenu(specializedRenderer, () =>\n render(null, containerNode)\n );\n\n return {\n ...makeWidget({\n attribute,\n limit,\n showMore,\n showMoreLimit,\n sortBy,\n transformItems,\n }),\n $$widgetType: 'ais.menu',\n };\n};\n\nexport default menu;\n","/** @jsx h */\n\nimport { h } from 'preact';\nimport cx from 'classnames';\nimport { find } from '../../lib/utils';\nimport Template from '../Template/Template';\nimport type {\n MenuSelectCSSClasses,\n MenuSelectTemplates,\n} from '../../widgets/menu-select/menu-select';\nimport type { MenuRenderState } from '../../connectors/menu/connectMenu';\nimport type { ComponentCSSClasses } from '../../types';\n\nexport type MenuSelectComponentCSSClasses =\n ComponentCSSClasses<MenuSelectCSSClasses>;\n\nexport type MenuSelectComponentTemplates = Required<MenuSelectTemplates>;\n\ntype MenuItem = {\n /**\n * The value of the menu item.\n **/\n value: string;\n /**\n * Human-readable value of the menu item.\n **/\n label: string;\n /**\n * Number of results matched after refinement is applied.\n **/\n count: number;\n /**\n * Indicates if the refinement is applied.\n **/\n isRefined: boolean;\n};\n\ntype Props = {\n cssClasses: MenuSelectComponentCSSClasses;\n items: MenuItem[];\n refine: MenuRenderState['refine'];\n templateProps: {\n templates: MenuSelectComponentTemplates;\n };\n};\n\nfunction MenuSelect({ cssClasses, templateProps, items, refine }: Props) {\n const { value: selectedValue } = find(items, (item) => item.isRefined) || {\n value: '',\n };\n\n return (\n <div\n className={cx(cssClasses.root, {\n [cssClasses.noRefinementRoot]: items.length === 0,\n })}\n >\n <select\n className={cssClasses.select}\n value={selectedValue}\n onChange={(event) => {\n refine((event.target as HTMLSelectElement).value);\n }}\n >\n <Template\n {...templateProps}\n templateKey=\"defaultOption\"\n rootTagName=\"option\"\n rootProps={{\n value: '',\n className: cssClasses.option,\n }}\n />\n\n {items.map((item) => (\n <Template\n {...templateProps}\n templateKey=\"item\"\n rootTagName=\"option\"\n rootProps={{\n value: item.value,\n className: cssClasses.option,\n }}\n key={item.value}\n data={item}\n />\n ))}\n </select>\n </div>\n );\n}\n\nexport default MenuSelect;\n","/** @jsx h */\n\nimport { h } from 'preact';\n\nexport type PaginationLinkComponentCSSClasses = {\n item: string;\n link: string;\n};\n\nexport type PaginationLinkProps = {\n ariaLabel: string;\n cssClasses: PaginationLinkComponentCSSClasses;\n handleClick(pageNumber: number, event: MouseEvent): void;\n isDisabled: boolean;\n label: string;\n pageNumber: number;\n url?: string;\n};\n\nconst PaginationLink = ({\n cssClasses,\n label,\n ariaLabel,\n url,\n isDisabled,\n handleClick,\n pageNumber,\n}: PaginationLinkProps) => {\n if (isDisabled) {\n return (\n <li className={cssClasses.item}>\n <span\n className={cssClasses.link}\n dangerouslySetInnerHTML={{\n __html: label,\n }}\n />\n </li>\n );\n }\n\n return (\n <li className={cssClasses.item}>\n <a\n className={cssClasses.link}\n aria-label={ariaLabel}\n href={url}\n onClick={(event) => handleClick(pageNumber, event)}\n dangerouslySetInnerHTML={{\n __html: label,\n }}\n />\n </li>\n );\n};\n\nexport default PaginationLink;\n","import type { MenuSelectComponentTemplates } from '../../components/MenuSelect/MenuSelect';\n\nconst defaultTemplates: MenuSelectComponentTemplates = {\n item: '{{label}} ({{#helpers.formatNumber}}{{count}}{{/helpers.formatNumber}})',\n defaultOption: 'See all',\n};\n\nexport default defaultTemplates;\n","/** @jsx h */\n\nimport { h, render } from 'preact';\nimport cx from 'classnames';\nimport type {\n MenuConnectorParams,\n MenuRenderState,\n MenuWidgetDescription,\n} from '../../connectors/menu/connectMenu';\nimport connectMenu from '../../connectors/menu/connectMenu';\nimport type {\n MenuSelectComponentCSSClasses,\n MenuSelectComponentTemplates,\n} from '../../components/MenuSelect/MenuSelect';\nimport MenuSelect from '../../components/MenuSelect/MenuSelect';\nimport defaultTemplates from './defaultTemplates';\nimport {\n prepareTemplateProps,\n getContainerNode,\n createDocumentationMessageGenerator,\n} from '../../lib/utils';\nimport { component } from '../../lib/suit';\nimport type { RendererOptions, Template, WidgetFactory } from '../../types';\nimport type { PreparedTemplateProps } from '../../lib/utils/prepareTemplateProps';\n\nconst withUsage = createDocumentationMessageGenerator({ name: 'menu-select' });\nconst suit = component('MenuSelect');\n\nexport type MenuSelectCSSClasses = Partial<{\n /**\n * CSS class to add to the root element.\n */\n root: string | string[];\n /**\n * CSS class to add to the root when there are no items to display\n */\n noRefinementRoot: string | string[];\n /**\n * CSS class to add to the select element.\n */\n select: string | string[];\n /**\n * CSS class to add to the option element.\n */\n option: string | string[];\n}>;\n\nexport type MenuSelectTemplates = Partial<{\n /**\n * Item template, provided with `label`, `count`, `isRefined` and `value` data properties.\n */\n item: Template<{\n label: string;\n value: string;\n count: number;\n isRefined: boolean;\n }>;\n /**\n * Label of the \"see all\" option in the select.\n */\n defaultOption: Template;\n}>;\n\nexport type MenuSelectWidgetParams = {\n /**\n * CSS Selector or HTMLElement to insert the widget.\n */\n container: string | HTMLElement;\n /**\n * Customize the output through templating.\n */\n templates?: MenuSelectTemplates;\n /**\n * CSS classes to add to the wrapping elements.\n */\n cssClasses?: MenuSelectCSSClasses;\n};\n\nconst renderer =\n ({\n containerNode,\n cssClasses,\n renderState,\n templates,\n }: {\n containerNode: HTMLElement;\n cssClasses: MenuSelectComponentCSSClasses;\n renderState: {\n templateProps?: PreparedTemplateProps<MenuSelectComponentTemplates>;\n };\n templates: MenuSelectTemplates;\n }) =>\n (\n {\n refine,\n items,\n instantSearchInstance,\n }: MenuRenderState & RendererOptions<MenuConnectorParams>,\n isFirstRendering: boolean\n ) => {\n if (isFirstRendering) {\n renderState.templateProps = prepareTemplateProps({\n defaultTemplates,\n templatesConfig: instantSearchInstance.templatesConfig,\n templates,\n });\n return;\n }\n\n render(\n <MenuSelect\n cssClasses={cssClasses}\n items={items}\n refine={refine}\n templateProps={renderState.templateProps!}\n />,\n containerNode\n );\n };\n\nexport type MenuSelectWidget = WidgetFactory<\n MenuWidgetDescription & { $$widgetType: 'ais.menuSelect' },\n MenuConnectorParams,\n MenuSelectWidgetParams\n>;\n\nconst menuSelect: MenuSelectWidget = function menuSelect(widgetParams) {\n const {\n container,\n attribute,\n sortBy = ['name:asc'],\n limit = 10,\n cssClasses: userCssClasses = {},\n templates = {},\n transformItems,\n } = widgetParams || {};\n\n if (!container) {\n throw new Error(withUsage('The `container` option is required.'));\n }\n\n const containerNode = getContainerNode(container);\n const cssClasses = {\n root: cx(suit(), userCssClasses.root),\n noRefinementRoot: cx(\n suit({ modifierName: 'noRefinement' }),\n userCssClasses.noRefinementRoot\n ),\n select: cx(suit({ descendantName: 'select' }), userCssClasses.select),\n option: cx(suit({ descendantName: 'option' }), userCssClasses.option),\n };\n\n const specializedRenderer = renderer({\n containerNode,\n cssClasses,\n renderState: {},\n templates,\n });\n\n const makeWidget = connectMenu(specializedRenderer, () =>\n render(null, containerNode)\n );\n\n return {\n ...makeWidget({ attribute, limit, sortBy, transformItems }),\n $$widgetType: 'ais.menuSelect',\n };\n};\n\nexport default menuSelect;\n","import type { NumericMenuComponentTemplates } from './numeric-menu';\n\nconst defaultTemplates: NumericMenuComponentTemplates = {\n item: `<label class=\"{{cssClasses.label}}\">\n <input type=\"radio\" class=\"{{cssClasses.radio}}\" name=\"{{attribute}}\"{{#isRefined}} checked{{/isRefined}} />\n <span class=\"{{cssClasses.labelText}}\">{{label}}</span>\n</label>`,\n};\n\nexport default defaultTemplates;\n","/** @jsx h */\n\nimport { h, render } from 'preact';\nimport cx from 'classnames';\nimport RefinementList from '../../components/RefinementList/RefinementList';\nimport type {\n NumericMenuConnectorParams,\n NumericMenuRenderState,\n NumericMenuWidgetDescription,\n} from '../../connectors/numeric-menu/connectNumericMenu';\nimport connectNumericMenu from '../../connectors/numeric-menu/connectNumericMenu';\nimport defaultTemplates from './defaultTemplates';\nimport {\n prepareTemplateProps,\n getContainerNode,\n createDocumentationMessageGenerator,\n} from '../../lib/utils';\nimport { component } from '../../lib/suit';\nimport type {\n ComponentCSSClasses,\n Renderer,\n Template,\n WidgetFactory,\n} from '../../types';\nimport type { PreparedTemplateProps } from '../../lib/utils/prepareTemplateProps';\n\nconst withUsage = createDocumentationMessageGenerator({ name: 'numeric-menu' });\nconst suit = component('NumericMenu');\n\nconst renderer =\n ({\n containerNode,\n attribute,\n cssClasses,\n renderState,\n templates,\n }: {\n containerNode: HTMLElement;\n attribute: string;\n cssClasses: NumericMenuComponentCSSClasses;\n renderState: {\n templateProps?: PreparedTemplateProps<NumericMenuTemplates>;\n };\n templates: NumericMenuTemplates;\n }): Renderer<NumericMenuRenderState, Partial<NumericMenuWidgetParams>> =>\n (\n { createURL, instantSearchInstance, refine, items },\n isFirstRendering: boolean\n ) => {\n if (isFirstRendering) {\n renderState.templateProps = prepareTemplateProps({\n defaultTemplates,\n templatesConfig: instantSearchInstance.templatesConfig,\n templates,\n });\n return;\n }\n\n render(\n <RefinementList\n createURL={createURL}\n cssClasses={cssClasses}\n facetValues={items}\n templateProps={renderState.templateProps!}\n toggleRefinement={refine}\n attribute={attribute}\n />,\n containerNode\n );\n };\n\nexport type NumericMenuCSSClasses = Partial<{\n /**\n * CSS class to add to the root element.\n */\n root: string | string[];\n\n /**\n * CSS class to add to the root element when no refinements.\n */\n noRefinementRoot: string | string[];\n\n /**\n * CSS class to add to the list element.\n */\n list: string | string[];\n\n /**\n * CSS class to add to each item element.\n */\n item: string | string[];\n\n /**\n * CSS class to add to each selected item element.\n */\n selectedItem: string | string[];\n\n /**\n * CSS class to add to each label element.\n */\n label: string | string[];\n\n /**\n * CSS class to add to each label text element.\n */\n labelText: string | string[];\n\n /**\n * CSS class to add to each radio element (when using the default template).\n */\n radio: string | string[];\n}>;\n\nexport type NumericMenuComponentCSSClasses =\n ComponentCSSClasses<NumericMenuCSSClasses>;\n\nexport type NumericMenuTemplates = Partial<{\n /**\n * Item template, provided with `label` (the name in the configuration), `isRefined`, `url`, `value` (the setting for the filter) data properties.\n */\n item: Template<{\n /**\n * The name of the attribute.\n */\n attribute: string;\n\n /**\n * The label for the option.\n */\n label: string;\n\n /**\n * The encoded URL of the bounds object with a {start, end} form. This\n * value can be used verbatim in the webpage and can be read by refine\n * directly. If you want to inspect the value, you can do JSON.parse(window.decodeURI(value))\n * to get the object.\n */\n value: string;\n\n /**\n * Whether or not the refinement is selected.\n */\n isRefined: boolean;\n\n /**\n * The URL with the applied refinement.\n */\n url: string;\n\n /**\n * The CSS classes provided to the widget.\n */\n cssClasses: NumericMenuComponentCSSClasses;\n }>;\n}>;\n\nexport type NumericMenuComponentTemplates = Required<NumericMenuTemplates>;\n\nexport type NumericMenuWidgetParams = {\n /**\n * CSS Selector or HTMLElement to insert the widget.\n */\n container: string | HTMLElement;\n\n /**\n * Templates to use for the widget.\n */\n templates?: NumericMenuTemplates;\n\n /**\n * CSS classes to add to the wrapping elements.\n */\n cssClasses?: NumericMenuCSSClasses;\n};\n\nexport type NumericMenuWidget = WidgetFactory<\n NumericMenuWidgetDescription & { $$widgetType: 'ais.numericMenu' },\n NumericMenuConnectorParams,\n NumericMenuWidgetParams\n>;\n\nconst numericMenu: NumericMenuWidget = function numericMenu(widgetParams) {\n const {\n container,\n attribute,\n items,\n cssClasses: userCssClasses = {},\n templates = {},\n transformItems,\n } = widgetParams || {};\n\n if (!container) {\n throw new Error(withUsage('The `container` option is required.'));\n }\n\n const containerNode = getContainerNode(container);\n\n const cssClasses = {\n root: cx(suit(), userCssClasses.root),\n noRefinementRoot: cx(\n suit({ modifierName: 'noRefinement' }),\n userCssClasses.noRefinementRoot\n ),\n list: cx(suit({ descendantName: 'list' }), userCssClasses.list),\n item: cx(suit({ descendantName: 'item' }), userCssClasses.item),\n selectedItem: cx(\n suit({ descendantName: 'item', modifierName: 'selected' }),\n userCssClasses.selectedItem\n ),\n label: cx(suit({ descendantName: 'label' }), userCssClasses.label),\n radio: cx(suit({ descendantName: 'radio' }), userCssClasses.radio),\n labelText: cx(\n suit({ descendantName: 'labelText' }),\n userCssClasses.labelText\n ),\n };\n\n const specializedRenderer = renderer({\n containerNode,\n attribute,\n cssClasses,\n renderState: {},\n templates,\n });\n\n const makeWidget = connectNumericMenu(specializedRenderer, () =>\n render(null, containerNode)\n );\n\n return {\n ...makeWidget({\n attribute,\n items,\n transformItems,\n }),\n $$widgetType: 'ais.numericMenu',\n };\n};\n\nexport default numericMenu;\n","/** @jsx h */\n\nimport { Component, h } from 'preact';\nimport cx from 'classnames';\n\nimport PaginationLink from './PaginationLink';\nimport { isSpecialClick } from '../../lib/utils';\nimport type {\n PaginationCSSClasses,\n PaginationTemplates,\n} from '../../widgets/pagination/pagination';\nimport type { ComponentCSSClasses } from '../../types';\n\nexport type PaginationComponentCSSClasses =\n ComponentCSSClasses<PaginationCSSClasses>;\n\nexport type PaginationComponentTemplates = Required<PaginationTemplates>;\n\nexport type PaginationProps = {\n createURL(value: number): string;\n cssClasses: PaginationComponentCSSClasses;\n currentPage: number;\n templates: PaginationComponentTemplates;\n nbPages?: number;\n pages?: number[];\n isFirstPage: boolean;\n isLastPage: boolean;\n setCurrentPage(value: number): void;\n showFirst?: boolean;\n showLast?: boolean;\n showPrevious?: boolean;\n showNext?: boolean;\n};\n\ntype PageLink = {\n label: string;\n ariaLabel: string;\n pageNumber: number;\n additionalClassName: string | null;\n isDisabled?: boolean;\n isSelected?: boolean;\n createURL(value: number): string;\n};\n\nconst defaultProps = {\n currentPage: 0,\n nbPages: 0,\n pages: [],\n};\n\nclass Pagination extends Component<PaginationProps> {\n public static defaultProps = defaultProps;\n\n private pageLink({\n label,\n ariaLabel,\n pageNumber,\n additionalClassName = null,\n isDisabled = false,\n isSelected = false,\n createURL,\n }: PageLink) {\n const cssClasses = {\n item: cx(this.props.cssClasses.item, additionalClassName),\n link: this.props.cssClasses.link,\n };\n\n if (isDisabled) {\n cssClasses.item = cx(cssClasses.item, this.props.cssClasses.disabledItem);\n } else if (isSelected) {\n cssClasses.item = cx(cssClasses.item, this.props.cssClasses.selectedItem);\n }\n\n const url = !isDisabled ? createURL(pageNumber) : '#';\n\n return (\n <PaginationLink\n ariaLabel={ariaLabel}\n cssClasses={cssClasses}\n handleClick={this.handleClick}\n isDisabled={isDisabled}\n key={label + pageNumber + ariaLabel}\n label={label}\n pageNumber={pageNumber}\n url={url}\n />\n );\n }\n\n public handleClick = (pageNumber: number, event: MouseEvent) => {\n if (isSpecialClick(event)) {\n // do not alter the default browser behavior\n // if one special key is down\n return;\n }\n event.preventDefault();\n this.props.setCurrentPage(pageNumber);\n };\n\n private previousPageLink = () => {\n return this.pageLink({\n ariaLabel: 'Previous',\n additionalClassName: this.props.cssClasses.previousPageItem,\n isDisabled: this.props.isFirstPage,\n label: this.props.templates.previous,\n pageNumber: this.props.currentPage - 1,\n createURL: this.props.createURL,\n });\n };\n\n private nextPageLink = () => {\n return this.pageLink({\n ariaLabel: 'Next',\n additionalClassName: this.props.cssClasses.nextPageItem,\n isDisabled: this.props.isLastPage,\n label: this.props.templates.next,\n pageNumber: this.props.currentPage + 1,\n createURL: this.props.createURL,\n });\n };\n\n private firstPageLink = () => {\n return this.pageLink({\n ariaLabel: 'First',\n additionalClassName: this.props.cssClasses.firstPageItem,\n isDisabled: this.props.isFirstPage,\n label: this.props.templates.first,\n pageNumber: 0,\n createURL: this.props.createURL,\n });\n };\n\n private lastPageLink = () => {\n return this.pageLink({\n ariaLabel: 'Last',\n additionalClassName: this.props.cssClasses.lastPageItem,\n isDisabled: this.props.isLastPage,\n label: this.props.templates.last,\n pageNumber: this.props.nbPages! - 1,\n createURL: this.props.createURL,\n });\n };\n\n private pages = () => {\n return this.props.pages!.map((pageNumber) =>\n this.pageLink({\n ariaLabel: `${pageNumber + 1}`,\n additionalClassName: this.props.cssClasses.pageItem,\n isSelected: pageNumber === this.props.currentPage,\n label: `${pageNumber + 1}`,\n pageNumber,\n createURL: this.props.createURL,\n })\n );\n };\n\n public render() {\n return (\n <div\n className={cx(this.props.cssClasses.root, {\n [this.props.cssClasses.noRefinementRoot]: this.props.nbPages! <= 1,\n })}\n >\n <ul className={this.props.cssClasses.list}>\n {this.props.showFirst && this.firstPageLink()}\n {this.props.showPrevious && this.previousPageLink()}\n {this.pages()}\n {this.props.showNext && this.nextPageLink()}\n {this.props.showLast && this.lastPageLink()}\n </ul>\n </div>\n );\n }\n}\n\nexport default Pagination;\n","/** @jsx h */\n\nimport { h, render } from 'preact';\nimport cx from 'classnames';\nimport type {\n PaginationComponentCSSClasses,\n PaginationComponentTemplates,\n} from '../../components/Pagination/Pagination';\nimport Pagination from '../../components/Pagination/Pagination';\nimport type {\n PaginationConnectorParams,\n PaginationRenderState,\n PaginationWidgetDescription,\n} from '../../connectors/pagination/connectPagination';\nimport connectPagination from '../../connectors/pagination/connectPagination';\nimport {\n getContainerNode,\n createDocumentationMessageGenerator,\n} from '../../lib/utils';\nimport { component } from '../../lib/suit';\nimport type { Renderer, WidgetFactory } from '../../types';\n\nconst suit = component('Pagination');\nconst withUsage = createDocumentationMessageGenerator({ name: 'pagination' });\n\nconst defaultTemplates: PaginationComponentTemplates = {\n previous: '‹',\n next: '›',\n first: '«',\n last: '»',\n};\n\nconst renderer =\n ({\n containerNode,\n cssClasses,\n templates,\n showFirst,\n showLast,\n showPrevious,\n showNext,\n scrollToNode,\n }: {\n containerNode: HTMLElement;\n cssClasses: PaginationComponentCSSClasses;\n templates: PaginationComponentTemplates;\n showFirst: boolean;\n showLast: boolean;\n showPrevious: boolean;\n showNext: boolean;\n scrollToNode: HTMLElement | false;\n }): Renderer<PaginationRenderState, Partial<PaginationWidgetParams>> =>\n (\n {\n createURL,\n currentRefinement,\n nbPages,\n pages,\n isFirstPage,\n isLastPage,\n refine,\n },\n isFirstRendering\n ) => {\n if (isFirstRendering) return;\n\n const setCurrentPage = (pageNumber: number) => {\n refine(pageNumber);\n\n if (scrollToNode !== false) {\n scrollToNode.scrollIntoView();\n }\n };\n\n render(\n <Pagination\n createURL={createURL}\n cssClasses={cssClasses}\n currentPage={currentRefinement}\n templates={templates}\n nbPages={nbPages}\n pages={pages}\n isFirstPage={isFirstPage}\n isLastPage={isLastPage}\n setCurrentPage={setCurrentPage}\n showFirst={showFirst}\n showLast={showLast}\n showPrevious={showPrevious}\n showNext={showNext}\n />,\n containerNode\n );\n };\n\nexport type PaginationCSSClasses = Partial<{\n /**\n * CSS classes added to the root element of the widget.\n */\n root: string | string[];\n\n /**\n * CSS class to add to the root element of the widget if there are no refinements.\n */\n noRefinementRoot: string | string[];\n\n /**\n * CSS classes added to the wrapping `<ul>`.\n */\n list: string | string[];\n\n /**\n * CSS classes added to each `<li>`.\n */\n item: string | string[];\n\n /**\n * CSS classes added to the first `<li>`.\n */\n firstPageItem: string | string[];\n\n /**\n * CSS classes added to the last `<li>`.\n */\n lastPageItem: string | string[];\n\n /**\n * CSS classes added to the previous `<li>`.\n */\n previousPageItem: string | string[];\n\n /**\n * CSS classes added to the next `<li>`.\n */\n nextPageItem: string | string[];\n\n /**\n * CSS classes added to page `<li>`.\n */\n pageItem: string | string[];\n\n /**\n * CSS classes added to the selected `<li>`.\n */\n selectedItem: string | string[];\n\n /**\n * CSS classes added to the disabled `<li>`.\n */\n disabledItem: string | string[];\n\n /**\n * CSS classes added to each link.\n */\n link: string | string[];\n}>;\n\nexport type PaginationTemplates = Partial<{\n /**\n * Label for the Previous link.\n */\n previous: string;\n\n /**\n * Label for the Next link.\n */\n next: string;\n\n /**\n * Label for the First link.\n */\n first: string;\n\n /**\n * Label for the Last link.\n */\n last: string;\n}>;\n\nexport type PaginationWidgetParams = {\n /**\n * CSS Selector or HTMLElement to insert the widget.\n */\n container: string | HTMLElement;\n\n /**\n * The max number of pages to browse.\n */\n totalPages?: number;\n\n /**\n * The number of pages to display on each side of the current page.\n * @default 3\n */\n padding?: number;\n\n /**\n * Where to scroll after a click, set to `false` to disable.\n * @default body\n */\n scrollTo?: string | HTMLElement | boolean;\n\n /**\n * Whether to show the \"first page\" control\n * @default true\n */\n showFirst?: boolean;\n\n /**\n * Whether to show the \"last page\" control\n * @default true\n */\n showLast?: boolean;\n\n /**\n * Whether to show the \"next page\" control\n * @default true\n */\n showNext?: boolean;\n\n /**\n * Whether to show the \"previous page\" control\n * @default true\n */\n showPrevious?: boolean;\n\n /**\n * Text to display in the links.\n */\n templates?: PaginationTemplates;\n\n /**\n * CSS classes to be added.\n */\n cssClasses?: PaginationCSSClasses;\n};\n\nexport type PaginationWidget = WidgetFactory<\n PaginationWidgetDescription & { $$widgetType: 'ais.pagination' },\n PaginationConnectorParams,\n PaginationWidgetParams\n>;\n\nconst pagination: PaginationWidget = function pagination(widgetParams) {\n const {\n container,\n templates: userTemplates = {},\n cssClasses: userCssClasses = {},\n totalPages,\n padding,\n showFirst = true,\n showLast = true,\n showPrevious = true,\n showNext = true,\n scrollTo: userScrollTo = 'body',\n } = widgetParams || {};\n\n if (!container) {\n throw new Error(withUsage('The `container` option is required.'));\n }\n\n const containerNode = getContainerNode(container);\n\n const scrollTo = userScrollTo === true ? 'body' : userScrollTo;\n const scrollToNode = scrollTo !== false ? getContainerNode(scrollTo) : false;\n\n const cssClasses = {\n root: cx(suit(), userCssClasses.root),\n noRefinementRoot: cx(\n suit({ modifierName: 'noRefinement' }),\n userCssClasses.noRefinementRoot\n ),\n list: cx(suit({ descendantName: 'list' }), userCssClasses.list),\n item: cx(suit({ descendantName: 'item' }), userCssClasses.item),\n firstPageItem: cx(\n suit({ descendantName: 'item', modifierName: 'firstPage' }),\n userCssClasses.firstPageItem\n ),\n lastPageItem: cx(\n suit({ descendantName: 'item', modifierName: 'lastPage' }),\n userCssClasses.lastPageItem\n ),\n previousPageItem: cx(\n suit({ descendantName: 'item', modifierName: 'previousPage' }),\n userCssClasses.previousPageItem\n ),\n nextPageItem: cx(\n suit({ descendantName: 'item', modifierName: 'nextPage' }),\n userCssClasses.nextPageItem\n ),\n pageItem: cx(\n suit({ descendantName: 'item', modifierName: 'page' }),\n userCssClasses.pageItem\n ),\n selectedItem: cx(\n suit({ descendantName: 'item', modifierName: 'selected' }),\n userCssClasses.selectedItem\n ),\n disabledItem: cx(\n suit({ descendantName: 'item', modifierName: 'disabled' }),\n userCssClasses.disabledItem\n ),\n link: cx(suit({ descendantName: 'link' }), userCssClasses.link),\n };\n\n const templates = {\n ...defaultTemplates,\n ...userTemplates,\n };\n\n const specializedRenderer = renderer({\n containerNode,\n cssClasses,\n templates,\n showFirst,\n showLast,\n showPrevious,\n showNext,\n scrollToNode,\n });\n\n const makeWidget = connectPagination(specializedRenderer, () =>\n render(null, containerNode)\n );\n\n return {\n ...makeWidget({ totalPages, padding }),\n $$widgetType: 'ais.pagination',\n };\n};\n\nexport default pagination;\n","import{options as n}from\"preact\";var t,r,u=[],i=n.__r;n.__r=function(n){i&&i(n),t=0,(r=n.__c).__H&&(r.__H.t=A(r.__H.t))};var f=n.diffed;n.diffed=function(n){f&&f(n);var t=n.__c;if(t){var r=t.__H;r&&(r.u=(r.u.some(function(n){n.ref&&(n.ref.current=n.createHandle())}),[]),r.i=A(r.i))}};var o=n.unmount;function e(t){n.__h&&n.__h(r);var u=r.__H||(r.__H={o:[],t:[],i:[],u:[]});return t>=u.o.length&&u.o.push({}),u.o[t]}function c(n){return a(q,n)}function a(n,u,i){var f=e(t++);return f.__c||(f.__c=r,f.v=[i?i(u):q(void 0,u),function(t){var r=n(f.v[0],t);f.v[0]!==r&&(f.v[0]=r,f.__c.setState({}))}]),f.v}function v(n,u){var i=e(t++);h(i.m,u)&&(i.v=n,i.m=u,r.__H.t.push(i),T(r))}function m(n,u){var i=e(t++);h(i.m,u)&&(i.v=n,i.m=u,r.__H.i.push(i))}function d(n){return l(function(){return{current:n}},[])}function p(n,u,i){var f=e(t++);h(f.m,i)&&(f.m=i,r.__H.u.push({ref:n,createHandle:u}))}function l(n,r){var u=e(t++);return h(u.m,r)?(u.m=r,u.p=n,u.v=n()):u.v}function s(n,t){return l(function(){return n},t)}function y(n){var u=r.context[n.__c];if(!u)return n.__p;var i=e(t++);return null==i.v&&(i.v=!0,u.sub(r)),u.props.value}function _(t,r){n.useDebugValue&&n.useDebugValue(r?r(t):t)}n.unmount=function(n){o&&o(n);var t=n.__c;if(t){var r=t.__H;r&&r.o.forEach(function(n){return n.l&&n.l()})}};var T=function(){};function g(){u.some(function(n){n.s=!1,n.__P&&(n.__H.t=A(n.__H.t))}),u=[]}if(\"undefined\"!=typeof window){var w=n.requestAnimationFrame;T=function(t){(!t.s&&(t.s=!0)&&1===u.push(t)||w!==n.requestAnimationFrame)&&(w=n.requestAnimationFrame,(n.requestAnimationFrame||function(n){var t=function(){clearTimeout(r),cancelAnimationFrame(u),setTimeout(n)},r=setTimeout(t,100),u=requestAnimationFrame(t)})(g))}}function A(n){return n.forEach(E),n.forEach(F),[]}function E(n){n.l&&n.l()}function F(n){var t=n.v();\"function\"==typeof t&&(n.l=t)}function h(n,t){return!n||t.some(function(t,r){return t!==n[r]})}function q(n,t){return\"function\"==typeof t?t(n):t}export{c as useState,a as useReducer,v as useEffect,m as useLayoutEffect,d as useRef,p as useImperativeHandle,l as useMemo,s as useCallback,y as useContext,_ as useDebugValue};\n//# sourceMappingURL=hooks.module.js.map\n","/** @jsx h */\n\nimport { h } from 'preact';\nimport { useState, useEffect, useRef } from 'preact/hooks';\nimport cx from 'classnames';\nimport Template from '../Template/Template';\nimport type {\n PanelCSSClasses,\n PanelSharedOptions,\n PanelTemplates,\n} from '../../widgets/panel/panel';\nimport type { ComponentCSSClasses, UnknownWidgetFactory } from '../../types';\n\nexport type PanelComponentCSSClasses = ComponentCSSClasses<\n // `collapseIcon` is only used in the default templates of the widget\n Omit<PanelCSSClasses, 'collapseIcon'>\n>;\n\nexport type PanelComponentTemplates<TWidget extends UnknownWidgetFactory> =\n Required<PanelTemplates<TWidget>>;\n\nexport type PanelProps<TWidget extends UnknownWidgetFactory> = {\n hidden: boolean;\n collapsible: boolean;\n isCollapsed: boolean;\n data: PanelSharedOptions<TWidget>;\n cssClasses: PanelComponentCSSClasses;\n templates: PanelComponentTemplates<TWidget>;\n bodyElement: HTMLElement;\n};\n\nfunction Panel<TWidget extends UnknownWidgetFactory>(\n props: PanelProps<TWidget>\n) {\n const [isCollapsed, setIsCollapsed] = useState<boolean>(props.isCollapsed);\n const [isControlled, setIsControlled] = useState<boolean>(false);\n const bodyRef = useRef<HTMLElement | null>(null);\n\n useEffect(() => {\n const node = bodyRef.current;\n if (!node) {\n return undefined;\n }\n\n node.appendChild(props.bodyElement);\n\n return () => {\n node.removeChild(props.bodyElement);\n };\n }, [bodyRef, props.bodyElement]);\n\n if (!isControlled && props.isCollapsed !== isCollapsed) {\n setIsCollapsed(props.isCollapsed);\n }\n\n return (\n <div\n className={cx(props.cssClasses.root, {\n [props.cssClasses.noRefinementRoot]: props.hidden,\n [props.cssClasses.collapsibleRoot]: props.collapsible,\n [props.cssClasses.collapsedRoot]: isCollapsed,\n })}\n hidden={props.hidden}\n >\n {props.templates.header && (\n <div className={props.cssClasses.header}>\n <Template\n templates={props.templates}\n templateKey=\"header\"\n rootTagName=\"span\"\n data={props.data}\n />\n\n {props.collapsible && (\n <button\n className={props.cssClasses.collapseButton}\n aria-expanded={!isCollapsed}\n onClick={(event) => {\n event.preventDefault();\n\n setIsControlled(true);\n setIsCollapsed((prevIsCollapsed) => !prevIsCollapsed);\n }}\n >\n <Template\n templates={props.templates}\n templateKey=\"collapseButtonText\"\n rootTagName=\"span\"\n data={{ collapsed: isCollapsed }}\n />\n </button>\n )}\n </div>\n )}\n\n <div className={props.cssClasses.body} ref={bodyRef} />\n\n {props.templates.footer && (\n <Template\n templates={props.templates}\n templateKey=\"footer\"\n rootProps={{\n className: props.cssClasses.footer,\n }}\n data={props.data}\n />\n )}\n </div>\n );\n}\n\nexport default Panel;\n","/** @jsx h */\n\nimport { h } from 'preact';\nimport type { ComponentCSSClasses } from '../../types';\nimport type { PoweredByCSSClasses } from '../../widgets/powered-by/powered-by';\n\nexport type PoweredByComponentCSSClasses =\n ComponentCSSClasses<PoweredByCSSClasses>;\n\nexport type PoweredByProps = {\n url: string;\n theme: string;\n cssClasses: PoweredByComponentCSSClasses;\n};\n\nconst PoweredBy = ({ url, theme, cssClasses }: PoweredByProps) => (\n <div className={cssClasses.root}>\n <a\n href={url}\n target=\"_blank\"\n className={cssClasses.link}\n aria-label=\"Search by Algolia\"\n rel=\"noopener noreferrer\"\n >\n <svg\n height=\"1.2em\"\n className={cssClasses.logo}\n viewBox=\"0 0 168 24\"\n // This style is necessary as long as it's not included in InstantSearch.css.\n // For now, InstantSearch.css sets a maximum width of 70px.\n style={{\n width: 'auto',\n }}\n >\n <path\n fill={theme === 'dark' ? '#FFF' : '#5D6494'}\n d=\"M6.97 6.68V8.3a4.47 4.47 0 00-2.42-.67 2.2 2.2 0 00-1.38.4c-.34.26-.5.6-.5 1.02 0 .43.16.77.49 1.03.33.25.83.53 1.51.83a7.04 7.04 0 011.9 1.08c.34.24.58.54.73.89.15.34.23.74.23 1.18 0 .95-.33 1.7-1 2.24a4 4 0 01-2.6.81 5.71 5.71 0 01-2.94-.68v-1.71c.84.63 1.81.94 2.92.94.58 0 1.05-.14 1.39-.4.34-.28.5-.65.5-1.13 0-.29-.1-.55-.3-.8a2.2 2.2 0 00-.65-.53 23.03 23.03 0 00-1.64-.78 13.67 13.67 0 01-1.11-.64c-.12-.1-.28-.22-.46-.4a1.72 1.72 0 01-.39-.5 4.46 4.46 0 01-.22-.6c-.07-.23-.1-.48-.1-.75 0-.91.33-1.63 1-2.17a4 4 0 012.57-.8c.97 0 1.8.18 2.47.52zm7.47 5.7v-.3a2.26 2.26 0 00-.5-1.44c-.3-.35-.74-.53-1.32-.53-.53 0-.99.2-1.37.58a2.9 2.9 0 00-.72 1.68h3.91zm1 2.79v1.4c-.6.34-1.38.51-2.36.51a4.02 4.02 0 01-3-1.13 4.04 4.04 0 01-1.11-2.97c0-1.3.34-2.32 1.02-3.06a3.38 3.38 0 012.6-1.1c1.03 0 1.85.32 2.46.96.6.64.9 1.57.9 2.78 0 .33-.03.68-.09 1.04h-5.31c.1.7.4 1.24.89 1.61.49.38 1.1.56 1.85.56.86 0 1.58-.2 2.15-.6zm6.61-1.78h-1.21c-.6 0-1.05.12-1.35.36-.3.23-.46.53-.46.89 0 .37.12.66.36.88.23.2.57.32 1.02.32.5 0 .9-.15 1.2-.43.3-.28.44-.65.44-1.1v-.92zm-4.07-2.55V9.33a4.96 4.96 0 012.5-.55c2.1 0 3.17 1.03 3.17 3.08V17H22.1v-.96c-.42.68-1.15 1.02-2.19 1.02-.76 0-1.38-.22-1.84-.66-.46-.44-.7-1-.7-1.68 0-.78.3-1.38.88-1.81.59-.43 1.4-.65 2.46-.65h1.34v-.46c0-.55-.13-.97-.4-1.25-.26-.29-.7-.43-1.32-.43-.86 0-1.65.24-2.35.72zm9.34-1.93v1.42c.39-1 1.1-1.5 2.12-1.5.15 0 .31.02.5.05v1.53c-.23-.1-.48-.14-.76-.14-.54 0-.99.24-1.34.71a2.8 2.8 0 00-.52 1.71V17h-1.57V8.91h1.57zm5 4.09a3 3 0 00.76 2.01c.47.53 1.14.8 2 .8.64 0 1.24-.18 1.8-.53v1.4c-.53.32-1.2.48-2 .48a3.98 3.98 0 01-4.17-4.18c0-1.16.38-2.15 1.14-2.98a4 4 0 013.1-1.23c.7 0 1.34.15 1.92.44v1.44a3.24 3.24 0 00-1.77-.5A2.65 2.65 0 0032.33 13zm7.92-7.28v4.58c.46-1 1.3-1.5 2.5-1.5.8 0 1.42.24 1.9.73.48.5.72 1.17.72 2.05V17H43.8v-5.1c0-.56-.14-.99-.43-1.29-.28-.3-.65-.45-1.1-.45-.54 0-1 .2-1.42.6-.4.4-.61 1.02-.61 1.85V17h-1.56V5.72h1.56zM55.2 15.74c.6 0 1.1-.25 1.5-.76.4-.5.6-1.16.6-1.95 0-.92-.2-1.62-.6-2.12-.4-.5-.92-.74-1.55-.74-.56 0-1.05.22-1.5.67-.44.45-.66 1.13-.66 2.06 0 .96.22 1.67.64 2.14.43.47.95.7 1.57.7zM53 5.72v4.42a2.74 2.74 0 012.43-1.34c1.03 0 1.86.38 2.51 1.15.65.76.97 1.78.97 3.05 0 1.13-.3 2.1-.92 2.9-.62.81-1.47 1.21-2.54 1.21s-1.9-.45-2.46-1.34V17h-1.58V5.72H53zm9.9 11.1l-3.22-7.9h1.74l1 2.62 1.26 3.42c.1-.32.48-1.46 1.15-3.42l.91-2.63h1.66l-2.92 7.87c-.78 2.07-1.96 3.1-3.56 3.1-.28 0-.53-.02-.73-.07v-1.34c.17.04.35.06.54.06 1.03 0 1.76-.57 2.17-1.7z\"\n />\n <path\n fill=\"#5468FF\"\n d=\"M78.99.94h16.6a2.97 2.97 0 012.96 2.96v16.6a2.97 2.97 0 01-2.97 2.96h-16.6a2.97 2.97 0 01-2.96-2.96V3.9A2.96 2.96 0 0179 .94\"\n />\n <path\n fill=\"#FFF\"\n d=\"M89.63 5.97v-.78a.98.98 0 00-.98-.97h-2.28a.98.98 0 00-.97.97V6c0 .09.08.15.17.13a7.13 7.13 0 013.9-.02c.08.02.16-.04.16-.13m-6.25 1L83 6.6a.98.98 0 00-1.38 0l-.46.46a.97.97 0 000 1.38l.38.39c.06.06.15.04.2-.02a7.49 7.49 0 011.63-1.62c.07-.04.08-.14.02-.2m4.16 2.45v3.34c0 .1.1.17.2.12l2.97-1.54c.06-.03.08-.12.05-.18a3.7 3.7 0 00-3.08-1.87c-.07 0-.14.06-.14.13m0 8.05a4.49 4.49 0 110-8.98 4.49 4.49 0 010 8.98m0-10.85a6.37 6.37 0 100 12.74 6.37 6.37 0 000-12.74\"\n />\n <path\n fill={theme === 'dark' ? '#FFF' : '#5468FF'}\n d=\"M120.92 18.8c-4.38.02-4.38-3.54-4.38-4.1V1.36l2.67-.42v13.25c0 .32 0 2.36 1.71 2.37v2.24zm-10.84-2.18c.82 0 1.43-.04 1.85-.12v-2.72a5.48 5.48 0 00-1.57-.2c-.3 0-.6.02-.9.07-.3.04-.57.12-.81.24-.24.11-.44.28-.58.49a.93.93 0 00-.22.65c0 .63.22 1 .61 1.23.4.24.94.36 1.62.36zm-.23-9.7c.88 0 1.62.11 2.23.33.6.22 1.09.53 1.44.92.36.4.61.92.76 1.48.16.56.23 1.17.23 1.85v6.87a21.69 21.69 0 01-4.68.5c-.69 0-1.32-.07-1.9-.2a4 4 0 01-1.46-.63 3.3 3.3 0 01-.96-1.13 4.3 4.3 0 01-.34-1.8 3.13 3.13 0 011.43-2.63c.45-.3.95-.5 1.54-.62a8.8 8.8 0 013.79.05v-.44c0-.3-.04-.6-.11-.87a1.78 1.78 0 00-1.1-1.22 3.2 3.2 0 00-1.15-.2 9.75 9.75 0 00-2.95.46l-.33-2.19a11.43 11.43 0 013.56-.53zm52.84 9.63c.82 0 1.43-.05 1.85-.13V13.7a5.42 5.42 0 00-1.57-.2c-.3 0-.6.02-.9.07-.3.04-.57.12-.81.24-.24.12-.44.28-.58.5a.93.93 0 00-.22.65c0 .63.22.99.61 1.23.4.24.94.36 1.62.36zm-.23-9.7c.88 0 1.63.11 2.23.33.6.22 1.1.53 1.45.92.35.39.6.92.76 1.48.15.56.23 1.18.23 1.85v6.88c-.41.08-1.03.19-1.87.31-.83.12-1.77.18-2.81.18-.7 0-1.33-.06-1.9-.2a4 4 0 01-1.47-.63c-.4-.3-.72-.67-.95-1.13a4.3 4.3 0 01-.34-1.8c0-.66.13-1.08.38-1.53.26-.45.61-.82 1.05-1.1.44-.3.95-.5 1.53-.62a8.8 8.8 0 013.8.05v-.43c0-.31-.04-.6-.12-.88-.07-.28-.2-.52-.38-.73a1.78 1.78 0 00-.73-.5c-.3-.1-.68-.2-1.14-.2a9.85 9.85 0 00-2.95.47l-.32-2.19a11.63 11.63 0 013.55-.53zm-8.03-1.27a1.62 1.62 0 000-3.24 1.62 1.62 0 100 3.24zm1.35 13.22h-2.7V7.27l2.7-.42V18.8zm-4.72 0c-4.38.02-4.38-3.54-4.38-4.1l-.01-13.34 2.67-.42v13.25c0 .32 0 2.36 1.72 2.37v2.24zm-8.7-5.9a4.7 4.7 0 00-.74-2.79 2.4 2.4 0 00-2.07-1 2.4 2.4 0 00-2.06 1 4.7 4.7 0 00-.74 2.8c0 1.16.25 1.94.74 2.62a2.4 2.4 0 002.07 1.02c.88 0 1.57-.34 2.07-1.02a4.2 4.2 0 00.73-2.63zm2.74 0a6.46 6.46 0 01-1.52 4.23c-.49.53-1.07.94-1.76 1.22-.68.29-1.73.45-2.26.45a6.6 6.6 0 01-2.25-.45 5.1 5.1 0 01-2.88-3.13 7.3 7.3 0 01-.01-4.84 5.13 5.13 0 012.9-3.1 5.67 5.67 0 012.22-.42c.81 0 1.56.14 2.24.42.69.29 1.28.69 1.75 1.22.49.52.87 1.15 1.14 1.89a7 7 0 01.43 2.5zm-20.14 0c0 1.11.25 2.36.74 2.88.5.52 1.13.78 1.91.78a4.07 4.07 0 002.12-.6V9.33c-.19-.04-.99-.2-1.76-.23a2.67 2.67 0 00-2.23 1 4.73 4.73 0 00-.78 2.8zm7.44 5.27c0 1.82-.46 3.16-1.4 4-.94.85-2.37 1.27-4.3 1.27-.7 0-2.17-.13-3.34-.4l.43-2.11c.98.2 2.27.26 2.95.26 1.08 0 1.84-.22 2.3-.66.46-.43.68-1.08.68-1.94v-.44a5.2 5.2 0 01-2.54.6 5.6 5.6 0 01-2.01-.36 4.2 4.2 0 01-2.58-2.71 9.88 9.88 0 01.02-5.35 4.92 4.92 0 012.93-2.96 6.6 6.6 0 012.43-.46 19.64 19.64 0 014.43.66v10.6z\"\n />\n </svg>\n </a>\n </div>\n);\n\nexport default PoweredBy;\n","/** @jsx h */\n\nimport { h } from 'preact';\nimport type { ComponentCSSClasses } from '../../types';\nimport type {\n QueryRuleCustomDataCSSClasses,\n QueryRuleCustomDataTemplates,\n} from '../../widgets/query-rule-custom-data/query-rule-custom-data';\nimport Template from '../Template/Template';\n\nexport type QueryRuleCustomDataComponentCSSClasses =\n ComponentCSSClasses<QueryRuleCustomDataCSSClasses>;\n\nexport type QueryRuleCustomDataComponentTemplates =\n Required<QueryRuleCustomDataTemplates>;\n\nexport type QueryRuleCustomDataProps = {\n cssClasses: QueryRuleCustomDataComponentCSSClasses;\n templates: QueryRuleCustomDataComponentTemplates;\n items: any[];\n};\n\nconst QueryRuleCustomData = ({\n cssClasses,\n templates,\n items,\n}: QueryRuleCustomDataProps) => (\n <Template\n templateKey=\"default\"\n templates={templates}\n rootProps={{ className: cssClasses.root }}\n data={{ items }}\n />\n);\n\nexport default QueryRuleCustomData;\n","/** @jsx h */\n\nimport { h, render } from 'preact';\nimport cx from 'classnames';\nimport {\n createDocumentationMessageGenerator,\n getContainerNode,\n getObjectType,\n warning,\n} from '../../lib/utils';\nimport { component } from '../../lib/suit';\nimport type { PanelComponentCSSClasses } from '../../components/Panel/Panel';\nimport Panel from '../../components/Panel/Panel';\nimport type {\n Template,\n RenderOptions,\n WidgetFactory,\n InitOptions,\n Widget,\n} from '../../types';\n\nexport type PanelCSSClasses = Partial<{\n /**\n * CSS classes to add to the root element of the widget.\n */\n root: string | string[];\n\n /**\n * CSS classes to add to the root element of the widget when there's no refinements.\n */\n noRefinementRoot: string | string[];\n\n /**\n * CSS classes to add to the root element when collapsible (`collapse` is defined).\n */\n collapsibleRoot: string | string[];\n\n /**\n * CSS classes to add to the root element when collapsed.\n */\n collapsedRoot: string | string[];\n\n /**\n * CSS classes to add to the collapse button element.\n */\n collapseButton: string | string[];\n\n /**\n * CSS classes to add to the collapse icon of the button.\n */\n collapseIcon: string | string[];\n\n /**\n * CSS classes to add to the header.\n */\n header: string | string[];\n\n /**\n * CSS classes to add to the body.\n */\n body: string | string[];\n\n /**\n * CSS classes to add to the footer.\n */\n footer: string | string[];\n}>;\n\ntype AnyWidgetFactory = WidgetFactory<\n {\n $$type: string;\n },\n Record<string, any>,\n // @TODO: this really should be _at least_ { container: string | HTMLElement }\n // but that or { container: string | HTMLElement; [key: string]: any }\n // still doesn't allow wider types with another key required.\n any\n>;\n\nexport type PanelTemplates<TWidget extends AnyWidgetFactory> = Partial<{\n /**\n * Template to use for the header.\n */\n header: Template<PanelRenderOptions<TWidget>>;\n\n /**\n * Template to use for the footer.\n */\n footer: Template<PanelRenderOptions<TWidget>>;\n\n /**\n * Template to use for collapse button.\n */\n collapseButtonText: Template<{ collapsed: boolean }>;\n}>;\n\ntype GetWidgetRenderState<TWidgetFactory extends AnyWidgetFactory> =\n ReturnType<TWidgetFactory>['getWidgetRenderState'] extends (\n renderOptions: any\n ) => infer TRenderState\n ? TRenderState extends Record<string, unknown>\n ? TRenderState\n : never\n : Record<string, unknown>;\n\nexport type PanelRenderOptions<TWidgetFactory extends AnyWidgetFactory> =\n RenderOptions & GetWidgetRenderState<TWidgetFactory>;\n\nexport type PanelSharedOptions<TWidgetFactory extends AnyWidgetFactory> = (\n | InitOptions\n | RenderOptions\n) &\n GetWidgetRenderState<TWidgetFactory>;\n\nexport type PanelWidgetParams<TWidgetFactory extends AnyWidgetFactory> = {\n /**\n * A function that is called on each render to determine if the\n * panel should be hidden based on the render options.\n */\n hidden?(options: PanelRenderOptions<TWidgetFactory>): boolean;\n\n /**\n * A function that is called on each render to determine if the\n * panel should be collapsed based on the render options.\n */\n collapsed?(options: PanelRenderOptions<TWidgetFactory>): boolean;\n\n /**\n * The templates to use for the widget.\n */\n templates?: PanelTemplates<TWidgetFactory>;\n\n /**\n * The CSS classes to override.\n */\n cssClasses?: PanelCSSClasses;\n};\n\nconst withUsage = createDocumentationMessageGenerator({ name: 'panel' });\nconst suit = component('Panel');\n\nconst renderer =\n <TWidget extends AnyWidgetFactory>({\n containerNode,\n bodyContainerNode,\n cssClasses,\n templates,\n }: {\n containerNode: HTMLElement;\n bodyContainerNode: HTMLElement;\n cssClasses: PanelComponentCSSClasses;\n templates: Required<PanelTemplates<TWidget>>;\n }) =>\n ({\n options,\n hidden,\n collapsible,\n collapsed,\n }: {\n options: PanelSharedOptions<TWidget>;\n hidden: boolean;\n collapsible: boolean;\n collapsed: boolean;\n }) => {\n render(\n <Panel<TWidget>\n cssClasses={cssClasses}\n hidden={hidden}\n collapsible={collapsible}\n isCollapsed={collapsed}\n templates={templates}\n data={options}\n bodyElement={bodyContainerNode}\n />,\n containerNode\n );\n };\n\ntype AugmentedWidget<\n TWidgetFactory extends AnyWidgetFactory,\n TOverriddenKeys extends keyof Widget = 'init' | 'render' | 'dispose'\n> = Omit<ReturnType<TWidgetFactory>, TOverriddenKeys> &\n Pick<Required<Widget>, TOverriddenKeys>;\n\nexport type PanelWidget = <TWidgetFactory extends AnyWidgetFactory>(\n panelWidgetParams?: PanelWidgetParams<TWidgetFactory>\n) => (\n widgetFactory: TWidgetFactory\n) => (\n widgetParams: Parameters<TWidgetFactory>[0]\n) => AugmentedWidget<TWidgetFactory>;\n\n/**\n * The panel widget wraps other widgets in a consistent panel design.\n * It also reacts, indicates and sets CSS classes when widgets are no longer relevant for refining.\n */\nconst panel: PanelWidget = (panelWidgetParams) => {\n const {\n templates = {},\n hidden = () => false,\n collapsed,\n cssClasses: userCssClasses = {},\n } = panelWidgetParams || {};\n\n warning(\n typeof hidden === 'function',\n `The \\`hidden\\` option in the \"panel\" widget expects a function returning a boolean (received type ${getObjectType(\n hidden\n )}).`\n );\n\n warning(\n typeof collapsed === 'undefined' || typeof collapsed === 'function',\n `The \\`collapsed\\` option in the \"panel\" widget expects a function returning a boolean (received type ${getObjectType(\n collapsed\n )}).`\n );\n\n const bodyContainerNode = document.createElement('div');\n const collapsible = Boolean(collapsed);\n const collapsedFn = typeof collapsed === 'function' ? collapsed : () => false;\n const cssClasses = {\n root: cx(suit(), userCssClasses.root),\n noRefinementRoot: cx(\n suit({ modifierName: 'noRefinement' }),\n userCssClasses.noRefinementRoot\n ),\n collapsibleRoot: cx(\n suit({ modifierName: 'collapsible' }),\n userCssClasses.collapsibleRoot\n ),\n collapsedRoot: cx(\n suit({ modifierName: 'collapsed' }),\n userCssClasses.collapsedRoot\n ),\n collapseButton: cx(\n suit({ descendantName: 'collapseButton' }),\n userCssClasses.collapseButton\n ),\n collapseIcon: cx(\n suit({ descendantName: 'collapseIcon' }),\n userCssClasses.collapseIcon\n ),\n body: cx(suit({ descendantName: 'body' }), userCssClasses.body),\n header: cx(suit({ descendantName: 'header' }), userCssClasses.header),\n footer: cx(suit({ descendantName: 'footer' }), userCssClasses.footer),\n };\n\n return (widgetFactory) => (widgetParams) => {\n if (!(widgetParams && widgetParams.container)) {\n throw new Error(\n withUsage(\n `The \\`container\\` option is required in the widget within the panel.`\n )\n );\n }\n\n const containerNode = getContainerNode(widgetParams.container);\n\n const defaultTemplates: Required<PanelTemplates<typeof widgetFactory>> = {\n header: '',\n footer: '',\n collapseButtonText: ({ collapsed: isCollapsed }) =>\n `<svg\n class=\"${cssClasses.collapseIcon}\"\n width=\"1em\"\n height=\"1em\"\n viewBox=\"0 0 500 500\"\n >\n <path d=\"${\n isCollapsed ? 'M100 250l300-150v300z' : 'M250 400l150-300H100z'\n }\" fill=\"currentColor\" />\n </svg>`,\n };\n\n const renderPanel = renderer<typeof widgetFactory>({\n containerNode,\n bodyContainerNode,\n cssClasses,\n templates: {\n ...defaultTemplates,\n ...templates,\n },\n });\n\n const widget = widgetFactory({\n ...widgetParams,\n container: bodyContainerNode,\n });\n\n // TypeScript somehow loses track of the ...widget type, since it's\n // not directly returned. Eventually the \"as AugmentedWidget<typeof widgetFactory>\"\n // will not be needed anymore.\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n return {\n ...widget,\n init(...args) {\n const [renderOptions] = args;\n\n const options = {\n ...(widget.getWidgetRenderState\n ? widget.getWidgetRenderState(renderOptions)\n : {}),\n ...renderOptions,\n };\n\n renderPanel({\n options,\n hidden: true,\n collapsible,\n collapsed: false,\n });\n\n if (typeof widget.init === 'function') {\n widget.init.call(this, ...args);\n }\n },\n render(...args) {\n const [renderOptions] = args;\n\n const options = {\n ...((widget.getWidgetRenderState\n ? widget.getWidgetRenderState(renderOptions)\n : {}) as GetWidgetRenderState<typeof widgetFactory>),\n ...renderOptions,\n };\n\n renderPanel({\n options,\n hidden: Boolean(hidden(options)),\n collapsible,\n collapsed: Boolean(collapsedFn(options)),\n });\n\n if (typeof widget.render === 'function') {\n widget.render.call(this, ...args);\n }\n },\n dispose(...args) {\n render(null, containerNode);\n\n if (typeof widget.dispose === 'function') {\n return widget.dispose.call(this, ...args);\n }\n\n return undefined;\n },\n } as AugmentedWidget<typeof widgetFactory>;\n };\n};\n\nexport default panel;\n","/** @jsx h */\n\nimport { h, render } from 'preact';\nimport cx from 'classnames';\nimport type { PoweredByComponentCSSClasses } from '../../components/PoweredBy/PoweredBy';\nimport PoweredBy from '../../components/PoweredBy/PoweredBy';\nimport type {\n PoweredByConnectorParams,\n PoweredByRenderState,\n PoweredByWidgetDescription,\n} from '../../connectors/powered-by/connectPoweredBy';\nimport connectPoweredBy from '../../connectors/powered-by/connectPoweredBy';\nimport {\n getContainerNode,\n createDocumentationMessageGenerator,\n} from '../../lib/utils';\nimport { component } from '../../lib/suit';\nimport type { Renderer, WidgetFactory } from '../../types';\n\nconst suit = component('PoweredBy');\nconst withUsage = createDocumentationMessageGenerator({ name: 'powered-by' });\n\nconst renderer =\n ({\n containerNode,\n cssClasses,\n }: {\n containerNode: HTMLElement;\n cssClasses: PoweredByComponentCSSClasses;\n }): Renderer<PoweredByRenderState, Partial<PoweredByWidgetParams>> =>\n ({ url, widgetParams }, isFirstRendering) => {\n if (isFirstRendering) {\n const { theme = 'light' } = widgetParams;\n\n render(\n <PoweredBy cssClasses={cssClasses} url={url} theme={theme} />,\n containerNode\n );\n\n return;\n }\n };\n\nexport type PoweredByCSSClasses = Partial<{\n /**\n * CSS class to add to the wrapping element.\n */\n root: string | string[];\n\n /**\n * CSS class to add to the link.\n */\n link: string | string[];\n\n /**\n * CSS class to add to the SVG logo.\n */\n logo: string | string[];\n}>;\n\nexport type PoweredByWidgetParams = {\n /**\n * CSS Selector or HTMLElement to insert the widget.\n */\n container: string | HTMLElement;\n\n /**\n * The theme of the logo.\n * @default 'light'\n */\n theme?: 'light' | 'dark';\n\n /**\n * CSS classes to add.\n */\n cssClasses?: PoweredByCSSClasses;\n};\n\nexport type PoweredByWidget = WidgetFactory<\n PoweredByWidgetDescription & { $$widgetType: 'ais.poweredBy' },\n PoweredByConnectorParams,\n PoweredByWidgetParams\n>;\n\nconst poweredBy: PoweredByWidget = function poweredBy(widgetParams) {\n const {\n container,\n cssClasses: userCssClasses = {},\n theme = 'light',\n } = widgetParams || {};\n\n if (!container) {\n throw new Error(withUsage('The `container` option is required.'));\n }\n\n const containerNode = getContainerNode(container);\n\n const cssClasses = {\n root: cx(\n suit(),\n suit({ modifierName: theme === 'dark' ? 'dark' : 'light' }),\n userCssClasses.root\n ),\n link: cx(suit({ descendantName: 'link' }), userCssClasses.link),\n logo: cx(suit({ descendantName: 'logo' }), userCssClasses.logo),\n };\n\n const specializedRenderer = renderer({\n containerNode,\n cssClasses,\n });\n\n const makeWidget = connectPoweredBy(specializedRenderer, () =>\n render(null, containerNode)\n );\n\n return {\n ...makeWidget({ theme }),\n $$widgetType: 'ais.poweredBy',\n };\n};\n\nexport default poweredBy;\n","import type { WidgetFactory } from '../../types';\nimport { createDocumentationMessageGenerator, noop } from '../../lib/utils';\nimport type {\n ParamTrackedFilters,\n ParamTransformRuleContexts,\n QueryRulesConnectorParams,\n QueryRulesWidgetDescription,\n} from '../../connectors/query-rules/connectQueryRules';\nimport connectQueryRules from '../../connectors/query-rules/connectQueryRules';\n\nexport type QueryRuleContextWidgetParams = {\n trackedFilters: ParamTrackedFilters;\n transformRuleContexts?: ParamTransformRuleContexts;\n};\n\nexport type QueryRuleContextWidget = WidgetFactory<\n QueryRulesWidgetDescription & { $$widgetType: 'ais.queryRuleContext' },\n QueryRulesConnectorParams,\n QueryRuleContextWidgetParams\n>;\n\nconst withUsage = createDocumentationMessageGenerator({\n name: 'query-rule-context',\n});\n\nconst queryRuleContext: QueryRuleContextWidget = (\n widgetParams = {} as QueryRuleContextWidgetParams\n) => {\n if (!widgetParams.trackedFilters) {\n throw new Error(withUsage('The `trackedFilters` option is required.'));\n }\n\n return {\n ...connectQueryRules<QueryRuleContextWidgetParams>(noop)(widgetParams),\n $$widgetType: 'ais.queryRuleContext',\n };\n};\n\nexport default queryRuleContext;\n","/** @jsx h */\n\nimport { h, render } from 'preact';\nimport cx from 'classnames';\nimport {\n getContainerNode,\n createDocumentationMessageGenerator,\n} from '../../lib/utils';\nimport { component } from '../../lib/suit';\nimport type { WidgetFactory, Template } from '../../types';\nimport type {\n QueryRulesConnectorParams,\n QueryRulesRenderState,\n QueryRulesWidgetDescription,\n} from '../../connectors/query-rules/connectQueryRules';\nimport connectQueryRules from '../../connectors/query-rules/connectQueryRules';\nimport type {\n QueryRuleCustomDataComponentCSSClasses,\n QueryRuleCustomDataComponentTemplates,\n} from '../../components/QueryRuleCustomData/QueryRuleCustomData';\nimport CustomData from '../../components/QueryRuleCustomData/QueryRuleCustomData';\nimport type { PreparedTemplateProps } from '../../lib/utils/prepareTemplateProps';\n\nexport type QueryRuleCustomDataCSSClasses = Partial<{\n root: string | string[];\n}>;\n\nexport type QueryRuleCustomDataTemplates = Partial<{\n default: Template<{ items: any[] }>;\n}>;\n\nexport type QueryRuleCustomDataWidgetParams = {\n container: string | HTMLElement;\n cssClasses?: QueryRuleCustomDataCSSClasses;\n templates?: QueryRuleCustomDataTemplates;\n};\n\nexport type QueryRuleCustomDataWidget = WidgetFactory<\n QueryRulesWidgetDescription & { $$widgetType: 'ais.queryRuleCustomData' },\n QueryRulesConnectorParams,\n QueryRuleCustomDataWidgetParams\n>;\n\nexport const defaultTemplates: QueryRuleCustomDataComponentTemplates = {\n default: ({ items }) => JSON.stringify(items, null, 2),\n};\n\nconst withUsage = createDocumentationMessageGenerator({\n name: 'query-rule-custom-data',\n});\n\nconst suit = component('QueryRuleCustomData');\n\nconst renderer =\n ({\n containerNode,\n cssClasses,\n templates,\n }: {\n containerNode: HTMLElement;\n cssClasses: QueryRuleCustomDataComponentCSSClasses;\n renderState: {\n templateProps?: PreparedTemplateProps<QueryRuleCustomDataComponentTemplates>;\n };\n templates: QueryRuleCustomDataComponentTemplates;\n }) =>\n ({ items }: QueryRulesRenderState) => {\n render(\n <CustomData\n cssClasses={cssClasses}\n templates={templates}\n items={items}\n />,\n containerNode\n );\n };\n\nconst queryRuleCustomData: QueryRuleCustomDataWidget = (widgetParams) => {\n const {\n container,\n cssClasses: userCssClasses = {},\n templates: userTemplates = {},\n transformItems = ((items) =>\n items) as QueryRulesConnectorParams['transformItems'],\n } = widgetParams || {};\n\n if (!container) {\n throw new Error(withUsage('The `container` option is required.'));\n }\n\n const cssClasses = {\n root: cx(suit(), userCssClasses.root),\n };\n\n const containerNode = getContainerNode(container);\n const templates = {\n ...defaultTemplates,\n ...userTemplates,\n };\n\n const specializedRenderer = renderer({\n containerNode,\n cssClasses,\n renderState: {},\n templates,\n });\n\n const makeWidget = connectQueryRules(specializedRenderer, () => {\n render(null, containerNode);\n });\n\n return {\n ...makeWidget({\n transformItems,\n }),\n $$widgetType: 'ais.queryRuleCustomData',\n };\n};\n\nexport default queryRuleCustomData;\n","/** @jsx h */\n\nimport { h, Component } from 'preact';\nimport cx from 'classnames';\nimport Template from '../Template/Template';\nimport type {\n RangeInputCSSClasses,\n RangeInputTemplates,\n} from '../../widgets/range-input/range-input';\nimport type {\n Range,\n RangeBoundaries,\n} from '../../connectors/range/connectRange';\nimport type { ComponentCSSClasses } from '../../types';\n\nexport type RangeInputComponentCSSClasses =\n ComponentCSSClasses<RangeInputCSSClasses>;\n\nexport type RangeInputComponentTemplates = Required<RangeInputTemplates>;\n\nexport type RangeInputProps = {\n min?: number;\n max?: number;\n step: number;\n values: Partial<Range>;\n cssClasses: RangeInputComponentCSSClasses;\n templateProps: {\n templates: RangeInputComponentTemplates;\n };\n refine(rangeValue: RangeBoundaries): void;\n};\n\nclass RangeInput extends Component<RangeInputProps, Partial<Range>> {\n public state = {\n min: this.props.values.min,\n max: this.props.values.max,\n };\n\n public componentWillReceiveProps(nextProps: RangeInputProps) {\n this.setState({\n min: nextProps.values.min,\n max: nextProps.values.max,\n });\n }\n\n private onInput = (key: string) => (event: Event) => {\n const { value } = event.currentTarget as HTMLInputElement;\n\n this.setState({\n [key]: Number(value),\n });\n };\n\n private onSubmit = (event: Event) => {\n event.preventDefault();\n\n this.props.refine([this.state.min, this.state.max]);\n };\n\n public render() {\n const { min: minValue, max: maxValue } = this.state;\n const { min, max, step, cssClasses, templateProps } = this.props;\n const isDisabled = min && max ? min >= max : false;\n const hasRefinements = Boolean(minValue || maxValue);\n const rootClassNames = cx(cssClasses.root, {\n [cssClasses.noRefinement]: !hasRefinements,\n });\n\n return (\n <div className={rootClassNames}>\n <form className={cssClasses.form} onSubmit={this.onSubmit}>\n <label className={cssClasses.label}>\n <input\n className={cx(cssClasses.input, cssClasses.inputMin)}\n type=\"number\"\n min={min}\n max={max}\n step={step}\n value={minValue ?? ''}\n onInput={this.onInput('min')}\n placeholder={min?.toString()}\n disabled={isDisabled}\n />\n </label>\n\n <Template\n {...templateProps}\n templateKey=\"separatorText\"\n rootTagName=\"span\"\n rootProps={{\n className: cssClasses.separator,\n }}\n />\n\n <label className={cssClasses.label}>\n <input\n className={cx(cssClasses.input, cssClasses.inputMax)}\n type=\"number\"\n min={min}\n max={max}\n step={step}\n value={maxValue ?? ''}\n onInput={this.onInput('max')}\n placeholder={max?.toString()}\n disabled={isDisabled}\n />\n </label>\n\n <Template\n {...templateProps}\n templateKey=\"submitText\"\n rootTagName=\"button\"\n rootProps={{\n type: 'submit',\n className: cssClasses.submit,\n disabled: isDisabled,\n }}\n />\n </form>\n </div>\n );\n }\n}\n\nexport default RangeInput;\n","/** @jsx h */\n\nimport { h, render } from 'preact';\nimport cx from 'classnames';\nimport type {\n RangeInputComponentCSSClasses,\n RangeInputComponentTemplates,\n} from '../../components/RangeInput/RangeInput';\nimport RangeInput from '../../components/RangeInput/RangeInput';\nimport type {\n RangeConnectorParams,\n RangeRenderState,\n RangeWidgetDescription,\n} from '../../connectors/range/connectRange';\nimport connectRange from '../../connectors/range/connectRange';\nimport {\n prepareTemplateProps,\n getContainerNode,\n createDocumentationMessageGenerator,\n} from '../../lib/utils';\nimport { component } from '../../lib/suit';\nimport type { Renderer, Template, WidgetFactory } from '../../types';\nimport type { PreparedTemplateProps } from '../../lib/utils/prepareTemplateProps';\n\nconst withUsage = createDocumentationMessageGenerator({ name: 'range-input' });\nconst suit = component('RangeInput');\n\nconst defaultTemplates: RangeInputComponentTemplates = {\n separatorText: 'to',\n submitText: 'Go',\n};\n\nexport type RangeInputTemplates = Partial<{\n /**\n * The label of the separator, between min and max.\n * @default \"to\"\n */\n separatorText: Template;\n /**\n * The label of the submit button\n * @default \"Go\"\n */\n submitText: Template;\n}>;\n\nexport type RangeInputCSSClasses = Partial<{\n /**\n * CSS class to add to the root element.\n */\n root: string | string[];\n /**\n * CSS class to add to the root element when there's no refinements.\n */\n noRefinement: string | string[];\n /**\n * CSS class to add to the form element.\n */\n form: string | string[];\n /**\n * CSS class to add to the label element.\n */\n label: string | string[];\n /**\n * CSS class to add to the input element.\n */\n input: string | string[];\n /**\n * CSS class to add to the min input element.\n */\n inputMin: string | string[];\n /**\n * CSS class to add to the max input element.\n */\n separator: string | string[];\n /**\n * CSS class to add to the separator of the form.\n */\n inputMax: string | string[];\n /**\n * CSS class to add to the submit button of the form.\n */\n submit: string | string[];\n}>;\n\nexport type RangeInputWidgetParams = {\n /**\n * Valid CSS Selector as a string or DOMElement.\n */\n container: string | HTMLElement;\n /**\n * Name of the attribute for faceting.\n */\n attribute: string;\n /**\n * Minimal slider value, default to automatically computed from the result set.\n */\n min?: number;\n /**\n * Maximal slider value, defaults to automatically computed from the result set.\n */\n max?: number;\n /**\n * Number of digits after decimal point to use.\n * @default 0\n */\n precision?: number;\n /**\n * Labels to use for the widget.\n */\n templates?: RangeInputTemplates;\n /**\n * CSS classes to add.\n */\n cssClasses?: RangeInputCSSClasses;\n};\n\nconst renderer =\n ({\n containerNode,\n cssClasses,\n renderState,\n templates,\n }: {\n containerNode: HTMLElement;\n cssClasses: RangeInputComponentCSSClasses;\n renderState: {\n templateProps?: PreparedTemplateProps<RangeInputComponentTemplates>;\n };\n templates: RangeInputTemplates;\n }): Renderer<RangeRenderState, Partial<RangeInputWidgetParams>> =>\n (\n { refine, range, start, widgetParams, instantSearchInstance },\n isFirstRendering\n ) => {\n if (isFirstRendering) {\n renderState.templateProps = prepareTemplateProps({\n defaultTemplates,\n templatesConfig: instantSearchInstance.templatesConfig,\n templates,\n });\n return;\n }\n\n const { min: rangeMin, max: rangeMax } = range;\n const [minValue, maxValue] = start;\n\n const step = 1 / Math.pow(10, widgetParams.precision || 0);\n\n const values = {\n min:\n minValue !== -Infinity && minValue !== rangeMin ? minValue : undefined,\n max:\n maxValue !== Infinity && maxValue !== rangeMax ? maxValue : undefined,\n };\n\n render(\n <RangeInput\n min={rangeMin}\n max={rangeMax}\n step={step}\n values={values}\n cssClasses={cssClasses}\n refine={refine}\n templateProps={renderState.templateProps!}\n />,\n containerNode\n );\n };\n\nexport type RangeInputWidget = WidgetFactory<\n Omit<RangeWidgetDescription, '$$type'> & {\n $$widgetType: 'ais.rangeInput';\n $$type: 'ais.rangeInput';\n },\n RangeConnectorParams,\n RangeInputWidgetParams\n>;\n\nconst rangeInput: RangeInputWidget = function rangeInput(widgetParams) {\n const {\n container,\n attribute,\n min,\n max,\n precision = 0,\n cssClasses: userCssClasses = {},\n templates = {},\n } = widgetParams || {};\n\n if (!container) {\n throw new Error(withUsage('The `container` option is required.'));\n }\n\n const containerNode = getContainerNode(container);\n\n const cssClasses = {\n root: cx(suit(), userCssClasses.root),\n noRefinement: cx(suit({ modifierName: 'noRefinement' })),\n form: cx(suit({ descendantName: 'form' }), userCssClasses.form),\n label: cx(suit({ descendantName: 'label' }), userCssClasses.label),\n input: cx(suit({ descendantName: 'input' }), userCssClasses.input),\n inputMin: cx(\n suit({ descendantName: 'input', modifierName: 'min' }),\n userCssClasses.inputMin\n ),\n inputMax: cx(\n suit({ descendantName: 'input', modifierName: 'max' }),\n userCssClasses.inputMax\n ),\n separator: cx(\n suit({ descendantName: 'separator' }),\n userCssClasses.separator\n ),\n submit: cx(suit({ descendantName: 'submit' }), userCssClasses.submit),\n };\n\n const specializedRenderer = renderer({\n containerNode,\n cssClasses,\n templates,\n renderState: {},\n });\n\n const makeWidget = connectRange(specializedRenderer, () =>\n render(null, containerNode)\n );\n\n return {\n ...makeWidget({\n attribute,\n min,\n max,\n precision,\n }),\n\n $$type: 'ais.rangeInput',\n $$widgetType: 'ais.rangeInput',\n };\n};\n\nexport default rangeInput;\n","/**\n * This is a fork of Rheostat for Preact X.\n *\n * @see https://github.com/airbnb/rheostat\n */\n\n/** @jsx h */\n\nimport type { ComponentChildren, ComponentType, JSX } from 'preact';\nimport { h, Component, createRef } from 'preact';\n\ntype BoundingBox = {\n height: number;\n left: number;\n top: number;\n width: number;\n};\n\nconst KEYS = {\n DOWN: 40,\n END: 35,\n ESC: 27,\n HOME: 36,\n LEFT: 37,\n PAGE_DOWN: 34,\n PAGE_UP: 33,\n RIGHT: 39,\n UP: 38,\n} as const;\nconst PERCENT_EMPTY = 0;\nconst PERCENT_FULL = 100;\n\nfunction getPosition(value: number, min: number, max: number) {\n return ((value - min) / (max - min)) * 100;\n}\n\nfunction getValue(pos: number, min: number, max: number) {\n const decimal = pos / 100;\n\n if (pos === 0) {\n return min;\n } else if (pos === 100) {\n return max;\n }\n\n return Math.round((max - min) * decimal + min);\n}\n\nfunction getClassName(props: Props) {\n const orientation =\n props.orientation === 'vertical'\n ? 'rheostat-vertical'\n : 'rheostat-horizontal';\n\n return ['rheostat', orientation]\n .concat(props.className!.split(' '))\n .join(' ');\n}\n\nfunction getHandleFor(ev: Event) {\n return Number(\n (ev.currentTarget as HTMLElement).getAttribute('data-handle-key')\n );\n}\n\nfunction killEvent(ev: Event) {\n ev.stopPropagation();\n ev.preventDefault();\n}\n\nfunction Button(props: JSX.IntrinsicElements['button']) {\n return <button {...props} type=\"button\" />;\n}\n\n// Preact doesn't have builtin types for Style, JSX.HTMLAttributes['style'] is just object\n// maybe migrate to csstype later?\ntype Style = {\n position?: 'absolute';\n top?: number | string;\n left?: number | string;\n height?: string;\n width?: string;\n};\n\nexport type PitProps = {\n children: number | string;\n style: Style;\n};\n\nexport type HandleProps = {\n 'aria-valuemax'?: number;\n 'aria-valuemin'?: number;\n 'aria-valuenow'?: number;\n 'aria-disabled': boolean;\n 'data-handle-key': number;\n className: 'rheostat-handle';\n key: string;\n onClick: (e: MouseEvent) => void;\n onKeyDown?: (e: KeyboardEvent) => void;\n onMouseDown?: (e: MouseEvent) => void;\n onTouchStart?: (e: TouchEvent) => void;\n role: 'slider';\n style: JSX.HTMLAttributes['style'];\n tabIndex: number;\n};\n\ntype Props = {\n children?: ComponentChildren;\n className?: string;\n disabled?: boolean;\n handle?: ComponentType<HandleProps>;\n max?: number;\n min?: number;\n onClick?(...args: unknown[]): unknown;\n onChange?(...args: unknown[]): unknown;\n onKeyPress?(...args: unknown[]): unknown;\n onSliderDragEnd?(...args: unknown[]): unknown;\n onSliderDragMove?(...args: unknown[]): unknown;\n onSliderDragStart?(...args: unknown[]): unknown;\n onValuesUpdated?(...args: unknown[]): unknown;\n orientation?: 'horizontal' | 'vertical';\n pitComponent?: ComponentType<PitProps>;\n pitPoints?: number[];\n progressBar?: ComponentType<JSX.HTMLAttributes>;\n snap?: boolean;\n snapPoints?: number[];\n values?: number[];\n};\n\ntype State = {\n className: string;\n handlePos: number[];\n handleDimensions: number;\n mousePos: { x: number; y: number } | null;\n sliderBox: Partial<BoundingBox>;\n slidingIndex: number | null;\n values: number[];\n};\n\nclass Rheostat extends Component<Props, State> {\n public static defaultProps = {\n className: '',\n children: null,\n disabled: false,\n handle: Button,\n max: PERCENT_FULL,\n min: PERCENT_EMPTY,\n onClick: null,\n onChange: null,\n onKeyPress: null,\n onSliderDragEnd: null,\n onSliderDragMove: null,\n onSliderDragStart: null,\n onValuesUpdated: null,\n orientation: 'horizontal',\n pitComponent: null,\n pitPoints: [],\n progressBar: 'div',\n snap: false,\n snapPoints: [],\n values: [PERCENT_EMPTY],\n };\n\n public state: State = {\n className: getClassName(this.props),\n // non-null thanks to defaultProps\n handlePos: this.props.values!.map((value) =>\n getPosition(value, this.props.min!, this.props.max!)\n ),\n handleDimensions: 0,\n mousePos: null,\n sliderBox: {},\n slidingIndex: null,\n // non-null thanks to defaultProps\n values: this.props.values!,\n };\n\n private rheostat = createRef<HTMLAnchorElement>();\n\n public constructor(props: Props) {\n super(props);\n\n this.getPublicState = this.getPublicState.bind(this);\n this.getSliderBoundingBox = this.getSliderBoundingBox.bind(this);\n this.getProgressStyle = this.getProgressStyle.bind(this);\n this.getMinValue = this.getMinValue.bind(this);\n this.getMaxValue = this.getMaxValue.bind(this);\n this.getHandleDimensions = this.getHandleDimensions.bind(this);\n this.getClosestSnapPoint = this.getClosestSnapPoint.bind(this);\n this.getSnapPosition = this.getSnapPosition.bind(this);\n this.getNextPositionForKey = this.getNextPositionForKey.bind(this);\n this.getNextState = this.getNextState.bind(this);\n this.handleClick = this.handleClick.bind(this);\n this.getClosestHandle = this.getClosestHandle.bind(this);\n this.setStartSlide = this.setStartSlide.bind(this);\n this.startMouseSlide = this.startMouseSlide.bind(this);\n this.startTouchSlide = this.startTouchSlide.bind(this);\n this.handleMouseSlide = this.handleMouseSlide.bind(this);\n this.handleTouchSlide = this.handleTouchSlide.bind(this);\n this.handleSlide = this.handleSlide.bind(this);\n this.endSlide = this.endSlide.bind(this);\n this.handleKeydown = this.handleKeydown.bind(this);\n this.validatePosition = this.validatePosition.bind(this);\n this.validateValues = this.validateValues.bind(this);\n this.canMove = this.canMove.bind(this);\n this.fireChangeEvent = this.fireChangeEvent.bind(this);\n this.slideTo = this.slideTo.bind(this);\n this.updateNewValues = this.updateNewValues.bind(this);\n }\n\n public componentWillReceiveProps(nextProps: Required<Props>) {\n const { className, disabled, min, max, orientation } = this.props;\n const { values, slidingIndex } = this.state;\n\n const minMaxChanged = nextProps.min !== min || nextProps.max !== max;\n\n const valuesChanged =\n values.length !== nextProps.values.length ||\n values.some((value, idx) => nextProps.values[idx] !== value);\n\n const orientationChanged =\n nextProps.className !== className ||\n nextProps.orientation !== orientation;\n\n const willBeDisabled = nextProps.disabled && !disabled;\n\n if (orientationChanged) {\n this.setState({\n className: getClassName(nextProps),\n });\n }\n\n if (minMaxChanged || valuesChanged) this.updateNewValues(nextProps);\n\n if (willBeDisabled && slidingIndex !== null) {\n this.endSlide();\n }\n }\n\n private getPublicState() {\n const { min, max } = this.props;\n const { values } = this.state;\n\n return { max, min, values };\n }\n\n private getSliderBoundingBox(): BoundingBox {\n // only gets called after render, so it will always be defined\n const node = this.rheostat.current!;\n const rect = node.getBoundingClientRect();\n\n return {\n height: rect.height || node.clientHeight,\n left: rect.left,\n top: rect.top,\n width: rect.width || node.clientWidth,\n };\n }\n\n private getProgressStyle(idx: number): Style {\n const { handlePos } = this.state;\n\n const value = handlePos[idx];\n\n if (idx === 0) {\n return this.props.orientation === 'vertical'\n ? { height: `${value}%`, top: 0 }\n : { left: 0, width: `${value}%` };\n }\n\n const prevValue = handlePos[idx - 1];\n const diffValue = value - prevValue;\n\n return this.props.orientation === 'vertical'\n ? { height: `${diffValue}%`, top: `${prevValue}%` }\n : { left: `${prevValue}%`, width: `${diffValue}%` };\n }\n\n private getMinValue(idx: number) {\n return this.state.values[idx - 1]\n ? Math.max(this.props.min!, this.state.values[idx - 1])\n : this.props.min;\n }\n\n private getMaxValue(idx: number) {\n return this.state.values[idx + 1]\n ? Math.min(this.props.max!, this.state.values[idx + 1])\n : this.props.max;\n }\n\n private getHandleDimensions(ev: Event, sliderBox: BoundingBox) {\n const handleNode = (ev.currentTarget as HTMLElement) || null;\n\n if (!handleNode) return 0;\n\n return this.props.orientation === 'vertical'\n ? ((handleNode.clientHeight / sliderBox.height) * PERCENT_FULL) / 2\n : ((handleNode.clientWidth / sliderBox.width) * PERCENT_FULL) / 2;\n }\n\n private getClosestSnapPoint(value: number) {\n // non-null thanks to defaultProps\n if (!this.props.snapPoints!.length) return value;\n\n return this.props.snapPoints!.reduce((snapTo, snap) =>\n Math.abs(snapTo - value) < Math.abs(snap - value) ? snapTo : snap\n );\n }\n\n private getSnapPosition(positionPercent: number) {\n if (!this.props.snap) return positionPercent;\n\n const { max, min } = this.props as Required<Props>;\n\n const value = getValue(positionPercent, min, max);\n\n const snapValue = this.getClosestSnapPoint(value);\n\n return getPosition(snapValue, min, max);\n }\n\n private getNextPositionForKey(idx: number, keyCode: number) {\n const { handlePos, values } = this.state;\n const { max, min, snapPoints } = this.props as Required<Props>;\n\n const shouldSnap = this.props.snap;\n\n let proposedValue = values[idx];\n let proposedPercentage = handlePos[idx];\n const originalPercentage = proposedPercentage;\n let stepValue = 1;\n\n if (max >= 100) {\n proposedPercentage = Math.round(proposedPercentage);\n } else {\n stepValue = 100 / (max - min);\n }\n\n let currentIndex: number | null = null;\n\n if (shouldSnap) {\n currentIndex = snapPoints.indexOf(this.getClosestSnapPoint(values[idx]));\n }\n\n type StepMultiplier = { [key: number]: (value: number) => number };\n\n const stepMultiplier: StepMultiplier = {\n [KEYS.LEFT]: (v) => v * -1,\n [KEYS.RIGHT]: (v) => v,\n [KEYS.UP]: (v) => v,\n [KEYS.DOWN]: (v) => v * -1,\n [KEYS.PAGE_DOWN]: (v) => (v > 1 ? -v : v * -10),\n [KEYS.PAGE_UP]: (v) => (v > 1 ? v : v * 10),\n };\n\n if (Object.prototype.hasOwnProperty.call(stepMultiplier, keyCode)) {\n proposedPercentage += stepMultiplier[keyCode](stepValue);\n\n if (shouldSnap) {\n if (!currentIndex) {\n // nothing happens\n } else if (proposedPercentage > originalPercentage) {\n // move cursor right unless overflow\n if (currentIndex < snapPoints.length - 1) {\n proposedValue = snapPoints[currentIndex + 1];\n }\n // move cursor left unless there is overflow\n } else if (currentIndex > 0) {\n proposedValue = snapPoints[currentIndex - 1];\n }\n }\n } else if (keyCode === KEYS.HOME) {\n proposedPercentage = PERCENT_EMPTY;\n\n if (shouldSnap) {\n proposedValue = snapPoints[0];\n }\n } else if (keyCode === KEYS.END) {\n proposedPercentage = PERCENT_FULL;\n\n if (shouldSnap) {\n proposedValue = snapPoints[snapPoints.length - 1];\n }\n } else {\n return null;\n }\n\n return shouldSnap\n ? getPosition(proposedValue, min, max)\n : proposedPercentage;\n }\n\n private getNextState(idx: number, proposedPosition: number) {\n const { handlePos } = this.state;\n const { max, min } = this.props as Required<Props>;\n\n const actualPosition = this.validatePosition(idx, proposedPosition);\n\n const nextHandlePos = handlePos.map((pos, index) =>\n index === idx ? actualPosition : pos\n );\n\n return {\n handlePos: nextHandlePos,\n values: nextHandlePos.map((pos) => getValue(pos, min, max)),\n };\n }\n\n private getClosestHandle(positionPercent: number) {\n const { handlePos } = this.state;\n\n return handlePos.reduce((closestIdx, _node, idx) => {\n const challenger = Math.abs(handlePos[idx] - positionPercent);\n const current = Math.abs(handlePos[closestIdx] - positionPercent);\n return challenger < current ? idx : closestIdx;\n }, 0);\n }\n\n private setStartSlide(ev: MouseEvent | TouchEvent, x: number, y: number) {\n const sliderBox = this.getSliderBoundingBox();\n\n this.setState({\n handleDimensions: this.getHandleDimensions(ev, sliderBox),\n mousePos: { x, y },\n sliderBox,\n slidingIndex: getHandleFor(ev),\n });\n }\n\n private startMouseSlide(ev: MouseEvent) {\n this.setStartSlide(ev, ev.clientX, ev.clientY);\n\n document.addEventListener('mousemove', this.handleMouseSlide, false);\n document.addEventListener('mouseup', this.endSlide, false);\n\n killEvent(ev);\n }\n\n private startTouchSlide(ev: TouchEvent) {\n if (ev.changedTouches.length > 1) return;\n\n const touch = ev.changedTouches[0];\n\n this.setStartSlide(ev, touch.clientX, touch.clientY);\n\n document.addEventListener('touchmove', this.handleTouchSlide, false);\n document.addEventListener('touchend', this.endSlide, false);\n\n if (this.props.onSliderDragStart) this.props.onSliderDragStart();\n\n killEvent(ev);\n }\n\n private handleMouseSlide(ev: MouseEvent) {\n if (this.state.slidingIndex === null) return;\n this.handleSlide(ev.clientX, ev.clientY);\n killEvent(ev);\n }\n\n private handleTouchSlide(ev: TouchEvent) {\n if (this.state.slidingIndex === null) return;\n\n if (ev.changedTouches.length > 1) {\n this.endSlide();\n return;\n }\n\n const touch = ev.changedTouches[0];\n\n this.handleSlide(touch.clientX, touch.clientY);\n killEvent(ev);\n }\n\n private handleSlide(x: number, y: number) {\n const { slidingIndex: idx, sliderBox } = this.state;\n\n const positionPercent =\n this.props.orientation === 'vertical'\n ? ((y - sliderBox.top!) / sliderBox.height!) * PERCENT_FULL\n : ((x - sliderBox.left!) / sliderBox.width!) * PERCENT_FULL;\n\n this.slideTo(idx!, positionPercent);\n\n if (this.canMove(idx!, positionPercent)) {\n // update mouse positions\n this.setState({ mousePos: { x, y } });\n if (this.props.onSliderDragMove) this.props.onSliderDragMove();\n }\n }\n\n private endSlide() {\n const idx = this.state.slidingIndex;\n\n this.setState({ slidingIndex: null });\n\n document.removeEventListener('mouseup', this.endSlide, false);\n document.removeEventListener('touchend', this.endSlide, false);\n document.removeEventListener('touchmove', this.handleTouchSlide, false);\n document.removeEventListener('mousemove', this.handleMouseSlide, false);\n\n if (this.props.onSliderDragEnd) this.props.onSliderDragEnd();\n if (this.props.snap) {\n const positionPercent = this.getSnapPosition(this.state.handlePos[idx!]);\n this.slideTo(idx!, positionPercent, () => this.fireChangeEvent());\n } else {\n this.fireChangeEvent();\n }\n }\n\n private handleClick(ev: MouseEvent) {\n if ((ev.target as HTMLDivElement).getAttribute('data-handle-key')) {\n return;\n }\n\n // Calculate the position of the slider on the page so we can determine\n // the position where you click in relativity.\n const sliderBox = this.getSliderBoundingBox();\n\n const positionDecimal =\n this.props.orientation === 'vertical'\n ? (ev.clientY - sliderBox.top) / sliderBox.height\n : (ev.clientX - sliderBox.left) / sliderBox.width;\n\n const positionPercent = positionDecimal * PERCENT_FULL;\n\n const handleId = this.getClosestHandle(positionPercent);\n\n const validPositionPercent = this.getSnapPosition(positionPercent);\n\n // Move the handle there\n this.slideTo(handleId, validPositionPercent, () => this.fireChangeEvent());\n\n if (this.props.onClick) this.props.onClick();\n }\n\n private handleKeydown(ev: KeyboardEvent) {\n const idx = getHandleFor(ev);\n\n if (ev.keyCode === KEYS.ESC) {\n (ev.currentTarget as HTMLElement).blur();\n return;\n }\n\n const proposedPercentage = this.getNextPositionForKey(idx, ev.keyCode);\n\n if (proposedPercentage === null) return;\n\n if (this.canMove(idx, proposedPercentage)) {\n this.slideTo(idx, proposedPercentage, () => this.fireChangeEvent());\n if (this.props.onKeyPress) this.props.onKeyPress();\n }\n\n killEvent(ev);\n }\n\n // Make sure the proposed position respects the bounds and\n // does not collide with other handles too much.\n private validatePosition(idx: number, proposedPosition: number) {\n const { handlePos, handleDimensions } = this.state;\n\n return Math.max(\n Math.min(\n proposedPosition,\n handlePos[idx + 1] !== undefined\n ? handlePos[idx + 1] - handleDimensions\n : PERCENT_FULL // 100% is the highest value\n ),\n handlePos[idx - 1] !== undefined\n ? handlePos[idx - 1] + handleDimensions\n : PERCENT_EMPTY // 0% is the lowest value\n );\n }\n\n private validateValues(proposedValues: number[], props: Required<Props>) {\n const { max, min } = props || this.props;\n\n return proposedValues.map((value, idx, values) => {\n const realValue = Math.max(Math.min(value, max), min);\n\n if (values.length && realValue < values[idx - 1]) {\n return values[idx - 1];\n }\n\n return realValue;\n });\n }\n\n public canMove(idx: number, proposedPosition: number) {\n const { handlePos, handleDimensions } = this.state;\n\n if (proposedPosition < PERCENT_EMPTY) return false;\n if (proposedPosition > PERCENT_FULL) return false;\n\n const nextHandlePosition =\n handlePos[idx + 1] !== undefined\n ? handlePos[idx + 1] - handleDimensions\n : Infinity;\n\n if (proposedPosition > nextHandlePosition) return false;\n\n const prevHandlePosition =\n handlePos[idx - 1] !== undefined\n ? handlePos[idx - 1] + handleDimensions\n : -Infinity;\n\n if (proposedPosition < prevHandlePosition) return false;\n\n return true;\n }\n\n public fireChangeEvent() {\n const { onChange } = this.props;\n if (onChange) onChange(this.getPublicState());\n }\n\n public slideTo(\n idx: number,\n proposedPosition: number,\n onAfterSet?: () => void\n ) {\n const nextState = this.getNextState(idx, proposedPosition);\n\n this.setState(nextState, () => {\n const { onValuesUpdated } = this.props;\n if (onValuesUpdated) onValuesUpdated(this.getPublicState());\n if (onAfterSet) onAfterSet();\n });\n }\n\n public updateNewValues(nextProps: Required<Props>) {\n const { slidingIndex } = this.state;\n\n // Don't update while the slider is sliding\n if (slidingIndex !== null) {\n return;\n }\n\n const { max, min, values } = nextProps;\n\n const nextValues = this.validateValues(values, nextProps);\n\n this.setState(\n {\n handlePos: nextValues.map((value) => getPosition(value, min, max)),\n values: nextValues,\n },\n () => this.fireChangeEvent()\n );\n }\n\n public render() {\n const {\n children,\n disabled,\n handle: Handle,\n max,\n min,\n orientation,\n pitComponent: PitComponent,\n pitPoints,\n progressBar: ProgressBar,\n } = this.props as Required<Props>; // all required thanks to defaultProps\n const { className, handlePos, values } = this.state;\n\n return (\n <div\n className={className}\n ref={this.rheostat}\n onClick={disabled ? undefined : this.handleClick}\n style={{ position: 'relative' }}\n >\n <div className=\"rheostat-background\" />\n {handlePos.map((pos, idx) => {\n const handleStyle: Style =\n orientation === 'vertical'\n ? { top: `${pos}%`, position: 'absolute' }\n : { left: `${pos}%`, position: 'absolute' };\n\n return (\n <Handle\n aria-valuemax={this.getMaxValue(idx)}\n aria-valuemin={this.getMinValue(idx)}\n aria-valuenow={values[idx]}\n aria-disabled={disabled}\n data-handle-key={idx}\n className=\"rheostat-handle\"\n key={`handle-${idx}`}\n onClick={killEvent}\n onKeyDown={disabled ? undefined : this.handleKeydown}\n onMouseDown={disabled ? undefined : this.startMouseSlide}\n onTouchStart={disabled ? undefined : this.startTouchSlide}\n role=\"slider\"\n style={handleStyle}\n tabIndex={0}\n />\n );\n })}\n\n {handlePos.map((_node, idx, arr) => {\n if (idx === 0 && arr.length > 1) {\n return null;\n }\n\n return (\n <ProgressBar\n className=\"rheostat-progress\"\n key={`progress-bar-${idx}`}\n style={this.getProgressStyle(idx)}\n />\n );\n })}\n\n {PitComponent &&\n pitPoints.map((n) => {\n const pos = getPosition(n, min, max);\n const pitStyle: Style =\n orientation === 'vertical'\n ? { top: `${pos}%`, position: 'absolute' }\n : { left: `${pos}%`, position: 'absolute' };\n\n return (\n <PitComponent key={`pit-${n}`} style={pitStyle}>\n {n}\n </PitComponent>\n );\n })}\n {children}\n </div>\n );\n }\n}\n\nexport default Rheostat;\n","/** @jsx h */\n\nimport { h } from 'preact';\nimport cx from 'classnames';\nimport type { PitProps } from './Rheostat';\n\nconst Pit = ({ style, children }: PitProps) => {\n // first, end & middle\n const positionValue = Math.round(parseFloat(style.left as string));\n const shouldDisplayValue = [0, 50, 100].includes(positionValue);\n\n const value = children as string;\n const pitValue = Math.round(parseInt(value, 10) * 100) / 100;\n\n return (\n <div\n style={{ ...style, marginLeft: positionValue === 100 ? '-2px' : 0 }}\n className={cx('rheostat-marker', 'rheostat-marker-horizontal', {\n 'rheostat-marker-large': shouldDisplayValue,\n })}\n >\n {shouldDisplayValue && <div className={'rheostat-value'}>{pitValue}</div>}\n </div>\n );\n};\n\nexport default Pit;\n","/** @jsx h */\n\nimport { h } from 'preact';\nimport Template from '../Template/Template';\nimport type {\n RelevantSortCSSClasses,\n RelevantSortTemplates,\n} from '../../widgets/relevant-sort/relevant-sort';\nimport type { ComponentCSSClasses } from '../../types';\n\nexport type RelevantSortComponentCSSClasses =\n ComponentCSSClasses<RelevantSortCSSClasses>;\n\nexport type RelevantSortComponentTemplates = Required<RelevantSortTemplates>;\n\ntype RelevantSortProps = {\n cssClasses: RelevantSortComponentCSSClasses;\n templates: RelevantSortComponentTemplates;\n isRelevantSorted: boolean;\n isVirtualReplica: boolean;\n refine(relevancyStrictness: number | undefined): void;\n};\n\nconst RelevantSort = ({\n cssClasses,\n templates,\n isRelevantSorted,\n isVirtualReplica,\n refine,\n}: RelevantSortProps) =>\n isVirtualReplica ? (\n <div className={cssClasses.root}>\n <Template\n templateKey=\"text\"\n templates={templates}\n rootProps={{\n className: cssClasses.text,\n }}\n data={{ isRelevantSorted }}\n />\n <button\n type=\"button\"\n className={cssClasses.button}\n onClick={() => {\n if (isRelevantSorted) {\n refine(0);\n } else {\n refine(undefined);\n }\n }}\n >\n <Template\n rootTagName=\"span\"\n templateKey=\"button\"\n templates={templates}\n data={{ isRelevantSorted }}\n />\n </button>\n </div>\n ) : null;\n\nexport default RelevantSort;\n","/** @jsx h */\n\nimport { h } from 'preact';\nimport cx from 'classnames';\nimport type {\n StatsCSSClasses,\n StatsTemplates,\n} from '../../widgets/stats/stats';\nimport Template from '../Template/Template';\nimport type { ComponentCSSClasses } from '../../types';\n\nexport type StatsComponentCSSClasses = ComponentCSSClasses<StatsCSSClasses>;\n\nexport type StatsComponentTemplates = Required<StatsTemplates>;\n\ntype StatsProps = {\n cssClasses: StatsComponentCSSClasses;\n templateProps: {\n [key: string]: any;\n templates: StatsComponentTemplates;\n };\n hitsPerPage: number | undefined;\n nbHits: number;\n nbSortedHits: number | undefined;\n areHitsSorted: boolean;\n nbPages: number;\n page: number;\n processingTimeMS: number;\n query: string;\n};\n\nconst Stats = ({\n nbHits,\n nbSortedHits,\n cssClasses,\n templateProps,\n ...rest\n}: StatsProps) => (\n <div className={cx(cssClasses.root)}>\n <Template\n {...templateProps}\n templateKey=\"text\"\n rootTagName=\"span\"\n rootProps={{ className: cssClasses.text }}\n data={{\n hasManySortedResults: nbSortedHits && nbSortedHits > 1,\n hasNoSortedResults: nbSortedHits === 0,\n hasOneSortedResults: nbSortedHits === 1,\n hasManyResults: nbHits > 1,\n hasNoResults: nbHits === 0,\n hasOneResult: nbHits === 1,\n nbHits,\n nbSortedHits,\n cssClasses,\n ...rest,\n }}\n />\n </div>\n);\n\nexport default Stats;\n","/** @jsx h */\n\nimport { h } from 'preact';\nimport type {\n ToggleRefinementRenderState,\n ToggleRefinementValue,\n} from '../../connectors/toggle-refinement/connectToggleRefinement';\nimport type { PreparedTemplateProps } from '../../lib/utils/prepareTemplateProps';\nimport type { ComponentCSSClasses } from '../../types';\nimport type {\n ToggleRefinementTemplates,\n ToggleRefinementCSSClasses,\n} from '../../widgets/toggle-refinement/toggle-refinement';\n\nimport Template from '../Template/Template';\n\nexport type ToggleRefinementComponentCSSClasses =\n ComponentCSSClasses<ToggleRefinementCSSClasses>;\n\nexport type ToggleRefinementComponentTemplates =\n Required<ToggleRefinementTemplates>;\n\nexport type ToggleRefinementProps = {\n currentRefinement: ToggleRefinementValue;\n refine: ToggleRefinementRenderState['refine'];\n cssClasses: ToggleRefinementComponentCSSClasses;\n templateProps: PreparedTemplateProps<ToggleRefinementComponentTemplates>;\n};\n\nconst ToggleRefinement = ({\n currentRefinement,\n refine,\n cssClasses,\n templateProps,\n}: ToggleRefinementProps) => (\n <div className={cssClasses.root}>\n <label className={cssClasses.label}>\n <input\n className={cssClasses.checkbox}\n type=\"checkbox\"\n checked={currentRefinement.isRefined}\n onChange={(event) =>\n refine({ isRefined: !(event.target as HTMLInputElement).checked })\n }\n />\n\n <Template\n {...templateProps}\n rootTagName=\"span\"\n rootProps={{ className: cssClasses.labelText }}\n templateKey=\"labelText\"\n data={currentRefinement}\n />\n </label>\n </div>\n);\n\nexport default ToggleRefinement;\n","/** @jsx h */\n\nimport { h } from 'preact';\nimport Template from '../Template/Template';\n\nimport type {\n VoiceSearchCSSClasses,\n VoiceSearchTemplates,\n} from '../../widgets/voice-search/voice-search';\nimport type { VoiceListeningState } from '../../lib/voiceSearchHelper/types';\nimport type { ComponentCSSClasses } from '../../types';\n\nexport type VoiceSearchComponentCSSClasses =\n ComponentCSSClasses<VoiceSearchCSSClasses>;\n\nexport type VoiceSearchComponentTemplates = Required<VoiceSearchTemplates>;\n\nexport type VoiceSearchProps = {\n cssClasses: VoiceSearchComponentCSSClasses;\n isBrowserSupported: boolean;\n isListening: boolean;\n toggleListening: () => void;\n voiceListeningState: VoiceListeningState;\n templates: VoiceSearchComponentTemplates;\n};\n\nconst VoiceSearch = ({\n cssClasses,\n isBrowserSupported,\n isListening,\n toggleListening,\n voiceListeningState,\n templates,\n}: VoiceSearchProps) => {\n const handleClick = (event: MouseEvent): void => {\n if (event.currentTarget instanceof HTMLElement) {\n event.currentTarget.blur();\n }\n toggleListening();\n };\n\n const { status, transcript, isSpeechFinal, errorCode } = voiceListeningState;\n return (\n <div className={cssClasses.root}>\n <Template\n templateKey=\"buttonText\"\n rootTagName=\"button\"\n rootProps={{\n className: cssClasses.button,\n type: 'button',\n title: `Search by voice${\n isBrowserSupported ? '' : ' (not supported on this browser)'\n }`,\n onClick: handleClick,\n disabled: !isBrowserSupported,\n }}\n data={{\n status,\n errorCode,\n isListening,\n transcript,\n isSpeechFinal,\n isBrowserSupported,\n }}\n templates={templates}\n />\n <Template\n templateKey=\"status\"\n rootProps={{\n className: cssClasses.status,\n }}\n data={{\n status,\n errorCode,\n isListening,\n transcript,\n isSpeechFinal,\n isBrowserSupported,\n }}\n templates={templates}\n />\n </div>\n );\n};\n\nexport default VoiceSearch;\n","/** @jsx h */\n\nimport { h, Component } from 'preact';\nimport type { HandleProps } from './Rheostat';\nimport Rheostat from './Rheostat';\nimport cx from 'classnames';\nimport { range } from '../../lib/utils';\nimport Pit from './Pit';\nimport type { RangeBoundaries } from '../../connectors/range/connectRange';\nimport type {\n RangeSliderCssClasses,\n RangeSliderWidgetParams,\n} from '../../widgets/range-slider/range-slider';\nimport type { ComponentCSSClasses } from '../../types';\n\nexport type RangeSliderComponentCSSClasses =\n ComponentCSSClasses<RangeSliderCssClasses>;\n\nexport type SliderProps = {\n refine(values: RangeBoundaries): void;\n min?: number;\n max?: number;\n values: RangeBoundaries;\n pips?: boolean;\n step?: number;\n tooltips?: RangeSliderWidgetParams['tooltips'];\n cssClasses: RangeSliderComponentCSSClasses;\n};\n\nclass Slider extends Component<SliderProps> {\n private get isDisabled() {\n return this.props.min! >= this.props.max!;\n }\n\n private handleChange = ({ values }: { values: RangeBoundaries }) => {\n if (!this.isDisabled) {\n this.props.refine(values);\n }\n };\n\n // creates an array number where to display a pit point on the slider\n private computeDefaultPitPoints({ min, max }: { min: number; max: number }) {\n const totalLength = max - min;\n const steps = 34;\n const stepsLength = totalLength / steps;\n\n const pitPoints = [\n min,\n ...range({\n end: steps - 1,\n }).map((step) => min + stepsLength * (step + 1)),\n max,\n ];\n\n return pitPoints;\n }\n\n // creates an array of values where the slider should snap to\n private computeSnapPoints({\n min,\n max,\n step,\n }: {\n min: number;\n max: number;\n step?: number;\n }) {\n if (!step) return undefined;\n return [...range({ start: min, end: max, step }), max];\n }\n\n private createHandleComponent =\n (tooltips: RangeSliderWidgetParams['tooltips']) => (props: HandleProps) => {\n // display only two decimals after comma,\n // and apply `tooltips.format()` if any\n const roundedValue =\n Math.round(\n // have to cast as a string, as the value given to the prop is a number, but becomes a string when read\n parseFloat(props['aria-valuenow'] as unknown as string) * 100\n ) / 100;\n const value =\n typeof tooltips === 'object' && tooltips.format\n ? tooltips.format(roundedValue)\n : roundedValue;\n\n const className = cx(props.className, {\n 'rheostat-handle-lower': props['data-handle-key'] === 0,\n 'rheostat-handle-upper': props['data-handle-key'] === 1,\n });\n\n return (\n <div {...props} className={className}>\n {tooltips && <div className=\"rheostat-tooltip\">{value}</div>}\n </div>\n );\n };\n\n public render() {\n const { tooltips, step, pips, values, cssClasses } = this.props;\n\n // @TODO: figure out why this.props needs to be non-null asserted\n const { min, max } = this.isDisabled\n ? { min: this.props.min!, max: this.props.max! + 0.001 }\n : (this.props as Required<SliderProps>);\n\n const snapPoints = this.computeSnapPoints({ min, max, step });\n const pitPoints =\n pips === false ? [] : this.computeDefaultPitPoints({ min, max });\n\n return (\n <div\n className={cx(cssClasses.root, {\n [cssClasses.disabledRoot]: this.isDisabled,\n })}\n >\n <Rheostat\n handle={this.createHandleComponent(tooltips)}\n onChange={this.handleChange}\n min={min}\n max={max}\n pitComponent={Pit}\n pitPoints={pitPoints}\n snap={true}\n snapPoints={snapPoints}\n values={(this.isDisabled ? [min, max] : values) as number[]}\n disabled={this.isDisabled}\n />\n </div>\n );\n }\n}\n\nexport default Slider;\n","/** @jsx h */\n\nimport { h, render } from 'preact';\nimport cx from 'classnames';\nimport type { RangeSliderComponentCSSClasses } from '../../components/Slider/Slider';\nimport Slider from '../../components/Slider/Slider';\nimport type {\n RangeBoundaries,\n RangeConnectorParams,\n RangeRenderState,\n RangeWidgetDescription,\n} from '../../connectors/range/connectRange';\nimport connectRange from '../../connectors/range/connectRange';\nimport {\n getContainerNode,\n createDocumentationMessageGenerator,\n} from '../../lib/utils';\nimport { component } from '../../lib/suit';\nimport type { Renderer, WidgetFactory } from '../../types';\n\nconst withUsage = createDocumentationMessageGenerator({ name: 'range-slider' });\nconst suit = component('RangeSlider');\n\nconst renderer =\n ({\n containerNode,\n cssClasses,\n pips,\n step,\n tooltips,\n }: {\n containerNode: HTMLElement;\n cssClasses: RangeSliderComponentCSSClasses;\n pips: boolean;\n step?: number;\n tooltips: RangeSliderWidgetParams['tooltips'];\n }): Renderer<RangeRenderState, Partial<RangeSliderWidgetParams>> =>\n ({ refine, range, start }, isFirstRendering) => {\n if (isFirstRendering) {\n // There's no information at this point, let's render nothing.\n return;\n }\n\n const { min: minRange, max: maxRange } = range;\n\n const [minStart, maxStart] = start;\n const minFinite = minStart === -Infinity ? minRange : minStart;\n const maxFinite = maxStart === Infinity ? maxRange : maxStart;\n\n // Clamp values to the range for avoid extra rendering & refinement\n // Should probably be done on the connector side, but we need to stay\n // backward compatible so we still need to pass [-Infinity, Infinity]\n const values: RangeBoundaries = [\n minFinite! > maxRange! ? maxRange : minFinite,\n maxFinite! < minRange! ? minRange : maxFinite,\n ];\n\n render(\n <Slider\n cssClasses={cssClasses}\n refine={refine}\n min={minRange}\n max={maxRange}\n values={values}\n tooltips={tooltips}\n step={step}\n pips={pips}\n />,\n containerNode\n );\n };\n\nexport type RangeSliderCssClasses = Partial<{\n /**\n * CSS class to add to the root element.\n */\n root: string | string[];\n /**\n * CSS class to add to the disabled root element.\n */\n disabledRoot: string | string[];\n}>;\n\ntype RangeSliderTooltipOptions = {\n /**\n * The function takes the raw value as input, and should return\n * a string for the label that should be used for this value.\n * @example\n * { format(rawValue) {return '$' + Math.round(rawValue).toLocaleString() } }\n */\n format(value: number): string;\n};\n\nexport type RangeSliderWidgetParams = {\n /**\n * CSS Selector or DOMElement to insert the widget.\n */\n container: string | HTMLElement;\n /**\n * Name of the attribute for faceting.;\n */\n attribute: string;\n /**\n * Should we show tooltips or not.\n * The default tooltip will show the raw value.\n * You can also provide an object with a format function as an attribute.\n * So that you can format the tooltip display value as you want.\n * @default true\n */\n tooltips?: boolean | RangeSliderTooltipOptions;\n /**\n * CSS classes to add to the wrapping elements.\n */\n cssClasses?: RangeSliderCssClasses;\n /**\n * Show slider pips.\n * @default true\n */\n pips?: boolean;\n /**\n * Number of digits after decimal point to use.\n * @default 0\n */\n precision?: number;\n /**\n * Every handle move will jump that number of steps.\n */\n step?: number;\n /**\n * Minimal slider value, default to automatically computed from the result set.\n */\n min?: number;\n /**\n * Maximal slider value, defaults to automatically computed from the result set.\n */\n max?: number;\n};\n\nexport type RangeSliderWidget = WidgetFactory<\n Omit<RangeWidgetDescription, '$$type'> & {\n $$widgetType: 'ais.rangeSlider';\n $$type: 'ais.rangeSlider';\n },\n RangeConnectorParams,\n RangeSliderWidgetParams\n>;\n\n/**\n * The range slider is a widget which provides a user-friendly way to filter the\n * results based on a single numeric range.\n *\n * @requirements\n * The attribute passed to `attribute` must be declared as an\n * [attribute for faceting](https://www.algolia.com/doc/guides/searching/faceting/#declaring-attributes-for-faceting)\n * in your Algolia settings.\n *\n * The values inside this attribute must be JavaScript numbers (not strings).\n */\nconst rangeSlider: RangeSliderWidget = function rangeSlider(widgetParams) {\n const {\n container,\n attribute,\n min,\n max,\n cssClasses: userCssClasses = {},\n step,\n pips = true,\n precision = 0,\n tooltips = true,\n } = widgetParams || {};\n if (!container) {\n throw new Error(withUsage('The `container` option is required.'));\n }\n\n const containerNode = getContainerNode(container);\n const cssClasses = {\n root: cx(suit(), userCssClasses.root),\n disabledRoot: cx(\n suit({ modifierName: 'disabled' }),\n userCssClasses.disabledRoot\n ),\n };\n\n const specializedRenderer = renderer({\n containerNode,\n step,\n pips,\n tooltips,\n cssClasses,\n });\n\n const makeWidget = connectRange(specializedRenderer, () =>\n render(null, containerNode)\n );\n\n return {\n ...makeWidget({ attribute, min, max, precision }),\n\n $$type: 'ais.rangeSlider',\n $$widgetType: 'ais.rangeSlider',\n };\n};\n\nexport default rangeSlider;\n","import type { RatingMenuComponentTemplates } from './rating-menu';\n\nconst defaultTemplates: RatingMenuComponentTemplates = {\n item: `{{#count}}<a class=\"{{cssClasses.link}}\" aria-label=\"{{value}} & up\" href=\"{{url}}\">{{/count}}{{^count}}<div class=\"{{cssClasses.link}}\" aria-label=\"{{value}} & up\" disabled>{{/count}}\n {{#stars}}<svg class=\"{{cssClasses.starIcon}} {{#.}}{{cssClasses.fullStarIcon}}{{/.}}{{^.}}{{cssClasses.emptyStarIcon}}{{/.}}\" aria-hidden=\"true\" width=\"24\" height=\"24\">\n {{#.}}<use xlink:href=\"#ais-RatingMenu-starSymbol\"></use>{{/.}}{{^.}}<use xlink:href=\"#ais-RatingMenu-starEmptySymbol\"></use>{{/.}}\n </svg>{{/stars}}\n <span class=\"{{cssClasses.label}}\">& Up</span>\n {{#count}}<span class=\"{{cssClasses.count}}\">{{#helpers.formatNumber}}{{count}}{{/helpers.formatNumber}}</span>{{/count}}\n{{#count}}</a>{{/count}}{{^count}}</div>{{/count}}`,\n};\n\nexport default defaultTemplates;\n","/** @jsx h */\n\nimport { h, render } from 'preact';\nimport cx from 'classnames';\nimport RefinementList from '../../components/RefinementList/RefinementList';\nimport type {\n RatingMenuWidgetDescription,\n RatingMenuConnectorParams,\n RatingMenuRenderState,\n} from '../../connectors/rating-menu/connectRatingMenu';\nimport connectRatingMenu from '../../connectors/rating-menu/connectRatingMenu';\nimport defaultTemplates from './defaultTemplates';\nimport {\n prepareTemplateProps,\n getContainerNode,\n createDocumentationMessageGenerator,\n} from '../../lib/utils';\nimport { component } from '../../lib/suit';\nimport type {\n ComponentCSSClasses,\n RendererOptions,\n Template,\n WidgetFactory,\n} from '../../types';\nimport type { PreparedTemplateProps } from '../../lib/utils/prepareTemplateProps';\n\nconst withUsage = createDocumentationMessageGenerator({ name: 'rating-menu' });\nconst suit = component('RatingMenu');\n\nexport type RatingMenuTemplates = Partial<{\n /**\n * Item template, provided with `name`, `count`, `isRefined`, `url` data properties.\n */\n item: Template<{\n name: string;\n count: number;\n isRefined: boolean;\n url: string;\n }>;\n}>;\n\nexport type RatingMenuCSSClasses = Partial<{\n /**\n * CSS class to add to the root element.\n */\n root: string | string[];\n /**\n * CSS class to add to the root element when there's no refinements.\n */\n noRefinementRoot: string | string[];\n /**\n * CSS class to add to the list element.\n */\n list: string | string[];\n /**\n * CSS class to add to each item element.\n */\n item: string | string[];\n /**\n * CSS class to add the selected item element.\n */\n selectedItem: string | string[];\n /**\n * CSS class to add a disabled item element.\n */\n disabledItem: string | string[];\n /**\n * CSS class to add to each link element.\n */\n link: string | string[];\n /**\n * CSS class to add to each star element (when using the default template).\n */\n starIcon: string | string[];\n /**\n * CSS class to add to each full star element (when using the default template).\n */\n fullStarIcon: string | string[];\n /**\n * CSS class to add to each empty star element (when using the default template).\n */\n emptyStarIcon: string | string[];\n /**\n * CSS class to add to each label.\n */\n label: string | string[];\n /**\n * CSS class to add to each counter.\n */\n count: string | string[];\n}>;\n\nexport type RatingMenuComponentCSSClasses =\n ComponentCSSClasses<RatingMenuCSSClasses>;\n\nexport type RatingMenuComponentTemplates = Required<RatingMenuTemplates>;\n\nexport type RatingMenuWidgetParams = {\n /**\n * Place where to insert the widget in your webpage.\n */\n container: string | HTMLElement;\n /**\n * Name of the attribute in your records that contains the ratings.\n */\n attribute: string;\n /**\n * The maximum rating value.\n */\n max?: number;\n /**\n * Templates to use for the widget.\n */\n templates?: RatingMenuTemplates;\n /**\n * CSS classes to add.\n */\n cssClasses?: RatingMenuCSSClasses;\n};\n\nconst renderer =\n ({\n containerNode,\n cssClasses,\n templates,\n renderState,\n }: {\n containerNode: HTMLElement;\n cssClasses: RatingMenuComponentCSSClasses;\n templates: RatingMenuTemplates;\n renderState: {\n templateProps?: PreparedTemplateProps<RatingMenuComponentTemplates>;\n };\n }) =>\n (\n {\n refine,\n items,\n createURL,\n instantSearchInstance,\n }: RatingMenuRenderState & RendererOptions<RatingMenuConnectorParams>,\n isFirstRendering: boolean\n ) => {\n if (isFirstRendering) {\n renderState.templateProps = prepareTemplateProps({\n defaultTemplates,\n templatesConfig: instantSearchInstance.templatesConfig,\n templates,\n });\n\n return;\n }\n\n render(\n <RefinementList\n createURL={createURL}\n cssClasses={cssClasses}\n facetValues={items}\n templateProps={renderState.templateProps!}\n toggleRefinement={refine}\n >\n <svg style=\"display:none;\">\n <symbol\n id={suit({ descendantName: 'starSymbol' })}\n viewBox=\"0 0 24 24\"\n >\n <path d=\"M12 .288l2.833 8.718h9.167l-7.417 5.389 2.833 8.718-7.416-5.388-7.417 5.388 2.833-8.718-7.416-5.389h9.167z\" />\n </symbol>\n <symbol\n id={suit({ descendantName: 'starEmptySymbol' })}\n viewBox=\"0 0 24 24\"\n >\n <path d=\"M12 6.76l1.379 4.246h4.465l-3.612 2.625 1.379 4.246-3.611-2.625-3.612 2.625 1.379-4.246-3.612-2.625h4.465l1.38-4.246zm0-6.472l-2.833 8.718h-9.167l7.416 5.389-2.833 8.718 7.417-5.388 7.416 5.388-2.833-8.718 7.417-5.389h-9.167l-2.833-8.718z\" />\n </symbol>\n </svg>\n </RefinementList>,\n containerNode\n );\n };\n\n/**\n * Rating menu is used for displaying grade like filters. The values are normalized within boundaries.\n *\n * The maximum value can be set (with `max`), the minimum is always 0.\n *\n * @requirements\n * The attribute passed to `attribute` must be declared as an\n * [attribute for faceting](https://www.algolia.com/doc/guides/searching/faceting/#declaring-attributes-for-faceting)\n * in your Algolia settings.\n *\n * The values inside this attribute must be JavaScript numbers (not strings).\n *\n * @type {WidgetFactory}\n * @devNovel RatingMenu\n * @category filter\n * @param {RatingMenuWidgetParams} widgetParams RatingMenu widget options.\n * @return {Widget} A new RatingMenu widget instance.\n * @example\n * search.addWidgets([\n * instantsearch.widgets.ratingMenu({\n * container: '#stars',\n * attribute: 'rating',\n * max: 5,\n * })\n * ]);\n */\nexport type RatingMenuWidget = WidgetFactory<\n RatingMenuWidgetDescription & { $$widgetType: 'ais.ratingMenu' },\n RatingMenuConnectorParams,\n RatingMenuWidgetParams\n>;\n\nconst ratingMenu: RatingMenuWidget = function ratingMenu(widgetParams) {\n const {\n container,\n attribute,\n max = 5,\n cssClasses: userCssClasses = {},\n templates = {},\n } = widgetParams || {};\n if (!container) {\n throw new Error(withUsage('The `container` option is required.'));\n }\n\n const containerNode = getContainerNode(container);\n\n const cssClasses = {\n root: cx(suit(), userCssClasses.root),\n noRefinementRoot: cx(\n suit({ modifierName: 'noRefinement' }),\n userCssClasses.noRefinementRoot\n ),\n list: cx(suit({ descendantName: 'list' }), userCssClasses.list),\n item: cx(suit({ descendantName: 'item' }), userCssClasses.item),\n selectedItem: cx(\n suit({ descendantName: 'item', modifierName: 'selected' }),\n userCssClasses.selectedItem\n ),\n disabledItem: cx(\n suit({ descendantName: 'item', modifierName: 'disabled' }),\n userCssClasses.disabledItem\n ),\n link: cx(suit({ descendantName: 'link' }), userCssClasses.link),\n starIcon: cx(suit({ descendantName: 'starIcon' }), userCssClasses.starIcon),\n fullStarIcon: cx(\n suit({ descendantName: 'starIcon', modifierName: 'full' }),\n userCssClasses.fullStarIcon\n ),\n emptyStarIcon: cx(\n suit({ descendantName: 'starIcon', modifierName: 'empty' }),\n userCssClasses.emptyStarIcon\n ),\n label: cx(suit({ descendantName: 'label' }), userCssClasses.label),\n count: cx(suit({ descendantName: 'count' }), userCssClasses.count),\n };\n\n const specializedRenderer = renderer({\n containerNode,\n cssClasses,\n renderState: {},\n templates,\n });\n\n const makeWidget = connectRatingMenu(specializedRenderer, () =>\n render(null, containerNode)\n );\n\n return {\n ...makeWidget({ attribute, max }),\n $$widgetType: 'ais.ratingMenu',\n };\n};\n\nexport default ratingMenu;\n","import type { SearchBoxComponentTemplates } from '../../components/SearchBox/SearchBox';\n\nconst defaultTemplate: SearchBoxComponentTemplates = {\n reset: `\n<svg class=\"{{cssClasses.resetIcon}}\" viewBox=\"0 0 20 20\" width=\"10\" height=\"10\">\n <path d=\"M8.114 10L.944 2.83 0 1.885 1.886 0l.943.943L10 8.113l7.17-7.17.944-.943L20 1.886l-.943.943-7.17 7.17 7.17 7.17.943.944L18.114 20l-.943-.943-7.17-7.17-7.17 7.17-.944.943L0 18.114l.943-.943L8.113 10z\"></path>\n</svg>\n `,\n submit: `\n<svg class=\"{{cssClasses.submitIcon}}\" width=\"10\" height=\"10\" viewBox=\"0 0 40 40\">\n <path d=\"M26.804 29.01c-2.832 2.34-6.465 3.746-10.426 3.746C7.333 32.756 0 25.424 0 16.378 0 7.333 7.333 0 16.378 0c9.046 0 16.378 7.333 16.378 16.378 0 3.96-1.406 7.594-3.746 10.426l10.534 10.534c.607.607.61 1.59-.004 2.202-.61.61-1.597.61-2.202.004L26.804 29.01zm-10.426.627c7.323 0 13.26-5.936 13.26-13.26 0-7.32-5.937-13.257-13.26-13.257C9.056 3.12 3.12 9.056 3.12 16.378c0 7.323 5.936 13.26 13.258 13.26z\"></path>\n</svg>\n `,\n loadingIndicator: `\n<svg class=\"{{cssClasses.loadingIcon}}\" width=\"16\" height=\"16\" viewBox=\"0 0 38 38\" stroke=\"#444\">\n <g fill=\"none\" fillRule=\"evenodd\">\n <g transform=\"translate(1 1)\" strokeWidth=\"2\">\n <circle strokeOpacity=\".5\" cx=\"18\" cy=\"18\" r=\"18\" />\n <path d=\"M36 18c0-9.94-8.06-18-18-18\">\n <animateTransform\n attributeName=\"transform\"\n type=\"rotate\"\n from=\"0 18 18\"\n to=\"360 18 18\"\n dur=\"1s\"\n repeatCount=\"indefinite\"\n />\n </path>\n </g>\n </g>\n</svg>\n `,\n};\n\nexport default defaultTemplate;\n","import type { RefinementListComponentTemplates } from './refinement-list';\n\nconst defaultTemplates: RefinementListComponentTemplates = {\n item: `<label class=\"{{cssClasses.label}}\">\n <input type=\"checkbox\"\n class=\"{{cssClasses.checkbox}}\"\n value=\"{{value}}\"\n {{#isRefined}}checked{{/isRefined}} />\n <span class=\"{{cssClasses.labelText}}\">{{#isFromSearch}}{{{highlighted}}}{{/isFromSearch}}{{^isFromSearch}}{{highlighted}}{{/isFromSearch}}</span>\n <span class=\"{{cssClasses.count}}\">{{#helpers.formatNumber}}{{count}}{{/helpers.formatNumber}}</span>\n</label>`,\n showMoreText: `\n {{#isShowingMore}}\n Show less\n {{/isShowingMore}}\n {{^isShowingMore}}\n Show more\n {{/isShowingMore}}\n `,\n searchableNoResults: 'No results',\n};\n\nexport default defaultTemplates;\n","/** @jsx h */\n\nimport { h, render } from 'preact';\nimport cx from 'classnames';\nimport type { RefinementListComponentCSSClasses } from '../../components/RefinementList/RefinementList';\nimport RefinementList from '../../components/RefinementList/RefinementList';\nimport type {\n RefinementListRenderState,\n RefinementListConnectorParams,\n RefinementListWidgetDescription,\n} from '../../connectors/refinement-list/connectRefinementList';\nimport connectRefinementList from '../../connectors/refinement-list/connectRefinementList';\nimport {\n prepareTemplateProps,\n getContainerNode,\n createDocumentationMessageGenerator,\n} from '../../lib/utils';\nimport { component } from '../../lib/suit';\nimport type { Template, WidgetFactory, Renderer } from '../../types';\nimport type { PreparedTemplateProps } from '../../lib/utils/prepareTemplateProps';\nimport searchBoxDefaultTemplates from '../search-box/defaultTemplates';\nimport type { SearchBoxTemplates } from '../search-box/search-box';\nimport type { SearchBoxComponentTemplates } from '../../components/SearchBox/SearchBox';\nimport defaultTemplates from './defaultTemplates';\n\nconst withUsage = createDocumentationMessageGenerator({\n name: 'refinement-list',\n});\nconst suit = component('RefinementList');\nconst searchBoxSuit = component('SearchBox');\n\nexport type RefinementListOwnCSSClasses = Partial<{\n /**\n * CSS class to add to the root element.\n */\n root: string | string[];\n /**\n * CSS class to add to the root element when no refinements.\n */\n noRefinementRoot: string | string[];\n /**\n * CSS class to add to the root element with no results.\n */\n noResults: string | string[];\n /**\n * CSS class to add to the list element.\n */\n list: string | string[];\n /**\n * CSS class to add to each item element.\n */\n item: string | string[];\n /**\n * CSS class to add to each selected element.\n */\n selectedItem: string | string[];\n /**\n * CSS class to add to each label element (when using the default template).\n */\n label: string | string[];\n /**\n * CSS class to add to each checkbox element (when using the default template).\n */\n checkbox: string | string[];\n /**\n * CSS class to add to each label text element.\n */\n labelText: string | string[];\n /**\n * CSS class to add to the show more element\n */\n showMore: string | string[];\n /**\n * CSS class to add to the disabled show more element\n */\n disabledShowMore: string | string[];\n /**\n * CSS class to add to each count element (when using the default template).\n */\n count: string | string[];\n /**\n * CSS class to add to the searchable container.\n */\n searchBox: string | string[];\n}>;\n\ntype RefinementListSearchableCSSClasses = Partial<{\n searchableRoot: string | string[];\n searchableForm: string | string[];\n searchableInput: string | string[];\n searchableSubmit: string | string[];\n searchableSubmitIcon: string | string[];\n searchableReset: string | string[];\n searchableResetIcon: string | string[];\n searchableLoadingIndicator: string | string[];\n searchableLoadingIcon: string | string[];\n}>;\n\nexport type RefinementListCSSClasses = RefinementListOwnCSSClasses &\n RefinementListSearchableCSSClasses;\n\nexport type RefinementListItemData = {\n /**\n * The number of occurrences of the facet in the result set.\n */\n count: number;\n /**\n * True if the value is selected.\n */\n isRefined: boolean;\n /**\n * The label to display.\n */\n label: string;\n /**\n * The value used for refining.\n */\n value: string;\n /**\n * The label highlighted (when using search for facet values). This value is displayed in the default template.\n */\n highlighted: string;\n /**\n * The url with this refinement selected.\n */\n url: string;\n /**\n * Object containing all the classes computed for the item.\n */\n cssClasses: RefinementListCSSClasses;\n};\n\nexport type RefinementListOwnTemplates = Partial<{\n /**\n * Item template, provided with `label`, `highlighted`, `value`, `count`, `isRefined`, `url` data properties.\n */\n item: Template<RefinementListItemData>;\n /**\n * Template used for the show more text, provided with `isShowingMore` data property.\n */\n showMoreText: Template;\n /**\n * Templates to use for search for facet values when there are no results.\n */\n searchableNoResults: Template;\n}>;\n\ntype RefinementListSearchableTemplates = Partial<{\n /**\n * Templates to use for search for facet values submit button.\n */\n searchableSubmit: SearchBoxTemplates['submit'];\n /**\n * Templates to use for search for facet values reset button.\n */\n searchableReset: SearchBoxTemplates['reset'];\n /**\n * Templates to use for the search for facet values loading indicator.\n */\n searchableLoadingIndicator: SearchBoxTemplates['loadingIndicator'];\n}>;\n\nexport type RefinementListTemplates = RefinementListOwnTemplates &\n RefinementListSearchableTemplates;\nexport type RefinementListComponentTemplates =\n Required<RefinementListOwnTemplates>;\n\nexport type RefinementListWidgetParams = {\n /**\n * CSS Selector or HTMLElement to insert the widget.\n */\n container: string | HTMLElement;\n /**\n * Add a search input to let the user search for more facet values. In order\n * to make this feature work, you need to make the attribute searchable\n * [using the API](https://www.algolia.com/doc/guides/searching/faceting/?language=js#declaring-a-searchable-attribute-for-faceting)\n * or [the dashboard](https://www.algolia.com/explorer/display/)\n */\n searchable?: boolean;\n /**\n * Value of the search field placeholder.\n */\n searchablePlaceholder?: string;\n /**\n * When `false` the search field will become disabled if there are less items\n * to display than the `options.limit`, otherwise the search field is always usable.\n */\n searchableIsAlwaysActive?: boolean;\n /**\n * When activated, it will escape the facet values that are returned from Algolia.\n * In this case, the surrounding tags will always be `<mark></mark>`.\n */\n searchableEscapeFacetValues?: boolean;\n /**\n * Templates to use for the widget.\n */\n templates?: RefinementListTemplates;\n /**\n * CSS classes to add to the wrapping elements.\n */\n cssClasses?: RefinementListCSSClasses;\n};\n\nconst renderer =\n ({\n containerNode,\n cssClasses,\n templates,\n searchBoxTemplates,\n renderState,\n showMore,\n searchable,\n searchablePlaceholder,\n searchableIsAlwaysActive,\n }: {\n containerNode: HTMLElement;\n cssClasses: RefinementListComponentCSSClasses;\n renderState: {\n templateProps?: PreparedTemplateProps<RefinementListComponentTemplates>;\n searchBoxTemplateProps?: PreparedTemplateProps<SearchBoxComponentTemplates>;\n };\n templates: RefinementListOwnTemplates;\n searchBoxTemplates: SearchBoxTemplates;\n showMore?: boolean;\n searchable?: boolean;\n searchablePlaceholder?: string;\n searchableIsAlwaysActive?: boolean;\n }): Renderer<RefinementListRenderState, RefinementListConnectorParams> =>\n (\n {\n refine,\n items,\n createURL,\n searchForItems,\n isFromSearch,\n instantSearchInstance,\n toggleShowMore,\n isShowingMore,\n hasExhaustiveItems,\n canToggleShowMore,\n },\n isFirstRendering\n ) => {\n if (isFirstRendering) {\n renderState.templateProps = prepareTemplateProps({\n defaultTemplates,\n templatesConfig: instantSearchInstance.templatesConfig,\n templates,\n });\n renderState.searchBoxTemplateProps = prepareTemplateProps({\n defaultTemplates: searchBoxDefaultTemplates,\n templatesConfig: instantSearchInstance.templatesConfig,\n templates: searchBoxTemplates,\n });\n return;\n }\n\n render(\n <RefinementList\n createURL={createURL}\n cssClasses={cssClasses}\n facetValues={items}\n templateProps={renderState.templateProps!}\n searchBoxTemplateProps={renderState.searchBoxTemplateProps}\n toggleRefinement={refine}\n searchFacetValues={searchable ? searchForItems : undefined}\n searchPlaceholder={searchablePlaceholder}\n searchIsAlwaysActive={searchableIsAlwaysActive}\n isFromSearch={isFromSearch}\n showMore={showMore && !isFromSearch && items.length > 0}\n toggleShowMore={toggleShowMore}\n isShowingMore={isShowingMore}\n hasExhaustiveItems={hasExhaustiveItems}\n canToggleShowMore={canToggleShowMore}\n />,\n containerNode\n );\n };\n\nexport type RefinementListWidget = WidgetFactory<\n RefinementListWidgetDescription & { $$widgetType: 'ais.refinementList' },\n RefinementListConnectorParams,\n RefinementListWidgetParams\n>;\n\n/**\n * The refinement list widget is one of the most common widget that you can find\n * in a search UI. With this widget, the user can filter the dataset based on facets.\n *\n * The refinement list displays only the most relevant facets for the current search\n * context. The sort option only affects the facet that are returned by the engine,\n * not which facets are returned.\n *\n * This widget also implements search for facet values, which is a mini search inside the\n * values of the facets. This makes easy to deal with uncommon facet values.\n *\n * @requirements\n *\n * The attribute passed to `attribute` must be declared as an\n * [attribute for faceting](https://www.algolia.com/doc/guides/searching/faceting/#declaring-attributes-for-faceting)\n * in your Algolia settings.\n *\n * If you also want to use search for facet values on this attribute, you need to make it searchable using the [dashboard](https://www.algolia.com/explorer/display/) or using the [API](https://www.algolia.com/doc/guides/searching/faceting/#search-for-facet-values).\n */\nconst refinementList: RefinementListWidget = function refinementList(\n widgetParams\n) {\n const {\n container,\n attribute,\n operator,\n sortBy,\n limit,\n showMore,\n showMoreLimit,\n searchable = false,\n searchablePlaceholder = 'Search...',\n searchableEscapeFacetValues = true,\n searchableIsAlwaysActive = true,\n cssClasses: userCssClasses = {},\n templates = {},\n transformItems,\n } = widgetParams || {};\n\n if (!container) {\n throw new Error(withUsage('The `container` option is required.'));\n }\n\n const escapeFacetValues = searchable\n ? Boolean(searchableEscapeFacetValues)\n : false;\n const containerNode = getContainerNode(container);\n\n const cssClasses = {\n root: cx(suit(), userCssClasses.root),\n noRefinementRoot: cx(\n suit({ modifierName: 'noRefinement' }),\n userCssClasses.noRefinementRoot\n ),\n list: cx(suit({ descendantName: 'list' }), userCssClasses.list),\n item: cx(suit({ descendantName: 'item' }), userCssClasses.item),\n selectedItem: cx(\n suit({ descendantName: 'item', modifierName: 'selected' }),\n userCssClasses.selectedItem\n ),\n searchBox: cx(\n suit({ descendantName: 'searchBox' }),\n userCssClasses.searchBox\n ),\n label: cx(suit({ descendantName: 'label' }), userCssClasses.label),\n checkbox: cx(suit({ descendantName: 'checkbox' }), userCssClasses.checkbox),\n labelText: cx(\n suit({ descendantName: 'labelText' }),\n userCssClasses.labelText\n ),\n count: cx(suit({ descendantName: 'count' }), userCssClasses.count),\n noResults: cx(\n suit({ descendantName: 'noResults' }),\n userCssClasses.noResults\n ),\n showMore: cx(suit({ descendantName: 'showMore' }), userCssClasses.showMore),\n disabledShowMore: cx(\n suit({ descendantName: 'showMore', modifierName: 'disabled' }),\n userCssClasses.disabledShowMore\n ),\n searchable: {\n root: cx(searchBoxSuit(), userCssClasses.searchableRoot),\n form: cx(\n searchBoxSuit({ descendantName: 'form' }),\n userCssClasses.searchableForm\n ),\n input: cx(\n searchBoxSuit({ descendantName: 'input' }),\n userCssClasses.searchableInput\n ),\n submit: cx(\n searchBoxSuit({ descendantName: 'submit' }),\n userCssClasses.searchableSubmit\n ),\n submitIcon: cx(\n searchBoxSuit({ descendantName: 'submitIcon' }),\n userCssClasses.searchableSubmitIcon\n ),\n reset: cx(\n searchBoxSuit({ descendantName: 'reset' }),\n userCssClasses.searchableReset\n ),\n resetIcon: cx(\n searchBoxSuit({ descendantName: 'resetIcon' }),\n userCssClasses.searchableResetIcon\n ),\n loadingIndicator: cx(\n searchBoxSuit({ descendantName: 'loadingIndicator' }),\n userCssClasses.searchableLoadingIndicator\n ),\n loadingIcon: cx(\n searchBoxSuit({ descendantName: 'loadingIcon' }),\n userCssClasses.searchableLoadingIcon\n ),\n },\n };\n\n const specializedRenderer = renderer({\n containerNode,\n cssClasses,\n templates,\n searchBoxTemplates: {\n submit: templates.searchableSubmit,\n reset: templates.searchableReset,\n loadingIndicator: templates.searchableLoadingIndicator,\n },\n renderState: {},\n searchable,\n searchablePlaceholder,\n searchableIsAlwaysActive,\n showMore,\n });\n\n const makeWidget = connectRefinementList(specializedRenderer, () =>\n render(null, containerNode)\n );\n\n return {\n ...makeWidget({\n attribute,\n operator,\n limit,\n showMore,\n showMoreLimit,\n sortBy,\n escapeFacetValues,\n transformItems,\n }),\n $$widgetType: 'ais.refinementList',\n };\n};\n\nexport default refinementList;\n","import type { RelevantSortComponentTemplates } from '../../components/RelevantSort/RelevantSort';\n\nconst defaultTemplates: RelevantSortComponentTemplates = {\n text: '',\n button: ({ isRelevantSorted }) =>\n isRelevantSorted ? 'See all results' : 'See relevant results',\n};\n\nexport default defaultTemplates;\n","/** @jsx h */\n\nimport { h, render } from 'preact';\nimport cx from 'classnames';\nimport {\n getContainerNode,\n createDocumentationMessageGenerator,\n} from '../../lib/utils';\nimport { component } from '../../lib/suit';\nimport type { WidgetFactory, Template } from '../../types';\nimport type {\n RelevantSortConnectorParams,\n RelevantSortRenderState,\n RelevantSortWidgetDescription,\n} from '../../connectors/relevant-sort/connectRelevantSort';\nimport connectRelevantSort from '../../connectors/relevant-sort/connectRelevantSort';\nimport type {\n RelevantSortComponentCSSClasses,\n RelevantSortComponentTemplates,\n} from '../../components/RelevantSort/RelevantSort';\nimport RelevantSort from '../../components/RelevantSort/RelevantSort';\nimport defaultTemplates from './defaultTemplates';\nimport type { PreparedTemplateProps } from '../../lib/utils/prepareTemplateProps';\n\nexport type RelevantSortCSSClasses = Partial<{\n root: string;\n text: string;\n button: string;\n}>;\n\nexport type RelevantSortTemplates = Partial<{\n text: Template<{ isRelevantSorted: boolean }>;\n button: Template<{ isRelevantSorted: boolean }>;\n}>;\n\nexport type RelevantSortWidgetParams = {\n container: string | HTMLElement;\n cssClasses?: RelevantSortCSSClasses;\n templates?: RelevantSortTemplates;\n};\n\nexport type RelevantSortWidget = WidgetFactory<\n RelevantSortWidgetDescription & { $$widgetType: 'ais.relevantSort' },\n RelevantSortConnectorParams,\n RelevantSortWidgetParams\n>;\n\nconst withUsage = createDocumentationMessageGenerator({\n name: 'relevant-sort',\n});\n\nconst suit = component('RelevantSort');\n\nconst renderer =\n ({\n containerNode,\n cssClasses,\n templates,\n }: {\n containerNode: HTMLElement;\n cssClasses: RelevantSortComponentCSSClasses;\n renderState: {\n templateProps?: PreparedTemplateProps<RelevantSortComponentTemplates>;\n };\n templates: RelevantSortComponentTemplates;\n }) =>\n ({ isRelevantSorted, isVirtualReplica, refine }: RelevantSortRenderState) => {\n render(\n <RelevantSort\n cssClasses={cssClasses}\n templates={templates}\n isRelevantSorted={isRelevantSorted}\n isVirtualReplica={isVirtualReplica}\n refine={refine}\n />,\n containerNode\n );\n };\n\nconst relevantSort: RelevantSortWidget = (widgetParams) => {\n const {\n container,\n templates: userTemplates = {},\n cssClasses: userCssClasses = {},\n } = widgetParams;\n\n if (!container) {\n throw new Error(withUsage('The `container` option is required.'));\n }\n\n const containerNode = getContainerNode(container);\n const cssClasses = {\n root: cx(suit(), userCssClasses.root),\n text: cx(suit({ descendantName: 'text' }), userCssClasses.text),\n button: cx(suit({ descendantName: 'button' }), userCssClasses.button),\n };\n const templates = {\n ...defaultTemplates,\n ...userTemplates,\n };\n\n const specializedRenderer = renderer({\n containerNode,\n cssClasses,\n renderState: {},\n templates,\n });\n\n const makeWidget = connectRelevantSort(specializedRenderer, () => {\n render(null, containerNode);\n });\n\n return {\n ...makeWidget({}),\n $$widgetType: 'ais.relevantSort',\n };\n};\n\nexport default relevantSort;\n","/** @jsx h */\n\nimport { h, render } from 'preact';\nimport cx from 'classnames';\nimport {\n getContainerNode,\n createDocumentationMessageGenerator,\n} from '../../lib/utils';\nimport { component } from '../../lib/suit';\nimport type { WidgetFactory, Template, RendererOptions } from '../../types';\nimport type {\n SearchBoxConnectorParams,\n SearchBoxRenderState,\n SearchBoxWidgetDescription,\n} from '../../connectors/search-box/connectSearchBox';\nimport connectSearchBox from '../../connectors/search-box/connectSearchBox';\nimport type {\n SearchBoxComponentCSSClasses,\n SearchBoxComponentTemplates,\n} from '../../components/SearchBox/SearchBox';\nimport SearchBox from '../../components/SearchBox/SearchBox';\nimport defaultTemplates from './defaultTemplates';\n\nconst withUsage = createDocumentationMessageGenerator({ name: 'search-box' });\nconst suit = component('SearchBox');\n\nexport type SearchBoxTemplates = Partial<{\n /**\n * Template used for displaying the submit button. Can accept a function or a Hogan string.\n */\n submit: Template;\n /**\n * Template used for displaying the reset button. Can accept a function or a Hogan string.\n */\n reset: Template;\n /**\n * Template used for displaying the loading indicator. Can accept a function or a Hogan string.\n */\n loadingIndicator: Template;\n}>;\n\nexport type SearchBoxCSSClasses = Partial<{\n /**\n * CSS class to add to the wrapping `<div>`\n */\n root: string | string[];\n /**\n * CSS class to add to the form\n */\n form: string | string[];\n /**\n * CSS class to add to the input.\n */\n input: string | string[];\n /**\n * CSS classes added to the submit button.\n */\n submit: string | string[];\n /**\n * CSS classes added to the submit icon.\n */\n submitIcon: string | string[];\n /**\n * CSS classes added to the reset button.\n */\n reset: string | string[];\n /**\n * CSS classes added to the reset icon.\n */\n resetIcon: string | string[];\n /**\n * CSS classes added to the loading indicator element.\n */\n loadingIndicator: string | string[];\n /**\n * CSS classes added to the loading indicator icon.\n */\n loadingIcon: string | string[];\n}>;\n\nexport type SearchBoxWidgetParams = {\n /**\n * CSS Selector or HTMLElement to insert the widget\n */\n container: string | HTMLElement;\n /**\n * The placeholder of the input\n */\n placeholder?: string;\n /**\n * Whether the input should be autofocused\n */\n autofocus?: boolean;\n /**\n * If set, trigger the search\n * once `<Enter>` is pressed only.\n */\n searchAsYouType?: boolean;\n /**\n * Whether to show the reset button\n */\n showReset?: boolean;\n /**\n * Whether to show the submit button\n */\n showSubmit?: boolean;\n /**\n * Whether to show the loading indicator (replaces the submit if\n * the search is stalled)\n */\n showLoadingIndicator?: boolean;\n /**\n * CSS classes to add\n */\n cssClasses?: SearchBoxCSSClasses;\n\n /**\n * Templates used for customizing the rendering of the searchbox\n */\n templates?: SearchBoxTemplates;\n /**\n * A function that is called every time a new search is done. You\n * will get the query as the first parameter and a search (query) function to call as the second parameter.\n * This `queryHook` can be used to debounce the number of searches done from the search box.\n */\n queryHook?: (query: string, hook: (value: string) => void) => void;\n};\n\nconst renderer =\n ({\n containerNode,\n cssClasses,\n placeholder,\n templates,\n autofocus,\n searchAsYouType,\n showReset,\n showSubmit,\n showLoadingIndicator,\n }: {\n containerNode: HTMLElement;\n cssClasses: SearchBoxComponentCSSClasses;\n placeholder: string;\n templates: SearchBoxComponentTemplates;\n autofocus: boolean;\n searchAsYouType: boolean;\n showReset: boolean;\n showSubmit: boolean;\n showLoadingIndicator: boolean;\n }) =>\n ({\n refine,\n query,\n isSearchStalled,\n }: SearchBoxRenderState & RendererOptions<SearchBoxConnectorParams>) => {\n render(\n <SearchBox\n query={query}\n placeholder={placeholder}\n autofocus={autofocus}\n refine={refine}\n searchAsYouType={searchAsYouType}\n templates={templates}\n showSubmit={showSubmit}\n showReset={showReset}\n showLoadingIndicator={showLoadingIndicator}\n isSearchStalled={isSearchStalled}\n cssClasses={cssClasses}\n />,\n containerNode\n );\n };\n\n/**\n * The searchbox widget is used to let the user set a text based query.\n *\n * This is usually the main entry point to start the search in an instantsearch context. For that\n * reason is usually placed on top, and not hidden so that the user can start searching right\n * away.\n *\n */\nexport type SearchBoxWidget = WidgetFactory<\n SearchBoxWidgetDescription & { $$widgetType: 'ais.searchBox' },\n SearchBoxConnectorParams,\n SearchBoxWidgetParams\n>;\n\nconst searchBox: SearchBoxWidget = function searchBox(widgetParams) {\n const {\n container,\n placeholder = '',\n cssClasses: userCssClasses = {},\n autofocus = false,\n searchAsYouType = true,\n showReset = true,\n showSubmit = true,\n showLoadingIndicator = true,\n queryHook,\n templates: userTemplates = {},\n } = widgetParams || {};\n if (!container) {\n throw new Error(withUsage('The `container` option is required.'));\n }\n\n const containerNode = getContainerNode(container);\n\n const cssClasses = {\n root: cx(suit(), userCssClasses.root),\n form: cx(suit({ descendantName: 'form' }), userCssClasses.form),\n input: cx(suit({ descendantName: 'input' }), userCssClasses.input),\n submit: cx(suit({ descendantName: 'submit' }), userCssClasses.submit),\n submitIcon: cx(\n suit({ descendantName: 'submitIcon' }),\n userCssClasses.submitIcon\n ),\n reset: cx(suit({ descendantName: 'reset' }), userCssClasses.reset),\n resetIcon: cx(\n suit({ descendantName: 'resetIcon' }),\n userCssClasses.resetIcon\n ),\n loadingIndicator: cx(\n suit({ descendantName: 'loadingIndicator' }),\n userCssClasses.loadingIndicator\n ),\n loadingIcon: cx(\n suit({ descendantName: 'loadingIcon' }),\n userCssClasses.loadingIcon\n ),\n };\n const templates = {\n ...defaultTemplates,\n ...userTemplates,\n };\n\n const specializedRenderer = renderer({\n containerNode,\n cssClasses,\n placeholder,\n templates,\n autofocus,\n searchAsYouType,\n showReset,\n showSubmit,\n showLoadingIndicator,\n });\n\n const makeWidget = connectSearchBox(specializedRenderer, () =>\n render(null, containerNode)\n );\n\n return {\n ...makeWidget({ queryHook }),\n $$widgetType: 'ais.searchBox',\n };\n};\n\nexport default searchBox;\n","/** @jsx h */\n\nimport { h, render } from 'preact';\nimport cx from 'classnames';\nimport type { SelectorComponentCSSClasses } from '../../components/Selector/Selector';\nimport Selector from '../../components/Selector/Selector';\nimport type {\n SortByConnectorParams,\n SortByItem,\n SortByRenderState,\n SortByWidgetDescription,\n} from '../../connectors/sort-by/connectSortBy';\nimport connectSortBy from '../../connectors/sort-by/connectSortBy';\nimport {\n getContainerNode,\n createDocumentationMessageGenerator,\n} from '../../lib/utils';\nimport { component } from '../../lib/suit';\nimport type { Renderer, TransformItems, WidgetFactory } from '../../types';\n\nconst withUsage = createDocumentationMessageGenerator({ name: 'sort-by' });\nconst suit = component('SortBy');\n\nexport type SortByWidgetCssClasses = Partial<{\n /**\n * CSS classes added to the outer `<div>`.\n */\n root: string | string[];\n /**\n * CSS classes added to the parent `<select>`.\n */\n select: string | string[];\n /**\n * CSS classes added to each `<option>`.\n */\n option: string | string[];\n}>;\n\nexport type SortByIndexDefinition = {\n /**\n * The name of the index to target.\n */\n value: string;\n /**\n * The label of the index to display.\n */\n label: string;\n};\n\nexport type SortByWidgetParams = {\n /**\n * CSS Selector or HTMLElement to insert the widget.\n */\n container: string | HTMLElement;\n /**\n * Array of objects defining the different indices to choose from.\n */\n items: SortByIndexDefinition[];\n /**\n * CSS classes to be added.\n */\n cssClasses?: SortByWidgetCssClasses;\n /**\n * Function to transform the items passed to the templates.\n */\n transformItems?: TransformItems<SortByItem>;\n};\n\nexport type SortByWidget = WidgetFactory<\n SortByWidgetDescription & { $$widgetType: 'ais.sortBy' },\n SortByConnectorParams,\n SortByWidgetParams\n>;\n\nconst renderer =\n ({\n containerNode,\n cssClasses,\n }: {\n containerNode: HTMLElement;\n cssClasses: SelectorComponentCSSClasses;\n }): Renderer<SortByRenderState, SortByWidgetParams> =>\n ({ currentRefinement, options, refine }, isFirstRendering) => {\n if (isFirstRendering) {\n return;\n }\n\n render(\n <div className={cssClasses.root}>\n <Selector\n cssClasses={cssClasses}\n currentValue={currentRefinement}\n options={options}\n setValue={refine}\n />\n </div>,\n containerNode\n );\n };\n\n/**\n * Sort by selector is a widget used for letting the user choose between different\n * indices that contains the same data with a different order / ranking formula.\n */\nconst sortBy: SortByWidget = (widgetParams) => {\n const {\n container,\n items,\n cssClasses: userCssClasses = {},\n transformItems,\n } = widgetParams || {};\n if (!container) {\n throw new Error(withUsage('The `container` option is required.'));\n }\n\n const containerNode = getContainerNode(container);\n\n const cssClasses = {\n root: cx(suit(), userCssClasses.root),\n select: cx(suit({ descendantName: 'select' }), userCssClasses.select),\n option: cx(suit({ descendantName: 'option' }), userCssClasses.option),\n };\n\n const specializedRenderer = renderer({\n containerNode,\n cssClasses,\n });\n\n const makeWidget = connectSortBy(specializedRenderer, () =>\n render(null, containerNode)\n );\n\n return {\n ...makeWidget({ container: containerNode, items, transformItems }),\n $$widgetType: 'ais.sortBy',\n };\n};\n\nexport default sortBy;\n","/** @jsx h */\n\nimport { h, render } from 'preact';\nimport cx from 'classnames';\nimport type {\n StatsComponentCSSClasses,\n StatsComponentTemplates,\n} from '../../components/Stats/Stats';\nimport Stats from '../../components/Stats/Stats';\nimport type {\n StatsConnectorParams,\n StatsRenderState,\n StatsWidgetDescription,\n} from '../../connectors/stats/connectStats';\nimport connectStats from '../../connectors/stats/connectStats';\nimport {\n prepareTemplateProps,\n getContainerNode,\n createDocumentationMessageGenerator,\n} from '../../lib/utils';\nimport { component } from '../../lib/suit';\nimport type { Renderer, Template, WidgetFactory } from '../../types';\nimport type { PreparedTemplateProps } from '../../lib/utils/prepareTemplateProps';\n\nconst withUsage = createDocumentationMessageGenerator({ name: 'stats' });\nconst suit = component('Stats');\n\nexport type StatsCSSClasses = Partial<{\n /**\n * CSS class to add to the root element.\n */\n root: string | string[];\n\n /**\n * CSS class to add to the text span element.\n */\n text: string | string[];\n}>;\n\nexport type StatsTemplates = Partial<{\n /**\n * Text template, provided with `hasManyResults`, `hasNoResults`, `hasOneResult`, `hitsPerPage`, `nbHits`, `nbSortedHits`, `nbPages`, `areHitsSorted`, `page`, `processingTimeMS`, `query`.\n */\n text: Template<\n {\n hasManyResults: boolean;\n hasNoResults: boolean;\n hasOneResult: boolean;\n } & StatsRenderState\n >;\n}>;\n\nexport type StatsWidgetParams = {\n /**\n * CSS Selector or HTMLElement to insert the widget.\n */\n container: string | HTMLElement;\n\n /**\n * Templates to use for the widget.\n */\n templates?: StatsTemplates;\n\n /**\n * CSS classes to add.\n */\n cssClasses?: StatsCSSClasses;\n};\n\nexport type StatsWidget = WidgetFactory<\n StatsWidgetDescription & { $$widgetType: 'ais.stats' },\n StatsConnectorParams,\n StatsWidgetParams\n>;\n\nexport const defaultTemplates: StatsComponentTemplates = {\n text: `\n {{#areHitsSorted}}\n {{#hasNoSortedResults}}No relevant results{{/hasNoSortedResults}}\n {{#hasOneSortedResults}}1 relevant result{{/hasOneSortedResults}}\n {{#hasManySortedResults}}{{#helpers.formatNumber}}{{nbSortedHits}}{{/helpers.formatNumber}} relevant results{{/hasManySortedResults}}\n sorted out of {{#helpers.formatNumber}}{{nbHits}}{{/helpers.formatNumber}}\n {{/areHitsSorted}}\n {{^areHitsSorted}}\n {{#hasNoResults}}No results{{/hasNoResults}}\n {{#hasOneResult}}1 result{{/hasOneResult}}\n {{#hasManyResults}}{{#helpers.formatNumber}}{{nbHits}}{{/helpers.formatNumber}} results{{/hasManyResults}}\n {{/areHitsSorted}}\n found in {{processingTimeMS}}ms`,\n};\n\nconst renderer =\n ({\n renderState,\n cssClasses,\n containerNode,\n templates,\n }: {\n renderState: {\n templateProps?: PreparedTemplateProps<StatsComponentTemplates>;\n };\n cssClasses: StatsComponentCSSClasses;\n containerNode: HTMLElement;\n templates: StatsTemplates;\n }): Renderer<StatsRenderState, Partial<StatsWidgetParams>> =>\n (\n {\n hitsPerPage,\n nbHits,\n nbSortedHits,\n areHitsSorted,\n nbPages,\n page,\n processingTimeMS,\n query,\n instantSearchInstance,\n },\n isFirstRendering\n ) => {\n if (isFirstRendering) {\n renderState.templateProps = prepareTemplateProps({\n defaultTemplates,\n templatesConfig: instantSearchInstance.templatesConfig,\n templates,\n });\n\n return;\n }\n\n render(\n <Stats\n cssClasses={cssClasses}\n hitsPerPage={hitsPerPage}\n nbHits={nbHits}\n nbSortedHits={nbSortedHits}\n areHitsSorted={areHitsSorted}\n nbPages={nbPages}\n page={page}\n processingTimeMS={processingTimeMS}\n query={query}\n templateProps={renderState.templateProps!}\n />,\n containerNode\n );\n };\n\n/**\n * The `stats` widget is used to display useful insights about the current results.\n *\n * By default, it will display the **number of hits** and the time taken to compute the\n * results inside the engine.\n */\nconst stats: StatsWidget = (widgetParams) => {\n const {\n container,\n cssClasses: userCssClasses = {},\n templates = {},\n } = widgetParams || {};\n if (!container) {\n throw new Error(withUsage('The `container` option is required.'));\n }\n\n const containerNode = getContainerNode(container);\n\n const cssClasses: StatsComponentCSSClasses = {\n root: cx(suit(), userCssClasses.root),\n text: cx(suit({ descendantName: 'text' }), userCssClasses.text),\n };\n\n const specializedRenderer = renderer({\n containerNode,\n cssClasses,\n templates,\n renderState: {},\n });\n\n const makeWidget = connectStats(specializedRenderer, () =>\n render(null, containerNode)\n );\n\n return {\n ...makeWidget({}),\n $$widgetType: 'ais.stats',\n };\n};\n\nexport default stats;\n","import type { ToggleRefinementComponentTemplates } from '../../components/ToggleRefinement/ToggleRefinement';\n\nconst defaultTemplates: ToggleRefinementComponentTemplates = {\n labelText: '{{name}}',\n};\n\nexport default defaultTemplates;\n","/** @jsx h */\n\nimport { h, render } from 'preact';\nimport cx from 'classnames';\nimport type {\n ToggleRefinementComponentCSSClasses,\n ToggleRefinementComponentTemplates,\n} from '../../components/ToggleRefinement/ToggleRefinement';\nimport ToggleRefinement from '../../components/ToggleRefinement/ToggleRefinement';\nimport type {\n ToggleRefinementConnectorParams,\n ToggleRefinementWidgetDescription,\n ToggleRefinementValue,\n ToggleRefinementRenderState,\n} from '../../connectors/toggle-refinement/connectToggleRefinement';\nimport connectToggleRefinement from '../../connectors/toggle-refinement/connectToggleRefinement';\nimport defaultTemplates from './defaultTemplates';\nimport {\n getContainerNode,\n prepareTemplateProps,\n createDocumentationMessageGenerator,\n} from '../../lib/utils';\nimport type { RendererOptions, Template, WidgetFactory } from '../../types';\nimport { component } from '../../lib/suit';\nimport type { PreparedTemplateProps } from '../../lib/utils/prepareTemplateProps';\n\nconst withUsage = createDocumentationMessageGenerator({\n name: 'toggle-refinement',\n});\nconst suit = component('ToggleRefinement');\n\nconst renderer =\n ({\n containerNode,\n cssClasses,\n renderState,\n templates,\n }: {\n containerNode: HTMLElement;\n cssClasses: ToggleRefinementComponentCSSClasses;\n renderState: {\n templateProps?: PreparedTemplateProps<ToggleRefinementComponentTemplates>;\n };\n templates: ToggleRefinementTemplates;\n }) =>\n (\n {\n value,\n refine,\n instantSearchInstance,\n }: ToggleRefinementRenderState &\n RendererOptions<ToggleRefinementConnectorParams>,\n isFirstRendering: boolean\n ) => {\n if (isFirstRendering) {\n renderState.templateProps = prepareTemplateProps({\n defaultTemplates,\n templatesConfig: instantSearchInstance.templatesConfig,\n templates,\n });\n\n return;\n }\n\n render(\n <ToggleRefinement\n cssClasses={cssClasses}\n currentRefinement={value}\n templateProps={renderState.templateProps!}\n refine={refine}\n />,\n containerNode\n );\n };\n\nexport type ToggleRefinementCSSClasses = Partial<{\n /**\n * CSS class to add to the root element.\n */\n root: string | string[];\n /**\n * CSS class to add to the label wrapping element.\n */\n label: string | string[];\n /**\n * CSS class to add to the checkbox.\n */\n checkbox: string | string[];\n /**\n * CSS class to add to the label text.\n */\n labelText: string | string[];\n}>;\n\nexport type ToggleRefinementTemplates = Partial<{\n /**\n * the text that describes the toggle action\n */\n labelText: Template<ToggleRefinementValue>;\n}>;\n\nexport type ToggleRefinementWidgetParams = {\n /**\n * CSS Selector or HTMLElement to insert the widget.\n */\n container: string | HTMLElement;\n\n /**\n * Templates to use for the widget.\n */\n templates?: ToggleRefinementTemplates;\n\n /**\n * CSS classes to be added.\n */\n cssClasses?: ToggleRefinementCSSClasses;\n};\n\nexport type ToggleRefinementWidget = WidgetFactory<\n ToggleRefinementWidgetDescription & {\n $$widgetType: 'ais.toggleRefinement';\n },\n ToggleRefinementConnectorParams,\n ToggleRefinementWidgetParams\n>;\n\n/**\n * The toggleRefinement widget lets the user either:\n * - switch between two values for a single facetted attribute (free_shipping / not_free_shipping)\n * - toggleRefinement a faceted value on and off (only 'canon' for brands)\n *\n * This widget is particularly useful if you have a boolean value in the records.\n *\n * @requirements\n * The attribute passed to `attribute` must be declared as an\n * [attribute for faceting](https://www.algolia.com/doc/guides/searching/faceting/#declaring-attributes-for-faceting)\n * in your Algolia settings.\n */\nconst toggleRefinement: ToggleRefinementWidget = function toggleRefinement(\n widgetParams\n) {\n const {\n container,\n attribute,\n cssClasses: userCssClasses = {},\n templates = {},\n on = true,\n off,\n } = widgetParams || {};\n if (!container) {\n throw new Error(withUsage('The `container` option is required.'));\n }\n\n const containerNode = getContainerNode(container);\n\n const cssClasses = {\n root: cx(suit(), userCssClasses.root),\n label: cx(suit({ descendantName: 'label' }), userCssClasses.label),\n checkbox: cx(suit({ descendantName: 'checkbox' }), userCssClasses.checkbox),\n labelText: cx(\n suit({ descendantName: 'labelText' }),\n userCssClasses.labelText\n ),\n };\n\n const specializedRenderer = renderer({\n containerNode,\n cssClasses,\n renderState: {},\n templates,\n });\n\n const makeWidget = connectToggleRefinement(specializedRenderer, () =>\n render(null, containerNode)\n );\n\n return {\n ...makeWidget({ attribute, on, off }),\n $$widgetType: 'ais.toggleRefinement',\n };\n};\n\nexport default toggleRefinement;\n","import type { VoiceSearchComponentTemplates } from '../../components/VoiceSearch/VoiceSearch';\n\nconst getButtonInnerElement = (\n status: string,\n errorCode: string,\n isListening: boolean\n) => {\n if (status === 'error' && errorCode === 'not-allowed') {\n return `<line x1=\"1\" y1=\"1\" x2=\"23\" y2=\"23\"></line>\n <path d=\"M9 9v3a3 3 0 0 0 5.12 2.12M15 9.34V4a3 3 0 0 0-5.94-.6\"></path>\n <path d=\"M17 16.95A7 7 0 0 1 5 12v-2m14 0v2a7 7 0 0 1-.11 1.23\"></path>\n <line x1=\"12\" y1=\"19\" x2=\"12\" y2=\"23\"></line>\n <line x1=\"8\" y1=\"23\" x2=\"16\" y2=\"23\"></line>`;\n }\n return `<path\n d=\"M12 1a3 3 0 0 0-3 3v8a3 3 0 0 0 6 0V4a3 3 0 0 0-3-3z\"\n fill=\"${isListening ? 'currentColor' : 'none'}\">\n </path>\n <path d=\"M19 10v2a7 7 0 0 1-14 0v-2\"></path>\n <line x1=\"12\" y1=\"19\" x2=\"12\" y2=\"23\"></line>\n <line x1=\"8\" y1=\"23\" x2=\"16\" y2=\"23\"></line>`;\n};\n\nconst defaultTemplates: VoiceSearchComponentTemplates = {\n buttonText({ status, errorCode, isListening }) {\n return `<svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n >\n ${getButtonInnerElement(status, errorCode, isListening)}\n </svg>`;\n },\n status: `<p>{{transcript}}</p>`,\n};\n\nexport default defaultTemplates;\n","/** @jsx h */\n\nimport { h, render } from 'preact';\nimport cx from 'classnames';\nimport type { PlainSearchParameters } from 'algoliasearch-helper';\nimport {\n getContainerNode,\n createDocumentationMessageGenerator,\n} from '../../lib/utils';\nimport { component } from '../../lib/suit';\nimport type {\n VoiceSearchConnectorParams,\n VoiceSearchRenderState,\n VoiceSearchWidgetDescription,\n} from '../../connectors/voice-search/connectVoiceSearch';\nimport connectVoiceSearch from '../../connectors/voice-search/connectVoiceSearch';\nimport type {\n VoiceSearchComponentCSSClasses,\n VoiceSearchComponentTemplates,\n} from '../../components/VoiceSearch/VoiceSearch';\nimport VoiceSearchComponent from '../../components/VoiceSearch/VoiceSearch';\nimport defaultTemplates from './defaultTemplates';\nimport type { WidgetFactory, Template, Renderer } from '../../types';\nimport type { CreateVoiceSearchHelper } from '../../lib/voiceSearchHelper/types';\n\nconst withUsage = createDocumentationMessageGenerator({ name: 'voice-search' });\nconst suit = component('VoiceSearch');\n\nexport type VoiceSearchCSSClasses = Partial<{\n root: string | string[];\n button: string | string[];\n status: string | string[];\n}>;\n\ntype VoiceSearchTemplateProps = {\n status: string;\n errorCode: string;\n isListening: boolean;\n transcript: string;\n isSpeechFinal: boolean;\n isBrowserSupported: boolean;\n};\n\nexport type VoiceSearchTemplates = Partial<{\n buttonText: Template<VoiceSearchTemplateProps>;\n status: Template<VoiceSearchTemplateProps>;\n}>;\n\nexport type VoiceSearchWidgetParams = {\n container: string | HTMLElement;\n cssClasses?: VoiceSearchCSSClasses;\n templates?: VoiceSearchTemplates;\n searchAsYouSpeak?: boolean;\n language?: string;\n additionalQueryParameters?: (params: {\n query: string;\n }) => PlainSearchParameters | void;\n createVoiceSearchHelper?: CreateVoiceSearchHelper;\n};\n\nexport type VoiceSearchWidget = WidgetFactory<\n VoiceSearchWidgetDescription & { $$type: 'ais.voiceSearch' },\n VoiceSearchConnectorParams,\n VoiceSearchWidgetParams\n>;\n\nconst renderer =\n ({\n containerNode,\n cssClasses,\n templates,\n }: {\n containerNode: HTMLElement;\n cssClasses: VoiceSearchComponentCSSClasses;\n templates: VoiceSearchComponentTemplates;\n }): Renderer<VoiceSearchRenderState, Partial<VoiceSearchWidgetParams>> =>\n ({\n isBrowserSupported,\n isListening,\n toggleListening,\n voiceListeningState,\n }) => {\n render(\n <VoiceSearchComponent\n cssClasses={cssClasses}\n templates={templates}\n isBrowserSupported={isBrowserSupported}\n isListening={isListening}\n toggleListening={toggleListening}\n voiceListeningState={voiceListeningState}\n />,\n containerNode\n );\n };\n\nconst voiceSearch: VoiceSearchWidget = (widgetParams) => {\n const {\n container,\n cssClasses: userCssClasses = {},\n templates: userTemplates = {},\n searchAsYouSpeak = false,\n language,\n additionalQueryParameters,\n createVoiceSearchHelper,\n }: VoiceSearchWidgetParams = widgetParams || {};\n if (!container) {\n throw new Error(withUsage('The `container` option is required.'));\n }\n\n const containerNode = getContainerNode(container);\n\n const cssClasses = {\n root: cx(suit(), userCssClasses.root),\n button: cx(suit({ descendantName: 'button' }), userCssClasses.button),\n status: cx(suit({ descendantName: 'status' }), userCssClasses.status),\n };\n const templates = {\n ...defaultTemplates,\n ...userTemplates,\n };\n\n const specializedRenderer = renderer({\n containerNode,\n cssClasses,\n templates,\n });\n\n const makeWidget = connectVoiceSearch(specializedRenderer, () =>\n render(null, containerNode)\n );\n\n return {\n ...makeWidget({\n container: containerNode,\n cssClasses,\n templates,\n searchAsYouSpeak,\n language,\n additionalQueryParameters,\n createVoiceSearchHelper,\n }),\n $$widgetType: 'ais.voiceSearch',\n };\n};\n\nexport default voiceSearch;\n","export { default as analytics } from './analytics/analytics';\nexport { default as breadcrumb } from './breadcrumb/breadcrumb';\nexport { default as clearRefinements } from './clear-refinements/clear-refinements';\nexport { default as configure } from './configure/configure';\nexport { default as currentRefinements } from './current-refinements/current-refinements';\nexport { default as EXPERIMENTAL_answers } from './answers/answers';\nexport { default as EXPERIMENTAL_configureRelatedItems } from './configure-related-items/configure-related-items';\n\nimport dynamicWidgets from './dynamic-widgets/dynamic-widgets';\nexport { dynamicWidgets };\nimport { deprecate } from '../lib/utils';\n/** @deprecated use dynamicWidgets */\nexport const EXPERIMENTAL_dynamicWidgets = deprecate(\n dynamicWidgets,\n 'use dynamicWidgets'\n);\n\nexport { default as geoSearch } from './geo-search/geo-search';\nexport { default as hierarchicalMenu } from './hierarchical-menu/hierarchical-menu';\nexport { default as hits } from './hits/hits';\nexport { default as hitsPerPage } from './hits-per-page/hits-per-page';\nexport { default as index } from './index/index';\nexport { default as infiniteHits } from './infinite-hits/infinite-hits';\nexport { default as menu } from './menu/menu';\nexport { default as menuSelect } from './menu-select/menu-select';\nexport { default as numericMenu } from './numeric-menu/numeric-menu';\nexport { default as pagination } from './pagination/pagination';\nexport { default as panel } from './panel/panel';\nexport { default as places } from './places/places';\nexport { default as poweredBy } from './powered-by/powered-by';\nexport { default as queryRuleContext } from './query-rule-context/query-rule-context';\nexport { default as queryRuleCustomData } from './query-rule-custom-data/query-rule-custom-data';\nexport { default as rangeInput } from './range-input/range-input';\nexport { default as rangeSlider } from './range-slider/range-slider';\nexport { default as ratingMenu } from './rating-menu/rating-menu';\nexport { default as refinementList } from './refinement-list/refinement-list';\nexport { default as relevantSort } from './relevant-sort/relevant-sort';\nexport { default as searchBox } from './search-box/search-box';\nexport { default as sortBy } from './sort-by/sort-by';\nexport { default as stats } from './stats/stats';\nexport { default as toggleRefinement } from './toggle-refinement/toggle-refinement';\nexport { default as voiceSearch } from './voice-search/voice-search';\n","import type {\n ConfigureConnectorParams,\n ConfigureWidgetDescription,\n} from '../../connectors/configure/connectConfigure';\nimport connectConfigure from '../../connectors/configure/connectConfigure';\nimport type { Widget } from '../../types';\nimport { noop } from '../../lib/utils';\n\n/**\n * A list of [search parameters](https://www.algolia.com/doc/api-reference/search-api-parameters/)\n * to enable when the widget mounts.\n */\nexport type ConfigureWidgetParams =\n ConfigureConnectorParams['searchParameters'];\n\nexport type ConfigureWidget = (widgetParams: ConfigureWidgetParams) => Widget<\n ConfigureWidgetDescription & {\n $$widgetType: 'ais.configure';\n widgetParams: ConfigureConnectorParams;\n }\n>;\n\nconst configure: ConfigureWidget = function configure(widgetParams) {\n // This is a renderless widget that falls back to the connector's\n // noop render and unmount functions.\n const makeWidget = connectConfigure(noop);\n\n return {\n ...makeWidget({ searchParameters: widgetParams }),\n $$widgetType: 'ais.configure',\n };\n};\n\nexport default configure;\n","import type { PlainSearchParameters } from 'algoliasearch-helper';\nimport { noop } from '../../lib/utils';\nimport type {\n ConfigureRelatedItemsConnectorParams,\n ConfigureRelatedItemsWidgetDescription,\n} from '../../connectors/configure-related-items/connectConfigureRelatedItems';\nimport connectConfigureRelatedItems from '../../connectors/configure-related-items/connectConfigureRelatedItems';\nimport type { WidgetFactory } from '../../types';\n\nexport type ConfigureRelatedItemsWidget = WidgetFactory<\n ConfigureRelatedItemsWidgetDescription & {\n $$widgetType: 'ais.configureRelatedItems';\n },\n ConfigureRelatedItemsConnectorParams,\n ConfigureRelatedItemsWidgetParams\n>;\n\nexport type ConfigureRelatedItemsWidgetParams = PlainSearchParameters;\n\nconst configureRelatedItems: ConfigureRelatedItemsWidget =\n function configureRelatedItems(widgetParams) {\n const makeWidget = connectConfigureRelatedItems(noop);\n\n return {\n ...makeWidget(widgetParams),\n $$widgetType: 'ais.configureRelatedItems',\n };\n };\n\nexport default configureRelatedItems;\n","/* global google EventListener */\n\nexport type HTMLMarkerArguments = {\n __id: string;\n position: google.maps.LatLngLiteral;\n map: google.maps.Map;\n template: string;\n title?: string;\n className: string;\n anchor?: { x: number; y: number };\n};\n\ninterface Marker {\n __id: string;\n anchor: { x: number; y: number };\n offset?: { x: number; y: number };\n listeners: { [key: string]: EventListener };\n latLng: google.maps.LatLng;\n element: HTMLDivElement;\n getPosition(): google.maps.LatLng;\n}\n\nconst createHTMLMarker = (\n googleReference: typeof google\n): new (args: HTMLMarkerArguments) => google.maps.OverlayView & Marker => {\n class HTMLMarker extends googleReference.maps.OverlayView {\n public __id: string;\n public anchor: {\n x: number;\n y: number;\n };\n public offset?: {\n x: number;\n y: number;\n };\n public listeners: { [key: string]: EventListener };\n public latLng: google.maps.LatLng;\n public element: HTMLDivElement;\n\n public constructor({\n __id,\n position,\n map,\n template,\n className,\n anchor = {\n x: 0,\n y: 0,\n },\n }: HTMLMarkerArguments) {\n super();\n\n this.__id = __id;\n this.anchor = anchor;\n this.listeners = {};\n this.latLng = new googleReference.maps.LatLng(position);\n\n this.element = document.createElement('div');\n this.element.className = className;\n this.element.style.position = 'absolute';\n this.element.innerHTML = template;\n\n this.setMap(map);\n }\n\n public onAdd() {\n // Append the element to the map\n this.getPanes()!.overlayMouseTarget.appendChild(this.element);\n\n // Compute the offset onAdd & cache it because afterwards\n // it won't retrieve the correct values, we also avoid\n // to read the values on every draw\n const bbBox = this.element.getBoundingClientRect();\n\n this.offset = {\n x: this.anchor.x + bbBox.width / 2,\n y: this.anchor.y + bbBox.height,\n };\n\n // Force the width of the element will avoid the\n // content to collapse when we move the map\n this.element.style.width = `${bbBox.width}px`;\n }\n\n public draw() {\n const position = this.getProjection().fromLatLngToDivPixel(this.latLng)!;\n\n this.element.style.left = `${Math.round(position.x - this.offset!.x)}px`;\n this.element.style.top = `${Math.round(position.y - this.offset!.y)}px`;\n\n // Markers to the south are in front of markers to the north\n // This is the default behaviour of Google Maps\n this.element.style.zIndex = String(parseInt(this.element.style.top, 10));\n }\n\n public onRemove() {\n if (this.element) {\n this.element.parentNode!.removeChild(this.element);\n\n Object.keys(this.listeners).forEach((eventName) => {\n this.element.removeEventListener(\n eventName,\n this.listeners[eventName]\n );\n });\n\n // after onRemove the class is no longer used, thus it can be deleted\n // @ts-expect-error\n delete this.element;\n // @ts-expect-error\n delete this.listeners;\n }\n }\n\n public addListener(eventName: string, listener: EventListener) {\n this.listeners[eventName] = listener;\n\n const element = this.element;\n\n element.addEventListener(eventName, listener);\n\n return {\n remove() {\n return element.removeEventListener(eventName, listener);\n },\n };\n }\n\n public getPosition() {\n return this.latLng;\n }\n }\n\n return HTMLMarker;\n};\n\nexport default createHTMLMarker;\n","/** @ts-ignore */\nimport type * as Places from 'places.js';\nimport type { WidgetFactory, WidgetRenderState } from '../../types';\n\n// using the type like this requires only one ts-ignore\ntype StaticOptions = Places.StaticOptions;\ntype ChangeEvent = Places.ChangeEvent;\ntype PlacesInstance = Places.PlacesInstance;\ntype ReconfigurableOptions = Places.ReconfigurableOptions;\n\nexport type PlacesWidgetParams = {\n /**\n * The Algolia Places reference to use.\n *\n * @see https://github.com/algolia/places\n */\n placesReference: (\n options: StaticOptions & ReconfigurableOptions\n ) => PlacesInstance;\n /**\n * The default position when the input is empty.\n */\n defaultPosition?: string[];\n} & StaticOptions;\n\ntype PlacesWidgetState = {\n query: string;\n initialLatLngViaIP: boolean | undefined;\n isInitialLatLngViaIPSet: boolean;\n};\n\nexport type PlacesWidgetDescription = {\n $$type: 'ais.places';\n $$widgetType: 'ais.places';\n renderState: Record<string, unknown>;\n indexRenderState: {\n places: WidgetRenderState<Record<string, unknown>, PlacesWidgetParams>;\n };\n indexUiState: {\n places: {\n query: string;\n position: string;\n };\n };\n};\n\nexport type PlacesWidget = WidgetFactory<\n PlacesWidgetDescription,\n PlacesWidgetParams,\n PlacesWidgetParams\n>;\n\n/**\n * This widget sets the geolocation value for the search based on the selected\n * result in the Algolia Places autocomplete.\n */\nconst placesWidget: PlacesWidget = (widgetParams) => {\n const {\n placesReference,\n defaultPosition = [],\n ...placesOptions\n } = widgetParams || {};\n\n if (typeof placesReference !== 'function') {\n throw new Error(\n 'The `placesReference` option requires a valid Places.js reference.'\n );\n }\n\n const placesAutocomplete = placesReference(placesOptions);\n\n const state: PlacesWidgetState = {\n query: '',\n initialLatLngViaIP: undefined,\n isInitialLatLngViaIPSet: false,\n };\n\n return {\n $$type: 'ais.places',\n $$widgetType: 'ais.places',\n\n init({ helper }) {\n placesAutocomplete.on('change', (eventOptions: ChangeEvent) => {\n const {\n suggestion: {\n value,\n latlng: { lat, lng },\n },\n } = eventOptions;\n\n state.query = value;\n\n helper\n .setQueryParameter('insideBoundingBox', undefined)\n .setQueryParameter('aroundLatLngViaIP', false)\n .setQueryParameter('aroundLatLng', `${lat},${lng}`)\n .search();\n });\n\n placesAutocomplete.on('clear', () => {\n state.query = '';\n\n helper.setQueryParameter('insideBoundingBox', undefined);\n\n if (defaultPosition.length > 1) {\n helper\n .setQueryParameter('aroundLatLngViaIP', false)\n .setQueryParameter('aroundLatLng', defaultPosition.join(','));\n } else {\n helper\n .setQueryParameter('aroundLatLngViaIP', state.initialLatLngViaIP)\n .setQueryParameter('aroundLatLng', undefined);\n }\n\n helper.search();\n });\n },\n\n getWidgetUiState(uiState, { searchParameters }) {\n const position =\n searchParameters.aroundLatLng || defaultPosition.join(',');\n const hasPositionSet = position !== defaultPosition.join(',');\n\n if (!hasPositionSet && !state.query) {\n const { places, ...uiStateWithoutPlaces } = uiState;\n\n return uiStateWithoutPlaces;\n }\n\n return {\n ...uiState,\n places: {\n query: state.query,\n position,\n },\n };\n },\n\n getWidgetSearchParameters(searchParameters, { uiState }) {\n const { query = '', position = defaultPosition.join(',') } =\n uiState.places || {};\n\n state.query = query;\n\n if (!state.isInitialLatLngViaIPSet) {\n state.isInitialLatLngViaIPSet = true;\n state.initialLatLngViaIP = searchParameters.aroundLatLngViaIP;\n }\n\n placesAutocomplete.setVal(query);\n placesAutocomplete.close();\n\n return searchParameters\n .setQueryParameter('insideBoundingBox', undefined)\n .setQueryParameter('aroundLatLngViaIP', false)\n .setQueryParameter('aroundLatLng', position || undefined);\n },\n\n getRenderState(renderState, renderOptions) {\n return {\n ...renderState,\n places: this.getWidgetRenderState(renderOptions),\n };\n },\n\n getWidgetRenderState() {\n return {\n widgetParams,\n };\n },\n };\n};\n\nexport default placesWidget;\n","import type {\n InsightsClient,\n InsightsClientMethod,\n InternalMiddleware,\n Hit,\n} from '../types';\nimport { getInsightsAnonymousUserTokenInternal } from '../helpers';\nimport { warning, noop, getAppIdAndApiKey, find } from '../lib/utils';\nimport connectConfigure from '../connectors/configure/connectConfigure';\n\nexport type InsightsEvent = {\n insightsMethod?: InsightsClientMethod;\n payload: any;\n widgetType: string;\n eventType: string; // 'view' | 'click' | 'conversion', but we're not restricting.\n hits?: Hit[];\n attribute?: string;\n};\n\nexport type InsightsProps = {\n insightsClient: null | InsightsClient;\n insightsInitParams?: {\n userHasOptedOut?: boolean;\n useCookie?: boolean;\n cookieDuration?: number;\n region?: 'de' | 'us';\n };\n onEvent?: (\n event: InsightsEvent,\n insightsClient: null | InsightsClient\n ) => void;\n};\n\nexport type CreateInsightsMiddleware = (\n props: InsightsProps\n) => InternalMiddleware;\n\nexport const createInsightsMiddleware: CreateInsightsMiddleware = (props) => {\n const {\n insightsClient: _insightsClient,\n insightsInitParams,\n onEvent,\n } = props || {};\n if (_insightsClient !== null && !_insightsClient) {\n if (__DEV__) {\n throw new Error(\n \"The `insightsClient` option is required if you want userToken to be automatically set in search calls. If you don't want this behaviour, set it to `null`.\"\n );\n } else {\n throw new Error(\n 'The `insightsClient` option is required. To disable, set it to `null`.'\n );\n }\n }\n\n const hasInsightsClient = Boolean(_insightsClient);\n const insightsClient =\n _insightsClient === null ? (noop as InsightsClient) : _insightsClient;\n\n return ({ instantSearchInstance }) => {\n const [appId, apiKey] = getAppIdAndApiKey(instantSearchInstance.client);\n\n // search-insights.js also throws an error so dev-only clarification is sufficient\n if (__DEV__ && !(appId && apiKey)) {\n throw new Error(\n '[insights middleware]: could not extract Algolia credentials from searchClient'\n );\n }\n\n let queuedUserToken: string | undefined = undefined;\n let userTokenBeforeInit: string | undefined = undefined;\n\n if (Array.isArray(insightsClient.queue)) {\n // Context: The umd build of search-insights is asynchronously loaded by the snippet.\n //\n // When user calls `aa('setUserToken', 'my-user-token')` before `search-insights` is loaded,\n // ['setUserToken', 'my-user-token'] gets stored in `aa.queue`.\n // Whenever `search-insights` is finally loaded, it will process the queue.\n //\n // But here's the reason why we handle it here:\n // At this point, even though `search-insights` is not loaded yet,\n // we still want to read the token from the queue.\n // Otherwise, the first search call will be fired without the token.\n [, queuedUserToken] =\n find(\n insightsClient.queue.slice().reverse(),\n ([method]) => method === 'setUserToken'\n ) || [];\n }\n insightsClient('getUserToken', null, (_error: any, userToken: string) => {\n // If user has called `aa('setUserToken', 'my-user-token')` before creating\n // the `insights` middleware, we store them temporarily and\n // set it later on.\n //\n // Otherwise, the `init` call might override it with anonymous user token.\n userTokenBeforeInit = userToken;\n });\n insightsClient('init', { appId, apiKey, ...insightsInitParams });\n\n const createWidget = connectConfigure(noop);\n let configureClickAnalytics: ReturnType<typeof createWidget> | undefined;\n let configureUserToken: ReturnType<typeof createWidget> | undefined;\n\n return {\n onStateChange() {},\n subscribe() {\n insightsClient('addAlgoliaAgent', 'insights-middleware');\n\n configureClickAnalytics = createWidget({\n searchParameters: { clickAnalytics: true },\n });\n instantSearchInstance.addWidgets([configureClickAnalytics]);\n\n const setUserTokenToSearch = (userToken?: string) => {\n if (configureUserToken) {\n instantSearchInstance.removeWidgets([configureUserToken]);\n }\n configureUserToken = createWidget({\n searchParameters: { userToken },\n });\n instantSearchInstance.addWidgets([configureUserToken]);\n };\n\n const anonymousUserToken = getInsightsAnonymousUserTokenInternal();\n if (hasInsightsClient && anonymousUserToken) {\n // When `aa('init', { ... })` is called, it creates an anonymous user token in cookie.\n // We can set it as userToken.\n setUserTokenToSearch(anonymousUserToken);\n }\n\n // We consider the `userToken` coming from a `init` call to have a higher\n // importance than the one coming from the queue.\n if (userTokenBeforeInit) {\n insightsClient('setUserToken', userTokenBeforeInit);\n } else if (queuedUserToken) {\n insightsClient('setUserToken', queuedUserToken);\n }\n\n // This updates userToken which is set explicitly by `aa('setUserToken', userToken)`\n insightsClient('onUserTokenChange', setUserTokenToSearch, {\n immediate: true,\n });\n\n instantSearchInstance.sendEventToInsights = (event: InsightsEvent) => {\n if (onEvent) {\n onEvent(event, _insightsClient);\n } else if (event.insightsMethod) {\n // At this point, instantSearchInstance must be started and\n // it means there is a configure widget (added above).\n const hasUserToken = Boolean(\n instantSearchInstance.renderState[instantSearchInstance.indexName]\n .configure!.widgetParams.searchParameters.userToken\n );\n if (hasUserToken) {\n insightsClient(event.insightsMethod, event.payload);\n } else {\n warning(\n false,\n `\nCannot send event to Algolia Insights because \\`userToken\\` is not set.\n\nSee documentation: https://www.algolia.com/doc/guides/building-search-ui/going-further/send-insights-events/js/#setting-the-usertoken\n`\n );\n }\n } else {\n warning(\n false,\n 'Cannot send event to Algolia Insights because `insightsMethod` option is missing.'\n );\n }\n };\n },\n unsubscribe() {\n insightsClient('onUserTokenChange', undefined);\n instantSearchInstance.removeWidgets([\n configureClickAnalytics!,\n configureUserToken!,\n ]);\n configureClickAnalytics = undefined;\n configureUserToken = undefined;\n instantSearchInstance.sendEventToInsights = noop;\n },\n };\n };\n};\n","// typed as any, since it accepts the _real_ js clients, not the interface we otherwise expect\nexport function getAppIdAndApiKey(searchClient: any) {\n if (searchClient.transporter) {\n // searchClient v4\n const { headers, queryParameters } = searchClient.transporter;\n const APP_ID = 'x-algolia-application-id';\n const API_KEY = 'x-algolia-api-key';\n const appId = headers[APP_ID] || queryParameters[APP_ID];\n const apiKey = headers[API_KEY] || queryParameters[API_KEY];\n return [appId, apiKey];\n } else {\n // searchClient v3\n return [searchClient.applicationID, searchClient.apiKey];\n }\n}\n","import type { StateMapping, IndexUiState, UiState } from '../../types';\n\nfunction getIndexStateWithoutConfigure<TIndexUiState extends IndexUiState>(\n uiState: TIndexUiState\n): TIndexUiState {\n const { configure, ...trackedUiState } = uiState;\n return trackedUiState as TIndexUiState;\n}\n\nexport default function singleIndexStateMapping<\n TUiState extends UiState = UiState\n>(\n indexName: keyof TUiState\n): StateMapping<TUiState, TUiState[typeof indexName]> {\n return {\n stateToRoute(uiState) {\n return getIndexStateWithoutConfigure(uiState[indexName] || {});\n },\n routeToState(routeState = {} as TUiState[typeof indexName]) {\n return {\n [indexName]: getIndexStateWithoutConfigure(routeState),\n } as unknown as TUiState;\n },\n };\n}\n","import type { PlainSearchParameters } from 'algoliasearch-helper';\nimport { isEqual, safelyRunOnBrowser } from '../utils';\nimport type { InfiniteHitsCache } from '../../connectors/infinite-hits/connectInfiniteHits';\n\nfunction getStateWithoutPage(state: PlainSearchParameters) {\n const { page, ...rest } = state || {};\n return rest;\n}\n\nconst KEY = 'ais.infiniteHits';\n\nexport default function createInfiniteHitsSessionStorageCache(): InfiniteHitsCache {\n return {\n read({ state }) {\n const sessionStorage = safelyRunOnBrowser<Storage | undefined>(\n ({ window }) => window.sessionStorage\n );\n\n if (!sessionStorage) {\n return null;\n }\n\n try {\n const cache = JSON.parse(\n // @ts-expect-error JSON.parse() requires a string, but it actually accepts null, too.\n sessionStorage.getItem(KEY)\n );\n\n return cache && isEqual(cache.state, getStateWithoutPage(state))\n ? cache.hits\n : null;\n } catch (error) {\n if (error instanceof SyntaxError) {\n try {\n sessionStorage.removeItem(KEY);\n } catch (err) {\n // do nothing\n }\n }\n return null;\n }\n },\n write({ state, hits }) {\n const sessionStorage = safelyRunOnBrowser<Storage | undefined>(\n ({ window }) => window.sessionStorage\n );\n\n if (!sessionStorage) {\n return;\n }\n\n try {\n sessionStorage.setItem(\n KEY,\n JSON.stringify({\n state: getStateWithoutPage(state),\n hits,\n })\n );\n } catch (error) {\n // do nothing\n }\n },\n };\n}\n","import type { InstantSearchOptions } from './lib/InstantSearch';\nimport InstantSearch from './lib/InstantSearch';\nimport type { Expand, UiState } from './types';\n\nimport version from './lib/version';\n\nimport * as connectors from './connectors/index';\nimport * as widgets from './widgets/index';\nimport * as helpers from './helpers/index';\nimport * as middlewares from './middlewares/index';\n\nimport * as routers from './lib/routers/index';\nimport * as stateMappings from './lib/stateMappings/index';\nimport { createInfiniteHitsSessionStorageCache } from './lib/infiniteHitsCache/index';\n\ntype InstantSearchModule = {\n <TUiState = Record<string, unknown>, TRouteState = TUiState>(\n options: InstantSearchOptions<Expand<UiState & TUiState>, TRouteState>\n ): InstantSearch<Expand<UiState & TUiState>, TRouteState>;\n version: string;\n\n connectors: typeof connectors;\n widgets: typeof widgets;\n middlewares: typeof middlewares;\n\n routers: typeof routers;\n stateMappings: typeof stateMappings;\n\n createInfiniteHitsSessionStorageCache: typeof createInfiniteHitsSessionStorageCache;\n highlight: typeof helpers.highlight;\n reverseHighlight: typeof helpers.reverseHighlight;\n snippet: typeof helpers.snippet;\n reverseSnippet: typeof helpers.reverseSnippet;\n insights: typeof helpers.insights;\n};\n\n/**\n * InstantSearch is the main component of InstantSearch.js. This object\n * manages the widget and lets you add new ones.\n *\n * Two parameters are required to get you started with InstantSearch.js:\n * - `indexName`: the main index that you will use for your new search UI\n * - `searchClient`: the search client to plug to InstantSearch.js\n *\n * The [search client provided by Algolia](algolia.com/doc/api-client/getting-started/what-is-the-api-client/javascript/)\n * needs an `appId` and an `apiKey`. Those parameters can be found in your\n * [Algolia dashboard](https://www.algolia.com/api-keys).\n *\n * If you want to get up and running quickly with InstantSearch.js, have a\n * look at the [getting started](https://www.algolia.com/doc/guides/building-search-ui/getting-started/js/).\n */\nconst instantsearch: InstantSearchModule = (options) =>\n new InstantSearch(options);\n\ninstantsearch.version = version;\n\ninstantsearch.connectors = connectors;\ninstantsearch.widgets = widgets;\ninstantsearch.middlewares = middlewares;\n\ninstantsearch.routers = routers;\ninstantsearch.stateMappings = stateMappings;\n\ninstantsearch.createInfiniteHitsSessionStorageCache =\n createInfiniteHitsSessionStorageCache;\ninstantsearch.highlight = helpers.highlight;\ninstantsearch.reverseHighlight = helpers.reverseHighlight;\ninstantsearch.snippet = helpers.snippet;\ninstantsearch.reverseSnippet = helpers.reverseSnippet;\ninstantsearch.insights = helpers.insights;\n\nexport default instantsearch;\n"],"names":["isObjectOrArrayOrFunction","value","Array","isArray","Object","prototype","toString","call","_merge","target","source","key","hasOwnProperty","sourceVal","targetVal","i","l","arguments","length","slice","reduceRight","acc","keys","forEach","undefined","arr1","arr2","filter","index","indexOf","array","comparator","valToNumber","v","parseFloat","map","Error","excluded","sourceKeys","obj","userToken","test","lib","addRefinement","refinementList","attribute","isRefined","valueAsString","facetRefinement","concat","mod","defaultsPure","removeRefinement","clearRefinement","f","toggleRefinement","refinementType","objectHasKeys","omit","hasChanged","newRefinementList","reduce","memo","values","facetList","refinementValue","containsRefinements","refinementValueAsString","isEqualNumericRefinement","a","b","every","el","SearchParameters","newParameters","params","_parseNumbers","isValidUserToken","console","warn","this","facets","disjunctiveFacets","hierarchicalFacets","facetsRefinements","facetsExcludes","disjunctiveFacetsRefinements","numericRefinements","tagRefinements","hierarchicalFacetsRefinements","self","paramName","isKeyKnown","PARAMETERS","isValueDefined","partialState","numbers","k","parsedValue","isNaN","insideBoundingBox","geoRect","operators","operator","parsedValues","vPrime","merge","make","instance","facet","rootPath","currentRefinement","getHierarchicalRefinement","name","clearRefinements","toggleHierarchicalFacetRefinement","validate","currentState","parameters","tagFilters","numericFilters","constructor","patch","_clearNumericRefinements","RefinementList","setQueryParameters","clearTags","setIndex","setQuery","newQuery","query","setPage","newPage","page","setFacets","setDisjunctiveFacets","setHitsPerPage","n","hitsPerPage","setTypoTolerance","typoTolerance","addNumericRefinement","isNumericRefined","push","getConjunctiveRefinements","facetName","isConjunctiveFacet","getDisjunctiveRefinements","isDisjunctiveFacet","getExcludeRefinements","removeNumericRefinement","paramValue","op","val","getNumericRefinements","getNumericRefinement","newNumericRefinements","operatorList","outValues","addFacet","addDisjunctiveFacet","addHierarchicalFacet","hierarchicalFacet","isHierarchicalFacet","addFacetRefinement","addExcludeRefinement","addDisjunctiveFacetRefinement","addTagRefinement","tag","isTagRefined","modification","removeFacet","removeDisjunctiveFacet","removeHierarchicalFacet","removeFacetRefinement","removeExcludeRefinement","removeDisjunctiveFacetRefinement","removeTagRefinement","t","toggleFacetRefinement","toggleConjunctiveFacetRefinement","toggleDisjunctiveFacetRefinement","toggleExcludeFacetRefinement","separator","_getHierarchicalFacetSeparator","getHierarchicalFacetByName","lastIndexOf","addHierarchicalFacetRefinement","path","isHierarchicalFacetRefined","removeHierarchicalFacetRefinement","toggleTagRefinement","isFacetRefined","isExcludeRefined","isDisjunctiveFacetRefined","refinements","isOperatorDefined","isAttributeValueDefined","searchedValue","find","currentValue","findArray","getRefinedDisjunctiveFacets","disjunctiveNumericRefinedFacets","intersection","getRefinedHierarchicalFacets","getUnrefinedDisjunctiveFacets","refinedFacets","managedParameters","getQueryParams","queryParams","setQueryParameter","parameter","error","nextWithNumbers","previousPlainObject","nextPlainObject","previous","isPreviousValueDefined","isNextValueDefined","resetPage","_getHierarchicalFacetSortBy","sortBy","_getHierarchicalRootPath","_getHierarchicalShowParentLevel","showParentLevel","hierarchicalFacetName","getHierarchicalFacetBreadcrumb","refinement","split","part","trim","JSON","stringify","compareAscending","other","valIsDefined","valIsNull","othIsDefined","othIsNull","Boolean","defaults","defaultInstructions","sort","out","sortInstruction","matchingDefault","defaultInstruction","collection","iteratees","orders","result","criteria","iteratee","object","res","state","hierarchicalFacetResult","hierarchicalFacetIndex","hierarchicalFacetRefinement","hierarchicalSeparator","hierarchicalRootPath","hierarchicalShowParentLevel","prepareHierarchicalFacetSortBy","rootExhaustive","facetResult","exhaustive","generateTreeFn","hierarchicalTree","currentHierarchicalLevel","parent","level","data","subtree","picked","facetValue","tuple","parentPath","onlyMatchingTree","orderBy","facetCount","parts","count","format","generateHierarchicalTree","results","getIndices","attributes","indices","idx","assignFacetStats","dest","facetStats","stats","SearchResults","mainSubResponse","_rawResults","processingTimeMS","sum","facetsIndices","disjunctiveFacetsIndices","nextDisjunctiveResult","mainFacets","facetKey","facetValueObject","hierarchicalAttributeName","findMatchingHierarchicalFacetFromAttributeName","facetIndex","idxAttributeName","findIndex","exhaustiveFacetsCount","position","isFacetDisjunctive","isFacetConjunctive","facets_stats","compact","disjunctiveFacet","dfacet","facetResults","attributeIndex","dataFromMainRequest","refinedFacet","defaultData","root","excludes","_state","getFacetStatsIfAvailable","getRefinement","type","attributeName","resultsFacets","getFacetByName","predicate","DEFAULT_SORT","getFacetValues","opts","facetValues","isExcluded","extractNormalizedFacetValues","options","facetOrdering","recSort","sortFn","node","names","children","childNode","sortedChildren","renderingContent","getFacetOrdering","orderedFacets","remainingFacets","reverseOrder","order","item","ordering","sortRemainingBy","sortViaFacetOrdering","formatSort","vanillaSortFn","getFacetStats","getRefinements","facetDeclaration","rootFacet","intermediateFacet","newFacet","numericValue","EventEmitter","_events","_maxListeners","isFunction","arg","isObject","isUndefined","defaultMaxListeners","setMaxListeners","isNumber","TypeError","emit","er","handler","len","args","listeners","err","context","apply","on","addListener","listener","m","newListener","warned","trace","once","fired","g","removeListener","list","splice","removeAllListeners","listenerCount","evlistener","emitter","ctor","superCtor","create","enumerable","writable","configurable","DerivedHelper","mainHelper","fn","main","lastResults","detach","detachDerivedHelper","getModifiedState","requestBuilder","_getQueries","queries","indexName","_getHitsSearchParams","_getDisjunctiveFacetSearchParams","_getHitsHierarchicalFacetsAttributes","facetFilters","_getFacetFilters","_getNumericFilters","_getTagFilters","additionalParams","hierarchicalRootLevel","attributesToRetrieve","attributesToHighlight","attributesToSnippet","analytics","clickAnalytics","_getDisjunctiveHierarchicalFacetAttribute","vs","join","orFilters","attributeToRefine","attributesIndex","allAttributes","hierarchicalRefinement","newAttributes","rootLevel","parentLevel","getSearchForFacetQuery","maxFacetHits","stateForSearchForFacetValues","searchForFacetSearchParameters","facetQuery","AlgoliaSearchHelper","client","addAlgoliaAgent","setClient","_queryId","_lastQueryIdReceived","derivedHelpers","_currentNbQueries","setCurrentPage","_change","isPageReset","getCurrentPage","search","_search","onlyWithDerivedHelpers","searchOnlyWithDerivedHelpers","getQuery","searchOnce","cb","tempState","then","content","_originalResponse","e","catch","findAnswers","derivedHelper","Promise","resolve","derivedState","attributesForPrediction","nbHits","errorMessage","initIndex","queryLanguages","searchForFacetValues","userState","clientHasSFFV","isDisjunctive","algoliaQuery","facetHits","q","addDisjunctiveRefine","addRefine","addFacetExclusion","addExclude","addTag","removeDisjunctiveRefine","removeRefine","removeFacetExclusion","removeExclude","removeTag","toggleFacetExclusion","toggleExclude","toggleRefine","toggleTag","nextPage","previousPage","setState","newState","overrideStateWithoutTriggeringChangeEvent","hasRefinements","isDisjunctiveRefined","hasTag","hasTagRefinements","getIndex","getPage","getTags","r","states","mainQueries","queriesCount","helper","derivedQueries","derivedStateQueries","queryId","_dispatchAlgoliaResponse","bind","_dispatchAlgoliaError","s","specificResults","formattedResponse","containsRefinement","_hasDisjunctiveRefinements","disjunctiveRefinements","event","clearCache","newClient","getClient","derive","pos","hasPendingRequests","algoliasearchHelper","version","require$$0","defer","callback","progress","nextMicroTask","cancelled","wait","cancel","getContainerNode","selectorOrHTMLElement","isSelectorString","domElement","document","querySelector","HTMLElement","nodeType","isDomElement","isSpecialClick","button","altKey","ctrlKey","metaKey","shiftKey","uniq","prepareTemplateProps","defaultTemplates","templates","templatesConfig","config","defaultTemplate","customTemplate","isCustomTemplate","useCustomCompileOptions","prepareTemplates","Hogan","rIsWhitespace","rQuot","rNewline","rCr","rSlash","rLineSep","rParagraphSep","cleanTripleStache","token","substr","substring","replace","tagChange","text","charAt","tags","#","^","<","$","/","!",">","=","_v","{","&","_t","scan","delimiters","close","closeIndex","tagType","buf","tokens","seenTag","lineStart","otag","ctag","addBuf","String","filterLine","haveSeenTag","noNewLine","isAllWhitespace","j","match","lineIsWhitespace","next","indent","allowedInSuper","\n","isOpener","o","isCloser","open","c","stringifyPartials","codeObj","partials","esc","items","stringifySubstitutions","subs","wrapMain","code","serialNo","chooseMethod","createPartial","sym","prefix","tripleStache","write","generate","tree","walk","asString","makeTemplate","template","Template","makePartials","Function","codegen","end","nodes","ctx","inPartial","last","nodelist","func","parse","buildTree","kind","stack","customTags","tail","instructions","opener","shift","pop","sectionTags","cache","cacheKey","disableLambda","modelGet","compile","exports","findInScope","scope","doModelGet","get","compiler","str","coerceToString","hChars","rAmp","rLt","rGt","rApos","render","ri","ep","symbol","partial","base","stackText","activeSub","stackSubs","stackPartials","PartialTemplate","Substitutions","subsText","createSpecializedPartial","rp","rs","section","inverted","start","pass","ms","d","returnFound","found","cx","mv","ls","oldTags","ct","fl","textSource","sub","renderTemplate","templateKey","compileOptions","helpers","bindEvent","transformedHelpers","helperKey","hogan","_this","transformHelpersToHogan","spaces","unescapeRefinement","resultsFacet","nameParts","facetData","refinementKey","getFacetRefinement","includesQuery","refinementName","exclude","operatorOriginal","valueOrValues","attributesToClear","finalState","escapeRefinement","checkRendering","rendering","usage","getObjectType","noop","deprecate","message","getPropertyByPath","current","isFiniteNumber","isFinite","isPlainObject","_typeof","isObjectLike","getTag","getPrototypeOf","proto","range","step","limitStep","arrayLength","Math","round","_toConsumableArray","_","isPrimitive","isEqual","first","second","htmlEscapes","regexUnescapedHtml","regexHasUnescapedHtml","RegExp","regexEscapedHtml","regexHasEscapedHtml","TAG_PLACEHOLDER","highlightPreTag","highlightPostTag","TAG_REPLACEMENT","replaceTagsAndEscape","character","escape","recursiveEscape","input","escapeHits","hits","__escaped","hit","_highlightResult","_snippetResult","concatHighlightedParts","isHighlighted","getHighlightedParts","highlightedValue","splitByPreTag","firstValue","elements","splitByPostTag","hasAlphanumeric","getHighlightFromSiblings","isNextHighlighted","isPreviousHighlighted","unescape","reverseHighlightedParts","some","mergeHierarchicalFacets","left","right","nextFacets","hierarchicalFacetsRefinementsMerged","mergeHierarchicalFacetsRefinements","ruleContexts","rest","mergeWithRest","mergeFacets","mergeRuleContexts","mergeDisjunctiveFacets","mergeFacetRefinements","mergeFacetsExcludes","mergeDisjunctiveFacetsRefinements","mergeNumericRefinements","mergeTagRefinements","toArray","createDocumentationMessageGenerator","widgets","links","widget","connector","createDocumentationLink","latLngRegExp","insideBoundingBoxToBoundingBox","neLat","neLng","swLat","swLng","northEast","lat","lng","southWest","insideBoundingBoxArrayToBoundingBox","insideBoundingBoxStringToBoundingBox","addAbsolutePosition","__position","addQueryID","queryID","__queryID","createSendEventForFacet","instantSearchInstance","widgetType","eventType","eventName","sendEventToInsights","insightsMethod","payload","filters","serializePayload","btoa","encodeURIComponent","deserializePayload","serialized","decodeURIComponent","atob","buildPayloads","methodName","hitsArray","removeEscapedFromHits","hitsChunks","arr","chunkSize","chunks","ceil","chunk","objectIDsByChunk","batch","objectID","positionsByChunk","objectIDs","positions","createSendEventForHits","createBindEventForHits","payloads","convertNumericRefinementsToFilters","filtersObj","debounce","lastTimeout","reject","clearTimeout","setTimeout","getWidgetAttribute","initOptions","renderState","getWidgetRenderState","_widget$getWidgetRend","widgetParams","safelyRunOnBrowser","fallback","window","withUsage","isIndexWidget","$$type","privateHelperSetState","_uiState","getLocalWidgetsUiState","widgetStateOptions","initialUiState","uiState","getWidgetUiState","getWidgetState","getLocalWidgetsSearchParameters","widgetSearchParametersOptions","initialSearchParameters","getWidgetSearchParameters","indexId","localWidgets","localUiState","localInstantSearchInstance","localParent","$$widgetType","getIndexName","getIndexId","getHelper","getResults","getScopedResults","widgetParent","getParent","resolveScopedResultsFromWidgets","scopedResults","getWidgets","createURL","nextState","_createURL","searchParameters","addWidgets","init","getRenderState","storeRenderState","_initialUiState","searchMetadata","isSearchStalled","_isSearchStalled","scheduleSearch","removeWidgets","dispose","_this2","onStateChange","mainIndex","setUiState","searchWithoutTriggeringOnStateChange","mergeSearchParameters","resolveSearchParameters","_this3","indexInitialResults","_initialResults","_instantSearchInstanc","resetPageFromWidgets","indexWidgets","widgetHelper","scheduleStalledRender","scheduleRender","onInternalStateChange","_this4","_this5","previousUiState","innerIndex","refreshUiState","parentIndexName","component","componentName","descendantName","modifierName","descendent","modifier","suit","highlight","highlightedTagName","cssClasses","attributeValue","className","highlighted","reverseHighlight","snippet","reverseSnippet","insights","method","serializedPayload","writeDataAttributes","getInsightsAnonymousUserTokenInternal","cookies","cookie","getCookie","getIndexStateWithoutConfigure","configure","simpleStateMapping","stateToRoute","routeToState","routeState","arrayToObject","plainObjects","pushToArray","valueOrArray","generateArrayPrefix","strictNullHandling","skipNulls","encoder","allowDots","serializeDate","formatter","encodeValuesOnly","charset","Date","utils","maybeMap","isNonNullishPrimitive","isBuffer","objKeys","keyPrefix","parseArrayValue","comma","parseKeys","givenKey","valuesParsed","child","segment","depth","exec","has","allowPrototypes","chain","leaf","parseArrays","cleanRoot","parseInt","arrayLimit","0","parseObject","setWindowTitle","title","percentTwenties","Format","default","formatters","RFC1738","RFC3986","hexTable","toUpperCase","assign","combine","queue","prop","refs","compacted","compactQueue","decode","decoder","strWithoutPlus","encode","defaultEncoder","string","Symbol","$0","charCodeAt","formats","isRegExp","mapped","mergeTarget","targetItem","arrayPrefixGenerators","brackets","repeat","toISO","toISOString","defaultFormat","addQueryPrefix","charsetSentinel","delimiter","date","ignoreQueryPrefix","interpretNumericEntities","parameterLimit","normalizeParseOptions","tempObj","cleanStr","limit","Infinity","skipIndex","bracketEqualsPos","encodedVal","numberStr","fromCharCode","parseValues","newObj","normalizeStringifyOptions","arrayFormat","joined","BrowserHistory","windowTitle","writeDelay","parseURL","getLocation","writeTimer","read","qsModule","qs","location","url","shouldPushState","history","pushState","_onPopState","addEventListener","removeEventListener","historyRouter","protocol","hostname","port","pathname","hash","queryString","portWithPrefix","createRouterMiddleware","props","router","stateMapping","route","lastRouteState","subscribe","onUpdate","unsubscribe","isMetadataEnabled","navigator","userAgent","createMetadataMiddleware","payloadContainer","createElement","refNode","ua","transporter","_ua","extractPayload","appendChild","remove","defaultCreateURL","connectClearRefinements","renderFn","unmountFn","includedAttributes","excludedAttributes","transformItems","cachedRefine","connectorState","refine","cachedCreateURL","renderOptions","scopedResult","getAttributesToClear","indexHelper","canRefine","attributeToClear","InstantSearch","started","_searchStalledTimer","nextUiState","middleware","numberLocale","routing","searchFunction","stalledSearchDelay","searchClient","insightsClient","formatNumber","Number","toLocaleString","createHelpers","_stalledSearchDelay","_searchFunction","routerOptions","use","newMiddlewareList","newMiddleware","creator","middlewareToUnuse","includes","fakeClient","_mainHelperSearch","mainIndexHelper","searchFunctionHelper","originalScheduleSearch","setIndexHelperState","indexWidget","nextIndexUiState","connectCurrentRefinements","currentRefinements","accResults","getRefinementsItems","clearRefinementFromState","filterFunction","normalizeRefinement","allItems","currentItem","label","getOperatorSymbol","normalizedRefinement","connectHierarchicalMenu","showMore","showMoreLimit","sendEvent","_refine","toggleShowMore","cachedToggleShowMore","isShowingMore","getLimit","createToggleShowMore","hierarchicalMenu","canToggleShowMore","facetItems","hasExhaustiveItems","maxValuesPerFacet","_prepareFacetValues","withFacetConfiguration","currentMaxValuesPerFacet","nextMaxValuesPerFacet","max","withMaxValuesPerFacet","connectHits","escapeHTML","hitsWithAbsolutePositionAndQueryID","inferPayload","selectedHits","selectedObjectIDs","h","getSelectedHits","queryIDs","getQueryID","getPositions","withInsights","isFirstRender","aa","withInstantSearchUsage","inferredPayload","wrapInsightsClient","u","parentNode","removeChild","defaultProps","ref","__k","__p","__b","__e","__c","vnode","w","__d","debounceRendering","__v","__P","__n","ownerSVGElement","p","y","x","nextSibling","insertBefore","D","A","P","setProperty","N","style","cssText","toLowerCase","T","removeAttributeNS","setAttributeNS","removeAttribute","setAttribute","C","contextType","__E","H","__h","__s","getDerivedStateFromProps","componentWillMount","componentDidMount","componentWillReceiveProps","shouldComponentUpdate","componentWillUpdate","__r","getChildContext","getSnapshotBeforeUpdate","componentDidUpdate","localName","createTextNode","createElementNS","childNodes","dangerouslySetInnerHTML","__html","innerHTML","checked","z","diffed","unmount","componentWillUnmount","I","forceUpdate","getDerivedStateFromError","componentDidCatch","findInsightsTarget","startElement","endElement","validator","element","parentElement","insightsListener","BaseComponent","onClick","targetWithEvent","currentTarget","hasAttribute","getAttribute","parseInsightsEvent","single","insightsTarget","hasDataAttributes","readDataAttributes","connectHitsPerPage","userItems","defaultItems","defaultItem","normalizeItems","hasNoResults","connectHitsWithInsights","getStateWithoutPage","connectInfiniteHits","getFirstReceivedPage","cachedHits","pages","min","getLastReceivedPage","showPrevious","cachedState","getInMemoryCache","widgetRenderState","currentPageHits","infiniteHits","isFirstPage","transformedHits","getShowPrevious","getShowMore","extractHitsFromCachedHits","isLastPage","nbPages","stateWithoutPage","widgetSearchParameters","connectMenu","menu","refinedItem","connectNumericMenu","equal","numericMenu","withoutRefinements","withMinRefinement","refinedState","getRefinedState","createSendEvent","encodeURI","prepareItems","connectInfiniteHitsWithInsights","option","hasNumericRefinement","resolvedState","refinedOption","decodeURI","connectPagination","totalPages","padding","pager","Paginator","currentPage","total","helperState","getMaxPage","pagination","totalDisplayedPages","nbPagesDisplayed","paddingLeft","calculatePaddingLeft","toPrecision","precision","pow","floor","connectRange","minBound","maxBound","currentRange","nextMin","nextMax","newNextMin","newNextMax","currentRangeMin","currentRangeMax","isResetMin","isResetMax","nextMinAsNumber","nextMaxAsNumber","isResetNewNextMin","isGreaterThanCurrentRange","isMinValid","isResetNewNextMax","isLowerThanRange","isMaxValid","sendEventWithRefinedState","rangeFormatter","from","to","toFixed","formatToNumber","_getCurrentRange","minValue","maxValue","_getCurrentRefinement","lowerBound","upperBound","connectRefinementList","escapeFacetValues","formatItems","lastResultsFromMainSearch","triggerRefine","lastItemsFromMainSearch","createSearchForFacetValues","escapeFacets","normalizedFacetValues","isFromSearch","maxValuesPerFacetConfig","currentLimit","searchFacetValues","searchForItems","withoutMaxValuesPerFacet","connectSearchBox","queryHook","_clear","_cachedClear","searchBox","setQueryAndSearch","clear","connectSortBy","currentIndex","initialIndex","connectRatingMenu","getRefinedStar","_values$","emptyState","ratingMenu","refinedStar","maxDecimalPlaces","decimal","getFacetsMaxDecimalPlaces","star","stars","reverse","withDisjunctiveFacet","connectStats","nbSortedHits","areHitsSorted","appliedRelevancyStrictness","connectToggleRefinement","userOn","userOff","off","hasAnOffValue","valuesToRemove","valuesToAdd","onFacetValue","offFacetValue","offValue","allFacetValues","onData","offData","nextRefinement","toggleRefinementFactory","toggle","connectBreadcrumb","breadcrumb","shiftItemsValues","getItems","getBoundingBoxAsString","setBoundingBoxAsString","connectGeoSearch","getPositionFromState","aroundLatLng","pattern","aroundLatLngToPosition","toggleRefineOnMapMove","widgetState","internalToggleRefineOnMapMove","createInternalToggleRefinementOnMapMove","isRefineOnMapMove","setMapMoveSinceLastRefine","internalSetMapMoveSinceLastRefine","createInternalSetMapMoveSinceLastRefine","shouldTriggerRender","hasMapMoveSinceLastRefine","enableRefineOnMapMove","lastRefinePosition","lastRefineBoundingBox","initArgs","renderArgs","positionChangedSinceLastRefine","boundingBoxChangedSinceLastRefine","_geoloc","getCurrentRefinementFromState","ne","sw","boundingBox","clearMapRefinement","isRefinedWithMap","geoSearch","connectPoweredBy","defaultUrl","poweredBy","getInitialSearchParameters","connectConfigure","_renderState$configur","actualState","nextSearchParameters","createOptionalFilter","attributeScore","connectConfigureRelatedItems","matchingPatterns","transformSearchParameters","optionalFilters","score","attributeSubValue","sumOrFiltersScores","makeWidget","applyRuleContexts","initialRuleContexts","trackedFilters","transformRuleContexts","sharedHelperState","previousRuleContexts","newRuleContexts","facetRefinements","trackedFacetValues","getTrackedFacetValues","ruleName","escapeRuleContext","getRuleContextsFromTrackedFilters","connectQueryRules","rules","onHelperChange","hasTrackedFilters","hasStateRefinements","userData","queryRules","createVoiceSearchHelper","getDefaultState","status","transcript","isSpeechFinal","errorCode","resetState","onStart","onError","onResult","isFinal","searchAsYouSpeak","onQueryChange","onEnd","recognition","stop","language","SpeechRecognitionAPI","webkitSpeechRecognition","SpeechRecognition","getState","isBrowserSupported","isListening","startListening","interimResults","lang","stopListening","connectVoiceSearch","additionalQueryParameters","builtInCreateVoiceSearchHelper","voiceSearch","ignorePlurals","removeStopWords","optionalWords","_voiceSearchHelper","toggleListening","voiceListeningState","additional","toReset","connectAnswers","renderDebounceTime","searchDebounceTime","extraParameters","debouncedRefine","runConcurrentSafePromise","basePromiseId","latestResolvedId","latestResolvedValue","promise","currentPromiseId","createConcurrentSafePromise","lastHits","isLoading","debouncedRender","answersIndex","hasFindAnswersMethod","answers","connectRelevantSort","relevantSort","relevancyStrictness","isVirtualReplica","isRelevantSorted","connectDynamicWidgets","fallbackWidget","Map","set","isMounted","widgetsToUnmount","widgetsToMount","attributesToRender","shouldMount","toRemove","curr","dynamicWidgets","_results$renderingCon2","_results$renderingCon3","_results$renderingCon4","EXPERIMENTAL_connectDynamicWidgets","autocomplete","stateWithoutQuery","classNames","classes","argType","inner","hasOwn","module","Component","nextProps","rootProps","RootTagName","rootTagName","Breadcrumb","templateProps","noRefinementRoot","selectedItem","link","href","preventDefault","isLast","ClearRefinements","disabledButton","disabled","CurrentRefinements","capitalize","createItemKey","category","categoryLabel","delete","handleClick","renderer","container","Answers","emptyRoot","header","loader","__hitIndex","home","resetLabel","createContainer","rootContainer","containerSelector","otherWidgetParams","userContainer","containers","connectorWidgets","childWidget","GeoSearchButton","GeoSearchToggle","classNameLabel","classNameInput","onToggle","onChange","GeoSearchControls","enableRefine","enableRefineControl","enableClearMapRefinement","onRefineToggle","onRefineClick","onClearClick","Fragment","control","selectedLabel","redo","disabledRedo","reset","refineWithMap","mapInstance","getBounds","getNorthEast","toJSON","getSouthWest","lockUserInteraction","functionThatAltersTheMapPosition","isUserInteraction","isFirstRendering","googleReference","initialZoom","initialPosition","mapOptions","createMarker","markerOptions","isPendingRefine","markers","rootElement","mapElement","treeElement","maps","mapTypeControl","fullscreenControl","streetViewControl","clickableIcons","zoomControlOptions","ControlPosition","LEFT_TOP","addListenerOnce","nextItemsIds","nextIds","marker","update","exit","__id","collectMarkersForNextRender","updateMarkers","exitMarkers","updateMarkerIds","nextPendingItems","setMap","events","shouldUpdate","boundingBoxPadding","google","latLngBounds","extend","getPosition","LatLngBounds","createBoundingBoxFromMarkers","fitBounds","setCenter","setZoom","HTMLMarker","RefinementListItem","facetValueToRefine","templateData","subItems","originalEvent","showSubmit","showReset","showLoadingIndicator","autofocus","searchAsYouType","onSubmit","onReset","SearchBox","focused","stopPropagation","blur","focus","placeholder","action","role","form","noValidate","autoFocus","autoComplete","autoCorrect","autoCapitalize","spellCheck","maxLength","onInput","onBlur","onFocus","submit","hidden","loadingIndicator","isHierarchicalMenuItem","handleItemClick","childList","refinementListItemClassName","disabledItem","parentItem","tagName","resetInput","actualValue","showMoreButtonClassName","disabledShowMore","showMoreButton","shouldDisableSearchBox","searchIsAlwaysActive","searchPlaceholder","searchable","searchBoxTemplateProps","refineFirstValue","_generateFacetItem","noResults","Hits","showMoreText","empty","HitsWithInsightsListener","withInsightsListener","Selector","setValue","select","showPreviousText","InfiniteHitsWithInsightsListener","hasShowPrevious","loadPrevious","disabledLoadPrevious","loadMore","disabledLoadMore","MenuSelect","selectedValue","PaginationLink","ariaLabel","isDisabled","pageNumber","defaultOption","Pagination","pageLink","additionalClassName","previousPageItem","nextPageItem","firstPageItem","lastPageItem","pageItem","isSelected","showFirst","firstPageLink","previousPageLink","showNext","nextPageLink","showLast","lastPageLink","__H","createHandle","requestAnimationFrame","cancelAnimationFrame","E","F","Panel","useState","isCollapsed","setIsCollapsed","isControlled","setIsControlled","bodyRef","useRef","useEffect","bodyElement","collapsibleRoot","collapsible","collapsedRoot","collapseButton","prevIsCollapsed","collapsed","body","footer","PoweredBy","theme","rel","height","logo","viewBox","width","fill","QueryRuleCustomData","RangeInput","noRefinement","inputMin","inputMax","separatorText","submitText","KEYS","PERCENT_FULL","getValue","getClassName","orientation","getHandleFor","ev","killEvent","Rheostat","handlePos","handleDimensions","mousePos","sliderBox","slidingIndex","getPublicState","getSliderBoundingBox","getProgressStyle","getMinValue","getMaxValue","getHandleDimensions","getClosestSnapPoint","getSnapPosition","getNextPositionForKey","getNextState","getClosestHandle","setStartSlide","startMouseSlide","startTouchSlide","handleMouseSlide","handleTouchSlide","handleSlide","endSlide","handleKeydown","validatePosition","validateValues","canMove","fireChangeEvent","slideTo","updateNewValues","minMaxChanged","valuesChanged","orientationChanged","willBeDisabled","rheostat","rect","getBoundingClientRect","clientHeight","top","clientWidth","prevValue","diffValue","handleNode","snapPoints","snapTo","snap","abs","positionPercent","keyCode","shouldSnap","proposedValue","proposedPercentage","originalPercentage","stepValue","stepMultiplier","proposedPosition","actualPosition","nextHandlePos","closestIdx","_node","clientX","clientY","changedTouches","touch","onSliderDragStart","onSliderDragMove","onSliderDragEnd","handleId","validPositionPercent","onKeyPress","proposedValues","realValue","onAfterSet","onValuesUpdated","nextValues","_this6","Handle","handle","PitComponent","pitComponent","pitPoints","ProgressBar","progressBar","handleStyle","_this7","onKeyDown","onMouseDown","onTouchStart","tabIndex","pitStyle","Pit","positionValue","shouldDisplayValue","pitValue","marginLeft","RelevantSort","Stats","hasManySortedResults","hasNoSortedResults","hasOneSortedResults","hasManyResults","hasOneResult","ToggleRefinement","checkbox","labelText","VoiceSearch","Slider","tooltips","roundedValue","stepsLength","steps","pips","computeSnapPoints","computeDefaultPitPoints","disabledRoot","createHandleComponent","handleChange","searchableNoResults","searchBoxSuit","buttonText","getButtonInnerElement","EXPERIMENTAL_dynamicWidgets","pushFunction","delay","triggerOnUIInteraction","pushInitialSearch","pushPagination","sendAnalytics","analyticsState","serializedParams","serializedRefinements","serializeRefinements","serializedNumericRefinements","equals","serializeNumericRefinements","stringifiedParams","dataToSend","lastSentData","pushTimeout","isInitialSearch","onUnload","userCssClasses","containerNode","specializedRenderer","userTemplates","builtInMarker","userBuiltInMarker","userCustomHTMLMarker","customHTMLMarker","createOptions","OverlayView","anchor","latLng","LatLng","getPanes","overlayMouseTarget","bbBox","offset","getProjection","fromLatLngToDivPixel","zIndex","createHTMLMarker","Marker","receivedHits","radio","scrollTo","userScrollTo","scrollToNode","scrollIntoView","panelWidgetParams","bodyContainerNode","collapsedFn","collapseIcon","widgetFactory","renderPanel","collapseButtonText","placesReference","defaultPosition","placesOptions","placesAutocomplete","initialLatLngViaIP","isInitialLatLngViaIPSet","eventOptions","suggestion","latlng","places","aroundLatLngViaIP","setVal","CustomData","rangeMin","rangeMax","minRange","maxRange","minStart","maxStart","minFinite","maxFinite","starIcon","fullStarIcon","emptyStarIcon","id","searchablePlaceholder","searchableEscapeFacetValues","searchableIsAlwaysActive","searchableRoot","searchableForm","searchableInput","searchableSubmit","submitIcon","searchableSubmitIcon","searchableReset","resetIcon","searchableResetIcon","searchableLoadingIndicator","loadingIcon","searchableLoadingIcon","searchBoxTemplates","searchBoxDefaultTemplates","VoiceSearchComponent","_insightsClient","insightsInitParams","onEvent","hasInsightsClient","headers","queryParameters","APP_ID","API_KEY","applicationID","apiKey","getAppIdAndApiKey","appId","queuedUserToken","userTokenBeforeInit","_error","configureClickAnalytics","configureUserToken","createWidget","setUserTokenToSearch","anonymousUserToken","immediate","KEY","instantsearch","connectors","middlewares","routers","stateMappings","createInfiniteHitsSessionStorageCache","sessionStorage","getItem","SyntaxError","removeItem","setItem"],"mappings":"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"}
\No newline at end of file