feat(dev): Re-implemented search
This commit is contained in:
parent
483daa10d7
commit
b3b5d225b8
10 changed files with 230 additions and 236 deletions
|
@ -236,6 +236,7 @@ dev:
|
|||
'react-dom': *react
|
||||
'react-hotkeys-hook': &reactHotkeysHook '4.4.0'
|
||||
'react-instantsearch-dom': &reactInstantsearchDom '6.40.0'
|
||||
'react-instantsearch-hooks-web': '6.44.0'
|
||||
'react-markdown': &reactMarkdown '8.0.7'
|
||||
'react-swipeable': &reactSwipeable '7.0.0'
|
||||
'react-timeago': &reactTimeago '7.1.0'
|
||||
|
@ -400,3 +401,4 @@ shared:
|
|||
'web-worker': '1.2.0'
|
||||
dev:
|
||||
'recursive-readdir': '^2.2.3'
|
||||
'html-to-text': '^9.0.5'
|
||||
|
|
|
@ -16,7 +16,7 @@ export const DocsLayout = ({ children = [], pageTitle = false }) => {
|
|||
{title && (
|
||||
<div className="xl:pl-4">
|
||||
<Breadcrumbs crumbs={crumbs} title={pageTitle ? pageTitle : title} />
|
||||
<h1 className="break-words">{pageTitle ? pageTitle : title}</h1>
|
||||
<h1 className="break-words searchme">{pageTitle ? pageTitle : title}</h1>
|
||||
</div>
|
||||
)}
|
||||
<div className="xl:pl-4">{children}</div>
|
||||
|
|
|
@ -1,64 +1,10 @@
|
|||
// Hooks
|
||||
import { useState, useRef } from 'react'
|
||||
import { useRouter } from 'next/router'
|
||||
import { useHotkeys } from 'react-hotkeys-hook'
|
||||
// Dependencies
|
||||
import algoliasearch from 'algoliasearch/lite'
|
||||
import {
|
||||
InstantSearch,
|
||||
connectHits,
|
||||
connectHighlight,
|
||||
connectSearchBox,
|
||||
} from 'react-instantsearch-dom'
|
||||
import config from 'site/algolia.config.mjs'
|
||||
// Components
|
||||
import { InstantSearch, SearchBox, Hits, Highlight, Snippet } from 'react-instantsearch-hooks-web'
|
||||
import { siteConfig } from 'site/site.config.mjs'
|
||||
import Link from 'next/link'
|
||||
import { CloseIcon } from 'shared/components/icons.mjs'
|
||||
import { ClearIcon } from 'shared/components/icons.mjs'
|
||||
|
||||
export const ns = ['search']
|
||||
|
||||
const searchClient = algoliasearch(config.algolia.app, config.algolia.key)
|
||||
|
||||
const Hits = (props) => {
|
||||
// When we hit enter in the text field, we want to navigate to the result
|
||||
// which means we must make the result links available in the input somehow
|
||||
// so let's stuff them in a data attribute
|
||||
const links = props.hits.map((hit) => hit.page)
|
||||
props.input.current.setAttribute('data-links', JSON.stringify(links))
|
||||
|
||||
return props.hits.map((hit, index) => (
|
||||
<Hit
|
||||
key={hit.page}
|
||||
{...props}
|
||||
hit={hit}
|
||||
index={index}
|
||||
len={props.hits.length}
|
||||
activeLink={links[props.active]}
|
||||
/>
|
||||
))
|
||||
}
|
||||
|
||||
const CustomHits = connectHits(Hits)
|
||||
|
||||
const Highlight = ({ highlight, attribute, hit, snippet = false }) => {
|
||||
const parsedHit = highlight({
|
||||
highlightProperty: snippet ? '_snippetResult' : '_highlightResult',
|
||||
attribute,
|
||||
hit,
|
||||
})
|
||||
|
||||
return parsedHit.map((part, index) =>
|
||||
part.isHighlighted ? (
|
||||
<mark className="text-base-content bg-secondary-focus bg-opacity-30" key={index}>
|
||||
{part.value}
|
||||
</mark>
|
||||
) : (
|
||||
<span key={index}>{part.value}</span>
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
const CustomHighlight = connectHighlight(Highlight)
|
||||
const searchClient = algoliasearch(siteConfig.algolia.app, siteConfig.algolia.key)
|
||||
|
||||
const Hit = (props) => (
|
||||
<div
|
||||
|
@ -67,152 +13,55 @@ const Hit = (props) => (
|
|||
text-base text-base-content
|
||||
sm:rounded
|
||||
lg:px-4 lg:py-2
|
||||
hover:bg-secondary hover:bg-opacity-10 hover:text-base-content
|
||||
${props.index === props.active ? 'bg-secondary bg-opacity-30' : 'bg-base-300 bg-opacity-10'}
|
||||
border border-solid border-secondary
|
||||
bg-secondary bg-opacity-10
|
||||
hover:bg-secondary hover:bg-opacity-30
|
||||
`}
|
||||
>
|
||||
<Link href={props.hit.page} className="flex flex-row justify-between gap-2">
|
||||
<span className="text-base sm:text-xl font-bold leading-5">
|
||||
{props.hit._highlightResult?.title ? (
|
||||
<CustomHighlight hit={props.hit} attribute="title" />
|
||||
<Highlight hit={props.hit} attribute="title" />
|
||||
) : (
|
||||
props.hit.title
|
||||
)}
|
||||
</span>
|
||||
<span className="text-xs pt-0.5 sm:text-base sm:pt-1 font-bold uppercase">
|
||||
<div>
|
||||
<badge className="badge badge-primary uppercase mr-1 badge-sm">{props.hit.type}</badge>
|
||||
<badge className="badge badge-secondary uppercase badge-sm">
|
||||
{props.hit.page.split('/')[1]}
|
||||
</span>
|
||||
</badge>
|
||||
</div>
|
||||
</Link>
|
||||
{props.hit._snippetResult?.body && (
|
||||
{props.hit._snippetResult?.body?.value ? (
|
||||
<Link href={props.hit.page} className="text-sm sm:text-base block py-1">
|
||||
<CustomHighlight hit={props.hit} attribute="body" snippet />
|
||||
<Snippet hit={props.hit} attribute="body" />
|
||||
</Link>
|
||||
)}
|
||||
{props.hit?._highlightResult?.page && (
|
||||
) : (
|
||||
<Link href={props.hit.page} className="text-xs sm:text-sm block opacity-70">
|
||||
<CustomHighlight hit={props.hit} attribute="page" />
|
||||
<Highlight hit={props.hit} attribute="body" />
|
||||
</Link>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
|
||||
// We use this for trapping ctrl-c
|
||||
const handleInputKeydown = (evt, setSearch, setActive, active, router) => {
|
||||
if (evt.key === 'Escape') setSearch(false)
|
||||
if (evt.key === 'ArrowDown') setActive((act) => act + 1)
|
||||
if (evt.key === 'ArrowUp') setActive((act) => act - 1)
|
||||
if (evt.key === 'Enter') {
|
||||
// Trigger navigation
|
||||
if (evt.target?.dataset?.links) {
|
||||
router.push(JSON.parse(evt.target.dataset.links)[active])
|
||||
setSearch(false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const SearchBox = (props) => {
|
||||
const input = useRef(null)
|
||||
const router = useRouter()
|
||||
useHotkeys('ctrl+x', () => {
|
||||
input.current.value = ''
|
||||
})
|
||||
if (input.current && props.active < 0) input.current.focus()
|
||||
|
||||
const { currentRefinement, refine, setSearch, setActive } = props
|
||||
|
||||
export const Search = () => {
|
||||
return (
|
||||
<div className="py-8">
|
||||
<form noValidate action="" role="search" onSubmit={(evt) => evt.preventDefault()}>
|
||||
<div className="form-control">
|
||||
<div className="relative">
|
||||
<input
|
||||
ref={input}
|
||||
type="search"
|
||||
<InstantSearch indexName={siteConfig.algolia.index} searchClient={searchClient}>
|
||||
<SearchBox
|
||||
searchAsYouType={true}
|
||||
autoFocus={true}
|
||||
value={currentRefinement}
|
||||
onChange={(event) => refine(event.currentTarget.value)}
|
||||
onKeyDown={(evt) =>
|
||||
handleInputKeydown(evt, setSearch, setActive, props.active, router)
|
||||
}
|
||||
className="input lg:input-lg input-bordered input-neutral w-full pr-16"
|
||||
placeholder="Type to search"
|
||||
classNames={{
|
||||
root: 'relative mb-4',
|
||||
input: 'input lg:input-lg input-bordered input-neutral w-full pr-16',
|
||||
reset:
|
||||
'absolute right-0 top-0 rounded-l-none btn btn-neutral lg:btn-lg text-neutral-content',
|
||||
submit: 'absolute right-0 top-0 rounded-l-none btn btn-neutral lg:btn-lg',
|
||||
}}
|
||||
resetIconComponent={() => <ClearIcon />}
|
||||
/>
|
||||
<button
|
||||
className="absolute right-0 top-0 rounded-l-none btn btn-neutral lg:btn-lg"
|
||||
onClick={() => props.setSearch(false)}
|
||||
>
|
||||
X
|
||||
</button>
|
||||
</div>
|
||||
<label className="label hidden sm:block">
|
||||
<div className="label-text flex flex-row gap-4 justify-between">
|
||||
<div>
|
||||
<b> Escape</b> to exit
|
||||
</div>
|
||||
<div>
|
||||
<b> Up</b> or <b>Down</b> to select
|
||||
</div>
|
||||
<div>
|
||||
<b> Enter</b> to navigate
|
||||
</div>
|
||||
</div>
|
||||
</label>
|
||||
</div>
|
||||
<div
|
||||
className="overscroll-auto overflow-y-auto mt-2"
|
||||
style={{ maxHeight: 'calc(100vh - 10rem)' }}
|
||||
>
|
||||
{input.current && input.current.value.length > 0 && (
|
||||
<CustomHits hitComponent={Hit} {...props} input={input} />
|
||||
)}
|
||||
</div>
|
||||
</form>
|
||||
<div
|
||||
className={`
|
||||
bg-neutral text-neutral-content
|
||||
z-20 w-full mx-auto
|
||||
lg:bg-base-100 lg:border-base-200
|
||||
fixed bottom-0 left-0 border-t-2
|
||||
lg:hidden
|
||||
`}
|
||||
>
|
||||
<div className="px-4 py-0 flex flex-row w-full lg:py-2">
|
||||
<button className={`btn btn-ghost btn-block`} onClick={() => props.setSearch(false)}>
|
||||
<span className="px-2 pt-2 pb-2">
|
||||
<CloseIcon />
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
const CustomSearchBox = connectSearchBox(SearchBox)
|
||||
|
||||
export const Search = (props) => {
|
||||
const [active, setActive] = useState(0)
|
||||
useHotkeys('esc', () => props.setSearch(false))
|
||||
useHotkeys('up', () => {
|
||||
if (active) setActive((act) => act - 1)
|
||||
})
|
||||
useHotkeys('down', () => {
|
||||
setActive((act) => act + 1)
|
||||
})
|
||||
useHotkeys('down', () => {
|
||||
console.log('enter', active)
|
||||
})
|
||||
|
||||
const stateProps = {
|
||||
setSearch: props.setSearch,
|
||||
setMenu: props.setMenu,
|
||||
active,
|
||||
setActive,
|
||||
}
|
||||
|
||||
return (
|
||||
<InstantSearch indexName={config.algolia.index} searchClient={searchClient}>
|
||||
<CustomSearchBox {...stateProps} />
|
||||
{/* Widgets */}
|
||||
<Hits hitComponent={Hit} />
|
||||
</InstantSearch>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -1,17 +1,10 @@
|
|||
import Head from 'next/head'
|
||||
import { Header, ns as headerNs } from 'site/components/header/index.mjs'
|
||||
import { Footer, ns as footerNs } from 'shared/components/footer/index.mjs'
|
||||
import { Search, ns as searchNs } from 'site/components/search.mjs'
|
||||
|
||||
export const ns = [...new Set([...headerNs, ...footerNs, ...searchNs])]
|
||||
export const ns = [...new Set([...headerNs, ...footerNs])]
|
||||
|
||||
export const LayoutWrapper = ({
|
||||
children = [],
|
||||
search,
|
||||
setSearch,
|
||||
noSearch = false,
|
||||
header = false,
|
||||
}) => {
|
||||
export const LayoutWrapper = ({ children = [], header = false }) => {
|
||||
const ChosenHeader = header ? header : Header
|
||||
|
||||
return (
|
||||
|
@ -25,24 +18,8 @@ export const LayoutWrapper = ({
|
|||
<Head>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
</Head>
|
||||
<ChosenHeader setSearch={setSearch} />
|
||||
<ChosenHeader />
|
||||
<main className="grow">{children}</main>
|
||||
{!noSearch && search && (
|
||||
<>
|
||||
<div
|
||||
className={`
|
||||
fixed w-full max-h-screen bg-base-100 top-0 z-30 pt-0 pb-16 px-8
|
||||
md:rounded-lg md:top-24
|
||||
md:max-w-xl md:m-auto md:inset-x-12
|
||||
md:max-w-2xl
|
||||
lg:max-w-4xl
|
||||
`}
|
||||
>
|
||||
<Search search={search} setSearch={setSearch} />
|
||||
</div>
|
||||
<div className="fixed top-0 left-0 w-full min-h-screen bg-neutral z-20 bg-opacity-70"></div>
|
||||
</>
|
||||
)}
|
||||
<Footer />
|
||||
</div>
|
||||
)
|
||||
|
|
|
@ -46,6 +46,7 @@
|
|||
"react-dom": "18.2.0",
|
||||
"react-hotkeys-hook": "4.4.0",
|
||||
"react-instantsearch-dom": "6.40.0",
|
||||
"react-instantsearch-hooks-web": "6.44.0",
|
||||
"react-markdown": "8.0.7",
|
||||
"react-swipeable": "7.0.0",
|
||||
"react-timeago": "7.1.0",
|
||||
|
|
|
@ -1,10 +1,8 @@
|
|||
/*
|
||||
* This will update (replace really) the Algolia index with the
|
||||
* current website contents. Or at least the markdown and Strapi
|
||||
* content
|
||||
* current website contents. Or at least the markdown content.
|
||||
*
|
||||
* It expects the following environment vars to be set in a
|
||||
* .env file in the 'sites/dev' folder:
|
||||
* It expects the following environment vars to be set:
|
||||
*
|
||||
* ALGOLIA_API_WRITE_KEY -> Needs permission to index/create/delete
|
||||
*
|
||||
|
@ -23,15 +21,18 @@ import remarkRehype from 'remark-rehype'
|
|||
import rehypeSanitize from 'rehype-sanitize'
|
||||
import rehypeStringify from 'rehype-stringify'
|
||||
import yaml from 'yaml'
|
||||
import { getMdxFileList } from '../../shared/prebuild/mdx.mjs'
|
||||
import config from '../algolia.config.mjs'
|
||||
import { getMdxFileList } from '../../shared/prebuild/docs.mjs'
|
||||
import { siteConfig } from '../site.config.mjs'
|
||||
import { compile } from 'html-to-text'
|
||||
dotenv.config()
|
||||
|
||||
const convert = compile()
|
||||
|
||||
/*
|
||||
* Initialize Algolia client
|
||||
*/
|
||||
const client = algoliasearch(config.algolia.app, process.env.ALGOLIA_API_WRITE_KEY)
|
||||
const index = client.initIndex(config.algolia.index)
|
||||
const client = algoliasearch(siteConfig.algolia.app, process.env.ALGOLIA_API_WRITE_KEY)
|
||||
const index = client.initIndex(siteConfig.algolia.index)
|
||||
|
||||
/*
|
||||
* Loads markdown from disk and compiles it into HTML for indexing
|
||||
|
@ -65,9 +66,21 @@ const markdownLoader = async (file) => {
|
|||
*/
|
||||
const clearIndex = async () => {
|
||||
console.log(`🗑️ Clearing index`)
|
||||
try {
|
||||
await index.clearObjects()
|
||||
} catch (err) {
|
||||
console.log(err)
|
||||
}
|
||||
}
|
||||
|
||||
const splitContent = (content) =>
|
||||
content.body.split('<h2>').map((chunk, i) => ({
|
||||
...content,
|
||||
objectID: `${content.objectID}-${i}`,
|
||||
title: content.title + ' / ' + chunk.split('</h2>')[0],
|
||||
body: convert(chunk.split('</h2>').slice(1).join('</h2>')),
|
||||
}))
|
||||
|
||||
/*
|
||||
* Get and index markdown content
|
||||
*/
|
||||
|
@ -82,9 +95,17 @@ const indexMarkdownContent = async () => {
|
|||
const list = await getMdxFileList(mdxRoot, 'en')
|
||||
const pages = []
|
||||
|
||||
// max page size
|
||||
const MAX = 1500
|
||||
|
||||
for (const file of list) {
|
||||
const content = await markdownLoader(file)
|
||||
pages.push(content)
|
||||
if (content.body.length < MAX)
|
||||
pages.push({
|
||||
...content,
|
||||
body: convert(content.body),
|
||||
})
|
||||
else pages.push(...splitContent(content))
|
||||
}
|
||||
// Index markdown to Algolia
|
||||
await index.clearObjects()
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
export const siteConfig = {
|
||||
algolia: {
|
||||
app: 'MA0Y5A2PF0', // Application ID
|
||||
index: 'canary_freesewing.dev',
|
||||
index: 'freesewing.dev',
|
||||
key: '589c7a7e4d9c95a4f12868581259bf3a', // Search-only API key
|
||||
},
|
||||
bugsnag: {
|
||||
|
|
|
@ -116,7 +116,7 @@ export const MdxWrapper = ({ MDX = false, frontmatter = {}, components = {}, chi
|
|||
updated={updates.u}
|
||||
{...{ locale, slug, t }}
|
||||
/>
|
||||
{MDX ? <MDX components={allComponents} /> : children}
|
||||
<div className="searchme">{MDX ? <MDX components={allComponents} /> : children}</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -59,7 +59,8 @@
|
|||
"web-worker": "1.2.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"recursive-readdir": "^2.2.3"
|
||||
"recursive-readdir": "^2.2.3",
|
||||
"html-to-text": "^9.0.5"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16.0.0",
|
||||
|
|
165
yarn.lock
165
yarn.lock
|
@ -111,6 +111,19 @@
|
|||
"@algolia/logger-common" "4.17.0"
|
||||
"@algolia/requester-common" "4.17.0"
|
||||
|
||||
"@algolia/ui-components-highlight-vdom@^1.2.1":
|
||||
version "1.2.1"
|
||||
resolved "https://registry.yarnpkg.com/@algolia/ui-components-highlight-vdom/-/ui-components-highlight-vdom-1.2.1.tgz#c430c9f090ef8c68477ef4b685324ed231ce0c13"
|
||||
integrity sha512-IlYgIaCUEkz9ezNbwugwKv991oOHhveyq6nzL0F1jDzg1p3q5Yj/vO4KpNG910r2dwGCG3nEm5GtChcLnarhFA==
|
||||
dependencies:
|
||||
"@algolia/ui-components-shared" "1.2.1"
|
||||
"@babel/runtime" "^7.0.0"
|
||||
|
||||
"@algolia/ui-components-shared@1.2.1", "@algolia/ui-components-shared@^1.2.1":
|
||||
version "1.2.1"
|
||||
resolved "https://registry.yarnpkg.com/@algolia/ui-components-shared/-/ui-components-shared-1.2.1.tgz#62e3a04fc11623f149312942cd764d4528dd994c"
|
||||
integrity sha512-a7mYHf/GVQfhAx/HRiMveKkFvHspQv/REdG+C/FIOosiSmNZxX7QebDwJkrGSmDWdXO12D0Qv1xn3AytFcEDlQ==
|
||||
|
||||
"@alloc/quick-lru@^5.2.0":
|
||||
version "5.2.0"
|
||||
resolved "https://registry.yarnpkg.com/@alloc/quick-lru/-/quick-lru-5.2.0.tgz#7bf68b20c0a350f936915fcae06f58e32007ce30"
|
||||
|
@ -3839,6 +3852,14 @@
|
|||
json5 "^2.2.3"
|
||||
lodash "^4.17.21"
|
||||
|
||||
"@selderee/plugin-htmlparser2@^0.11.0":
|
||||
version "0.11.0"
|
||||
resolved "https://registry.yarnpkg.com/@selderee/plugin-htmlparser2/-/plugin-htmlparser2-0.11.0.tgz#d5b5e29a7ba6d3958a1972c7be16f4b2c188c517"
|
||||
integrity sha512-P33hHGdldxGabLFjPPpaTxVolMrzrcegejx+0GxjrIb9Zv48D8yAIA/QTDR2dFl7Uz7urX8aX6+5bCZslr+gWQ==
|
||||
dependencies:
|
||||
domhandler "^5.0.3"
|
||||
selderee "^0.11.0"
|
||||
|
||||
"@sigstore/protobuf-specs@^0.1.0":
|
||||
version "0.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@sigstore/protobuf-specs/-/protobuf-specs-0.1.0.tgz#957cb64ea2f5ce527cc9cf02a096baeb0d2b99b4"
|
||||
|
@ -4092,6 +4113,11 @@
|
|||
resolved "https://registry.yarnpkg.com/@types/diff-match-patch/-/diff-match-patch-1.0.32.tgz#d9c3b8c914aa8229485351db4865328337a3d09f"
|
||||
integrity sha512-bPYT5ECFiblzsVzyURaNhljBH2Gh1t9LowgUwciMrNAhFewLkHT2H0Mto07Y4/3KCOGZHRQll3CTtQZ0X11D/A==
|
||||
|
||||
"@types/dom-speech-recognition@^0.0.1":
|
||||
version "0.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/dom-speech-recognition/-/dom-speech-recognition-0.0.1.tgz#e326761a04b4a49c0eec2ac7948afc1c6aa12baa"
|
||||
integrity sha512-udCxb8DvjcDKfk1WTBzDsxFbLgYxmQGKrE/ricoMqHRNjSlSUCcamVTA5lIQqzY10mY5qCY0QDwBfFEwhfoDPw==
|
||||
|
||||
"@types/estree-jsx@^1.0.0":
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/estree-jsx/-/estree-jsx-1.0.0.tgz#7bfc979ab9f692b492017df42520f7f765e98df1"
|
||||
|
@ -4146,6 +4172,11 @@
|
|||
"@types/minimatch" "*"
|
||||
"@types/node" "*"
|
||||
|
||||
"@types/google.maps@^3.45.3":
|
||||
version "3.53.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/google.maps/-/google.maps-3.53.1.tgz#c1fb7325eaa5af3574aedb9390d16798be0dad00"
|
||||
integrity sha512-+7JVpq+kFzTU3TweSz6huYuFedZ4s60WeABaXYU6rDZczdpfoQ5DuZNCDc/eAAcdFJpxMMDpzf3d9YTMNodBFg==
|
||||
|
||||
"@types/hast@^2.0.0":
|
||||
version "2.3.4"
|
||||
resolved "https://registry.yarnpkg.com/@types/hast/-/hast-2.3.4.tgz#8aa5ef92c117d20d974a82bdfb6a648b08c0bafc"
|
||||
|
@ -4153,6 +4184,11 @@
|
|||
dependencies:
|
||||
"@types/unist" "*"
|
||||
|
||||
"@types/hogan.js@^3.0.0":
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/hogan.js/-/hogan.js-3.0.1.tgz#64c54407b30da359763e14877f5702b8ae85d61c"
|
||||
integrity sha512-D03i/2OY7kGyMq9wdQ7oD8roE49z/ZCZThe/nbahtvuqCNZY9T2MfedOWyeBdbEpY2W8Gnh/dyJLdFtUCOkYbg==
|
||||
|
||||
"@types/hoist-non-react-statics@^3.3.1":
|
||||
version "3.3.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz#1124aafe5118cb591977aeb1ceaaed1070eb039f"
|
||||
|
@ -4277,7 +4313,7 @@
|
|||
resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.5.tgz#5f19d2b85a98e9558036f6a3cacc8819420f05cf"
|
||||
integrity sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==
|
||||
|
||||
"@types/qs@*":
|
||||
"@types/qs@*", "@types/qs@^6.5.3":
|
||||
version "6.9.7"
|
||||
resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.7.tgz#63bb7d067db107cc1e457c303bc25d511febf6cb"
|
||||
integrity sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==
|
||||
|
@ -7388,7 +7424,7 @@ deep-is@^0.1.3, deep-is@~0.1.3:
|
|||
resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831"
|
||||
integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==
|
||||
|
||||
deepmerge@^4.2.2:
|
||||
deepmerge@^4.2.2, deepmerge@^4.3.1:
|
||||
version "4.3.1"
|
||||
resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.3.1.tgz#44b5f2147cd3b00d4b56137685966f26fd25dd4a"
|
||||
integrity sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==
|
||||
|
@ -10177,6 +10213,14 @@ history@^5.3.0:
|
|||
dependencies:
|
||||
"@babel/runtime" "^7.7.6"
|
||||
|
||||
hogan.js@^3.0.2:
|
||||
version "3.0.2"
|
||||
resolved "https://registry.yarnpkg.com/hogan.js/-/hogan.js-3.0.2.tgz#4cd9e1abd4294146e7679e41d7898732b02c7bfd"
|
||||
integrity sha512-RqGs4wavGYJWE07t35JQccByczmNUXQT0E12ZYV1VKYu5UiAU9lsos/yBAcf840+zrUQQxgVduCR5/B8nNtibg==
|
||||
dependencies:
|
||||
mkdirp "0.3.0"
|
||||
nopt "1.0.10"
|
||||
|
||||
hoist-non-react-statics@^3.0.0, hoist-non-react-statics@^3.3.0, hoist-non-react-statics@^3.3.2:
|
||||
version "3.3.2"
|
||||
resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45"
|
||||
|
@ -10222,6 +10266,11 @@ hosted-git-info@^6.0.0, hosted-git-info@^6.1.1:
|
|||
dependencies:
|
||||
lru-cache "^7.5.1"
|
||||
|
||||
htm@^3.0.0:
|
||||
version "3.1.1"
|
||||
resolved "https://registry.yarnpkg.com/htm/-/htm-3.1.1.tgz#49266582be0dc66ed2235d5ea892307cc0c24b78"
|
||||
integrity sha512-983Vyg8NwUE7JkZ6NmOqpCZ+sh1bKv2iYTlUkzlWmA5JD2acKoxd4KVxbMmxX/85mtfdnDmTFoNKcg5DGAvxNQ==
|
||||
|
||||
html-crush@^4.0.0, html-crush@^4.2.0:
|
||||
version "4.2.0"
|
||||
resolved "https://registry.yarnpkg.com/html-crush/-/html-crush-4.2.0.tgz#ec5774d252ab15235c5c27af056d691b4f5abb07"
|
||||
|
@ -10254,6 +10303,17 @@ html-parse-stringify@^3.0.1:
|
|||
dependencies:
|
||||
void-elements "3.1.0"
|
||||
|
||||
html-to-text@^9.0.5:
|
||||
version "9.0.5"
|
||||
resolved "https://registry.yarnpkg.com/html-to-text/-/html-to-text-9.0.5.tgz#6149a0f618ae7a0db8085dca9bbf96d32bb8368d"
|
||||
integrity sha512-qY60FjREgVZL03vJU6IfMV4GDjGBIoOyvuFdpBDIX9yTlDw0TjxVBQp+P8NvpdIXNJvfWBTNul7fsAQJq2FNpg==
|
||||
dependencies:
|
||||
"@selderee/plugin-htmlparser2" "^0.11.0"
|
||||
deepmerge "^4.3.1"
|
||||
dom-serializer "^2.0.0"
|
||||
htmlparser2 "^8.0.2"
|
||||
selderee "^0.11.0"
|
||||
|
||||
html-void-elements@^2.0.0:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/html-void-elements/-/html-void-elements-2.0.1.tgz#29459b8b05c200b6c5ee98743c41b979d577549f"
|
||||
|
@ -10305,7 +10365,7 @@ htmlparser2@^7.1.1:
|
|||
domutils "^2.8.0"
|
||||
entities "^3.0.1"
|
||||
|
||||
htmlparser2@^8.0.1:
|
||||
htmlparser2@^8.0.1, htmlparser2@^8.0.2:
|
||||
version "8.0.2"
|
||||
resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-8.0.2.tgz#f002151705b383e62433b5cf466f5b716edaec21"
|
||||
integrity sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==
|
||||
|
@ -10703,6 +10763,25 @@ inquirer@^8.0.0, inquirer@^8.2.4:
|
|||
through "^2.3.6"
|
||||
wrap-ansi "^7.0.0"
|
||||
|
||||
instantsearch.js@4.56.0:
|
||||
version "4.56.0"
|
||||
resolved "https://registry.yarnpkg.com/instantsearch.js/-/instantsearch.js-4.56.0.tgz#faedcbaac1c94575703470a048cf39e4170fc6d0"
|
||||
integrity sha512-A50GZjcK9c3o3y49fqOX6ghI4leCPAiz0h5xY/yvU7mMXCwwXZw1BsUbOPM02gDvaUdYvibycW7byVQno3DK1g==
|
||||
dependencies:
|
||||
"@algolia/events" "^4.0.1"
|
||||
"@algolia/ui-components-highlight-vdom" "^1.2.1"
|
||||
"@algolia/ui-components-shared" "^1.2.1"
|
||||
"@types/dom-speech-recognition" "^0.0.1"
|
||||
"@types/google.maps" "^3.45.3"
|
||||
"@types/hogan.js" "^3.0.0"
|
||||
"@types/qs" "^6.5.3"
|
||||
algoliasearch-helper "^3.13.0"
|
||||
hogan.js "^3.0.2"
|
||||
htm "^3.0.0"
|
||||
preact "^10.10.0"
|
||||
qs "^6.5.1 < 6.10"
|
||||
search-insights "^2.6.0"
|
||||
|
||||
internal-slot@^1.0.3, internal-slot@^1.0.4, internal-slot@^1.0.5:
|
||||
version "1.0.5"
|
||||
resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.5.tgz#f2a2ee21f668f8627a4667f309dc0f4fb6674986"
|
||||
|
@ -11804,6 +11883,11 @@ lazystream@^1.0.0:
|
|||
dependencies:
|
||||
readable-stream "^2.0.5"
|
||||
|
||||
leac@^0.6.0:
|
||||
version "0.6.0"
|
||||
resolved "https://registry.yarnpkg.com/leac/-/leac-0.6.0.tgz#dcf136e382e666bd2475f44a1096061b70dc0912"
|
||||
integrity sha512-y+SqErxb8h7nE/fiEX07jsbuhrpO9lL8eca7/Y1nuWV2moNlXhyd59iDGcRf6moVyDMbmTNzL40SUyrFU/yDpg==
|
||||
|
||||
lerna@^6.0.0:
|
||||
version "6.6.2"
|
||||
resolved "https://registry.yarnpkg.com/lerna/-/lerna-6.6.2.tgz#ad921f913aca4e7307123a598768b6f15ca5804f"
|
||||
|
@ -13727,6 +13811,11 @@ mkdirp-infer-owner@^2.0.0:
|
|||
infer-owner "^1.0.4"
|
||||
mkdirp "^1.0.3"
|
||||
|
||||
mkdirp@0.3.0:
|
||||
version "0.3.0"
|
||||
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.3.0.tgz#1bbf5ab1ba827af23575143490426455f481fe1e"
|
||||
integrity sha512-OHsdUcVAQ6pOtg5JYWpCBo9W/GySVuwvP9hueRMW7UqshC0tbfzLv8wjySTPm3tfUZ/21CE9E1pJagOA91Pxew==
|
||||
|
||||
mkdirp@^1.0.3, mkdirp@^1.0.4:
|
||||
version "1.0.4"
|
||||
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e"
|
||||
|
@ -14044,6 +14133,13 @@ non-layered-tidy-tree-layout@^2.0.2:
|
|||
resolved "https://registry.yarnpkg.com/non-layered-tidy-tree-layout/-/non-layered-tidy-tree-layout-2.0.2.tgz#57d35d13c356643fc296a55fb11ac15e74da7804"
|
||||
integrity sha512-gkXMxRzUH+PB0ax9dUN0yYF0S25BqeAYqhgMaLUFmpXLEk7Fcu8f4emJuOAY0V8kjDICxROIKsTAKsV/v355xw==
|
||||
|
||||
nopt@1.0.10, nopt@~1.0.10:
|
||||
version "1.0.10"
|
||||
resolved "https://registry.yarnpkg.com/nopt/-/nopt-1.0.10.tgz#6ddd21bd2a31417b92727dd585f8a6f37608ebee"
|
||||
integrity sha512-NWmpvLSqUrgrAC9HCuxEvb+PSloHpqVu+FqcO4eeF2h5qYRhA7ev6KvelyQAKtegUbC6RypJnlEOhd8vloNKYg==
|
||||
dependencies:
|
||||
abbrev "1"
|
||||
|
||||
nopt@^6.0.0:
|
||||
version "6.0.0"
|
||||
resolved "https://registry.yarnpkg.com/nopt/-/nopt-6.0.0.tgz#245801d8ebf409c6df22ab9d95b65e1309cdb16d"
|
||||
|
@ -14058,13 +14154,6 @@ nopt@^7.0.0:
|
|||
dependencies:
|
||||
abbrev "^2.0.0"
|
||||
|
||||
nopt@~1.0.10:
|
||||
version "1.0.10"
|
||||
resolved "https://registry.yarnpkg.com/nopt/-/nopt-1.0.10.tgz#6ddd21bd2a31417b92727dd585f8a6f37608ebee"
|
||||
integrity sha512-NWmpvLSqUrgrAC9HCuxEvb+PSloHpqVu+FqcO4eeF2h5qYRhA7ev6KvelyQAKtegUbC6RypJnlEOhd8vloNKYg==
|
||||
dependencies:
|
||||
abbrev "1"
|
||||
|
||||
normalize-package-data@^2.3.2, normalize-package-data@^2.5.0:
|
||||
version "2.5.0"
|
||||
resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8"
|
||||
|
@ -15150,6 +15239,14 @@ parse5@^7.0.0, parse5@^7.1.1:
|
|||
dependencies:
|
||||
entities "^4.4.0"
|
||||
|
||||
parseley@^0.12.0:
|
||||
version "0.12.1"
|
||||
resolved "https://registry.yarnpkg.com/parseley/-/parseley-0.12.1.tgz#4afd561d50215ebe259e3e7a853e62f600683aef"
|
||||
integrity sha512-e6qHKe3a9HWr0oMRVDTRhKce+bRO8VGQR3NyVwcjwrbhMmFCX9KszEV35+rn4AdilFAq9VPxP/Fe1wC9Qjd2lw==
|
||||
dependencies:
|
||||
leac "^0.6.0"
|
||||
peberminta "^0.9.0"
|
||||
|
||||
parseurl@~1.3.2, parseurl@~1.3.3:
|
||||
version "1.3.3"
|
||||
resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4"
|
||||
|
@ -15276,6 +15373,11 @@ pdfkit@0.13.0:
|
|||
linebreak "^1.0.2"
|
||||
png-js "^1.0.0"
|
||||
|
||||
peberminta@^0.9.0:
|
||||
version "0.9.0"
|
||||
resolved "https://registry.yarnpkg.com/peberminta/-/peberminta-0.9.0.tgz#8ec9bc0eb84b7d368126e71ce9033501dca2a352"
|
||||
integrity sha512-XIxfHpEuSJbITd1H3EeQwpcZbTLHc+VVr8ANI9t5sit565tsI4/xK3KWTUFE2e6QiangUkh3B0jihzmGnNrRsQ==
|
||||
|
||||
peek-stream@^1.1.0, peek-stream@^1.1.2:
|
||||
version "1.1.3"
|
||||
resolved "https://registry.yarnpkg.com/peek-stream/-/peek-stream-1.1.3.tgz#3b35d84b7ccbbd262fff31dc10da56856ead6d67"
|
||||
|
@ -15772,6 +15874,11 @@ posthtml@^0.16.4, posthtml@^0.16.5, posthtml@^0.16.6:
|
|||
posthtml-parser "^0.11.0"
|
||||
posthtml-render "^3.0.0"
|
||||
|
||||
preact@^10.10.0:
|
||||
version "10.15.0"
|
||||
resolved "https://registry.yarnpkg.com/preact/-/preact-10.15.0.tgz#14bae0afe3547ca9d45d22fda2a4266462d31cf3"
|
||||
integrity sha512-nZSa8M2R2m1n7nJSBlzDpxRJaIsejrTO1vlFbdpFvyC8qM1iU+On2y0otfoUm6SRB5o0lF0CKDFxg6grEFU0iQ==
|
||||
|
||||
prebuild-install@^7.1.1:
|
||||
version "7.1.1"
|
||||
resolved "https://registry.yarnpkg.com/prebuild-install/-/prebuild-install-7.1.1.tgz#de97d5b34a70a0c81334fd24641f2a1702352e45"
|
||||
|
@ -16074,6 +16181,11 @@ qs@^6.11.0, qs@^6.5.1:
|
|||
dependencies:
|
||||
side-channel "^1.0.4"
|
||||
|
||||
"qs@^6.5.1 < 6.10":
|
||||
version "6.9.7"
|
||||
resolved "https://registry.yarnpkg.com/qs/-/qs-6.9.7.tgz#4610846871485e1e048f44ae3b94033f0e675afe"
|
||||
integrity sha512-IhMFgUmuNpyRfxA90umL7ByLlgRXu6tIfKPpF5TmcfRLlLCckfP/g3IQmju6jjpu+Hh8rA+2p6A27ZSPOOHdKw==
|
||||
|
||||
query-string@7.1.3, query-string@^7.1.3:
|
||||
version "7.1.3"
|
||||
resolved "https://registry.yarnpkg.com/query-string/-/query-string-7.1.3.tgz#a1cf90e994abb113a325804a972d98276fe02328"
|
||||
|
@ -16283,6 +16395,25 @@ react-instantsearch-dom@6.40.0:
|
|||
react-fast-compare "^3.0.0"
|
||||
react-instantsearch-core "6.40.0"
|
||||
|
||||
react-instantsearch-hooks-web@6.44.0:
|
||||
version "6.44.0"
|
||||
resolved "https://registry.yarnpkg.com/react-instantsearch-hooks-web/-/react-instantsearch-hooks-web-6.44.0.tgz#cd40bcdcfd6953652e4d9b9cc94c38adaa512772"
|
||||
integrity sha512-jLCU0r1UtVPEbMIP7YL+qU8Lfoy/Z3nLMDS6iBVn3ybB/IBESjYASJsqYGZ1Yk17W6Dl0TWSIacgQsfu8QcE2Q==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.1.2"
|
||||
instantsearch.js "4.56.0"
|
||||
react-instantsearch-hooks "6.44.0"
|
||||
|
||||
react-instantsearch-hooks@6.44.0:
|
||||
version "6.44.0"
|
||||
resolved "https://registry.yarnpkg.com/react-instantsearch-hooks/-/react-instantsearch-hooks-6.44.0.tgz#59d98a6f2938009add633998832cd0f842df8c5a"
|
||||
integrity sha512-1c/cd6OHAe8hP3PBeEUBwdVi6j3lu0AxGR17wun6j+aKC8/7gTyW0LXGUgm54xU5CORez8/OVh0akK+XDxu+9g==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.1.2"
|
||||
algoliasearch-helper "^3.13.0"
|
||||
instantsearch.js "4.56.0"
|
||||
use-sync-external-store "^1.0.0"
|
||||
|
||||
react-is@18.2.0, react-is@^18.0.0, react-is@^18.2.0:
|
||||
version "18.2.0"
|
||||
resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.2.0.tgz#199431eeaaa2e09f86427efbb4f1473edb47609b"
|
||||
|
@ -17774,6 +17905,18 @@ scroll-into-view-if-needed@^3.0.3:
|
|||
dependencies:
|
||||
compute-scroll-into-view "^3.0.2"
|
||||
|
||||
search-insights@^2.6.0:
|
||||
version "2.6.0"
|
||||
resolved "https://registry.yarnpkg.com/search-insights/-/search-insights-2.6.0.tgz#bb8771a73b83c4a0f1f207c2f64fea01acd3e7d0"
|
||||
integrity sha512-vU2/fJ+h/Mkm/DJOe+EaM5cafJv/1rRTZpGJTuFPf/Q5LjzgMDsqPdSaZsAe+GAWHHsfsu+rQSAn6c8IGtBEVw==
|
||||
|
||||
selderee@^0.11.0:
|
||||
version "0.11.0"
|
||||
resolved "https://registry.yarnpkg.com/selderee/-/selderee-0.11.0.tgz#6af0c7983e073ad3e35787ffe20cefd9daf0ec8a"
|
||||
integrity sha512-5TF+l7p4+OsnP8BCCvSyZiSPc4x4//p5uPwK8TCnVPJYRmU2aYKMpOXvw8zM5a5JvuuCGN1jmsMwuU2W02ukfA==
|
||||
dependencies:
|
||||
parseley "^0.12.0"
|
||||
|
||||
semver-diff@^3.1.1:
|
||||
version "3.1.1"
|
||||
resolved "https://registry.yarnpkg.com/semver-diff/-/semver-diff-3.1.1.tgz#05f77ce59f325e00e2706afd67bb506ddb1ca32b"
|
||||
|
@ -19981,7 +20124,7 @@ use-sidecar@^1.1.2:
|
|||
detect-node-es "^1.1.0"
|
||||
tslib "^2.0.0"
|
||||
|
||||
use-sync-external-store@^1.2.0:
|
||||
use-sync-external-store@^1.0.0, use-sync-external-store@^1.2.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz#7dbefd6ef3fe4e767a0cf5d7287aacfb5846928a"
|
||||
integrity sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue