2
0

Add Bubble and Popup in embed lib v2

Closes #214
This commit is contained in:
Baptiste Arnaud
2023-01-09 14:51:36 +01:00
parent 4bf93b4872
commit 21f1c7a17e
38 changed files with 1586 additions and 96 deletions

View File

@@ -3,7 +3,7 @@ import {
getExistingResultFromSession,
setResultInSession,
} from '@/utils/sessionStorage'
import Bot from '@typebot.io/react'
import { Standard } from '@typebot.io/react'
import { BackgroundType, InitialChatReply, Typebot } from 'models'
import { useRouter } from 'next/router'
import { useCallback, useEffect, useState } from 'react'
@@ -38,6 +38,7 @@ export const TypebotPageV2 = ({ url, typebot }: TypebotPageV2Props) => {
}, [asPath, push, typebot.settings.general.isHideQueryParamsEnabled])
useEffect(() => {
console.log(open)
clearQueryParamsIfNecessary()
}, [clearQueryParamsIfNecessary])
@@ -89,10 +90,7 @@ export const TypebotPageV2 = ({ url, typebot }: TypebotPageV2Props) => {
metadata={typebot.settings.metadata}
/>
{initialChatReply && (
<Bot.Standard
typebotId={typebot.id}
initialChatReply={initialChatReply}
/>
<Standard typebotId={typebot.id} initialChatReply={initialChatReply} />
)}
</div>
)

View File

