1 |
- {"version":3,"file":"static/chunks/pages/search-9f486be340a521f9.js","mappings":"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","sources":["webpack://_N_E/?3d78","webpack://_N_E/./src/components/NextSeoWrapper.tsx","webpack://_N_E/./src/hooks/useAddQueryParamsToUrl.ts","webpack://_N_E/./public/icons/filter.svg","webpack://_N_E/./src/components/Search/Filters/TranslationGroup.tsx","webpack://_N_E/./src/components/Search/Filters/TranslationsFilter.tsx","webpack://_N_E/./src/pages/search.tsx","webpack://_N_E/./src/utils/string.ts","webpack://_N_E/./src/components/Search/Filters/Filter.module.scss","webpack://_N_E/./src/components/Search/Filters/TranslationGroup.module.scss","webpack://_N_E/./src/pages/search.module.scss"],"sourcesContent":["\n (window.__NEXT_P = window.__NEXT_P || []).push([\n \"/search\",\n function () {\n return require(\"private-next-pages/search.tsx\");\n }\n ]);\n if(module.hot) {\n module.hot.dispose(function () {\n window.__NEXT_P.push([\"/search\"])\n });\n }\n ","import React from 'react';\n\nimport { NextSeo } from 'next-seo';\n\nimport { SEOProps } from '@/utils/seo';\nimport { truncateString } from '@/utils/string';\n\ninterface Props extends SEOProps {\n url?: string;\n image?: string;\n imageAlt?: string;\n imageWidth?: number;\n imageHeight?: number;\n}\n\nconst NextSeoWrapper: React.FC<Props> = (props) => {\n const { url, image, imageAlt, imageHeight, imageWidth, openGraph, description, ...rest } = props;\n const openGraphParams = {\n ...(openGraph && { openGraph }),\n ...(url && { url }),\n ...(image && {\n images: [{ url: image, width: imageWidth, height: imageHeight, alt: imageAlt }],\n }),\n };\n const params = {\n ...rest,\n ...(description && { description: truncateString(description, 150) }),\n };\n return <NextSeo {...params} openGraph={openGraphParams} />;\n};\n\nexport default NextSeoWrapper;\n","import { useEffect } from 'react';\n\n/**\n * A hook that appends query parameters to the url. We could've used shallow routing for Next.js\n * but it causes re-rendering to the whole app @see https://github.com/vercel/next.js/discussions/18072\n *\n * @param {string} relativeUrl the relative url e.g. '/search' for the search page.\n * @param {Record<string, unknown>} params a map of each parameter and its value that we will listen to and in the event of changing any of them, we will re-generate the url.\n */\nconst useAddQueryParamsToUrl = (relativeUrl: string, params: Record<string, unknown>) => {\n useEffect(() => {\n if (typeof window !== 'undefined') {\n let url = relativeUrl;\n let isFirstParameter = true;\n Object.keys(params).forEach((parameter) => {\n const parameterValue = params[parameter];\n // if the value of the parameter exists\n if (parameterValue) {\n url = `${url}${isFirstParameter ? '?' : '&'}${parameter}=${parameterValue}`;\n isFirstParameter = false;\n }\n });\n window.history.replaceState({ ...window.history.state, as: url, url }, '', url);\n }\n }, [relativeUrl, params]);\n};\n\nexport default useAddQueryParamsToUrl;\n","var _path;\nfunction _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }\nimport * as React from \"react\";\nvar SvgFilter = function SvgFilter(props) {\n return /*#__PURE__*/React.createElement(\"svg\", _extends({\n xmlns: \"http://www.w3.org/2000/svg\",\n width: 24,\n height: 24,\n viewBox: \"0 0 24 24\",\n fill: \"none\",\n stroke: \"currentColor\",\n strokeWidth: 2,\n strokeLinecap: \"round\",\n strokeLinejoin: \"round\",\n className: \"feather feather-filter\"\n }, props), _path || (_path = /*#__PURE__*/React.createElement(\"path\", {\n d: \"M22 3H2l8 9.46V19l4 2v-8.54L22 3z\"\n })));\n};\nexport default SvgFilter;","import styles from './TranslationGroup.module.scss';\n\nimport Checkbox from '@/dls/Forms/Checkbox/Checkbox';\nimport AvailableTranslation from 'types/AvailableTranslation';\n\ntype TranslationGroupProps = {\n language: string;\n translations: AvailableTranslation[];\n selectedTranslations: string[];\n onTranslationsChange: (translationsId: string[]) => void;\n};\nconst TranslationGroup = ({\n language,\n translations,\n selectedTranslations,\n onTranslationsChange,\n}: TranslationGroupProps) => {\n const areAllTranslationsSelected = translations.every((translation) =>\n selectedTranslations.includes(translation.id.toString()),\n );\n\n const areSomeTranslationsSelected = translations.some((translation) =>\n selectedTranslations.includes(translation.id.toString()),\n );\n\n const onLanguageSelected = () => {\n const nextSelectedTranslations = areAllTranslationsSelected\n ? []\n : translations.map((translation) => translation.id.toString());\n onTranslationsChange(nextSelectedTranslations);\n };\n\n const onSelectedTranslationsChange = (translationId: number) => (checked: boolean) => {\n const nextTranslations = checked\n ? [...selectedTranslations, translationId.toString()]\n : selectedTranslations.filter((id) => id !== translationId.toString());\n onTranslationsChange(nextTranslations);\n };\n\n let languageCheckboxCheckedStatus;\n if (areSomeTranslationsSelected) languageCheckboxCheckedStatus = 'indeterminate';\n if (areAllTranslationsSelected) languageCheckboxCheckedStatus = true;\n if (!areSomeTranslationsSelected && !areAllTranslationsSelected) {\n languageCheckboxCheckedStatus = false;\n }\n\n return (\n <div key={language}>\n <span className={styles.header}>\n <Checkbox\n id={language}\n checked={languageCheckboxCheckedStatus}\n label={language}\n onChange={onLanguageSelected}\n />\n </span>\n <div className={styles.itemsContainer}>\n {translations\n .sort((a: AvailableTranslation, b: AvailableTranslation) =>\n a.authorName.localeCompare(b.authorName),\n )\n .map((translation: AvailableTranslation) => (\n <div key={translation.id} className={styles.item}>\n <Checkbox\n id={translation.id.toString()}\n checked={selectedTranslations.includes(translation.id.toString())}\n label={translation.translatedName.name}\n onChange={onSelectedTranslationsChange(translation.id)}\n />\n </div>\n ))}\n </div>\n </div>\n );\n};\n\nexport default TranslationGroup;\n","import React, { memo } from 'react';\n\nimport styles from './Filter.module.scss';\nimport TranslationGroup from './TranslationGroup';\n\nimport { getTranslationsByLanguages } from '@/utils/search';\nimport AvailableTranslation from 'types/AvailableTranslation';\n\ninterface Props {\n onTranslationChange: (translationId: string[]) => void;\n selectedTranslations: string;\n translations: AvailableTranslation[];\n}\n\nconst TranslationsFilter: React.FC<Props> = memo(\n ({ translations, selectedTranslations, onTranslationChange }) => {\n const translationsByLanguages = getTranslationsByLanguages(translations);\n return (\n <div className={styles.comboboxItems}>\n {Object.entries(translationsByLanguages).map(([language, languageTranslations]) => {\n return (\n <TranslationGroup\n language={language}\n key={language}\n translations={languageTranslations}\n onTranslationsChange={(nextTranslations) => onTranslationChange(nextTranslations)}\n selectedTranslations={selectedTranslations.split(',')}\n />\n );\n })}\n </div>\n );\n },\n);\n\nexport default TranslationsFilter;\n","/* eslint-disable react-func/max-lines-per-function */\n/* eslint-disable max-lines */\nimport { RefObject, useCallback, useEffect, useMemo, useRef, useState } from 'react';\n\nimport { GetStaticProps, NextPage } from 'next';\nimport { useRouter } from 'next/router';\nimport useTranslation from 'next-translate/useTranslation';\nimport { useDispatch } from 'react-redux';\n\nimport styles from './search.module.scss';\n\nimport { getAvailableLanguages, getAvailableTranslations } from '@/api';\nimport NextSeoWrapper from '@/components/NextSeoWrapper';\nimport TranslationsFilter from '@/components/Search/Filters/TranslationsFilter';\nimport SearchBodyContainer from '@/components/Search/SearchBodyContainer';\nimport Button, { ButtonSize, ButtonVariant } from '@/dls/Button/Button';\nimport ContentModal, { ContentModalSize } from '@/dls/ContentModal/ContentModal';\nimport Input, { InputVariant } from '@/dls/Forms/Input';\nimport useAddQueryParamsToUrl from '@/hooks/useAddQueryParamsToUrl';\nimport useDebounce from '@/hooks/useDebounce';\nimport useFocus from '@/hooks/useFocusElement';\nimport FilterIcon from '@/icons/filter.svg';\nimport SearchIcon from '@/icons/search.svg';\nimport SearchQuerySource from '@/types/SearchQuerySource';\nimport { getAllChaptersData } from '@/utils/chapter';\nimport { logButtonClick, logEvent, logValueChange } from '@/utils/eventLogger';\nimport filterTranslations from '@/utils/filter-translations';\nimport { getLanguageAlternates, toLocalizedNumber } from '@/utils/locale';\nimport { getCanonicalUrl } from '@/utils/navigation';\nimport {\n addToSearchHistory,\n getDefaultTranslationIdsByLang,\n searchGetResults,\n} from '@/utils/search';\nimport { SearchResponse } from 'types/ApiResponses';\nimport AvailableLanguage from 'types/AvailableLanguage';\nimport AvailableTranslation from 'types/AvailableTranslation';\nimport ChaptersData from 'types/ChaptersData';\n\nconst PAGE_SIZE = 10;\nconst DEBOUNCING_PERIOD_MS = 1000;\n\ntype SearchProps = {\n languages: AvailableLanguage[];\n translations: AvailableTranslation[];\n chaptersData: ChaptersData;\n};\n\nconst Search: NextPage<SearchProps> = ({ translations }): JSX.Element => {\n const { t, lang } = useTranslation('common');\n const router = useRouter();\n const [searchQuery, setSearchQuery] = useState<string>('');\n const [focusInput, searchInputRef]: [() => void, RefObject<HTMLInputElement>] = useFocus();\n const [currentPage, setCurrentPage] = useState<number>(1);\n const [selectedLanguages, setSelectedLanguages] = useState<string>('');\n const [selectedTranslations, setSelectedTranslations] = useState<string>(() => {\n return getDefaultTranslationIdsByLang(translations, lang) as string;\n });\n const [translationSearchQuery, setTranslationSearchQuery] = useState('');\n const [isContentModalOpen, setIsContentModalOpen] = useState<boolean>(false);\n const [isSearching, setIsSearching] = useState(false);\n const [hasError, setHasError] = useState(false);\n const [searchResult, setSearchResult] = useState<SearchResponse>(null);\n // Debounce search query to avoid having to call the API on every type. The API will be called once the user stops typing.\n const debouncedSearchQuery = useDebounce<string>(searchQuery, DEBOUNCING_PERIOD_MS);\n const dispatch = useDispatch();\n // the query params that we want added to the url\n const queryParams = useMemo(\n () => ({\n page: currentPage,\n languages: selectedLanguages,\n q: debouncedSearchQuery,\n translations: selectedTranslations,\n }),\n [currentPage, debouncedSearchQuery, selectedLanguages, selectedTranslations],\n );\n useAddQueryParamsToUrl('/search', queryParams);\n\n // We need this since pages that are statically optimized will be hydrated\n // without their route parameters provided, i.e query will be an empty object ({}).\n // After hydration, Next.js will trigger an update to provide the route parameters\n // in the query object. @see https://nextjs.org/docs/routing/dynamic-routes#caveats\n useEffect(() => {\n // we don't want to focus the main search input when the translation filter modal is open.\n if (router.isReady && !isContentModalOpen) {\n focusInput();\n }\n }, [focusInput, router, isContentModalOpen]);\n\n // handle when language changes\n useEffect(() => {\n setSelectedTranslations(getDefaultTranslationIdsByLang(translations, lang) as string);\n }, [lang, translations]);\n\n useEffect(() => {\n if (router.query.q || router.query.query) {\n let query = router.query.q as string;\n if (router.query.query) {\n query = router.query.query as string;\n }\n setSearchQuery(query);\n }\n\n if (router.query.page) {\n setCurrentPage(Number(router.query.page));\n }\n if (router.query.languages) {\n setSelectedLanguages(router.query.languages as string);\n }\n if (router.query.translations) {\n setSelectedTranslations(router.query.translations as string);\n }\n }, [\n router.query.q,\n router.query.query,\n router.query.page,\n router.query.languages,\n router.query.translations,\n ]);\n\n /**\n * Handle when the search query is changed.\n *\n * @param {string} newSearchQuery\n * @returns {void}\n */\n const onSearchQueryChange = (newSearchQuery: string): void => {\n setSearchQuery(newSearchQuery || '');\n };\n\n const onClearClicked = () => {\n logButtonClick('search_page_clear_query');\n setSearchQuery('');\n };\n\n /**\n * Call BE to fetch the results using the passed filters.\n *\n * @param {string} query\n * @param {number} page\n * @param {string} translation\n * @param {string} language\n */\n const getResults = useCallback(\n (query: string, page: number, translation: string, language: string) => {\n searchGetResults(\n SearchQuerySource.SearchPage,\n query,\n page,\n PAGE_SIZE,\n setIsSearching,\n setHasError,\n setSearchResult,\n language,\n translation,\n );\n },\n [],\n );\n\n // a ref to know whether this is the initial search request made when the user loads the page or not\n const isInitialSearch = useRef(true);\n\n // listen to any changes in the API params and call BE on change.\n useEffect(() => {\n // only when the search query has a value we call the API.\n if (debouncedSearchQuery) {\n // we don't want to reset pagination when the user reloads the page with a ?page={number} in the url query\n if (!isInitialSearch.current) {\n setCurrentPage(1);\n }\n\n addToSearchHistory(dispatch, debouncedSearchQuery, SearchQuerySource.SearchPage);\n\n getResults(\n debouncedSearchQuery,\n // if it is the initial search request, use the page number in the url, otherwise, reset it\n isInitialSearch.current ? currentPage : 1,\n selectedTranslations,\n selectedLanguages,\n );\n\n // if it was the initial request, update the ref\n if (isInitialSearch.current) {\n isInitialSearch.current = false;\n }\n }\n // we don't want to run this effect when currentPage is changed\n // because we are already handeling this in onPageChange\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [debouncedSearchQuery, getResults, selectedLanguages, selectedTranslations]);\n\n const onPageChange = (page: number) => {\n logEvent('search_page_number_change', { page });\n setCurrentPage(page);\n getResults(debouncedSearchQuery, page, selectedTranslations, selectedLanguages);\n };\n\n const onTranslationChange = useCallback((translationIds: string[]) => {\n // convert the array into a string\n setSelectedTranslations((prevTranslationIds) => {\n // filter out the empty strings\n const newTranslationIds = translationIds.filter((id) => id !== '').join(',');\n logValueChange('search_page_selected_translations', prevTranslationIds, newTranslationIds);\n return newTranslationIds;\n });\n // reset the current page since most probable the results will change.\n setCurrentPage(1);\n }, []);\n\n const onSearchKeywordClicked = useCallback((keyword: string) => {\n setSearchQuery(keyword);\n }, []);\n\n const navigationUrl = '/search';\n\n const formattedSelectedTranslations = useMemo(() => {\n if (!selectedTranslations) return t('search:default-translations');\n\n let selectedValueString;\n\n const selectedTranslationsArray = selectedTranslations.split(',');\n\n const firstSelectedTranslation = translations.find(\n (translation) => translation.id.toString() === selectedTranslationsArray[0],\n );\n\n if (!firstSelectedTranslation) return t('search:all-translations');\n\n if (selectedTranslationsArray.length === 1) {\n selectedValueString = firstSelectedTranslation.name;\n }\n if (selectedTranslationsArray.length === 2) {\n selectedValueString = t('settings.value-and-other', {\n value: firstSelectedTranslation?.name,\n othersCount: toLocalizedNumber(selectedTranslationsArray.length - 1, lang),\n });\n }\n if (selectedTranslationsArray.length > 2) {\n selectedValueString = t('settings.value-and-others', {\n value: firstSelectedTranslation?.name,\n othersCount: toLocalizedNumber(selectedTranslationsArray.length - 1, lang),\n });\n }\n\n return selectedValueString;\n }, [lang, selectedTranslations, t, translations]);\n\n const filteredTranslations = translationSearchQuery\n ? filterTranslations(translations, translationSearchQuery)\n : translations;\n\n const onResetButtonClicked = () => {\n logButtonClick('search_page_reset_button');\n const defaultLangTranslationIds = getDefaultTranslationIdsByLang(\n translations,\n lang,\n false,\n ) as string[];\n onTranslationChange(defaultLangTranslationIds);\n };\n\n const onTranslationSearchQueryChange = (newTranslationSearchQuery: string) => {\n logValueChange(\n 'search_page_translation_search_query',\n translationSearchQuery,\n newTranslationSearchQuery,\n );\n setTranslationSearchQuery(newTranslationSearchQuery);\n };\n\n const onTranslationSearchClearClicked = () => {\n logButtonClick('search_page_translation_search_clear');\n setTranslationSearchQuery('');\n };\n\n const onTranslationsFiltersClicked = () => {\n logButtonClick('search_page_translation_filter');\n setIsContentModalOpen(true);\n };\n\n return (\n <>\n <NextSeoWrapper\n title={\n debouncedSearchQuery !== ''\n ? t('search:search-title', {\n searchQuery: debouncedSearchQuery,\n })\n : t('search:search')\n }\n description={t('search:search-desc')}\n canonical={getCanonicalUrl(lang, navigationUrl)}\n languageAlternates={getLanguageAlternates(navigationUrl)}\n />\n <div className={styles.pageContainer}>\n <div className={styles.headerOuterContainer}>\n <div className={styles.headerInnerContainer}>\n <Input\n id=\"searchQuery\"\n prefix={<SearchIcon />}\n onChange={onSearchQueryChange}\n onClearClicked={onClearClicked}\n inputRef={searchInputRef}\n clearable\n value={searchQuery}\n disabled={isSearching}\n placeholder={t('search.title')}\n fixedWidth={false}\n variant={InputVariant.Main}\n />\n <ContentModal\n size={ContentModalSize.SMALL}\n isFixedHeight\n header={\n <div className={styles.modalContainer}>\n <div className={styles.translationSearchContainer}>\n <Input\n id=\"searchQuery\"\n prefix={<SearchIcon />}\n onChange={onTranslationSearchQueryChange}\n onClearClicked={onTranslationSearchClearClicked}\n clearable\n value={translationSearchQuery}\n placeholder={t('settings.search-translations')}\n fixedWidth={false}\n variant={InputVariant.Main}\n />\n </div>\n <Button\n className={styles.resetButton}\n variant={ButtonVariant.Ghost}\n onClick={onResetButtonClicked}\n >\n {t('search:reset')}\n </Button>\n </div>\n }\n isOpen={isContentModalOpen}\n onClose={() => setIsContentModalOpen(false)}\n >\n <TranslationsFilter\n translations={filteredTranslations}\n selectedTranslations={selectedTranslations}\n onTranslationChange={onTranslationChange}\n />\n </ContentModal>\n <div className={styles.filtersContainer}>\n <Button\n onClick={onTranslationsFiltersClicked}\n size={ButtonSize.Small}\n variant={ButtonVariant.Compact}\n prefix={<FilterIcon />}\n className={styles.filterButton}\n >\n {t('search:filter')}\n </Button>\n <div>\n {/* eslint-disable-next-line i18next/no-literal-string */}\n <span className={styles.searching}>{t('search:searching-translations')}: </span>\n {formattedSelectedTranslations}\n </div>\n </div>\n </div>\n </div>\n <div className={styles.pageBody}>\n <div className={styles.searchBodyContainer}>\n <SearchBodyContainer\n onSearchKeywordClicked={onSearchKeywordClicked}\n isSearchDrawer={false}\n searchQuery={debouncedSearchQuery}\n searchResult={searchResult}\n currentPage={currentPage}\n onPageChange={onPageChange}\n pageSize={PAGE_SIZE}\n isSearching={isSearching}\n hasError={hasError}\n />\n </div>\n </div>\n </div>\n </>\n );\n};\n\nexport const getStaticProps: GetStaticProps = async ({ locale }) => {\n const [availableLanguagesResponse, availableTranslationsResponse] = await Promise.all([\n getAvailableLanguages(locale),\n getAvailableTranslations(locale),\n ]);\n\n let translations = [];\n let languages = [];\n if (availableLanguagesResponse.status !== 500) {\n const { languages: responseLanguages } = availableLanguagesResponse;\n languages = responseLanguages;\n }\n if (availableTranslationsResponse.status !== 500) {\n const { translations: responseTranslations } = availableTranslationsResponse;\n translations = responseTranslations;\n }\n const chaptersData = await getAllChaptersData(locale);\n\n return {\n props: {\n chaptersData,\n languages,\n translations,\n },\n };\n};\n\nexport default Search;\n","/**\n * Shorten a text by setting the maximum number of characters\n * by the value of the parameter and adding \"...\" at the end.\n *\n * @param {string} rawString\n * @param {number} length\n * @param {string} suffix\n * @returns {string}\n */\nexport const truncateString = (rawString: string, length: number, suffix = '...'): string => {\n const characters = rawString.split('', length);\n let shortenedText = '';\n for (let index = 0; index < characters.length; index += 1) {\n const character = characters[index];\n if (shortenedText.length === length - 1) {\n shortenedText = `${shortenedText}${character}${suffix}`;\n break;\n }\n shortenedText = `${shortenedText}${character}`;\n }\n return shortenedText;\n};\n\n/**\n * Strip HTML tags from a string.\n *\n * @param {string} rawString\n * @returns {string}\n */\nexport const stripHTMLTags = (rawString: string): string => rawString.replace(/(<([^>]+)>)/gi, '');\n\n/**\n * Convert a slugified collection id to collection id only after\n * removing the slug.\n *\n * @param {string} slugifiedCollectionId\n * @returns {string}\n */\nexport const slugifiedCollectionIdToCollectionId = (slugifiedCollectionId: string): string => {\n if (!slugifiedCollectionId) {\n return '';\n }\n const splits = slugifiedCollectionId.split('-');\n // if there is no slug in the url (collections with a name that cannot be slugified e.g. emoticons)\n if (splits.length === 1) {\n return splits[0];\n }\n return splits[splits.length - 1];\n};\n","// extracted by mini-css-extract-plugin\nmodule.exports = {\"dropdownLabel\":\"Filter_dropdownLabel__2Oqf9\",\"comboboxItems\":\"Filter_comboboxItems__KohLK\"};","// extracted by mini-css-extract-plugin\nmodule.exports = {\"header\":\"TranslationGroup_header__i2C2P\",\"item\":\"TranslationGroup_item__uc7kH\",\"itemsContainer\":\"TranslationGroup_itemsContainer__p0HAL\"};","// extracted by mini-css-extract-plugin\nmodule.exports = {\"pageContainer\":\"search_pageContainer__pfKhT\",\"paginationContainer\":\"search_paginationContainer__Ubx_R\",\"searchInputContainer\":\"search_searchInputContainer__a_oW9\",\"rtlFlexDirection\":\"search_rtlFlexDirection__VH_JG\",\"searchInput\":\"search_searchInput__33AwX\",\"pageBody\":\"search_pageBody__FKfdc\",\"searchBodyContainer\":\"search_searchBodyContainer__mmo7q\",\"filtersContainer\":\"search_filtersContainer__GgipQ\",\"headerInnerContainer\":\"search_headerInnerContainer__a_6bG\",\"headerOuterContainer\":\"search_headerOuterContainer__iCXA0\",\"filterButton\":\"search_filterButton__gCMTe\",\"searching\":\"search_searching__N2_so\",\"languagePopover\":\"search_languagePopover__egWCE\",\"translationPopover\":\"search_translationPopover__is8iS\",\"translationFilterContainer\":\"search_translationFilterContainer__Idt70\",\"resetButton\":\"search_resetButton__lNhvG\",\"modalContainer\":\"search_modalContainer__0tqXi\",\"translationSearchContainer\":\"search_translationSearchContainer__mRzQ9\"};"],"names":["window","__NEXT_P","push","props","url","image","imageAlt","imageHeight","imageWidth","openGraph","description","rest","openGraphParams","images","width","height","alt","params","truncateString","NextSeo","relativeUrl","useEffect","isFirstParameter","Object","keys","forEach","parameter","parameterValue","history","replaceState","state","as","_path","languageCheckboxCheckedStatus","language","translations","selectedTranslations","onTranslationsChange","areAllTranslationsSelected","every","translation","includes","id","toString","areSomeTranslationsSelected","some","div","span","className","styles","Checkbox","checked","label","onChange","nextSelectedTranslations","map","sort","a","b","authorName","localeCompare","translatedName","name","translationId","nextTranslations","filter","memo","onTranslationChange","translationsByLanguages","getTranslationsByLanguages","entries","languageTranslations","TranslationGroup","split","_extends","assign","bind","n","e","arguments","length","t","r","hasOwnProperty","call","apply","xmlns","viewBox","fill","stroke","strokeWidth","strokeLinecap","strokeLinejoin","d","useTranslation","lang","router","useRouter","useState","searchQuery","setSearchQuery","useFocus","focusInput","searchInputRef","currentPage","setCurrentPage","selectedLanguages","setSelectedLanguages","getDefaultTranslationIdsByLang","setSelectedTranslations","translationSearchQuery","setTranslationSearchQuery","isContentModalOpen","setIsContentModalOpen","isSearching","setIsSearching","hasError","setHasError","searchResult","setSearchResult","debouncedSearchQuery","useDebounce","dispatch","useDispatch","queryParams","useMemo","page","languages","q","useAddQueryParamsToUrl","isReady","query","Number","getResults","useCallback","searchGetResults","SearchQuerySource","isInitialSearch","useRef","current","addToSearchHistory","translationIds","prevTranslationIds","newTranslationIds","join","logValueChange","onSearchKeywordClicked","keyword","navigationUrl","formattedSelectedTranslations","selectedValueString","selectedTranslationsArray","firstSelectedTranslation","find","value","othersCount","toLocalizedNumber","filteredTranslations","filterTranslations","NextSeoWrapper","title","canonical","getCanonicalUrl","languageAlternates","getLanguageAlternates","Input","prefix","SearchIcon","newSearchQuery","onClearClicked","logButtonClick","inputRef","clearable","disabled","placeholder","fixedWidth","variant","InputVariant","ContentModal","size","ContentModalSize","isFixedHeight","header","newTranslationSearchQuery","Button","ButtonVariant","onClick","defaultLangTranslationIds","isOpen","onClose","TranslationsFilter","ButtonSize","FilterIcon","SearchBodyContainer","isSearchDrawer","onPageChange","logEvent","pageSize","rawString","suffix","characters","shortenedText","index","character","stripHTMLTags","replace","slugifiedCollectionIdToCollectionId","slugifiedCollectionId","splits","module","exports"],"sourceRoot":""}
|