@@ -6,7 +6,11 @@ import { NextApiRequest, NextApiResponse } from 'next'
const handler = async (req: NextApiRequest, res: NextApiResponse) => {
await cors(req, res, {
origin: ['https://docs.typebot.io', 'http://localhost:3005'],
origin: [
'https://docs.typebot.io',
'http://localhost:3005',
'http://localhost:3006',
],
})
return createOpenApiNextHandler({

View File

@@ -1,3 +1,2 @@
export * from './components/TypebotViewer'
export { parseVariables } from '@/features/variables'
export * from 'util'

View File

@@ -1 +1,9 @@
export * from '@prisma/client'
// Named export for enums to avoid vite barrel export bug (https://github.com/nrwl/nx/issues/13704)
export {
Plan,
WorkspaceRole,
GraphNavigation,
CollaborationType,
} from '@prisma/client'

View File

@@ -28,7 +28,7 @@ export const AvatarSideContainer = (props: Props) => {
<div
ref={avatarContainer}
class={
'flex w-10 mr-2 mb-2 flex-shrink-0 items-center relative typebot-avatar-container ' +
'flex mr-2 mb-2 flex-shrink-0 items-center relative typebot-avatar-container ' +
(isMobile() ? 'w-6' : 'w-10')
}
>

View File

@@ -42,7 +42,7 @@ export const ConversationContainer = (props: Props) => {
}
return (
<div class="overflow-y-scroll w-full lg:w-3/4 min-h-full rounded lg:px-5 px-3 pt-10 relative scrollable-container typebot-chat-view">
<div class="overflow-y-scroll w-full min-h-full rounded px-3 pt-10 relative scrollable-container typebot-chat-view">
<For each={chatChunks()}>
{(chatChunk, index) => (
<ChatChunk

View File

@@ -1,52 +1,124 @@
import styles from '../../../assets/index.css'
import { createSignal } from 'solid-js'
import { createSignal, onMount, Show, splitProps, onCleanup } from 'solid-js'
import { Bot, BotProps } from '../../../components/Bot'
import { CommandData } from '@/features/commands'
import { BubbleButton } from './BubbleButton'
import { PreviewMessage, PreviewMessageProps } from './PreviewMessage'
import { isDefined } from 'utils'
import { BubbleParams } from '../types'
export type BubbleProps = BotProps &
BubbleParams & {
onOpen?: () => void
onClose?: () => void
onPreviewMessageClick?: () => void
}
export const Bubble = (props: BubbleProps) => {
const [bubbleProps, botProps] = splitProps(props, [
'onOpen',
'onClose',
'previewMessage',
'onPreviewMessageClick',
'button',
])
const [prefilledVariables, setPrefilledVariables] = createSignal(
// eslint-disable-next-line solid/reactivity
botProps.prefilledVariables
)
const [isPreviewMessageDisplayed, setIsPreviewMessageDisplayed] =
createSignal(false)
const [previewMessage, setPreviewMessage] = createSignal<
Pick<PreviewMessageProps, 'avatarUrl' | 'message'>
>({
message: bubbleProps.previewMessage?.message ?? '',
avatarUrl: bubbleProps.previewMessage?.avatarUrl,
})
export const Bubble = () => {
const [isBotOpened, setIsBotOpened] = createSignal(false)
const [isBotStarted, setIsBotStarted] = createSignal(false)
onMount(() => {
window.addEventListener('message', processIncomingEvent)
const autoShowDelay = bubbleProps.previewMessage?.autoShowDelay
if (isDefined(autoShowDelay)) {
setTimeout(() => {
showMessage()
}, autoShowDelay)
}
})
onCleanup(() => {
window.removeEventListener('message', processIncomingEvent)
})
const processIncomingEvent = (event: MessageEvent<CommandData>) => {
const { data } = event
if (!data.isFromTypebot) return
if (data.command === 'open') openBot()
if (data.command === 'close') closeBot()
if (data.command === 'toggle') toggleBot()
if (data.command === 'showPreviewMessage') showMessage(data.message)
if (data.command === 'hidePreviewMessage') hideMessage()
if (data.command === 'setPrefilledVariables')
setPrefilledVariables((existingPrefilledVariables) => ({
...existingPrefilledVariables,
...data.variables,
}))
}
const openBot = () => {
if (!isBotStarted()) setIsBotStarted(true)
hideMessage()
setIsBotOpened(true)
if (isBotOpened()) bubbleProps.onOpen?.()
}
const closeBot = () => {
setIsBotOpened(false)
if (isBotOpened()) bubbleProps.onClose?.()
}
const toggleBot = () => {
setIsBotOpened(!isBotOpened())
isBotOpened() ? closeBot() : openBot()
}
const handlePreviewMessageClick = () => {
bubbleProps.onPreviewMessageClick?.()
openBot()
}
const showMessage = (
previewMessage?: Pick<PreviewMessageProps, 'avatarUrl' | 'message'>
) => {
if (previewMessage) setPreviewMessage(previewMessage)
if (isBotOpened()) return
setIsPreviewMessageDisplayed(true)
}
const hideMessage = () => {
setIsPreviewMessageDisplayed(false)
}
return (
<>
<style>{styles}</style>
<button
onClick={toggleBot}
class="bg-blue-500 text-red-300 absolute bottom-4 right-4 w-12 h-12 rounded-full hover:scale-110 active:scale-95 transition-transform duration-200 flex justify-center items-center"
>
<svg
viewBox="0 0 24 24"
style={{ transition: 'transform 200ms, opacity 200ms' }}
class={
'w-7 stroke-white stroke-2 fill-transparent absolute ' +
(isBotOpened() ? 'scale-0 opacity-0' : 'scale-100 opacity-100')
}
>
<path d="M21 11.5a8.38 8.38 0 0 1-.9 3.8 8.5 8.5 0 0 1-7.6 4.7 8.38 8.38 0 0 1-3.8-.9L3 21l1.9-5.7a8.38 8.38 0 0 1-.9-3.8 8.5 8.5 0 0 1 4.7-7.6 8.38 8.38 0 0 1 3.8-.9h.5a8.48 8.48 0 0 1 8 8v.5z" />
</svg>
<svg
viewBox="0 0 24 24"
style={{ transition: 'transform 200ms, opacity 200ms' }}
class={
'w-7 fill-white absolute ' +
(isBotOpened()
? 'scale-100 rotate-0 opacity-100'
: 'scale-0 -rotate-180 opacity-0')
}
>
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M18.601 8.39897C18.269 8.06702 17.7309 8.06702 17.3989 8.39897L12 13.7979L6.60099 8.39897C6.26904 8.06702 5.73086 8.06702 5.39891 8.39897C5.06696 8.73091 5.06696 9.2691 5.39891 9.60105L11.3989 15.601C11.7309 15.933 12.269 15.933 12.601 15.601L18.601 9.60105C18.9329 9.2691 18.9329 8.73091 18.601 8.39897Z"
/>
</svg>
</button>
<Show when={isPreviewMessageDisplayed()}>
<PreviewMessage
{...previewMessage()}
button={bubbleProps.button}
onClick={handlePreviewMessageClick}
onCloseClick={hideMessage}
/>
</Show>
<BubbleButton
{...bubbleProps.button}
toggleBot={toggleBot}
isBotOpened={isBotOpened()}
/>
<div
style={{
width: '400px',
height: 'calc(100% - 104px)',
'max-height': '704px',
height: 'calc(100% - 80px)',
transition:
'transform 200ms cubic-bezier(0, 1.2, 1, 1), opacity 150ms ease-out',
'transform-origin': 'bottom right',
@@ -54,10 +126,14 @@ export const Bubble = () => {
'box-shadow': 'rgb(0 0 0 / 16%) 0px 5px 40px',
}}
class={
'absolute bottom-20 right-4 rounded-2xl ' +
'absolute bottom-20 sm:right-4 rounded-lg bg-white w-full sm:w-[400px] max-h-[704px] ' +
(isBotOpened() ? 'opacity-1' : 'opacity-0 pointer-events-none')
}
/>
>
<Show when={isBotStarted()}>
<Bot {...botProps} prefilledVariables={prefilledVariables()} />
</Show>
</div>
</>
)
}

View File

@@ -0,0 +1,67 @@
import { Show } from 'solid-js'
import { ButtonParams } from '../types'
type Props = ButtonParams & {
isBotOpened: boolean
toggleBot: () => void
}
const defaultButtonColor = '#0042DA'
export const BubbleButton = (props: Props) => {
return (
<button
// eslint-disable-next-line solid/reactivity
onClick={props.toggleBot}
class={
'absolute bottom-4 right-4 shadow-md w-12 h-12 rounded-full hover:scale-110 active:scale-95 transition-transform duration-200 flex justify-center items-center animate-fade-in'
}
style={{
'background-color': props.backgroundColor ?? defaultButtonColor,
}}
>
<Show when={props.icon?.color} keyed>
{(color) => (
<svg
viewBox="0 0 24 24"
style={{
stroke: color,
}}
class={
`w-7 stroke-2 fill-transparent absolute duration-200 transition ` +
(props.isBotOpened
? 'scale-0 opacity-0'
: 'scale-100 opacity-100')
}
>
<path d="M21 11.5a8.38 8.38 0 0 1-.9 3.8 8.5 8.5 0 0 1-7.6 4.7 8.38 8.38 0 0 1-3.8-.9L3 21l1.9-5.7a8.38 8.38 0 0 1-.9-3.8 8.5 8.5 0 0 1 4.7-7.6 8.38 8.38 0 0 1 3.8-.9h.5a8.48 8.48 0 0 1 8 8v.5z" />
</svg>
)}
</Show>
<Show when={props.icon?.url}>
<img
src={props.icon?.url}
class="w-7 h-7 rounded-full object-cover"
alt="Bubble button icon"
/>
</Show>
<svg
viewBox="0 0 24 24"
style={{ fill: props.icon?.color ?? 'white' }}
class={
`w-7 absolute duration-200 transition ` +
(props.isBotOpened
? 'scale-100 rotate-0 opacity-100'
: 'scale-0 -rotate-180 opacity-0')
}
>
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M18.601 8.39897C18.269 8.06702 17.7309 8.06702 17.3989 8.39897L12 13.7979L6.60099 8.39897C6.26904 8.06702 5.73086 8.06702 5.39891 8.39897C5.06696 8.73091 5.06696 9.2691 5.39891 9.60105L11.3989 15.601C11.7309 15.933 12.269 15.933 12.601 15.601L18.601 9.60105C18.9329 9.2691 18.9329 8.73091 18.601 8.39897Z"
/>
</svg>
</button>
)
}

View File

@@ -0,0 +1,68 @@
import { createSignal } from 'solid-js'
import { BubbleParams, PreviewMessageParams } from '../types'
export type PreviewMessageProps = Pick<
PreviewMessageParams,
'avatarUrl' | 'message' | 'style'
> &
Pick<BubbleParams, 'button'> & {
onClick: () => void
onCloseClick: () => void
}
const defaultFontFamily =
"-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'"
export const PreviewMessage = (props: PreviewMessageProps) => {
const [isPreviewMessageHovered, setIsPreviewMessageHovered] =
createSignal(false)
return (
<div
// eslint-disable-next-line solid/reactivity
onClick={props.onClick}
class="absolute bottom-20 right-4 w-64 rounded-md duration-200 flex items-center gap-4 shadow-md animate-fade-in cursor-pointer hover:shadow-lg p-4"
style={{
'font-family': props.style?.fontFamily ?? defaultFontFamily,
'background-color': props.style?.backgroundColor ?? '#F7F8FF',
color: props.style?.color ?? '#303235',
}}
onMouseEnter={() => setIsPreviewMessageHovered(true)}
onMouseLeave={() => setIsPreviewMessageHovered(false)}
>
<button
class={
`absolute -top-3 -right-3 rounded-full w-6 h-6 p-1 hover:brightness-95 active:brightness-90 transition-all ` +
(isPreviewMessageHovered() ? 'opacity-100' : 'opacity-0')
}
onClick={(e) => {
e.stopPropagation()
return props.onCloseClick()
}}
style={{
'background-color': props.style?.closeButtonBgColor ?? '#F7F8FF',
color: props.style?.closeButtonColor ?? '#303235',
}}
>
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
<line x1="18" y1="6" x2="6" y2="18" />
<line x1="6" y1="6" x2="18" y2="18" />
</svg>
</button>
<img
src={props.avatarUrl}
class="rounded-full w-8 h-8 object-cover"
alt="Bot avatar"
/>
<p>{props.message}</p>
</div>
)
}

View File

@@ -0,0 +1,27 @@
export type BubbleParams = {
button: ButtonParams
previewMessage: PreviewMessageParams
}
export type ButtonParams = {
backgroundColor?: string
icon?: {
color?: string
url?: string
}
}
export type PreviewMessageParams = {
avatarUrl?: string
message: string
autoShowDelay?: number
style?: PreviewMessageStyle
}
type PreviewMessageStyle = Partial<{
backgroundColor: string
color: string
fontFamily: string
closeButtonBgColor: string
closeButtonColor: string
}>

View File

@@ -0,0 +1,2 @@
export * from './types'
export * from './utils'

View File

@@ -0,0 +1,21 @@
import { PreviewMessageParams } from '../bubble/types'
export type CommandData = {
isFromTypebot: boolean
} & (
| {
command: 'open' | 'toggle' | 'close' | 'hidePreviewMessage'
}
| ShowMessageCommandData
| SetPrefilledVariablesCommandData
)
export type ShowMessageCommandData = {
command: 'showPreviewMessage'
message?: Pick<PreviewMessageParams, 'avatarUrl' | 'message'>
}
export type SetPrefilledVariablesCommandData = {
command: 'setPrefilledVariables'
variables: Record<string, string | number | boolean>
}

View File

@@ -0,0 +1,9 @@
import { CommandData } from '../types'
export const close = () => {
const message: CommandData = {
isFromTypebot: true,
command: 'close',
}
window.postMessage(message)
}

View File

@@ -0,0 +1,9 @@
import { CommandData } from '../types'
export const hidePreviewMessage = () => {
const message: CommandData = {
isFromTypebot: true,
command: 'hidePreviewMessage',
}
window.postMessage(message)
}

View File

@@ -0,0 +1,6 @@
export * from './close'
export * from './hidePreviewMessage'
export * from './open'
export * from './setPrefilledVariables'
export * from './showPreviewMessage'
export * from './toggle'

View File

@@ -0,0 +1,9 @@
import { CommandData } from '../types'
export const open = () => {
const message: CommandData = {
isFromTypebot: true,
command: 'open',
}
window.postMessage(message)
}

View File

@@ -0,0 +1,12 @@
import { CommandData } from '../types'
export const setPrefilledVariables = (
variables: Record<string, string | number | boolean>
) => {
const message: CommandData = {
isFromTypebot: true,
command: 'setPrefilledVariables',
variables,
}
window.postMessage(message)
}

View File

@@ -0,0 +1,12 @@
import { CommandData, ShowMessageCommandData } from '../types'
export const showPreviewMessage = (
proactiveMessage?: ShowMessageCommandData['message']
) => {
const message: CommandData = {
isFromTypebot: true,
command: 'showPreviewMessage',
message: proactiveMessage,
}
window.postMessage(message)
}

View File

@@ -0,0 +1,9 @@
import { CommandData } from '../types'
export const toggle = () => {
const message: CommandData = {
isFromTypebot: true,
command: 'toggle',
}
window.postMessage(message)
}

View File

@@ -1,3 +1,106 @@
export const Popup = () => {
return <div />
import styles from '../../../assets/index.css'
import { createSignal, onMount, Show, splitProps, onCleanup } from 'solid-js'
import { Bot, BotProps } from '../../../components/Bot'
import { CommandData } from '@/features/commands'
import { isDefined } from 'utils'
import { PopupParams } from '../types'
export type PopupProps = BotProps &
PopupParams & {
onOpen?: () => void
onClose?: () => void
}
export const Popup = (props: PopupProps) => {
let botContainer: HTMLDivElement | undefined
const [popupProps, botProps] = splitProps(props, [
'onOpen',
'onClose',
'autoShowDelay',
'style',
])
const [prefilledVariables, setPrefilledVariables] = createSignal(
// eslint-disable-next-line solid/reactivity
botProps.prefilledVariables
)
const [isBotOpened, setIsBotOpened] = createSignal(false)
onMount(() => {
window.addEventListener('click', processWindowClick)
window.addEventListener('message', processIncomingEvent)
const autoShowDelay = popupProps.autoShowDelay
if (isDefined(autoShowDelay)) {
setTimeout(() => {
openBot()
}, autoShowDelay)
}
})
onCleanup(() => {
window.removeEventListener('message', processIncomingEvent)
window.removeEventListener('click', processWindowClick)
})
const processWindowClick = (event: MouseEvent) => {
if (!botContainer || botContainer.contains(event.target as Node)) return
setIsBotOpened(false)
}
const processIncomingEvent = (event: MessageEvent<CommandData>) => {
const { data } = event
if (!data.isFromTypebot) return
if (data.command === 'open') openBot()
if (data.command === 'close') closeBot()
if (data.command === 'toggle') toggleBot()
if (data.command === 'setPrefilledVariables')
setPrefilledVariables((existingPrefilledVariables) => ({
...existingPrefilledVariables,
...data.variables,
}))
}
const openBot = () => {
setIsBotOpened(true)
if (isBotOpened()) popupProps.onOpen?.()
}
const closeBot = () => {
setIsBotOpened(false)
if (isBotOpened()) popupProps.onClose?.()
}
const toggleBot = () => {
isBotOpened() ? closeBot() : openBot()
}
return (
<Show when={isBotOpened()}>
<div
class="relative z-10"
aria-labelledby="modal-title"
role="dialog"
aria-modal="true"
>
<style>{styles}</style>
<div class="fixed inset-0 bg-gray-500 bg-opacity-75 transition-opacity animate-fade-in" />
<div class="fixed inset-0 z-10 overflow-y-auto">
<div class="flex min-h-full items-center justify-center p-4 text-center sm:p-0">
<div
class="relative h-[80vh] transform overflow-hidden rounded-lg text-left shadow-xl transition-all sm:my-8 sm:w-full sm:max-w-lg"
style={{
width: popupProps.style?.width ?? '100%',
'background-color': popupProps.style?.backgroundColor ?? '#fff',
}}
ref={botContainer}
>
<Bot {...botProps} prefilledVariables={prefilledVariables()} />
</div>
</div>
</div>
</div>
</Show>
)
}

View File

@@ -0,0 +1,7 @@
export type PopupParams = {
autoShowDelay?: number
style?: {
width?: string
backgroundColor?: string
}
}

View File

@@ -1,2 +1,5 @@
export { registerWebComponents } from './register'
export * from './register'
export type { BotProps } from './components/Bot'
export type { BubbleProps } from './features/bubble'
export type { PopupProps } from './features/popup'
export * from './features/commands'

View File

@@ -1,7 +1,19 @@
/* eslint-disable solid/reactivity */
import { customElement } from 'solid-element'
import { Bot, BotProps } from './components/Bot'
import { Bubble, BubbleProps } from './features/bubble'
import { Popup, PopupProps } from './features/popup'
export const registerWebComponents = (props: BotProps) => {
export const registerStandardComponent = (props: BotProps) => {
if (typeof window === 'undefined') return
customElement('typebot-standard', props, Bot)
}
export const registerBubbleComponent = (props: BubbleProps) => {
if (typeof window === 'undefined') return
customElement('typebot-bubble', props, Bubble)
}
export const registerPopupComponent = (props: PopupProps) => {
if (typeof window === 'undefined') return
customElement('typebot-popup', props, Popup)
}

View File

@@ -0,0 +1 @@
DATABASE_URL=postgresql://postgres:typebot@localhost:5432/typebot

View File

@@ -2,9 +2,13 @@
"name": "@typebot.io/react",
"version": "1.0.0",
"description": "",
"main": "dist/index.mjs",
"main": "dist/index.js",
"module": "dist/index.mjs",
"types": "dist/index.d.ts",
"scripts": {
"db:seed": "tsx scripts/seedDatabase.ts",
"stories:dev": "pnpm db:seed && ladle serve -p 3006",
"stories:build": "ladle build",
"build": "pnpm tsc --noEmit && tsup",
"dev": "tsup --watch",
"lint": "eslint --fix \"src/**/*.ts*\""
@@ -13,16 +17,22 @@
"author": "Baptiste Arnaud",
"license": "ISC",
"dependencies": {
"@typebot.io/js": "workspace:*"
"@ladle/react": "^2.4.5"
},
"devDependencies": {
"@typebot.io/js": "workspace:*",
"@types/node": "18.11.18",
"@types/react": "18.0.26",
"db": "workspace:*",
"eslint": "^8.31.0",
"eslint-config-custom": "workspace:*",
"react": "18.2.0",
"tsconfig": "workspace:*",
"tsup": "6.5.0",
"typescript": "^4.9.4"
"tsx": "3.12.1",
"typescript": "^4.9.4",
"utils": "workspace:*",
"models": "workspace:*"
},
"peerDependencies": {
"react": "18.0.0"

View File

@@ -0,0 +1,486 @@
{
"id": "clckrl4q5000t3b6sabwokaar",
"createdAt": "2023-01-06T17:01:33.101Z",
"updatedAt": "2023-01-06T17:02:28.305Z",
"icon": "🤝",
"name": "Lead Generation copy",
"publishedTypebotId": null,
"folderId": null,
"groups": [
{
"id": "clckrl4q5000g3b6skizhd262",
"title": "Start",
"blocks": [
{
"id": "22HP69iipkLjJDTUcc1AWW",
"type": "start",
"label": "Start",
"groupId": "clckrl4q5000g3b6skizhd262",
"outgoingEdgeId": "clckrlxp400173b6sktq7gqm2"
}
],
"graphCoordinates": { "x": 0, "y": 0 }
},
{
"id": "clckrl4q5000h3b6sjipn4qga",
"title": "Welcome",
"blocks": [
{
"id": "sc1y8VwDabNJgiVTBi4qtif",
"type": "text",
"content": {
"html": "<div>Welcome to <span class=\"slate-bold\">AA</span> (Awesome Agency)</div>",
"richText": [
{
"type": "p",
"children": [
{ "text": "Welcome to " },
{ "bold": true, "text": "AA" },
{ "text": " (Awesome Agency)" }
]
}
],
"plainText": "Welcome to AA (Awesome Agency)"
},
"groupId": "clckrl4q5000h3b6sjipn4qga"
},
{
"id": "s7YqZTBeyCa4Hp3wN2j922c",
"type": "image",
"content": {
"url": "https://media2.giphy.com/media/XD9o33QG9BoMis7iM4/giphy.gif?cid=fe3852a3ihg8rvipzzky5lybmdyq38fhke2tkrnshwk52c7d&rid=giphy.gif&ct=g"
},
"groupId": "clckrl4q5000h3b6sjipn4qga"
},
{
"id": "sbjZWLJGVkHAkDqS4JQeGow",
"type": "choice input",
"items": [
{
"id": "hQw2zbp7FDX7XYK9cFpbgC",
"type": 0,
"blockId": "sbjZWLJGVkHAkDqS4JQeGow",
"content": "Hi!"
}
],
"groupId": "clckrl4q5000h3b6sjipn4qga",
"options": { "buttonLabel": "Send", "isMultipleChoice": false },
"outgoingEdgeId": "clckrm7td001b3b6s2769fh7k"
}
],
"graphCoordinates": { "x": -8.26171875, "y": 457.515625 }
},
{
"id": "clckrl4q5000i3b6stgxyvscq",
"title": "Email",
"blocks": [
{
"id": "sxeYubYN6XzhAfG7m9Fivhc",
"type": "text",
"content": {
"html": "<div>Great! Nice to meet you {{Name}}</div>",
"richText": [
{
"type": "p",
"children": [{ "text": "Great! Nice to meet you {{Name}}" }]
}
],
"plainText": "Great! Nice to meet you {{Name}}"
},
"groupId": "clckrl4q5000i3b6stgxyvscq"
},
{
"id": "scQ5kduafAtfP9T8SHUJnGi",
"type": "text",
"content": {
"html": "<div>What&#x27;s the best email we can reach you at?</div>",
"richText": [
{
"type": "p",
"children": [
{ "text": "What's the best email we can reach you at?" }
]
}
],
"plainText": "What's the best email we can reach you at?"
},
"groupId": "clckrl4q5000i3b6stgxyvscq"
},
{
"id": "snbsad18Bgry8yZ8DZCfdFD",
"type": "email input",
"groupId": "clckrl4q5000i3b6stgxyvscq",
"options": {
"labels": { "button": "Send", "placeholder": "Type your email..." },
"variableId": "v3VFChNVSCXQ2rXv4DrJ8Ah",
"retryMessageContent": "This email doesn't seem to be valid. Can you type it again?"
},
"outgoingEdgeId": "clckrl4q5000q3b6s5czdtm8x"
}
],
"graphCoordinates": { "x": 669, "y": 141 }
},
{
"id": "clckrl4q5000j3b6sloirnxza",
"title": "Name",
"blocks": [
{
"id": "sgtE2Sy7cKykac9B223Kq9R",
"type": "text",
"content": {
"html": "<div>What&#x27;s your name?</div>",
"richText": [
{ "type": "p", "children": [{ "text": "What's your name?" }] }
],
"plainText": "What's your name?"
},
"groupId": "clckrl4q5000j3b6sloirnxza"
},
{
"id": "sqEsMo747LTDnY9FjQcEwUv",
"type": "text input",
"groupId": "clckrl4q5000j3b6sloirnxza",
"options": {
"isLong": false,
"labels": {
"button": "Send",
"placeholder": "Type your answer..."
},
"variableId": "giiLFGw5xXBCHzvp1qAbdX"
},
"outgoingEdgeId": "clckrl4q5000p3b6shb5bfnzt"
}
],
"graphCoordinates": { "x": 340, "y": 143 }
},
{
"id": "clckrl4q5000k3b6s0anufmgy",
"title": "Services",
"blocks": [
{
"id": "su7HceVXWyTCzi2vv3m4QbK",
"type": "text",
"content": {
"html": "<div>What services are you interested in?</div>",
"richText": [
{
"type": "p",
"children": [{ "text": "What services are you interested in?" }]
}
],
"plainText": "What services are you interested in?"
},
"groupId": "clckrl4q5000k3b6s0anufmgy"
},
{
"id": "s5VQGsVF4hQgziQsXVdwPDW",
"type": "choice input",
"items": [
{
"id": "fnLCBF4NdraSwcubnBhk8H",
"type": 0,
"blockId": "s5VQGsVF4hQgziQsXVdwPDW",
"content": "Website dev"
},
{
"id": "a782h8ynMouY84QjH7XSnR",
"type": 0,
"blockId": "s5VQGsVF4hQgziQsXVdwPDW",
"content": "Content Marketing"
},
{
"id": "jGvh94zBByvVFpSS3w97zY",
"type": 0,
"blockId": "s5VQGsVF4hQgziQsXVdwPDW",
"content": "Social Media"
},
{
"id": "6PRLbKUezuFmwWtLVbvAQ7",
"type": 0,
"blockId": "s5VQGsVF4hQgziQsXVdwPDW",
"content": "UI / UX Design"
}
],
"groupId": "clckrl4q5000k3b6s0anufmgy",
"options": { "buttonLabel": "Send", "isMultipleChoice": true },
"outgoingEdgeId": "clckrl4q5000r3b6s9yxsuxu7"
}
],
"graphCoordinates": { "x": 1002, "y": 144 }
},
{
"id": "clckrl4q5000l3b6scn1r1nns",
"title": "Additional information",
"blocks": [
{
"id": "sqR8Sz9gW21aUYKtUikq7qZ",
"type": "text",
"content": {
"html": "<div>Can you tell me a bit more about your needs?</div>",
"richText": [
{
"type": "p",
"children": [
{ "text": "Can you tell me a bit more about your needs?" }
]
}
],
"plainText": "Can you tell me a bit more about your needs?"
},
"groupId": "clckrl4q5000l3b6scn1r1nns"
},
{
"id": "sqFy2G3C1mh9p6s3QBdSS5x",
"type": "text input",
"groupId": "clckrl4q5000l3b6scn1r1nns",
"options": {
"isLong": true,
"labels": { "button": "Send", "placeholder": "Type your answer..." }
},
"outgoingEdgeId": "clckrl4q5000s3b6stx5nnqbz"
}
],
"graphCoordinates": { "x": 1337, "y": 145 }
},
{
"id": "clckrl4q5000m3b6srabr5a2s",
"title": "Bye",
"blocks": [
{
"id": "seLegenCgUwMopRFeAefqZ7",
"type": "text",
"content": {
"html": "<div>Perfect!</div>",
"richText": [{ "type": "p", "children": [{ "text": "Perfect!" }] }],
"plainText": "Perfect!"
},
"groupId": "clckrl4q5000m3b6srabr5a2s"
},
{
"id": "s779Q1y51aVaDUJVrFb16vv",
"type": "text",
"content": {
"html": "<div>We&#x27;ll get back to you at {{Email}}</div>",
"richText": [
{
"type": "p",
"children": [{ "text": "We'll get back to you at {{Email}}" }]
}
],
"plainText": "We'll get back to you at {{Email}}"
},
"groupId": "clckrl4q5000m3b6srabr5a2s"
}
],
"graphCoordinates": { "x": 1668, "y": 143 }
},
{
"id": "clckrlksq000z3b6sequnj9m3",
"graphCoordinates": { "x": -355.04296875, "y": 187.5078125 },
"title": "Group #7",
"blocks": [
{
"id": "clckrlksq00103b6s3exi90al",
"groupId": "clckrlksq000z3b6sequnj9m3",
"type": "Condition",
"items": [
{
"id": "clckrlksq00113b6sz8naxdwx",
"blockId": "clckrlksq00103b6s3exi90al",
"type": 1,
"content": {
"comparisons": [
{
"id": "clckrllsm00123b6sz38325aw",
"variableId": "giiLFGw5xXBCHzvp1qAbdX",
"comparisonOperator": "Is set"
}
],
"logicalOperator": "AND"
},
"outgoingEdgeId": "clckrlt0000143b6sn9euzwnm"
}
],
"outgoingEdgeId": "clckrluh600153b6s66p2q6wa"
}
]
},
{
"id": "clckrm1zq00183b6sz8ydapth",
"graphCoordinates": { "x": 333.8046875, "y": 408.1328125 },
"title": "Group #7 copy",
"blocks": [
{
"id": "clckrm1zr00193b6szpz37plc",
"groupId": "clckrm1zq00183b6sz8ydapth",
"type": "Condition",
"items": [
{
"id": "clckrm1zr001a3b6s1hlfm2jh",
"blockId": "clckrm1zr00193b6szpz37plc",
"type": 1,
"content": {
"comparisons": [
{
"id": "clckrllsm00123b6sz38325aw",
"variableId": "giiLFGw5xXBCHzvp1qAbdX",
"comparisonOperator": "Is set"
}
],
"logicalOperator": "AND"
},
"outgoingEdgeId": "clckrma26001c3b6sup2bdbte"
}
],
"outgoingEdgeId": "clckrmbbk001d3b6shr35s2ao"
}
]
},
{
"id": "clckrlqil00133b6sk6msgqt1",
"graphCoordinates": { "x": -23.78515625, "y": 199.6875 },
"title": "Group #8",
"blocks": [
{
"id": "clckrl870000y3b6sxyd24qwc",
"groupId": "clckrlqil00133b6sk6msgqt1",
"type": "text",
"content": {
"html": "<div>Hi {{Name}}!</div>",
"richText": [
{ "type": "p", "children": [{ "text": "Hi {{Name}}!" }] }
],
"plainText": "Hi {{Name}}!"
},
"outgoingEdgeId": "clckrlwmd00163b6sjlass4p8"
}
]
}
],
"variables": [
{ "id": "giiLFGw5xXBCHzvp1qAbdX", "name": "Name" },
{ "id": "v3VFChNVSCXQ2rXv4DrJ8Ah", "name": "Email" }
],
"edges": [
{
"id": "clckrl4q5000p3b6shb5bfnzt",
"to": { "groupId": "clckrl4q5000i3b6stgxyvscq" },
"from": {
"blockId": "sqEsMo747LTDnY9FjQcEwUv",
"groupId": "clckrl4q5000j3b6sloirnxza"
}
},
{
"id": "clckrl4q5000q3b6s5czdtm8x",
"to": { "groupId": "clckrl4q5000k3b6s0anufmgy" },
"from": {
"blockId": "snbsad18Bgry8yZ8DZCfdFD",
"groupId": "clckrl4q5000i3b6stgxyvscq"
}
},
{
"id": "clckrl4q5000r3b6s9yxsuxu7",
"to": { "groupId": "clckrl4q5000l3b6scn1r1nns" },
"from": {
"blockId": "s5VQGsVF4hQgziQsXVdwPDW",
"groupId": "clckrl4q5000k3b6s0anufmgy"
}
},
{
"id": "clckrl4q5000s3b6stx5nnqbz",
"to": { "groupId": "clckrl4q5000m3b6srabr5a2s" },
"from": {
"blockId": "sqFy2G3C1mh9p6s3QBdSS5x",
"groupId": "clckrl4q5000l3b6scn1r1nns"
}
},
{
"from": {
"groupId": "clckrlksq000z3b6sequnj9m3",
"blockId": "clckrlksq00103b6s3exi90al",
"itemId": "clckrlksq00113b6sz8naxdwx"
},
"to": { "groupId": "clckrlqil00133b6sk6msgqt1" },
"id": "clckrlt0000143b6sn9euzwnm"
},
{
"from": {
"groupId": "clckrlksq000z3b6sequnj9m3",
"blockId": "clckrlksq00103b6s3exi90al"
},
"to": { "groupId": "clckrl4q5000h3b6sjipn4qga" },
"id": "clckrluh600153b6s66p2q6wa"
},
{
"from": {
"groupId": "clckrlqil00133b6sk6msgqt1",
"blockId": "clckrl870000y3b6sxyd24qwc"
},
"to": { "groupId": "clckrl4q5000h3b6sjipn4qga" },
"id": "clckrlwmd00163b6sjlass4p8"
},
{
"from": {
"groupId": "clckrl4q5000g3b6skizhd262",
"blockId": "22HP69iipkLjJDTUcc1AWW"
},
"to": { "groupId": "clckrlksq000z3b6sequnj9m3" },
"id": "clckrlxp400173b6sktq7gqm2"
},
{
"from": {
"groupId": "clckrl4q5000h3b6sjipn4qga",
"blockId": "sbjZWLJGVkHAkDqS4JQeGow"
},
"to": { "groupId": "clckrm1zq00183b6sz8ydapth" },
"id": "clckrm7td001b3b6s2769fh7k"
},
{
"from": {
"groupId": "clckrm1zq00183b6sz8ydapth",
"blockId": "clckrm1zr00193b6szpz37plc",
"itemId": "clckrm1zr001a3b6s1hlfm2jh"
},
"to": { "groupId": "clckrl4q5000i3b6stgxyvscq" },
"id": "clckrma26001c3b6sup2bdbte"
},
{
"from": {
"groupId": "clckrm1zq00183b6sz8ydapth",
"blockId": "clckrm1zr00193b6szpz37plc"
},
"to": { "groupId": "clckrl4q5000j3b6sloirnxza" },
"id": "clckrmbbk001d3b6shr35s2ao"
}
],
"theme": {
"chat": {
"inputs": {
"color": "#303235",
"backgroundColor": "#FFFFFF",
"placeholderColor": "#9095A0"
},
"buttons": { "color": "#FFFFFF", "backgroundColor": "#0042DA" },
"hostAvatar": {
"url": "https://avatars.githubusercontent.com/u/16015833?v=4",
"isEnabled": true
},
"hostBubbles": { "color": "#303235", "backgroundColor": "#F7F8FF" },
"guestBubbles": { "color": "#FFFFFF", "backgroundColor": "#FF8E21" }
},
"general": { "font": "Open Sans", "background": { "type": "None" } }
},
"settings": {
"general": { "isBrandingEnabled": true },
"metadata": {
"description": "Build beautiful conversational forms and embed them directly in your applications without a line of code. Triple your response rate and collect answers that has more value compared to a traditional form."
},
"typingEmulation": { "speed": 300, "enabled": true, "maxDelay": 1.5 }
},
"publicId": null,
"customDomain": null,
"workspaceId": "clc0lcuiu00021awrludgbbym",
"resultsTablePreferences": null,
"isArchived": false,
"isClosed": false
}

View File

@@ -0,0 +1,60 @@
import { PrismaClient } from 'db'
import { Typebot } from 'models'
import { parseCreateTypebot } from 'utils/playwright/databaseActions'
import { join } from 'path'
import { parseTypebotToPublicTypebot } from 'utils/playwright/databaseHelpers'
import { readFileSync } from 'fs'
// eslint-disable-next-line @typescript-eslint/no-var-requires
require('dotenv').config({
override: true,
path: join(__dirname, `.env.local`),
})
const seedDatabase = async () => {
const prisma = new PrismaClient()
const data = JSON.parse(
readFileSync(join(__dirname, 'ladleTypebot.json')).toString()
) as Typebot
const ladleWorkspace = {
id: 'ladleWorkspace',
name: 'Ladle',
}
await prisma.workspace.upsert({
where: { id: ladleWorkspace.id },
update: {},
create: ladleWorkspace,
})
const ladleTypebot = parseCreateTypebot({
...data,
id: 'ladleTypebot',
folderId: undefined,
workspaceId: ladleWorkspace.id,
theme: {
...data.theme,
chat: {
...data.theme.chat,
hostAvatar: {
isEnabled: true,
},
},
},
}) as Typebot
const ladlePublicTypebot = parseTypebotToPublicTypebot(
ladleTypebot.id + 'Public',
ladleTypebot
)
await prisma.typebot.upsert({
where: { id: ladleTypebot.id },
update: ladleTypebot,
create: ladleTypebot,
})
await prisma.publicTypebot.upsert({
where: { id: ladlePublicTypebot.id },
update: ladlePublicTypebot,
create: ladlePublicTypebot,
})
}
seedDatabase().then()

View File

@@ -0,0 +1,24 @@
import { useEffect } from 'react'
import type { BubbleProps } from '@typebot.io/js'
declare global {
namespace JSX {
interface IntrinsicElements {
'typebot-bubble': React.DetailedHTMLProps<
React.HTMLAttributes<HTMLElement>,
HTMLElement
>
}
}
}
export const Bubble = (props: BubbleProps) => {
useEffect(() => {
;(async () => {
const { registerBubbleComponent } = await import('@typebot.io/js')
registerBubbleComponent(props)
})()
}, [props])
return <typebot-bubble />
}

View File

@@ -0,0 +1,24 @@
import { useEffect } from 'react'
import type { PopupProps } from '@typebot.io/js'
declare global {
namespace JSX {
interface IntrinsicElements {
'typebot-popup': React.DetailedHTMLProps<
React.HTMLAttributes<HTMLElement>,
HTMLElement
>
}
}
}
export const Popup = (props: PopupProps) => {
useEffect(() => {
;(async () => {
const { registerPopupComponent } = await import('@typebot.io/js')
registerPopupComponent(props)
})()
}, [props])
return <typebot-popup />
}

View File

@@ -17,8 +17,8 @@ declare global {
export const Standard = (props: Props) => {
useEffect(() => {
;(async () => {
const { registerWebComponents } = await import('@typebot.io/js')
registerWebComponents(props)
const { registerStandardComponent } = await import('@typebot.io/js')
registerStandardComponent(props)
})()
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [])

View File

@@ -1,6 +1,10 @@
/* eslint-disable import/no-anonymous-default-export */
import { Standard } from './Standard'
import { Bubble } from './Bubble'
import { Popup } from './Popup'
export { Standard }
export { Standard, Bubble, Popup }
export default { Standard }
export default { Standard, Bubble, Popup }
export * from '@typebot.io/js/src/features/commands'

View File

@@ -0,0 +1,54 @@
import { Bubble } from '@/Bubble'
import {
open,
toggle,
close,
showPreviewMessage,
hidePreviewMessage,
setPrefilledVariables,
} from '@typebot.io/js'
import { useState } from 'react'
export const Default = () => {
const [name, setName] = useState('John')
return (
<div>
<div style={{ display: 'flex', flexDirection: 'column', gap: '1rem' }}>
<button onClick={toggle}>Toggle chat window</button>
<button onClick={open}>Open chat window</button>
<button onClick={close}>Close chat window</button>
<button onClick={() => showPreviewMessage()}>
Show Preview Message
</button>
<button onClick={hidePreviewMessage}>Close Preview Message</button>
<div>
<p>Predefined name:</p>
<input value={name} onChange={(e) => setName(e.target.value)} />
<button onClick={() => setPrefilledVariables({ Name: name })}>
Set predefined name
</button>
</div>
</div>
<Bubble
typebotId="ladleTypebot"
apiHost="http://localhost:3001"
prefilledVariables={{
Name: 'John',
}}
previewMessage={{
avatarUrl: 'https://avatars.githubusercontent.com/u/16015833?v=4',
message: 'Hello, I am a preview message',
autoShowDelay: 3000,
}}
button={{
backgroundColor: '#FF7537',
icon: {
color: 'white',
},
}}
/>
</div>
)
}

View File

@@ -0,0 +1,16 @@
import { Popup } from '../Popup'
import { open, toggle } from '@typebot.io/js'
export const Default = () => {
return (
<>
<button onClick={open}>Open modal</button>
<button onClick={toggle}>Toggle modal</button>
<Popup
typebotId="ladleTypebot"
apiHost="http://localhost:3001"
autoShowDelay={3000}
/>
</>
)
}

View File

@@ -0,0 +1,9 @@
import { Standard } from '..'
export const Default = () => {
return (
<div style={{ height: '500px' }}>
<Standard typebotId="ladleTypebot" apiHost="http://localhost:3001" />
</div>
)
}

View File

@@ -5,5 +5,6 @@ export default defineConfig((options) => ({
sourcemap: options.watch,
minify: !options.watch,
dts: true,
format: ['esm'],
format: ['esm', 'cjs'],
external: ['db', 'cuid'],
}))

View File

@@ -195,7 +195,7 @@ export const updateWorkspace = async (
})
}
const parseCreateTypebot = (typebot: Typebot) => ({
export const parseCreateTypebot = (typebot: Typebot) => ({
...typebot,
resultsTablePreferences:
typebot.resultsTablePreferences === null

View File

@@ -245,15 +245,14 @@ export const uploadFiles = async ({
declare const window: any
const isBrowser = () => Boolean(typeof window !== 'undefined')
export const env = (key = ''): string | undefined => {
if (isBrowser() && window.__env)
return isEmpty(window.__env[key]) ? undefined : window.__env[key]
if (typeof window === 'undefined')
return isEmpty(process.env['NEXT_PUBLIC_' + key])
? undefined
: (process.env['NEXT_PUBLIC_' + key] as string)
return isEmpty(process.env['NEXT_PUBLIC_' + key])
? undefined
: (process.env['NEXT_PUBLIC_' + key] as string)
if (typeof window !== 'undefined' && window.__env)
return isEmpty(window.__env[key]) ? undefined : window.__env[key]
}
export const hasValue = (
@@ -276,8 +275,8 @@ export const getViewerUrl = (props?: {
return (
'https://' +
(props?.isBuilder
? process.env.NEXT_PUBLIC_VERCEL_URL?.replace('builder-v2', 'viewer-v2')
: process.env.NEXT_PUBLIC_VERCEL_URL)
? env('VERCEL_URL')?.replace('builder-v2', 'viewer-v2')
: env('VERCEL_URL'))
)
}

391
pnpm-lock.yaml generated
View File

@@ -653,24 +653,36 @@ importers:
packages/react:
specifiers:
'@ladle/react': ^2.4.5
'@typebot.io/js': workspace:*
'@types/node': 18.11.18
'@types/react': 18.0.26
db: workspace:*
eslint: ^8.31.0
eslint-config-custom: workspace:*
models: workspace:*
react: 18.2.0
tsconfig: workspace:*
tsup: 6.5.0
tsx: 3.12.1
typescript: ^4.9.4
utils: workspace:*
dependencies:
'@typebot.io/js': link:../js
'@ladle/react': 2.4.5_l6igfz5ga4q4fmcl3ncwfbj5tu
devDependencies:
'@typebot.io/js': link:../js
'@types/node': 18.11.18
'@types/react': 18.0.26
db: link:../db
eslint: 8.31.0
eslint-config-custom: link:../eslint-config-custom
models: link:../models
react: 18.2.0
tsconfig: link:../tsconfig
tsup: 6.5.0_typescript@4.9.4
tsx: 3.12.1
typescript: 4.9.4
utils: link:../utils
packages/scripts:
specifiers:
@@ -1857,6 +1869,26 @@ packages:
'@babel/plugin-transform-react-jsx': 7.19.0_@babel+core@7.20.12
dev: false
/@babel/plugin-transform-react-jsx-self/7.18.6_@babel+core@7.20.12:
resolution: {integrity: sha512-A0LQGx4+4Jv7u/tWzoJF7alZwnBDQd6cGLh9P+Ttk4dpiL+J5p7NSNv/9tlEFFJDq3kjxOavWmbm6t0Gk+A3Ig==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
'@babel/core': 7.20.12
'@babel/helper-plugin-utils': 7.20.2
dev: false
/@babel/plugin-transform-react-jsx-source/7.19.6_@babel+core@7.20.12:
resolution: {integrity: sha512-RpAi004QyMNisst/pvSanoRdJ4q+jMCWyk9zdw/CyLB9j8RXEahodR6l2GyttDRyEVWZtbN+TpLiHJ3t34LbsQ==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
'@babel/core': 7.20.12
'@babel/helper-plugin-utils': 7.20.2
dev: false
/@babel/plugin-transform-react-jsx/7.19.0_@babel+core@7.20.12:
resolution: {integrity: sha512-UVEvX3tXie3Szm3emi1+G63jyw1w5IcMY0FSKM+CRnKRI5Mr1YbCNgsSTwoTwKphQEG9P+QqmuRFneJPZuHNhg==}
engines: {node: '>=6.9.0'}
@@ -3394,6 +3426,10 @@ packages:
dev: false
optional: true
/@cush/relative/1.0.0:
resolution: {integrity: sha512-RpfLEtTlyIxeNPGKcokS+p3BZII/Q3bYxryFRglh5H3A3T8q9fsLYm72VYAMEOOIBLEa8o93kFLiBDUWKrwXZA==}
dev: false
/@dnd-kit/accessibility/3.0.1_react@18.2.0:
resolution: {integrity: sha512-HXRrwS9YUYQO9lFRc/49uO/VICbM+O+ZRpFDe9Pd1rwVv2PCNkRiTZRdxrDgng/UkvdC3Re9r2vwPpXXrWeFzg==}
peerDependencies:
@@ -4317,7 +4353,6 @@ packages:
cpu: [arm]
os: [android]
requiresBuild: true
dev: true
optional: true
/@esbuild/android-arm/0.16.15:
@@ -4416,7 +4451,6 @@ packages:
cpu: [loong64]
os: [linux]
requiresBuild: true
dev: true
optional: true
/@esbuild/linux-loong64/0.16.15:
@@ -4966,6 +5000,71 @@ packages:
'@jridgewell/resolve-uri': 3.1.0
'@jridgewell/sourcemap-codec': 1.4.14
/@ladle/react-context/1.0.1_biqbaboplfbrettd7655fr4n2y:
resolution: {integrity: sha512-xVQ8siyOEQG6e4Knibes1uA3PTyXnqiMmfSmd5pIbkzeDty8NCBtYHhTXSlfmcDNEsw/G8OzNWo4VbyQAVDl2A==}
peerDependencies:
react: '>=16.14.0'
react-dom: '>=16.14.0'
dependencies:
react: 18.2.0
react-dom: 18.2.0_react@18.2.0
dev: false
/@ladle/react/2.4.5_l6igfz5ga4q4fmcl3ncwfbj5tu:
resolution: {integrity: sha512-Aso5YYCm1EwJ7GxP0vaEYrBSnGLMkPHy3YK7k4la/zlWxqxMb7sQhbjXu8Q1wJtj9Qby58MryknpbznbG75Fng==}
engines: {node: '>=16.0.0'}
hasBin: true
peerDependencies:
react: '>=16.14.0'
react-dom: '>=16.14.0'
dependencies:
'@babel/code-frame': 7.18.6
'@babel/core': 7.20.12
'@babel/generator': 7.20.7
'@babel/parser': 7.20.7
'@babel/plugin-proposal-class-properties': 7.18.6_@babel+core@7.20.12
'@babel/preset-env': 7.20.2_@babel+core@7.20.12
'@babel/preset-react': 7.18.6_@babel+core@7.20.12
'@babel/preset-typescript': 7.18.6_@babel+core@7.20.12
'@babel/runtime': 7.20.6
'@babel/template': 7.20.7
'@babel/traverse': 7.20.12
'@babel/types': 7.20.7
'@ladle/react-context': 1.0.1_biqbaboplfbrettd7655fr4n2y
'@vitejs/plugin-react': 2.2.0_vite@3.2.5
axe-core: 4.6.1
boxen: 7.0.1
chokidar: 3.5.3
classnames: 2.3.2
commander: 9.5.0
cross-spawn: 7.0.3
debug: 4.3.4
default-browser: 3.1.0
express: 4.18.2
get-port: 6.1.2
globby: 13.1.3
history: 5.3.0
lodash.merge: 4.6.2
open: 8.4.0
prism-react-renderer: 1.3.5_react@18.2.0
prop-types: 15.8.1
query-string: 7.1.3
react: 18.2.0
react-dom: 18.2.0_react@18.2.0
react-frame-component: 5.2.4_v2m5e27vhdewzwhryxwfaorcca
react-inspector: 6.0.1_react@18.2.0
vite: 3.2.5_@types+node@18.11.18
vite-tsconfig-paths: 3.6.0_vite@3.2.5
transitivePeerDependencies:
- '@types/node'
- less
- sass
- stylus
- sugarss
- supports-color
- terser
dev: false
/@leichtgewicht/ip-codec/2.0.4:
resolution: {integrity: sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A==}
dev: false
@@ -7144,6 +7243,24 @@ packages:
react: 18.2.0
dev: false
/@vitejs/plugin-react/2.2.0_vite@3.2.5:
resolution: {integrity: sha512-FFpefhvExd1toVRlokZgxgy2JtnBOdp4ZDsq7ldCWaqGSGn9UhWMAVm/1lxPL14JfNS5yGz+s9yFrQY6shoStA==}
engines: {node: ^14.18.0 || >=16.0.0}
peerDependencies:
vite: ^3.0.0
dependencies:
'@babel/core': 7.20.12
'@babel/plugin-transform-react-jsx': 7.19.0_@babel+core@7.20.12
'@babel/plugin-transform-react-jsx-development': 7.18.6_@babel+core@7.20.12
'@babel/plugin-transform-react-jsx-self': 7.18.6_@babel+core@7.20.12
'@babel/plugin-transform-react-jsx-source': 7.19.6_@babel+core@7.20.12
magic-string: 0.26.7
react-refresh: 0.14.0
vite: 3.2.5_@types+node@18.11.18
transitivePeerDependencies:
- supports-color
dev: false
/@webassemblyjs/ast/1.11.1:
resolution: {integrity: sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw==}
dependencies:
@@ -8004,6 +8121,11 @@ packages:
resolution: {integrity: sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==}
dev: false
/big-integer/1.6.51:
resolution: {integrity: sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg==}
engines: {node: '>=0.6'}
dev: false
/big.js/5.2.2:
resolution: {integrity: sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==}
dev: false
@@ -8089,6 +8211,27 @@ packages:
wrap-ansi: 8.0.1
dev: false
/boxen/7.0.1:
resolution: {integrity: sha512-8k2eH6SRAK00NDl1iX5q17RJ8rfl53TajdYxE3ssMLehbg487dEVgsad4pIsZb/QqBgYWIl6JOauMTLGX2Kpkw==}
engines: {node: '>=14.16'}
dependencies:
ansi-align: 3.0.1
camelcase: 7.0.1
chalk: 5.2.0
cli-boxes: 3.0.0
string-width: 5.1.2
type-fest: 2.19.0
widest-line: 4.0.1
wrap-ansi: 8.0.1
dev: false
/bplist-parser/0.2.0:
resolution: {integrity: sha512-z0M+byMThzQmD9NILRniCUXYsYpjwnlO8N5uCFaCqIOpqRsJCrQL9NK3JsD67CN5a08nF5oIL2bD6loTdHOuKw==}
engines: {node: '>= 5.10.0'}
dependencies:
big-integer: 1.6.51
dev: false
/brace-expansion/1.1.11:
resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==}
dependencies:
@@ -8225,6 +8368,13 @@ packages:
engines: {node: '>=6'}
dev: true
/bundle-name/3.0.0:
resolution: {integrity: sha512-PKA4BeSvBpQKQ8iPOGCSiell+N8P+Tf1DlwqmYhpe2gAhKPHn8EYOxVT+ShuGmhg8lN8XiSlS80yiExKXrURlw==}
engines: {node: '>=12'}
dependencies:
run-applescript: 5.0.0
dev: false
/bundle-require/3.1.2_esbuild@0.15.18:
resolution: {integrity: sha512-Of6l6JBAxiyQ5axFxUM6dYeP/W7X2Sozeo/4EYB9sJhL+dqL7TKjg+shwxp6jlu/6ZSERfsYtIpSJ1/x3XkAEA==}
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
@@ -8319,6 +8469,11 @@ packages:
resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==}
engines: {node: '>=10'}
/camelcase/7.0.1:
resolution: {integrity: sha512-xlx1yCK2Oc1APsPXDL2LdlNP6+uu8OCDdhOBSVT279M/S+y75O30C2VuD8T2ogdePBBl7PfPF4504tnLgX3zfw==}
engines: {node: '>=14.16'}
dev: false
/camelize/1.0.1:
resolution: {integrity: sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==}
dev: false
@@ -8393,6 +8548,11 @@ packages:
ansi-styles: 4.3.0
supports-color: 7.2.0
/chalk/5.2.0:
resolution: {integrity: sha512-ree3Gqw/nazQAPuJJEy+avdl7QfZMcUvmHIKgEZkGL+xOBzRvup5Hxo6LHuMceSxOabuJLJm5Yp/92R9eMmMvA==}
engines: {node: ^12.17.0 || ^14.13 || >=16.0.0}
dev: false
/char-regex/1.0.2:
resolution: {integrity: sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==}
engines: {node: '>=10'}
@@ -8718,6 +8878,11 @@ packages:
engines: {node: '>= 12'}
dev: false
/commander/9.5.0:
resolution: {integrity: sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==}
engines: {node: ^12.20.0 || >=14}
dev: false
/commondir/1.0.1:
resolution: {integrity: sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==}
dev: false
@@ -9012,6 +9177,14 @@ packages:
- encoding
dev: false
/cross-spawn-async/2.2.5:
resolution: {integrity: sha512-snteb3aVrxYYOX9e8BabYFK9WhCDhTlw1YQktfTthBogxri4/2r9U2nQc0ffY73ZAxezDc+U8gvHAeU1wy1ubQ==}
deprecated: cross-spawn no longer requires a build toolchain, use it instead
dependencies:
lru-cache: 4.1.5
which: 1.3.1
dev: false
/cross-spawn/7.0.3:
resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==}
engines: {node: '>= 8'}
@@ -9464,6 +9637,24 @@ packages:
resolution: {integrity: sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==}
engines: {node: '>=0.10.0'}
/default-browser-id/3.0.0:
resolution: {integrity: sha512-OZ1y3y0SqSICtE8DE4S8YOE9UZOJ8wO16fKWVP5J1Qz42kV9jcnMVFrEE/noXb/ss3Q4pZIH79kxofzyNNtUNA==}
engines: {node: '>=12'}
dependencies:
bplist-parser: 0.2.0
untildify: 4.0.0
dev: false
/default-browser/3.1.0:
resolution: {integrity: sha512-SOHecvSoairSAWxEHP/0qcsld/KtI3DargfEuELQDyHIYmS2EMgdGhHOTC1GxaYr+NLUV6kDroeiSBfnNHnn8w==}
engines: {node: '>=12'}
dependencies:
bundle-name: 3.0.0
default-browser-id: 3.0.0
execa: 5.1.1
xdg-default-browser: 2.1.0
dev: false
/default-gateway/6.0.3:
resolution: {integrity: sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg==}
engines: {node: '>= 10'}
@@ -9975,7 +10166,6 @@ packages:
cpu: [x64]
os: [android]
requiresBuild: true
dev: true
optional: true
/esbuild-android-arm64/0.15.18:
@@ -9984,7 +10174,6 @@ packages:
cpu: [arm64]
os: [android]
requiresBuild: true
dev: true
optional: true
/esbuild-darwin-64/0.15.18:
@@ -9993,7 +10182,6 @@ packages:
cpu: [x64]
os: [darwin]
requiresBuild: true
dev: true
optional: true
/esbuild-darwin-arm64/0.15.18:
@@ -10002,7 +10190,6 @@ packages:
cpu: [arm64]
os: [darwin]
requiresBuild: true
dev: true
optional: true
/esbuild-freebsd-64/0.15.18:
@@ -10011,7 +10198,6 @@ packages:
cpu: [x64]
os: [freebsd]
requiresBuild: true
dev: true
optional: true
/esbuild-freebsd-arm64/0.15.18:
@@ -10020,7 +10206,6 @@ packages:
cpu: [arm64]
os: [freebsd]
requiresBuild: true
dev: true
optional: true
/esbuild-linux-32/0.15.18:
@@ -10029,7 +10214,6 @@ packages:
cpu: [ia32]
os: [linux]
requiresBuild: true
dev: true
optional: true
/esbuild-linux-64/0.15.18:
@@ -10038,7 +10222,6 @@ packages:
cpu: [x64]
os: [linux]
requiresBuild: true
dev: true
optional: true
/esbuild-linux-arm/0.15.18:
@@ -10047,7 +10230,6 @@ packages:
cpu: [arm]
os: [linux]
requiresBuild: true
dev: true
optional: true
/esbuild-linux-arm64/0.15.18:
@@ -10056,7 +10238,6 @@ packages:
cpu: [arm64]
os: [linux]
requiresBuild: true
dev: true
optional: true
/esbuild-linux-mips64le/0.15.18:
@@ -10065,7 +10246,6 @@ packages:
cpu: [mips64el]
os: [linux]
requiresBuild: true
dev: true
optional: true
/esbuild-linux-ppc64le/0.15.18:
@@ -10074,7 +10254,6 @@ packages:
cpu: [ppc64]
os: [linux]
requiresBuild: true
dev: true
optional: true
/esbuild-linux-riscv64/0.15.18:
@@ -10083,7 +10262,6 @@ packages:
cpu: [riscv64]
os: [linux]
requiresBuild: true
dev: true
optional: true
/esbuild-linux-s390x/0.15.18:
@@ -10092,7 +10270,6 @@ packages:
cpu: [s390x]
os: [linux]
requiresBuild: true
dev: true
optional: true
/esbuild-netbsd-64/0.15.18:
@@ -10101,7 +10278,6 @@ packages:
cpu: [x64]
os: [netbsd]
requiresBuild: true
dev: true
optional: true
/esbuild-openbsd-64/0.15.18:
@@ -10110,7 +10286,6 @@ packages:
cpu: [x64]
os: [openbsd]
requiresBuild: true
dev: true
optional: true
/esbuild-sunos-64/0.15.18:
@@ -10119,7 +10294,6 @@ packages:
cpu: [x64]
os: [sunos]
requiresBuild: true
dev: true
optional: true
/esbuild-windows-32/0.15.18:
@@ -10128,7 +10302,6 @@ packages:
cpu: [ia32]
os: [win32]
requiresBuild: true
dev: true
optional: true
/esbuild-windows-64/0.15.18:
@@ -10137,7 +10310,6 @@ packages:
cpu: [x64]
os: [win32]
requiresBuild: true
dev: true
optional: true
/esbuild-windows-arm64/0.15.18:
@@ -10146,7 +10318,6 @@ packages:
cpu: [arm64]
os: [win32]
requiresBuild: true
dev: true
optional: true
/esbuild/0.15.18:
@@ -10177,7 +10348,6 @@ packages:
esbuild-windows-32: 0.15.18
esbuild-windows-64: 0.15.18
esbuild-windows-arm64: 0.15.18
dev: true
/esbuild/0.16.15:
resolution: {integrity: sha512-v+3ozjy9wyj8cOElzx3//Lsb4TCxPfZxRmdsfm0YaEkvZu7y6rKH7Zi1UpDx4JI7dSQui+U1Qxhfij9KBbHfrA==}
@@ -10611,6 +10781,17 @@ packages:
safe-buffer: 5.2.1
dev: false
/execa/0.2.2:
resolution: {integrity: sha512-zmBGzLd3nhA/NB9P7VLoceAO6vyYPftvl809Vjwe5U2fYI9tYWbeKqP3wZlAw9WS+znnkogf/bhSU+Gcn2NbkQ==}
engines: {node: '>=0.12'}
dependencies:
cross-spawn-async: 2.2.5
npm-run-path: 1.0.0
object-assign: 4.1.1
path-key: 1.0.0
strip-eof: 1.0.0
dev: false
/execa/5.1.1:
resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==}
engines: {node: '>=10'}
@@ -11199,6 +11380,11 @@ packages:
engines: {node: '>=8.0.0'}
dev: true
/get-port/6.1.2:
resolution: {integrity: sha512-BrGGraKm2uPqurfGVj/z97/zv8dPleC6x9JBNRTrDNtCkkRF4rPwrQXFgL7+I+q8QSdU4ntLQX2D7KIxSy8nGw==}
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
dev: false
/get-stdin/5.0.1:
resolution: {integrity: sha512-jZV7n6jGE3Gt7fgSTJoz91Ak5MuTLwMwkoYdjxuJ/AmjIsE1UC03y/IWkZCQGEvVNS9qoRNwy5BCqxImv0FVeA==}
engines: {node: '>=0.12.0'}
@@ -11248,6 +11434,10 @@ packages:
dependencies:
is-glob: 4.0.3
/glob-regex/0.3.2:
resolution: {integrity: sha512-m5blUd3/OqDTWwzBBtWBPrGlAzatRywHameHeekAZyZrskYouOGdNB8T/q6JucucvJXtOuyHIn0/Yia7iDasDw==}
dev: false
/glob-to-regexp/0.4.1:
resolution: {integrity: sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==}
@@ -11690,6 +11880,12 @@ packages:
value-equal: 1.0.1
dev: false
/history/5.3.0:
resolution: {integrity: sha512-ZqaKwjjrAYUYfLG+htGaIIZ4nioX2L70ZUMIFysS3xvBsSG4x/n1V6TXV3N8ZYNuFGlDirFg32T7B6WOUPDYcQ==}
dependencies:
'@babel/runtime': 7.20.6
dev: false
/hmac-drbg/1.0.1:
resolution: {integrity: sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==}
dependencies:
@@ -13607,6 +13803,13 @@ packages:
resolution: {integrity: sha512-Pn9cox5CsMYngeDbmChANltQl+5pi6XmTrraMSzhPmMBbmgcxmqWry0U3PGapCU1yB4/LqCcom7qhHZiF/jGfQ==}
dev: false
/magic-string/0.26.7:
resolution: {integrity: sha512-hX9XH3ziStPoPhJxLq1syWuZMxbDvGNbVchfrdCtanC7D13888bMFow61x8axrx+GfHLtVeAx2kxL7tTGRl+Ow==}
engines: {node: '>=12'}
dependencies:
sourcemap-codec: 1.4.8
dev: false
/magic-string/0.27.0:
resolution: {integrity: sha512-8UnnX2PeRAPZuN12svgR9j7M1uWMovg/CEnIwIG0LFkXSJJe4PdfUGiTGl8V9bsBHFUtfVINcSyYxd7q+kx9fA==}
engines: {node: '>=12'}
@@ -14591,6 +14794,13 @@ packages:
resolution: {integrity: sha512-uVFpKhj5MheNBJRTiMZ9pE/7hD1QTeEvugSJW/OmLzAp78PB5O6adfMNTvmfKhXBkvCzC+rqifWcVYpGFwTjnw==}
engines: {node: '>=14.16'}
/npm-run-path/1.0.0:
resolution: {integrity: sha512-PrGAi1SLlqNvKN5uGBjIgnrTb8fl0Jz0a3JJmeMcGnIBh7UE9Gc4zsAMlwDajOMg2b1OgP6UPvoLUboTmMZPFA==}
engines: {node: '>=0.10.0'}
dependencies:
path-key: 1.0.0
dev: false
/npm-run-path/4.0.1:
resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==}
engines: {node: '>=8'}
@@ -15031,6 +15241,11 @@ packages:
resolution: {integrity: sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w==}
dev: false
/path-key/1.0.0:
resolution: {integrity: sha512-T3hWy7tyXlk3QvPFnT+o2tmXRzU4GkitkUWLp/WZ0S/FXd7XMx176tRurgTvHTNMJOQzTcesHNpBqetH86mQ9g==}
engines: {node: '>=0.10.0'}
dev: false
/path-key/3.1.1:
resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==}
engines: {node: '>=8'}
@@ -16067,6 +16282,14 @@ packages:
react: 17.0.2
dev: false
/prism-react-renderer/1.3.5_react@18.2.0:
resolution: {integrity: sha512-IJ+MSwBWKG+SM3b2SUfdrhC+gu01QkV2KmRQgREThBfSQRoufqRfxfHUxpG1WcaFjP+kojcFyO9Qqtpgt3qLCg==}
peerDependencies:
react: '>=0.14.9'
dependencies:
react: 18.2.0
dev: false
/prisma/4.8.1:
resolution: {integrity: sha512-ZMLnSjwulIeYfaU1O6/LF6PEJzxN5par5weykxMykS9Z6ara/j76JH3Yo2AH3bgJbPN4Z6NeCK9s5fDkzf33cg==}
engines: {node: '>=14.17'}
@@ -16423,6 +16646,14 @@ packages:
react-dom: 18.2.0_react@18.2.0
dev: false
/react-inspector/6.0.1_react@18.2.0:
resolution: {integrity: sha512-cxKSeFTf7jpSSVddm66sKdolG90qURAX3g1roTeaN6x0YEbtWc8JpmFN9+yIqLNH2uEkYerWLtJZIXRIFuBKrg==}
peerDependencies:
react: ^16.8.4 || ^17.0.0 || ^18.0.0
dependencies:
react: 18.2.0
dev: false
/react-is/16.13.1:
resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==}
@@ -16507,6 +16738,11 @@ packages:
react-is: 17.0.2
dev: false
/react-refresh/0.14.0:
resolution: {integrity: sha512-wViHqhAd8OHeLS/IRMJjTSDHF3U9eWi62F/MledQGPdJGDhodXJ9PBLNGr6WWL7qlH12Mt3TyTpbS+hGXMjCzQ==}
engines: {node: '>=0.10.0'}
dev: false
/react-remove-scroll-bar/2.3.4_kzbn2opkn2327fwg5yzwzya5o4:
resolution: {integrity: sha512-63C4YQBUt0m6ALadE9XV56hV8BgJWDmmTPY758iIJjfQKt2nYwoUrPk0LXRXcB/yIj82T1/Ixfdpdk68LwIB0A==}
engines: {node: '>=10'}
@@ -16802,6 +17038,16 @@ packages:
resolve: 1.22.1
dev: false
/recrawl-sync/2.2.3:
resolution: {integrity: sha512-vSaTR9t+cpxlskkdUFrsEpnf67kSmPk66yAGT1fZPrDudxQjoMzPgQhSMImQ0pAw5k0NPirefQfhopSjhdUtpQ==}
dependencies:
'@cush/relative': 1.0.0
glob-regex: 0.3.2
slash: 3.0.0
sucrase: 3.29.0
tslib: 1.14.1
dev: false
/recursive-readdir/2.2.3:
resolution: {integrity: sha512-8HrF5ZsXk5FAH9dgsx3BlUer73nIhuj+9OrQwEbLTPOBzGkL1lsFCR01am+v+0m2Cmbs1nP12hLDl5FA7EszKA==}
engines: {node: '>=6.0.0'}
@@ -17193,6 +17439,14 @@ packages:
fsevents: 2.3.2
dev: false
/rollup/2.79.1:
resolution: {integrity: sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==}
engines: {node: '>=10.0.0'}
hasBin: true
optionalDependencies:
fsevents: 2.3.2
dev: false
/rollup/3.7.5:
resolution: {integrity: sha512-z0ZbqHBtS/et2EEUKMrAl2CoSdwN7ZPzL17UMiKN9RjjqHShTlv7F9J6ZJZJNREYjBh3TvBrdfjkFDIXFNeuiQ==}
engines: {node: '>=14.18.0', npm: '>=8.0.0'}
@@ -17229,6 +17483,13 @@ packages:
strip-json-comments: 3.1.1
dev: false
/run-applescript/5.0.0:
resolution: {integrity: sha512-XcT5rBksx1QdIhlFOCtgZkB99ZEouFZ1E2Kc2LHqNW13U3/74YGdkQRmThTwxy4QIyookibDKYZOPqX//6BlAg==}
engines: {node: '>=12'}
dependencies:
execa: 5.1.1
dev: false
/run-async/2.4.1:
resolution: {integrity: sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==}
engines: {node: '>=0.12.0'}
@@ -18025,6 +18286,11 @@ packages:
engines: {node: '>=8'}
dev: true
/strip-eof/1.0.0:
resolution: {integrity: sha512-7FCwGGmx8mD5xQd3RPUvnSpUXHM3BWuzjtpD4TXsfcZ9EL4azvVVUscFYwD9nx8Kh+uCBC00XBtAykoMHwTh8Q==}
engines: {node: '>=0.10.0'}
dev: false
/strip-final-newline/2.0.0:
resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==}
engines: {node: '>=6'}
@@ -18405,6 +18671,11 @@ packages:
'@popperjs/core': 2.11.6
dev: false
/titleize/1.0.1:
resolution: {integrity: sha512-rUwGDruKq1gX+FFHbTl5qjI7teVO7eOe+C8IcQ7QT+1BK3eEUXJqbZcBOeaRP4FwSC/C1A5jDoIVta0nIQ9yew==}
engines: {node: '>=0.10.0'}
dev: false
/tmp/0.0.33:
resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==}
engines: {node: '>=0.6.0'}
@@ -18558,6 +18829,15 @@ packages:
strip-bom: 3.0.0
dev: false
/tsconfig-paths/4.1.2:
resolution: {integrity: sha512-uhxiMgnXQp1IR622dUXI+9Ehnws7i/y6xvpZB9IbUVOPy0muvdvgXeZOn88UcGPiT98Vp3rJPTa8bFoalZ3Qhw==}
engines: {node: '>=6'}
dependencies:
json5: 2.2.2
minimist: 1.2.7
strip-bom: 3.0.0
dev: false
/tslib/1.14.1:
resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==}
@@ -18631,7 +18911,7 @@ packages:
joycon: 3.1.1
postcss-load-config: 3.1.4
resolve-from: 5.0.0
rollup: 3.9.1
rollup: 3.7.5
source-map: 0.8.0-beta.0
sucrase: 3.29.0
tree-kill: 1.2.2
@@ -18939,6 +19219,11 @@ packages:
engines: {node: '>= 0.8'}
dev: false
/untildify/4.0.0:
resolution: {integrity: sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==}
engines: {node: '>=8'}
dev: false
/update-browserslist-db/1.0.10_browserslist@4.21.4:
resolution: {integrity: sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==}
hasBin: true
@@ -19267,6 +19552,54 @@ packages:
- supports-color
dev: true
/vite-tsconfig-paths/3.6.0_vite@3.2.5:
resolution: {integrity: sha512-UfsPYonxLqPD633X8cWcPFVuYzx/CMNHAjZTasYwX69sXpa4gNmQkR0XCjj82h7zhLGdTWagMjC1qfb9S+zv0A==}
peerDependencies:
vite: '>2.0.0-0'
dependencies:
debug: 4.3.4
globrex: 0.1.2
recrawl-sync: 2.2.3
tsconfig-paths: 4.1.2
vite: 3.2.5_@types+node@18.11.18
transitivePeerDependencies:
- supports-color
dev: false
/vite/3.2.5_@types+node@18.11.18:
resolution: {integrity: sha512-4mVEpXpSOgrssFZAOmGIr85wPHKvaDAcXqxVxVRZhljkJOMZi1ibLibzjLHzJvcok8BMguLc7g1W6W/GqZbLdQ==}
engines: {node: ^14.18.0 || >=16.0.0}
hasBin: true
peerDependencies:
'@types/node': '>= 14'
less: '*'
sass: '*'
stylus: '*'
sugarss: '*'
terser: ^5.4.0
peerDependenciesMeta:
'@types/node':
optional: true
less:
optional: true
sass:
optional: true
stylus:
optional: true
sugarss:
optional: true
terser:
optional: true
dependencies:
'@types/node': 18.11.18
esbuild: 0.15.18
postcss: 8.4.21
resolve: 1.22.1
rollup: 2.79.1
optionalDependencies:
fsevents: 2.3.2
dev: false
/vite/4.0.4:
resolution: {integrity: sha512-xevPU7M8FU0i/80DMR+YhgrzR5KS2ORy1B4xcX/cXLsvnUWvfHuqMmVU6N0YiJ4JWGRJJsLCgjEzKjG9/GKoSw==}
engines: {node: ^14.18.0 || >=16.0.0}
@@ -19734,6 +20067,14 @@ packages:
engines: {node: '>=8'}
dev: false
/xdg-default-browser/2.1.0:
resolution: {integrity: sha512-HY4G725+IDQr16N8XOjAms5qJGArdJaWIuC7Q7A8UXIwj2mifqnPXephazyL7sIkQPvmEoPX3E0v2yFv6hQUNg==}
engines: {node: '>=4'}
dependencies:
execa: 0.2.2
titleize: 1.0.1
dev: false
/xml-js/1.6.11:
resolution: {integrity: sha512-7rVi2KMfwfWFl+GpPg6m80IVMWXLRjO+PxTq7V2CDhoGak0wzYzFgUY2m4XJ47OGdXd8eLE8EmwfAmdjw7lC1g==}
hasBin: true