@wallavi/widget 1.6.7 → 1.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +75 -5
- package/dist/index.d.ts +75 -5
- package/dist/index.js +399 -24
- package/dist/index.mjs +400 -26
- package/package.json +8 -3
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { useRef, useEffect, useState, useCallback, useMemo } from 'react';
|
|
2
|
-
import { UploadCloud, X, RotateCcw, Loader2, Square, Mic, Paperclip, ArrowUp, Zap, ChevronDown, CheckCircle2, AlertCircle,
|
|
2
|
+
import { UploadCloud, X, RotateCcw, Loader2, Square, Mic, Paperclip, ArrowUp, Zap, ChevronDown, CheckCircle2, AlertCircle, Check, Search, FileText, FileSpreadsheet } from 'lucide-react';
|
|
3
3
|
import { clsx } from 'clsx';
|
|
4
4
|
import { extendTailwindMerge, twMerge as twMerge$1 } from 'tailwind-merge';
|
|
5
5
|
import * as AvatarPrimitive from '@radix-ui/react-avatar';
|
|
@@ -30,7 +30,7 @@ function styleInject(css, { insertAt } = {}) {
|
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
// src/styles.css
|
|
33
|
-
styleInject(".ww-pointer-events-none {\n pointer-events: none;\n}\n.ww-absolute {\n position: absolute;\n}\n.ww-relative {\n position: relative;\n}\n.ww-inset-0 {\n inset: 0px;\n}\n.ww-left-2\\.5 {\n left: 0.625rem;\n}\n.ww-top-1\\/2 {\n top: 50%;\n}\n.ww-z-50 {\n z-index: 50;\n}\n.ww-mb-1 {\n margin-bottom: 0.25rem;\n}\n.ww-mb-2 {\n margin-bottom: 0.5rem;\n}\n.ww-ml-0\\.5 {\n margin-left: 0.125rem;\n}\n.ww-mt-0\\.5 {\n margin-top: 0.125rem;\n}\n.ww-mt-1 {\n margin-top: 0.25rem;\n}\n.ww-block {\n display: block;\n}\n.ww-inline-block {\n display: inline-block;\n}\n.ww-flex {\n display: flex;\n}\n.ww-inline-flex {\n display: inline-flex;\n}\n.ww-grid {\n display: grid;\n}\n.ww-hidden {\n display: none;\n}\n.ww-h-10 {\n height: 2.5rem;\n}\n.ww-h-2\\.5 {\n height: 0.625rem;\n}\n.ww-h-20 {\n height: 5rem;\n}\n.ww-h-3 {\n height: 0.75rem;\n}\n.ww-h-3\\.5 {\n height: 0.875rem;\n}\n.ww-h-4 {\n height: 1rem;\n}\n.ww-h-6 {\n height: 1.5rem;\n}\n.ww-h-7 {\n height: 1.75rem;\n}\n.ww-h-8 {\n height: 2rem;\n}\n.ww-h-full {\n height: 100%;\n}\n.ww-max-h-32 {\n max-height: 8rem;\n}\n.ww-max-h-48 {\n max-height: 12rem;\n}\n.ww-max-h-\\[168px\\] {\n max-height: 168px;\n}\n.ww-max-h-\\[180px\\] {\n max-height: 180px;\n}\n.ww-w-0\\.5 {\n width: 0.125rem;\n}\n.ww-w-10 {\n width: 2.5rem;\n}\n.ww-w-2\\.5 {\n width: 0.625rem;\n}\n.ww-w-20 {\n width: 5rem;\n}\n.ww-w-3 {\n width: 0.75rem;\n}\n.ww-w-3\\.5 {\n width: 0.875rem;\n}\n.ww-w-4 {\n width: 1rem;\n}\n.ww-w-6 {\n width: 1.5rem;\n}\n.ww-w-7 {\n width: 1.75rem;\n}\n.ww-w-8 {\n width: 2rem;\n}\n.ww-w-fit {\n width: -moz-fit-content;\n width: fit-content;\n}\n.ww-w-full {\n width: 100%;\n}\n.ww-min-w-0 {\n min-width: 0px;\n}\n.ww-max-w-\\[120px\\] {\n max-width: 120px;\n}\n.ww-max-w-\\[200px\\] {\n max-width: 200px;\n}\n.ww-max-w-\\[78\\%\\] {\n max-width: 78%;\n}\n.ww-max-w-\\[82\\%\\] {\n max-width: 82%;\n}\n.ww-max-w-none {\n max-width: none;\n}\n.ww-flex-1 {\n flex: 1 1 0%;\n}\n.ww-shrink-0 {\n flex-shrink: 0;\n}\n.ww-rotate-180 {\n --tw-rotate: 180deg;\n transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));\n}\n@keyframes ww-pulse {\n 50% {\n opacity: .5;\n }\n}\n.ww-animate-pulse {\n animation: ww-pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;\n}\n@keyframes ww-spin {\n to {\n transform: rotate(360deg);\n }\n}\n.ww-animate-spin {\n animation: ww-spin 1s linear infinite;\n}\n.ww-cursor-default {\n cursor: default;\n}\n.ww-cursor-pointer {\n cursor: pointer;\n}\n.ww-select-none {\n -webkit-user-select: none;\n -moz-user-select: none;\n user-select: none;\n}\n.ww-resize-none {\n resize: none;\n}\n.ww-grid-cols-2 {\n grid-template-columns: repeat(2, minmax(0, 1fr));\n}\n.ww-flex-col {\n flex-direction: column;\n}\n.ww-flex-wrap {\n flex-wrap: wrap;\n}\n.ww-items-start {\n align-items: flex-start;\n}\n.ww-items-end {\n align-items: flex-end;\n}\n.ww-items-center {\n align-items: center;\n}\n.ww-justify-end {\n justify-content: flex-end;\n}\n.ww-justify-center {\n justify-content: center;\n}\n.ww-justify-between {\n justify-content: space-between;\n}\n.ww-gap-0\\.5 {\n gap: 0.125rem;\n}\n.ww-gap-1 {\n gap: 0.25rem;\n}\n.ww-gap-1\\.5 {\n gap: 0.375rem;\n}\n.ww-gap-2 {\n gap: 0.5rem;\n}\n.ww-gap-2\\.5 {\n gap: 0.625rem;\n}\n.ww-gap-4 {\n gap: 1rem;\n}\n.ww-divide-y > :not([hidden]) ~ :not([hidden]) {\n --tw-divide-y-reverse: 0;\n border-top-width: calc(1px * calc(1 - var(--tw-divide-y-reverse)));\n border-bottom-width: calc(1px * var(--tw-divide-y-reverse));\n}\n.ww-divide-border\\/40 > :not([hidden]) ~ :not([hidden]) {\n border-color: hsl(var(--border) / 0.4);\n}\n.ww-overflow-hidden {\n overflow: hidden;\n}\n.ww-overflow-y-auto {\n overflow-y: auto;\n}\n.ww-overscroll-contain {\n overscroll-behavior: contain;\n}\n.ww-truncate {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.ww-whitespace-pre-wrap {\n white-space: pre-wrap;\n}\n.ww-rounded {\n border-radius: 0.25rem;\n}\n.ww-rounded-2xl {\n border-radius: 1rem;\n}\n.ww-rounded-full {\n border-radius: 9999px;\n}\n.ww-rounded-lg {\n border-radius: var(--radius);\n}\n.ww-rounded-xl {\n border-radius: 0.75rem;\n}\n.ww-rounded-tl-none {\n border-top-left-radius: 0px;\n}\n.ww-rounded-tl-sm {\n border-top-left-radius: calc(var(--radius) - 4px);\n}\n.ww-rounded-tr-sm {\n border-top-right-radius: calc(var(--radius) - 4px);\n}\n.ww-border {\n border-width: 1px;\n}\n.ww-border-2 {\n border-width: 2px;\n}\n.ww-border-b {\n border-bottom-width: 1px;\n}\n.ww-border-l-2 {\n border-left-width: 2px;\n}\n.ww-border-t {\n border-top-width: 1px;\n}\n.ww-border-background {\n border-color: hsl(var(--background));\n}\n.ww-border-black\\/10 {\n border-color: rgb(0 0 0 / 0.1);\n}\n.ww-border-border {\n border-color: hsl(var(--border));\n}\n.ww-border-border\\/30 {\n border-color: hsl(var(--border) / 0.3);\n}\n.ww-border-border\\/40 {\n border-color: hsl(var(--border) / 0.4);\n}\n.ww-border-border\\/50 {\n border-color: hsl(var(--border) / 0.5);\n}\n.ww-border-border\\/60 {\n border-color: hsl(var(--border) / 0.6);\n}\n.ww-border-border\\/70 {\n border-color: hsl(var(--border) / 0.7);\n}\n.ww-border-muted {\n border-color: hsl(var(--muted));\n}\n.ww-border-muted-foreground\\/30 {\n border-color: hsl(var(--muted-foreground) / 0.3);\n}\n.ww-border-red-200 {\n --tw-border-opacity: 1;\n border-color: rgb(254 202 202 / var(--tw-border-opacity, 1));\n}\n.ww-border-white\\/20 {\n border-color: rgb(255 255 255 / 0.2);\n}\n.ww-bg-background {\n background-color: hsl(var(--background));\n}\n.ww-bg-background\\/20 {\n background-color: hsl(var(--background) / 0.2);\n}\n.ww-bg-background\\/40 {\n background-color: hsl(var(--background) / 0.4);\n}\n.ww-bg-background\\/50 {\n background-color: hsl(var(--background) / 0.5);\n}\n.ww-bg-background\\/90 {\n background-color: hsl(var(--background) / 0.9);\n}\n.ww-bg-black\\/10 {\n background-color: rgb(0 0 0 / 0.1);\n}\n.ww-bg-foreground {\n background-color: hsl(var(--foreground));\n}\n.ww-bg-foreground\\/60 {\n background-color: hsl(var(--foreground) / 0.6);\n}\n.ww-bg-muted {\n background-color: hsl(var(--muted));\n}\n.ww-bg-muted-foreground\\/10 {\n background-color: hsl(var(--muted-foreground) / 0.1);\n}\n.ww-bg-muted\\/50 {\n background-color: hsl(var(--muted) / 0.5);\n}\n.ww-bg-muted\\/60 {\n background-color: hsl(var(--muted) / 0.6);\n}\n.ww-bg-primary {\n background-color: hsl(var(--primary));\n}\n.ww-bg-primary\\/5 {\n background-color: hsl(var(--primary) / 0.05);\n}\n.ww-bg-red-50 {\n --tw-bg-opacity: 1;\n background-color: rgb(254 242 242 / var(--tw-bg-opacity, 1));\n}\n.ww-bg-transparent {\n background-color: transparent;\n}\n.ww-bg-white\\/10 {\n background-color: rgb(255 255 255 / 0.1);\n}\n.ww-bg-white\\/15 {\n background-color: rgb(255 255 255 / 0.15);\n}\n.ww-fill-current {\n fill: currentColor;\n}\n.ww-object-cover {\n -o-object-fit: cover;\n object-fit: cover;\n}\n.ww-p-0\\.5 {\n padding: 0.125rem;\n}\n.ww-p-1\\.5 {\n padding: 0.375rem;\n}\n.ww-p-3 {\n padding: 0.75rem;\n}\n.ww-px-1 {\n padding-left: 0.25rem;\n padding-right: 0.25rem;\n}\n.ww-px-2 {\n padding-left: 0.5rem;\n padding-right: 0.5rem;\n}\n.ww-px-2\\.5 {\n padding-left: 0.625rem;\n padding-right: 0.625rem;\n}\n.ww-px-3 {\n padding-left: 0.75rem;\n padding-right: 0.75rem;\n}\n.ww-px-3\\.5 {\n padding-left: 0.875rem;\n padding-right: 0.875rem;\n}\n.ww-px-4 {\n padding-left: 1rem;\n padding-right: 1rem;\n}\n.ww-py-0\\.5 {\n padding-top: 0.125rem;\n padding-bottom: 0.125rem;\n}\n.ww-py-1 {\n padding-top: 0.25rem;\n padding-bottom: 0.25rem;\n}\n.ww-py-1\\.5 {\n padding-top: 0.375rem;\n padding-bottom: 0.375rem;\n}\n.ww-py-2 {\n padding-top: 0.5rem;\n padding-bottom: 0.5rem;\n}\n.ww-py-2\\.5 {\n padding-top: 0.625rem;\n padding-bottom: 0.625rem;\n}\n.ww-py-3 {\n padding-top: 0.75rem;\n padding-bottom: 0.75rem;\n}\n.ww-py-4 {\n padding-top: 1rem;\n padding-bottom: 1rem;\n}\n.ww-pb-1\\.5 {\n padding-bottom: 0.375rem;\n}\n.ww-pb-4 {\n padding-bottom: 1rem;\n}\n.ww-pl-2 {\n padding-left: 0.5rem;\n}\n.ww-pl-7 {\n padding-left: 1.75rem;\n}\n.ww-pr-0\\.5 {\n padding-right: 0.125rem;\n}\n.ww-pr-3 {\n padding-right: 0.75rem;\n}\n.ww-pt-2 {\n padding-top: 0.5rem;\n}\n.ww-pt-5 {\n padding-top: 1.25rem;\n}\n.ww-text-left {\n text-align: left;\n}\n.ww-text-center {\n text-align: center;\n}\n.ww-align-middle {\n vertical-align: middle;\n}\n.ww-text-\\[10\\.5px\\] {\n font-size: 10.5px;\n}\n.ww-text-\\[10px\\] {\n font-size: 10px;\n}\n.ww-text-\\[11px\\] {\n font-size: 11px;\n}\n.ww-text-\\[12\\.5px\\] {\n font-size: 12.5px;\n}\n.ww-text-\\[12px\\] {\n font-size: 12px;\n}\n.ww-text-\\[8px\\] {\n font-size: 8px;\n}\n.ww-text-sm {\n font-size: 0.875rem;\n line-height: 1.25rem;\n}\n.ww-text-xs {\n font-size: 0.75rem;\n line-height: 1rem;\n}\n.ww-font-medium {\n font-weight: 500;\n}\n.ww-font-semibold {\n font-weight: 600;\n}\n.ww-uppercase {\n text-transform: uppercase;\n}\n.ww-leading-none {\n line-height: 1;\n}\n.ww-leading-relaxed {\n line-height: 1.625;\n}\n.ww-leading-snug {\n line-height: 1.375;\n}\n.ww-leading-tight {\n line-height: 1.25;\n}\n.ww-tracking-widest {\n letter-spacing: 0.1em;\n}\n.ww-text-background {\n color: hsl(var(--background));\n}\n.ww-text-black\\/40 {\n color: rgb(0 0 0 / 0.4);\n}\n.ww-text-black\\/60 {\n color: rgb(0 0 0 / 0.6);\n}\n.ww-text-destructive {\n color: hsl(var(--destructive));\n}\n.ww-text-destructive\\/70 {\n color: hsl(var(--destructive) / 0.7);\n}\n.ww-text-emerald-500 {\n --tw-text-opacity: 1;\n color: rgb(16 185 129 / var(--tw-text-opacity, 1));\n}\n.ww-text-foreground {\n color: hsl(var(--foreground));\n}\n.ww-text-foreground\\/60 {\n color: hsl(var(--foreground) / 0.6);\n}\n.ww-text-foreground\\/70 {\n color: hsl(var(--foreground) / 0.7);\n}\n.ww-text-foreground\\/80 {\n color: hsl(var(--foreground) / 0.8);\n}\n.ww-text-muted-foreground {\n color: hsl(var(--muted-foreground));\n}\n.ww-text-muted-foreground\\/40 {\n color: hsl(var(--muted-foreground) / 0.4);\n}\n.ww-text-muted-foreground\\/50 {\n color: hsl(var(--muted-foreground) / 0.5);\n}\n.ww-text-muted-foreground\\/70 {\n color: hsl(var(--muted-foreground) / 0.7);\n}\n.ww-text-muted-foreground\\/80 {\n color: hsl(var(--muted-foreground) / 0.8);\n}\n.ww-text-primary {\n color: hsl(var(--primary));\n}\n.ww-text-primary-foreground {\n color: hsl(var(--primary-foreground));\n}\n.ww-text-primary\\/70 {\n color: hsl(var(--primary) / 0.7);\n}\n.ww-text-primary\\/80 {\n color: hsl(var(--primary) / 0.8);\n}\n.ww-text-red-400 {\n --tw-text-opacity: 1;\n color: rgb(248 113 113 / var(--tw-text-opacity, 1));\n}\n.ww-text-red-500 {\n --tw-text-opacity: 1;\n color: rgb(239 68 68 / var(--tw-text-opacity, 1));\n}\n.ww-text-red-600 {\n --tw-text-opacity: 1;\n color: rgb(220 38 38 / var(--tw-text-opacity, 1));\n}\n.ww-text-white\\/60 {\n color: rgb(255 255 255 / 0.6);\n}\n.ww-text-white\\/80 {\n color: rgb(255 255 255 / 0.8);\n}\n.ww-line-through {\n text-decoration-line: line-through;\n}\n.ww-no-underline {\n text-decoration-line: none;\n}\n.ww-decoration-foreground\\/20 {\n text-decoration-color: hsl(var(--foreground) / 0.2);\n}\n.ww-opacity-100 {\n opacity: 1;\n}\n.ww-opacity-30 {\n opacity: 0.3;\n}\n.ww-opacity-35 {\n opacity: 0.35;\n}\n.ww-opacity-40 {\n opacity: 0.4;\n}\n.ww-opacity-60 {\n opacity: 0.6;\n}\n.ww-opacity-70 {\n opacity: 0.7;\n}\n.ww-opacity-80 {\n opacity: 0.8;\n}\n.ww-shadow-2xl {\n --tw-shadow: 0 25px 50px -12px rgb(0 0 0 / 0.25);\n --tw-shadow-colored: 0 25px 50px -12px var(--tw-shadow-color);\n box-shadow:\n var(--tw-ring-offset-shadow, 0 0 #0000),\n var(--tw-ring-shadow, 0 0 #0000),\n var(--tw-shadow);\n}\n.ww-shadow-sm {\n --tw-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05);\n --tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);\n box-shadow:\n var(--tw-ring-offset-shadow, 0 0 #0000),\n var(--tw-ring-shadow, 0 0 #0000),\n var(--tw-shadow);\n}\n.ww-shadow-xl {\n --tw-shadow: 0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1);\n --tw-shadow-colored: 0 20px 25px -5px var(--tw-shadow-color), 0 8px 10px -6px var(--tw-shadow-color);\n box-shadow:\n var(--tw-ring-offset-shadow, 0 0 #0000),\n var(--tw-ring-shadow, 0 0 #0000),\n var(--tw-shadow);\n}\n.ww-outline-none {\n outline: 2px solid transparent;\n outline-offset: 2px;\n}\n.ww-ring-2 {\n --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);\n --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);\n box-shadow:\n var(--tw-ring-offset-shadow),\n var(--tw-ring-shadow),\n var(--tw-shadow, 0 0 #0000);\n}\n.ww-ring-inset {\n --tw-ring-inset: inset;\n}\n.ww-ring-primary\\/60 {\n --tw-ring-color: hsl(var(--primary) / 0.6);\n}\n.ww-backdrop-blur-sm {\n --tw-backdrop-blur: blur(4px);\n backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);\n}\n.ww-transition-all {\n transition-property: all;\n transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);\n transition-duration: 150ms;\n}\n.ww-transition-colors {\n transition-property:\n color,\n background-color,\n border-color,\n text-decoration-color,\n fill,\n stroke;\n transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);\n transition-duration: 150ms;\n}\n.ww-transition-shadow {\n transition-property: box-shadow;\n transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);\n transition-duration: 150ms;\n}\n.ww-transition-transform {\n transition-property: transform;\n transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);\n transition-duration: 150ms;\n}\n.ww-duration-100 {\n transition-duration: 100ms;\n}\n.ww-duration-150 {\n transition-duration: 150ms;\n}\n.ww-duration-200 {\n transition-duration: 200ms;\n}\n@keyframes enter {\n from {\n opacity: var(--tw-enter-opacity, 1);\n transform: translate3d(var(--tw-enter-translate-x, 0), var(--tw-enter-translate-y, 0), 0) scale3d(var(--tw-enter-scale, 1), var(--tw-enter-scale, 1), var(--tw-enter-scale, 1)) rotate(var(--tw-enter-rotate, 0));\n }\n}\n@keyframes exit {\n to {\n opacity: var(--tw-exit-opacity, 1);\n transform: translate3d(var(--tw-exit-translate-x, 0), var(--tw-exit-translate-y, 0), 0) scale3d(var(--tw-exit-scale, 1), var(--tw-exit-scale, 1), var(--tw-exit-scale, 1)) rotate(var(--tw-exit-rotate, 0));\n }\n}\n.ww-duration-100 {\n animation-duration: 100ms;\n}\n.ww-duration-150 {\n animation-duration: 150ms;\n}\n.ww-duration-200 {\n animation-duration: 200ms;\n}\n.wallavi-widget *,\n.wallavi-widget *::before,\n.wallavi-widget *::after {\n box-sizing: border-box;\n border-width: 0;\n border-style: solid;\n}\n.wallavi-widget button {\n cursor: pointer;\n}\n.wallavi-widget img,\n.wallavi-widget video {\n max-width: 100%;\n height: auto;\n}\n.placeholder\\:ww-text-muted-foreground\\/40::-moz-placeholder {\n color: hsl(var(--muted-foreground) / 0.4);\n}\n.placeholder\\:ww-text-muted-foreground\\/40::placeholder {\n color: hsl(var(--muted-foreground) / 0.4);\n}\n.placeholder\\:ww-text-muted-foreground\\/50::-moz-placeholder {\n color: hsl(var(--muted-foreground) / 0.5);\n}\n.placeholder\\:ww-text-muted-foreground\\/50::placeholder {\n color: hsl(var(--muted-foreground) / 0.5);\n}\n.focus-within\\:ww-ring-1:focus-within {\n --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);\n --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);\n box-shadow:\n var(--tw-ring-offset-shadow),\n var(--tw-ring-shadow),\n var(--tw-shadow, 0 0 #0000);\n}\n.focus-within\\:ww-ring-ring\\/40:focus-within {\n --tw-ring-color: hsl(var(--ring) / 0.4);\n}\n.hover\\:ww-border-foreground\\/25:hover {\n border-color: hsl(var(--foreground) / 0.25);\n}\n.hover\\:ww-border-foreground\\/30:hover {\n border-color: hsl(var(--foreground) / 0.3);\n}\n.hover\\:ww-bg-background:hover {\n background-color: hsl(var(--background));\n}\n.hover\\:ww-bg-foreground\\/10:hover {\n background-color: hsl(var(--foreground) / 0.1);\n}\n.hover\\:ww-bg-muted:hover {\n background-color: hsl(var(--muted));\n}\n.hover\\:ww-bg-white\\/10:hover {\n background-color: rgb(255 255 255 / 0.1);\n}\n.hover\\:ww-text-foreground:hover {\n color: hsl(var(--foreground));\n}\n.focus\\:ww-ring-1:focus {\n --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);\n --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);\n box-shadow:\n var(--tw-ring-offset-shadow),\n var(--tw-ring-shadow),\n var(--tw-shadow, 0 0 #0000);\n}\n.focus\\:ww-ring-ring\\/40:focus {\n --tw-ring-color: hsl(var(--ring) / 0.4);\n}\n.disabled\\:ww-opacity-40:disabled {\n opacity: 0.4;\n}\n.disabled\\:ww-opacity-50:disabled {\n opacity: 0.5;\n}\n.dark\\:ww-border-red-800:is(.ww-dark *) {\n --tw-border-opacity: 1;\n border-color: rgb(153 27 27 / var(--tw-border-opacity, 1));\n}\n.dark\\:ww-bg-red-950:is(.ww-dark *) {\n --tw-bg-opacity: 1;\n background-color: rgb(69 10 10 / var(--tw-bg-opacity, 1));\n}\n.dark\\:ww-text-red-400:is(.ww-dark *) {\n --tw-text-opacity: 1;\n color: rgb(248 113 113 / var(--tw-text-opacity, 1));\n}\n");
|
|
33
|
+
styleInject(".ww-pointer-events-none {\n pointer-events: none;\n}\n.ww-absolute {\n position: absolute;\n}\n.ww-relative {\n position: relative;\n}\n.ww-inset-0 {\n inset: 0px;\n}\n.ww-left-2\\.5 {\n left: 0.625rem;\n}\n.ww-top-1\\/2 {\n top: 50%;\n}\n.ww-z-50 {\n z-index: 50;\n}\n.ww-mb-1 {\n margin-bottom: 0.25rem;\n}\n.ww-mb-2 {\n margin-bottom: 0.5rem;\n}\n.ww-ml-0\\.5 {\n margin-left: 0.125rem;\n}\n.ww-mt-0\\.5 {\n margin-top: 0.125rem;\n}\n.ww-mt-1 {\n margin-top: 0.25rem;\n}\n.ww-block {\n display: block;\n}\n.ww-inline-block {\n display: inline-block;\n}\n.ww-flex {\n display: flex;\n}\n.ww-inline-flex {\n display: inline-flex;\n}\n.ww-grid {\n display: grid;\n}\n.ww-hidden {\n display: none;\n}\n.ww-h-10 {\n height: 2.5rem;\n}\n.ww-h-2 {\n height: 0.5rem;\n}\n.ww-h-2\\.5 {\n height: 0.625rem;\n}\n.ww-h-20 {\n height: 5rem;\n}\n.ww-h-3 {\n height: 0.75rem;\n}\n.ww-h-3\\.5 {\n height: 0.875rem;\n}\n.ww-h-4 {\n height: 1rem;\n}\n.ww-h-6 {\n height: 1.5rem;\n}\n.ww-h-7 {\n height: 1.75rem;\n}\n.ww-h-8 {\n height: 2rem;\n}\n.ww-h-full {\n height: 100%;\n}\n.ww-max-h-32 {\n max-height: 8rem;\n}\n.ww-max-h-48 {\n max-height: 12rem;\n}\n.ww-max-h-\\[168px\\] {\n max-height: 168px;\n}\n.ww-max-h-\\[180px\\] {\n max-height: 180px;\n}\n.ww-w-0\\.5 {\n width: 0.125rem;\n}\n.ww-w-10 {\n width: 2.5rem;\n}\n.ww-w-2 {\n width: 0.5rem;\n}\n.ww-w-2\\.5 {\n width: 0.625rem;\n}\n.ww-w-20 {\n width: 5rem;\n}\n.ww-w-3 {\n width: 0.75rem;\n}\n.ww-w-3\\.5 {\n width: 0.875rem;\n}\n.ww-w-4 {\n width: 1rem;\n}\n.ww-w-6 {\n width: 1.5rem;\n}\n.ww-w-7 {\n width: 1.75rem;\n}\n.ww-w-8 {\n width: 2rem;\n}\n.ww-w-fit {\n width: -moz-fit-content;\n width: fit-content;\n}\n.ww-w-full {\n width: 100%;\n}\n.ww-min-w-0 {\n min-width: 0px;\n}\n.ww-max-w-\\[120px\\] {\n max-width: 120px;\n}\n.ww-max-w-\\[200px\\] {\n max-width: 200px;\n}\n.ww-max-w-\\[78\\%\\] {\n max-width: 78%;\n}\n.ww-max-w-\\[82\\%\\] {\n max-width: 82%;\n}\n.ww-max-w-none {\n max-width: none;\n}\n.ww-flex-1 {\n flex: 1 1 0%;\n}\n.ww-shrink-0 {\n flex-shrink: 0;\n}\n.ww-rotate-180 {\n --tw-rotate: 180deg;\n transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));\n}\n@keyframes ww-ping {\n 75%, 100% {\n transform: scale(2);\n opacity: 0;\n }\n}\n.ww-animate-ping {\n animation: ww-ping 1s cubic-bezier(0, 0, 0.2, 1) infinite;\n}\n@keyframes ww-pulse {\n 50% {\n opacity: .5;\n }\n}\n.ww-animate-pulse {\n animation: ww-pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;\n}\n@keyframes ww-spin {\n to {\n transform: rotate(360deg);\n }\n}\n.ww-animate-spin {\n animation: ww-spin 1s linear infinite;\n}\n.ww-cursor-default {\n cursor: default;\n}\n.ww-cursor-pointer {\n cursor: pointer;\n}\n.ww-select-none {\n -webkit-user-select: none;\n -moz-user-select: none;\n user-select: none;\n}\n.ww-resize-none {\n resize: none;\n}\n.ww-grid-cols-2 {\n grid-template-columns: repeat(2, minmax(0, 1fr));\n}\n.ww-flex-col {\n flex-direction: column;\n}\n.ww-flex-wrap {\n flex-wrap: wrap;\n}\n.ww-items-start {\n align-items: flex-start;\n}\n.ww-items-end {\n align-items: flex-end;\n}\n.ww-items-center {\n align-items: center;\n}\n.ww-justify-end {\n justify-content: flex-end;\n}\n.ww-justify-center {\n justify-content: center;\n}\n.ww-justify-between {\n justify-content: space-between;\n}\n.ww-gap-0\\.5 {\n gap: 0.125rem;\n}\n.ww-gap-1 {\n gap: 0.25rem;\n}\n.ww-gap-1\\.5 {\n gap: 0.375rem;\n}\n.ww-gap-2 {\n gap: 0.5rem;\n}\n.ww-gap-2\\.5 {\n gap: 0.625rem;\n}\n.ww-gap-4 {\n gap: 1rem;\n}\n.ww-divide-y > :not([hidden]) ~ :not([hidden]) {\n --tw-divide-y-reverse: 0;\n border-top-width: calc(1px * calc(1 - var(--tw-divide-y-reverse)));\n border-bottom-width: calc(1px * var(--tw-divide-y-reverse));\n}\n.ww-divide-border\\/40 > :not([hidden]) ~ :not([hidden]) {\n border-color: hsl(var(--border) / 0.4);\n}\n.ww-overflow-hidden {\n overflow: hidden;\n}\n.ww-overflow-y-auto {\n overflow-y: auto;\n}\n.ww-overscroll-contain {\n overscroll-behavior: contain;\n}\n.ww-truncate {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.ww-whitespace-pre-wrap {\n white-space: pre-wrap;\n}\n.ww-rounded {\n border-radius: 0.25rem;\n}\n.ww-rounded-2xl {\n border-radius: 1rem;\n}\n.ww-rounded-full {\n border-radius: 9999px;\n}\n.ww-rounded-lg {\n border-radius: var(--radius);\n}\n.ww-rounded-xl {\n border-radius: 0.75rem;\n}\n.ww-rounded-tl-none {\n border-top-left-radius: 0px;\n}\n.ww-rounded-tl-sm {\n border-top-left-radius: calc(var(--radius) - 4px);\n}\n.ww-rounded-tr-sm {\n border-top-right-radius: calc(var(--radius) - 4px);\n}\n.ww-border {\n border-width: 1px;\n}\n.ww-border-2 {\n border-width: 2px;\n}\n.ww-border-b {\n border-bottom-width: 1px;\n}\n.ww-border-l-2 {\n border-left-width: 2px;\n}\n.ww-border-t {\n border-top-width: 1px;\n}\n.ww-border-background {\n border-color: hsl(var(--background));\n}\n.ww-border-black\\/10 {\n border-color: rgb(0 0 0 / 0.1);\n}\n.ww-border-border {\n border-color: hsl(var(--border));\n}\n.ww-border-border\\/30 {\n border-color: hsl(var(--border) / 0.3);\n}\n.ww-border-border\\/40 {\n border-color: hsl(var(--border) / 0.4);\n}\n.ww-border-border\\/50 {\n border-color: hsl(var(--border) / 0.5);\n}\n.ww-border-border\\/60 {\n border-color: hsl(var(--border) / 0.6);\n}\n.ww-border-border\\/70 {\n border-color: hsl(var(--border) / 0.7);\n}\n.ww-border-muted {\n border-color: hsl(var(--muted));\n}\n.ww-border-muted-foreground\\/30 {\n border-color: hsl(var(--muted-foreground) / 0.3);\n}\n.ww-border-red-200 {\n --tw-border-opacity: 1;\n border-color: rgb(254 202 202 / var(--tw-border-opacity, 1));\n}\n.ww-border-white\\/20 {\n border-color: rgb(255 255 255 / 0.2);\n}\n.ww-bg-background {\n background-color: hsl(var(--background));\n}\n.ww-bg-background\\/20 {\n background-color: hsl(var(--background) / 0.2);\n}\n.ww-bg-background\\/40 {\n background-color: hsl(var(--background) / 0.4);\n}\n.ww-bg-background\\/50 {\n background-color: hsl(var(--background) / 0.5);\n}\n.ww-bg-background\\/90 {\n background-color: hsl(var(--background) / 0.9);\n}\n.ww-bg-black\\/10 {\n background-color: rgb(0 0 0 / 0.1);\n}\n.ww-bg-emerald-400 {\n --tw-bg-opacity: 1;\n background-color: rgb(52 211 153 / var(--tw-bg-opacity, 1));\n}\n.ww-bg-emerald-500 {\n --tw-bg-opacity: 1;\n background-color: rgb(16 185 129 / var(--tw-bg-opacity, 1));\n}\n.ww-bg-foreground {\n background-color: hsl(var(--foreground));\n}\n.ww-bg-foreground\\/60 {\n background-color: hsl(var(--foreground) / 0.6);\n}\n.ww-bg-muted {\n background-color: hsl(var(--muted));\n}\n.ww-bg-muted-foreground\\/10 {\n background-color: hsl(var(--muted-foreground) / 0.1);\n}\n.ww-bg-muted\\/50 {\n background-color: hsl(var(--muted) / 0.5);\n}\n.ww-bg-muted\\/60 {\n background-color: hsl(var(--muted) / 0.6);\n}\n.ww-bg-primary {\n background-color: hsl(var(--primary));\n}\n.ww-bg-primary\\/5 {\n background-color: hsl(var(--primary) / 0.05);\n}\n.ww-bg-red-50 {\n --tw-bg-opacity: 1;\n background-color: rgb(254 242 242 / var(--tw-bg-opacity, 1));\n}\n.ww-bg-transparent {\n background-color: transparent;\n}\n.ww-bg-white\\/10 {\n background-color: rgb(255 255 255 / 0.1);\n}\n.ww-bg-white\\/15 {\n background-color: rgb(255 255 255 / 0.15);\n}\n.ww-fill-current {\n fill: currentColor;\n}\n.ww-object-cover {\n -o-object-fit: cover;\n object-fit: cover;\n}\n.ww-p-0\\.5 {\n padding: 0.125rem;\n}\n.ww-p-1\\.5 {\n padding: 0.375rem;\n}\n.ww-p-3 {\n padding: 0.75rem;\n}\n.ww-px-1 {\n padding-left: 0.25rem;\n padding-right: 0.25rem;\n}\n.ww-px-2 {\n padding-left: 0.5rem;\n padding-right: 0.5rem;\n}\n.ww-px-2\\.5 {\n padding-left: 0.625rem;\n padding-right: 0.625rem;\n}\n.ww-px-3 {\n padding-left: 0.75rem;\n padding-right: 0.75rem;\n}\n.ww-px-3\\.5 {\n padding-left: 0.875rem;\n padding-right: 0.875rem;\n}\n.ww-px-4 {\n padding-left: 1rem;\n padding-right: 1rem;\n}\n.ww-py-0\\.5 {\n padding-top: 0.125rem;\n padding-bottom: 0.125rem;\n}\n.ww-py-1 {\n padding-top: 0.25rem;\n padding-bottom: 0.25rem;\n}\n.ww-py-1\\.5 {\n padding-top: 0.375rem;\n padding-bottom: 0.375rem;\n}\n.ww-py-2 {\n padding-top: 0.5rem;\n padding-bottom: 0.5rem;\n}\n.ww-py-2\\.5 {\n padding-top: 0.625rem;\n padding-bottom: 0.625rem;\n}\n.ww-py-3 {\n padding-top: 0.75rem;\n padding-bottom: 0.75rem;\n}\n.ww-py-4 {\n padding-top: 1rem;\n padding-bottom: 1rem;\n}\n.ww-pb-1\\.5 {\n padding-bottom: 0.375rem;\n}\n.ww-pb-2 {\n padding-bottom: 0.5rem;\n}\n.ww-pb-4 {\n padding-bottom: 1rem;\n}\n.ww-pl-2 {\n padding-left: 0.5rem;\n}\n.ww-pl-7 {\n padding-left: 1.75rem;\n}\n.ww-pr-0\\.5 {\n padding-right: 0.125rem;\n}\n.ww-pr-3 {\n padding-right: 0.75rem;\n}\n.ww-pt-2 {\n padding-top: 0.5rem;\n}\n.ww-pt-5 {\n padding-top: 1.25rem;\n}\n.ww-text-left {\n text-align: left;\n}\n.ww-text-center {\n text-align: center;\n}\n.ww-align-middle {\n vertical-align: middle;\n}\n.ww-text-\\[10\\.5px\\] {\n font-size: 10.5px;\n}\n.ww-text-\\[10px\\] {\n font-size: 10px;\n}\n.ww-text-\\[11px\\] {\n font-size: 11px;\n}\n.ww-text-\\[12\\.5px\\] {\n font-size: 12.5px;\n}\n.ww-text-\\[12px\\] {\n font-size: 12px;\n}\n.ww-text-\\[8px\\] {\n font-size: 8px;\n}\n.ww-text-sm {\n font-size: 0.875rem;\n line-height: 1.25rem;\n}\n.ww-text-xs {\n font-size: 0.75rem;\n line-height: 1rem;\n}\n.ww-font-medium {\n font-weight: 500;\n}\n.ww-font-semibold {\n font-weight: 600;\n}\n.ww-uppercase {\n text-transform: uppercase;\n}\n.ww-leading-none {\n line-height: 1;\n}\n.ww-leading-relaxed {\n line-height: 1.625;\n}\n.ww-leading-snug {\n line-height: 1.375;\n}\n.ww-leading-tight {\n line-height: 1.25;\n}\n.ww-tracking-widest {\n letter-spacing: 0.1em;\n}\n.ww-text-background {\n color: hsl(var(--background));\n}\n.ww-text-black\\/40 {\n color: rgb(0 0 0 / 0.4);\n}\n.ww-text-black\\/60 {\n color: rgb(0 0 0 / 0.6);\n}\n.ww-text-destructive {\n color: hsl(var(--destructive));\n}\n.ww-text-destructive\\/70 {\n color: hsl(var(--destructive) / 0.7);\n}\n.ww-text-emerald-500 {\n --tw-text-opacity: 1;\n color: rgb(16 185 129 / var(--tw-text-opacity, 1));\n}\n.ww-text-foreground {\n color: hsl(var(--foreground));\n}\n.ww-text-foreground\\/60 {\n color: hsl(var(--foreground) / 0.6);\n}\n.ww-text-foreground\\/70 {\n color: hsl(var(--foreground) / 0.7);\n}\n.ww-text-foreground\\/80 {\n color: hsl(var(--foreground) / 0.8);\n}\n.ww-text-muted-foreground {\n color: hsl(var(--muted-foreground));\n}\n.ww-text-muted-foreground\\/40 {\n color: hsl(var(--muted-foreground) / 0.4);\n}\n.ww-text-muted-foreground\\/50 {\n color: hsl(var(--muted-foreground) / 0.5);\n}\n.ww-text-muted-foreground\\/70 {\n color: hsl(var(--muted-foreground) / 0.7);\n}\n.ww-text-muted-foreground\\/80 {\n color: hsl(var(--muted-foreground) / 0.8);\n}\n.ww-text-primary {\n color: hsl(var(--primary));\n}\n.ww-text-primary-foreground {\n color: hsl(var(--primary-foreground));\n}\n.ww-text-primary\\/70 {\n color: hsl(var(--primary) / 0.7);\n}\n.ww-text-primary\\/80 {\n color: hsl(var(--primary) / 0.8);\n}\n.ww-text-red-400 {\n --tw-text-opacity: 1;\n color: rgb(248 113 113 / var(--tw-text-opacity, 1));\n}\n.ww-text-red-500 {\n --tw-text-opacity: 1;\n color: rgb(239 68 68 / var(--tw-text-opacity, 1));\n}\n.ww-text-red-600 {\n --tw-text-opacity: 1;\n color: rgb(220 38 38 / var(--tw-text-opacity, 1));\n}\n.ww-text-white\\/60 {\n color: rgb(255 255 255 / 0.6);\n}\n.ww-text-white\\/80 {\n color: rgb(255 255 255 / 0.8);\n}\n.ww-line-through {\n text-decoration-line: line-through;\n}\n.ww-no-underline {\n text-decoration-line: none;\n}\n.ww-decoration-foreground\\/20 {\n text-decoration-color: hsl(var(--foreground) / 0.2);\n}\n.ww-opacity-100 {\n opacity: 1;\n}\n.ww-opacity-25 {\n opacity: 0.25;\n}\n.ww-opacity-30 {\n opacity: 0.3;\n}\n.ww-opacity-35 {\n opacity: 0.35;\n}\n.ww-opacity-40 {\n opacity: 0.4;\n}\n.ww-opacity-60 {\n opacity: 0.6;\n}\n.ww-opacity-70 {\n opacity: 0.7;\n}\n.ww-opacity-75 {\n opacity: 0.75;\n}\n.ww-opacity-80 {\n opacity: 0.8;\n}\n.ww-shadow-2xl {\n --tw-shadow: 0 25px 50px -12px rgb(0 0 0 / 0.25);\n --tw-shadow-colored: 0 25px 50px -12px var(--tw-shadow-color);\n box-shadow:\n var(--tw-ring-offset-shadow, 0 0 #0000),\n var(--tw-ring-shadow, 0 0 #0000),\n var(--tw-shadow);\n}\n.ww-shadow-sm {\n --tw-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05);\n --tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);\n box-shadow:\n var(--tw-ring-offset-shadow, 0 0 #0000),\n var(--tw-ring-shadow, 0 0 #0000),\n var(--tw-shadow);\n}\n.ww-shadow-xl {\n --tw-shadow: 0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1);\n --tw-shadow-colored: 0 20px 25px -5px var(--tw-shadow-color), 0 8px 10px -6px var(--tw-shadow-color);\n box-shadow:\n var(--tw-ring-offset-shadow, 0 0 #0000),\n var(--tw-ring-shadow, 0 0 #0000),\n var(--tw-shadow);\n}\n.ww-outline-none {\n outline: 2px solid transparent;\n outline-offset: 2px;\n}\n.ww-ring-2 {\n --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);\n --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);\n box-shadow:\n var(--tw-ring-offset-shadow),\n var(--tw-ring-shadow),\n var(--tw-shadow, 0 0 #0000);\n}\n.ww-ring-inset {\n --tw-ring-inset: inset;\n}\n.ww-ring-primary\\/60 {\n --tw-ring-color: hsl(var(--primary) / 0.6);\n}\n.ww-backdrop-blur-sm {\n --tw-backdrop-blur: blur(4px);\n backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);\n}\n.ww-transition-all {\n transition-property: all;\n transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);\n transition-duration: 150ms;\n}\n.ww-transition-colors {\n transition-property:\n color,\n background-color,\n border-color,\n text-decoration-color,\n fill,\n stroke;\n transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);\n transition-duration: 150ms;\n}\n.ww-transition-opacity {\n transition-property: opacity;\n transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);\n transition-duration: 150ms;\n}\n.ww-transition-shadow {\n transition-property: box-shadow;\n transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);\n transition-duration: 150ms;\n}\n.ww-transition-transform {\n transition-property: transform;\n transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);\n transition-duration: 150ms;\n}\n.ww-duration-100 {\n transition-duration: 100ms;\n}\n.ww-duration-150 {\n transition-duration: 150ms;\n}\n.ww-duration-200 {\n transition-duration: 200ms;\n}\n@keyframes enter {\n from {\n opacity: var(--tw-enter-opacity, 1);\n transform: translate3d(var(--tw-enter-translate-x, 0), var(--tw-enter-translate-y, 0), 0) scale3d(var(--tw-enter-scale, 1), var(--tw-enter-scale, 1), var(--tw-enter-scale, 1)) rotate(var(--tw-enter-rotate, 0));\n }\n}\n@keyframes exit {\n to {\n opacity: var(--tw-exit-opacity, 1);\n transform: translate3d(var(--tw-exit-translate-x, 0), var(--tw-exit-translate-y, 0), 0) scale3d(var(--tw-exit-scale, 1), var(--tw-exit-scale, 1), var(--tw-exit-scale, 1)) rotate(var(--tw-exit-rotate, 0));\n }\n}\n.ww-duration-100 {\n animation-duration: 100ms;\n}\n.ww-duration-150 {\n animation-duration: 150ms;\n}\n.ww-duration-200 {\n animation-duration: 200ms;\n}\n.wallavi-widget *,\n.wallavi-widget *::before,\n.wallavi-widget *::after {\n box-sizing: border-box;\n border-width: 0;\n border-style: solid;\n}\n.wallavi-widget button {\n -moz-appearance: none;\n appearance: none;\n -webkit-appearance: none;\n background: transparent;\n border: none;\n cursor: pointer;\n}\n.wallavi-widget textarea,\n.wallavi-widget input,\n.wallavi-widget select {\n font-family: inherit;\n font-size: inherit;\n}\n.wallavi-widget img,\n.wallavi-widget video {\n max-width: 100%;\n height: auto;\n}\n.placeholder\\:ww-text-muted-foreground\\/40::-moz-placeholder {\n color: hsl(var(--muted-foreground) / 0.4);\n}\n.placeholder\\:ww-text-muted-foreground\\/40::placeholder {\n color: hsl(var(--muted-foreground) / 0.4);\n}\n.placeholder\\:ww-text-muted-foreground\\/50::-moz-placeholder {\n color: hsl(var(--muted-foreground) / 0.5);\n}\n.placeholder\\:ww-text-muted-foreground\\/50::placeholder {\n color: hsl(var(--muted-foreground) / 0.5);\n}\n.focus-within\\:ww-ring-1:focus-within {\n --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);\n --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);\n box-shadow:\n var(--tw-ring-offset-shadow),\n var(--tw-ring-shadow),\n var(--tw-shadow, 0 0 #0000);\n}\n.focus-within\\:ww-ring-ring\\/40:focus-within {\n --tw-ring-color: hsl(var(--ring) / 0.4);\n}\n.hover\\:ww-border-foreground\\/25:hover {\n border-color: hsl(var(--foreground) / 0.25);\n}\n.hover\\:ww-border-foreground\\/30:hover {\n border-color: hsl(var(--foreground) / 0.3);\n}\n.hover\\:ww-bg-background:hover {\n background-color: hsl(var(--background));\n}\n.hover\\:ww-bg-foreground\\/10:hover {\n background-color: hsl(var(--foreground) / 0.1);\n}\n.hover\\:ww-bg-muted:hover {\n background-color: hsl(var(--muted));\n}\n.hover\\:ww-bg-white\\/10:hover {\n background-color: rgb(255 255 255 / 0.1);\n}\n.hover\\:ww-text-foreground:hover {\n color: hsl(var(--foreground));\n}\n.hover\\:ww-opacity-80:hover {\n opacity: 0.8;\n}\n.hover\\:ww-opacity-85:hover {\n opacity: 0.85;\n}\n.focus\\:ww-ring-1:focus {\n --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);\n --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);\n box-shadow:\n var(--tw-ring-offset-shadow),\n var(--tw-ring-shadow),\n var(--tw-shadow, 0 0 #0000);\n}\n.focus\\:ww-ring-ring\\/40:focus {\n --tw-ring-color: hsl(var(--ring) / 0.4);\n}\n.active\\:ww-scale-\\[0\\.98\\]:active {\n --tw-scale-x: 0.98;\n --tw-scale-y: 0.98;\n transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));\n}\n.disabled\\:ww-pointer-events-none:disabled {\n pointer-events: none;\n}\n.disabled\\:ww-opacity-40:disabled {\n opacity: 0.4;\n}\n.disabled\\:ww-opacity-50:disabled {\n opacity: 0.5;\n}\n.dark\\:ww-border-red-800:is(.ww-dark *) {\n --tw-border-opacity: 1;\n border-color: rgb(153 27 27 / var(--tw-border-opacity, 1));\n}\n.dark\\:ww-bg-red-950:is(.ww-dark *) {\n --tw-bg-opacity: 1;\n background-color: rgb(69 10 10 / var(--tw-bg-opacity, 1));\n}\n.dark\\:ww-text-red-400:is(.ww-dark *) {\n --tw-text-opacity: 1;\n color: rgb(248 113 113 / var(--tw-text-opacity, 1));\n}\n");
|
|
34
34
|
var twMerge = extendTailwindMerge({ prefix: "ww-" });
|
|
35
35
|
var cn = (...inputs) => twMerge(clsx(inputs));
|
|
36
36
|
|
|
@@ -79,7 +79,8 @@ function useChat({
|
|
|
79
79
|
userContext,
|
|
80
80
|
persist = false,
|
|
81
81
|
onNavigate,
|
|
82
|
-
playgroundOverrides
|
|
82
|
+
playgroundOverrides,
|
|
83
|
+
customBackend
|
|
83
84
|
}) {
|
|
84
85
|
const persistKey = persist ? `wallavi_${agentId}` : null;
|
|
85
86
|
const onNavigateRef = useRef(onNavigate);
|
|
@@ -99,26 +100,47 @@ function useChat({
|
|
|
99
100
|
const [streaming, setStreaming] = useState(false);
|
|
100
101
|
const [threadId, setThreadId] = useState(() => {
|
|
101
102
|
if (persistKey && typeof window !== "undefined") {
|
|
102
|
-
const saved =
|
|
103
|
+
const saved = localStorage.getItem(`${persistKey}_tid`);
|
|
103
104
|
if (saved) return saved;
|
|
104
105
|
}
|
|
105
106
|
return crypto.randomUUID();
|
|
106
107
|
});
|
|
107
108
|
const streamingMsgIdRef = useRef(null);
|
|
108
109
|
useEffect(() => {
|
|
109
|
-
if (!persistKey) return;
|
|
110
|
+
if (customBackend || !persistKey) return;
|
|
110
111
|
try {
|
|
111
112
|
sessionStorage.setItem(`${persistKey}_msgs`, JSON.stringify(messages));
|
|
112
113
|
} catch {
|
|
113
114
|
}
|
|
114
|
-
}, [persistKey, messages]);
|
|
115
|
+
}, [customBackend, persistKey, messages]);
|
|
115
116
|
useEffect(() => {
|
|
116
|
-
if (!persistKey) return;
|
|
117
|
+
if (customBackend || !persistKey) return;
|
|
117
118
|
try {
|
|
118
|
-
|
|
119
|
+
localStorage.setItem(`${persistKey}_tid`, threadId);
|
|
119
120
|
} catch {
|
|
120
121
|
}
|
|
121
|
-
}, [persistKey, threadId]);
|
|
122
|
+
}, [customBackend, persistKey, threadId]);
|
|
123
|
+
useEffect(() => {
|
|
124
|
+
if (customBackend || !persistKey || typeof window === "undefined") return;
|
|
125
|
+
if (messages.length > 0) return;
|
|
126
|
+
void (async () => {
|
|
127
|
+
try {
|
|
128
|
+
const res = await fetch(
|
|
129
|
+
`${API_URL}/api/chat/messages?agentId=${encodeURIComponent(agentId)}&threadId=${encodeURIComponent(threadId)}`
|
|
130
|
+
);
|
|
131
|
+
if (!res.ok) return;
|
|
132
|
+
const { data } = await res.json();
|
|
133
|
+
if (!data?.length) return;
|
|
134
|
+
const restored = data.map((m) => ({
|
|
135
|
+
id: m.id,
|
|
136
|
+
role: m.role,
|
|
137
|
+
parts: m.parts.filter((p) => p?.type)
|
|
138
|
+
})).filter((m) => m.parts.length > 0);
|
|
139
|
+
if (restored.length > 0) setMessages(restored);
|
|
140
|
+
} catch {
|
|
141
|
+
}
|
|
142
|
+
})();
|
|
143
|
+
}, []);
|
|
122
144
|
const reset = useCallback(() => {
|
|
123
145
|
setMessages([]);
|
|
124
146
|
setInput("");
|
|
@@ -129,6 +151,7 @@ function useChat({
|
|
|
129
151
|
try {
|
|
130
152
|
sessionStorage.removeItem(`${persistKey}_msgs`);
|
|
131
153
|
sessionStorage.removeItem(`${persistKey}_tid`);
|
|
154
|
+
localStorage.removeItem(`${persistKey}_tid`);
|
|
132
155
|
} catch {
|
|
133
156
|
}
|
|
134
157
|
}
|
|
@@ -273,6 +296,15 @@ function useChat({
|
|
|
273
296
|
const pendingAttachmentsRef = useRef([]);
|
|
274
297
|
const send = useCallback(
|
|
275
298
|
async (text) => {
|
|
299
|
+
if (customBackend) {
|
|
300
|
+
const content = (text ?? input).trim();
|
|
301
|
+
const attachments2 = pendingAttachmentsRef.current.length > 0 ? [...pendingAttachmentsRef.current] : void 0;
|
|
302
|
+
pendingAttachmentsRef.current = [];
|
|
303
|
+
if (!content && !attachments2?.length || customBackend.streaming) return;
|
|
304
|
+
setInput("");
|
|
305
|
+
await customBackend.send(content, attachments2);
|
|
306
|
+
return;
|
|
307
|
+
}
|
|
276
308
|
const userInput = (text ?? input).trim();
|
|
277
309
|
if (!userInput || streaming) return;
|
|
278
310
|
setInput("");
|
|
@@ -361,7 +393,18 @@ function useChat({
|
|
|
361
393
|
});
|
|
362
394
|
await send(lastText);
|
|
363
395
|
}, [streaming, messages, send]);
|
|
364
|
-
return {
|
|
396
|
+
return {
|
|
397
|
+
messages: customBackend ? customBackend.messages : messages,
|
|
398
|
+
streaming: customBackend ? customBackend.streaming : streaming,
|
|
399
|
+
input,
|
|
400
|
+
setInput,
|
|
401
|
+
threadId,
|
|
402
|
+
send,
|
|
403
|
+
queueAttachments,
|
|
404
|
+
regenerate,
|
|
405
|
+
reset: customBackend?.reset ?? reset,
|
|
406
|
+
selectPickerOption
|
|
407
|
+
};
|
|
365
408
|
}
|
|
366
409
|
function getPreferredMimeType() {
|
|
367
410
|
if (typeof MediaRecorder === "undefined") return "";
|
|
@@ -745,11 +788,12 @@ function PlanStepIcon({ status }) {
|
|
|
745
788
|
if (status === "failed") return /* @__PURE__ */ jsx(AlertCircle, { className: "ww-h-3 ww-w-3 ww-text-destructive" });
|
|
746
789
|
return /* @__PURE__ */ jsx("div", { className: "ww-h-3 ww-w-3 ww-rounded-full ww-border-2 ww-border-muted-foreground/30" });
|
|
747
790
|
}
|
|
748
|
-
function PlanCard({ part }) {
|
|
791
|
+
function PlanCard({ part, onSend, disabled }) {
|
|
749
792
|
const successCount = part.steps.filter((s) => s.status === "success").length;
|
|
750
793
|
const hasExecuting = part.steps.some((s) => s.status === "executing");
|
|
751
794
|
const allDone = successCount === part.steps.length && part.steps.length > 0;
|
|
752
795
|
const anyFailed = part.steps.some((s) => s.status === "failed");
|
|
796
|
+
const allPending = part.steps.length > 0 && part.steps.every((s) => s.status === "pending");
|
|
753
797
|
return /* @__PURE__ */ jsxs("div", { className: "ww-rounded-xl ww-border ww-bg-background ww-overflow-hidden ww-text-xs ww-w-full ww-shadow-sm", children: [
|
|
754
798
|
/* @__PURE__ */ jsxs("div", { className: "ww-flex ww-items-center ww-gap-2 ww-px-3 ww-py-2 ww-bg-muted/50 ww-border-b", children: [
|
|
755
799
|
hasExecuting ? /* @__PURE__ */ jsx(Loader2, { className: "ww-h-3.5 ww-w-3.5 ww-shrink-0 ww-animate-spin ww-text-primary/80" }) : allDone ? /* @__PURE__ */ jsx(CheckCircle2, { className: "ww-h-3.5 ww-w-3.5 ww-shrink-0 ww-text-emerald-500" }) : anyFailed ? /* @__PURE__ */ jsx(AlertCircle, { className: "ww-h-3.5 ww-w-3.5 ww-shrink-0 ww-text-destructive" }) : /* @__PURE__ */ jsx(Zap, { className: "ww-h-3.5 ww-w-3.5 ww-shrink-0 ww-text-primary/70" }),
|
|
@@ -790,7 +834,34 @@ function PlanCard({ part }) {
|
|
|
790
834
|
]
|
|
791
835
|
},
|
|
792
836
|
step.index
|
|
793
|
-
)) })
|
|
837
|
+
)) }),
|
|
838
|
+
allPending && onSend && /* @__PURE__ */ jsxs("div", { className: "ww-flex ww-gap-2 ww-px-3 ww-py-2.5 ww-border-t", children: [
|
|
839
|
+
/* @__PURE__ */ jsxs(
|
|
840
|
+
"button",
|
|
841
|
+
{
|
|
842
|
+
onClick: () => onSend("s\xED, proceder"),
|
|
843
|
+
disabled,
|
|
844
|
+
className: "ww-flex-1 ww-flex ww-items-center ww-justify-center ww-gap-1.5 ww-rounded-lg ww-py-1.5 ww-text-xs ww-font-semibold ww-transition-opacity hover:ww-opacity-85 active:ww-scale-[0.98] disabled:ww-opacity-50 disabled:ww-pointer-events-none",
|
|
845
|
+
style: { backgroundColor: "var(--primary, #18181b)", color: "var(--primary-foreground, #fff)" },
|
|
846
|
+
children: [
|
|
847
|
+
/* @__PURE__ */ jsx(Check, { className: "ww-h-3 ww-w-3 ww-shrink-0" }),
|
|
848
|
+
"Proceder"
|
|
849
|
+
]
|
|
850
|
+
}
|
|
851
|
+
),
|
|
852
|
+
/* @__PURE__ */ jsxs(
|
|
853
|
+
"button",
|
|
854
|
+
{
|
|
855
|
+
onClick: () => onSend("cancelar"),
|
|
856
|
+
disabled,
|
|
857
|
+
className: "ww-flex ww-items-center ww-justify-center ww-gap-1.5 ww-rounded-lg ww-px-3 ww-py-1.5 ww-text-xs ww-font-medium ww-bg-muted ww-text-muted-foreground ww-transition-opacity hover:ww-opacity-80 active:ww-scale-[0.98] disabled:ww-opacity-50 disabled:ww-pointer-events-none",
|
|
858
|
+
children: [
|
|
859
|
+
/* @__PURE__ */ jsx(X, { className: "ww-h-3 ww-w-3 ww-shrink-0" }),
|
|
860
|
+
"Cancelar"
|
|
861
|
+
]
|
|
862
|
+
}
|
|
863
|
+
)
|
|
864
|
+
] })
|
|
794
865
|
] });
|
|
795
866
|
}
|
|
796
867
|
function ThinkingDots() {
|
|
@@ -974,7 +1045,8 @@ function MessageBubble({
|
|
|
974
1045
|
profilePicture,
|
|
975
1046
|
isStreaming,
|
|
976
1047
|
showThinking = true,
|
|
977
|
-
onPickerSelect
|
|
1048
|
+
onPickerSelect,
|
|
1049
|
+
onSend
|
|
978
1050
|
}) {
|
|
979
1051
|
const isUser = message.role === "user";
|
|
980
1052
|
const textPart = message.parts.find((p) => p.type === "text");
|
|
@@ -997,12 +1069,12 @@ function MessageBubble({
|
|
|
997
1069
|
) });
|
|
998
1070
|
}
|
|
999
1071
|
const visibleToolParts = showThinking ? toolParts : [];
|
|
1000
|
-
const isEmpty = !textPart?.text && visibleToolParts.length === 0 && pickerParts.length === 0;
|
|
1072
|
+
const isEmpty = !textPart?.text && visibleToolParts.length === 0 && pickerParts.length === 0 && planParts.length === 0;
|
|
1001
1073
|
return /* @__PURE__ */ jsxs("div", { className: "ww-flex ww-gap-2.5 ww-items-start", children: [
|
|
1002
1074
|
/* @__PURE__ */ jsx(Avatar2, { style: { width: 28, height: 28, marginTop: 2, border: "1px solid rgba(0,0,0,0.08)" }, children: profilePicture ? /* @__PURE__ */ jsx(AvatarImage2, { src: profilePicture, alt: agentName }) : /* @__PURE__ */ jsx(AvatarFallback2, { style: { fontSize: 10, fontWeight: 600, backgroundColor: "var(--primary, #19191c)", color: "var(--primary-foreground, #fff)" }, children: agentName.slice(0, 2).toUpperCase() }) }),
|
|
1003
1075
|
/* @__PURE__ */ jsxs("div", { className: "ww-flex ww-flex-col ww-gap-1.5 ww-min-w-0 ww-max-w-[82%]", children: [
|
|
1004
1076
|
showThinking && reasoningPart && /* @__PURE__ */ jsx(ReasoningBlock, { text: reasoningPart.text }),
|
|
1005
|
-
planParts.map((p) => /* @__PURE__ */ jsx(PlanCard, { part: p }, p.planId)),
|
|
1077
|
+
planParts.map((p) => /* @__PURE__ */ jsx(PlanCard, { part: p, onSend, disabled: isStreaming }, p.planId)),
|
|
1006
1078
|
visibleToolParts.map((t) => /* @__PURE__ */ jsx(ToolCallBadge, { part: t }, t.toolCallId)),
|
|
1007
1079
|
pickerParts.map((p) => /* @__PURE__ */ jsx(
|
|
1008
1080
|
PickerSelector,
|
|
@@ -1065,7 +1137,7 @@ function ChatMessages({
|
|
|
1065
1137
|
const showGreeting = messages.length === 0;
|
|
1066
1138
|
useEffect(() => {
|
|
1067
1139
|
bottomRef.current?.scrollIntoView({ behavior: "smooth" });
|
|
1068
|
-
}, [messages]);
|
|
1140
|
+
}, [messages, streaming]);
|
|
1069
1141
|
return /* @__PURE__ */ jsxs("div", { className: "ww-flex-1 ww-flex ww-flex-col ww-overflow-y-auto ww-overscroll-contain", children: [
|
|
1070
1142
|
showGreeting && /* @__PURE__ */ jsxs("div", { className: "ww-flex ww-gap-2.5 ww-items-start ww-px-4 ww-pt-5", children: [
|
|
1071
1143
|
/* @__PURE__ */ jsx(Avatar3, { className: "ww-h-7 ww-w-7 ww-shrink-0 ww-mt-0.5 ww-border", children: profilePicture ? /* @__PURE__ */ jsx(AvatarImage3, { src: profilePicture, alt: agentName }) : /* @__PURE__ */ jsx(AvatarFallback3, { className: "ww-text-[10px] ww-font-semibold ww-bg-primary ww-text-primary-foreground", children: agentName.slice(0, 2).toUpperCase() }) }),
|
|
@@ -1081,10 +1153,41 @@ function ChatMessages({
|
|
|
1081
1153
|
profilePicture,
|
|
1082
1154
|
isStreaming: streaming && i === messages.length - 1 && msg.role === "assistant",
|
|
1083
1155
|
showThinking,
|
|
1084
|
-
onPickerSelect
|
|
1156
|
+
onPickerSelect,
|
|
1157
|
+
onSend: i === messages.length - 1 ? onSuggest : void 0
|
|
1085
1158
|
},
|
|
1086
1159
|
msg.id
|
|
1087
1160
|
)) }),
|
|
1161
|
+
streaming && messages.length > 0 && messages[messages.length - 1]?.role !== "assistant" && /* @__PURE__ */ jsxs("div", { className: "ww-flex ww-gap-2.5 ww-items-start ww-px-4 ww-pb-2", children: [
|
|
1162
|
+
/* @__PURE__ */ jsx(Avatar3, { className: "ww-h-7 ww-w-7 ww-shrink-0 ww-mt-0.5 ww-border", children: profilePicture ? /* @__PURE__ */ jsx(AvatarImage3, { src: profilePicture, alt: agentName }) : /* @__PURE__ */ jsx(AvatarFallback3, { className: "ww-text-[10px] ww-font-semibold ww-bg-primary ww-text-primary-foreground", children: agentName.slice(0, 2).toUpperCase() }) }),
|
|
1163
|
+
/* @__PURE__ */ jsx("style", { children: `
|
|
1164
|
+
@keyframes wDotBounce {
|
|
1165
|
+
0%, 80%, 100% { transform: translateY(0) scale(1); opacity: 0.35; }
|
|
1166
|
+
40% { transform: translateY(-6px) scale(1.15); opacity: 1; }
|
|
1167
|
+
}
|
|
1168
|
+
` }),
|
|
1169
|
+
/* @__PURE__ */ jsx(
|
|
1170
|
+
"div",
|
|
1171
|
+
{
|
|
1172
|
+
className: "ww-bg-muted",
|
|
1173
|
+
style: { display: "inline-flex", alignItems: "center", gap: 6, borderRadius: "18px 18px 18px 4px", padding: "13px 18px" },
|
|
1174
|
+
children: [0, 1, 2].map((i) => /* @__PURE__ */ jsx(
|
|
1175
|
+
"span",
|
|
1176
|
+
{
|
|
1177
|
+
style: {
|
|
1178
|
+
display: "block",
|
|
1179
|
+
width: 7,
|
|
1180
|
+
height: 7,
|
|
1181
|
+
borderRadius: "50%",
|
|
1182
|
+
backgroundColor: "currentColor",
|
|
1183
|
+
animation: `wDotBounce 1.2s cubic-bezier(0.4,0,0.2,1) ${i * 0.16}s infinite`
|
|
1184
|
+
}
|
|
1185
|
+
},
|
|
1186
|
+
i
|
|
1187
|
+
))
|
|
1188
|
+
}
|
|
1189
|
+
)
|
|
1190
|
+
] }),
|
|
1088
1191
|
showGreeting && suggestedMessages.length > 0 && /* @__PURE__ */ jsx("div", { className: "ww-flex ww-flex-wrap ww-gap-2 ww-px-4 ww-pb-4", children: suggestedMessages.map((msg, i) => /* @__PURE__ */ jsx(
|
|
1089
1192
|
"button",
|
|
1090
1193
|
{
|
|
@@ -1260,7 +1363,7 @@ function ChatWidget({
|
|
|
1260
1363
|
suggestedMessages = [],
|
|
1261
1364
|
messagePlaceholder,
|
|
1262
1365
|
watermark = true,
|
|
1263
|
-
watermarkLogoUrl = "https
|
|
1366
|
+
watermarkLogoUrl = "https://app.wallavi.com/wallavi.svg",
|
|
1264
1367
|
footer,
|
|
1265
1368
|
theme,
|
|
1266
1369
|
showThinking = false,
|
|
@@ -1274,13 +1377,15 @@ function ChatWidget({
|
|
|
1274
1377
|
enableVoice = false,
|
|
1275
1378
|
voiceAutoSend = false,
|
|
1276
1379
|
enableAttachments = false,
|
|
1380
|
+
customBackend,
|
|
1277
1381
|
className,
|
|
1278
1382
|
onClose,
|
|
1279
1383
|
onReset,
|
|
1280
1384
|
onExpand,
|
|
1281
|
-
expanded
|
|
1385
|
+
expanded,
|
|
1386
|
+
embedded = false
|
|
1282
1387
|
}) {
|
|
1283
|
-
const chat = useChat({ agentId, workspaceId, source, userContext, persist, onNavigate, playgroundOverrides });
|
|
1388
|
+
const chat = useChat({ agentId, workspaceId, source, userContext, persist, onNavigate, playgroundOverrides, customBackend });
|
|
1284
1389
|
const voice = useVoice({
|
|
1285
1390
|
agentId,
|
|
1286
1391
|
onTranscript: (text) => {
|
|
@@ -1333,6 +1438,7 @@ function ChatWidget({
|
|
|
1333
1438
|
};
|
|
1334
1439
|
const isDark = theme === "dark";
|
|
1335
1440
|
const cssVars = {
|
|
1441
|
+
fontFamily: 'ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif',
|
|
1336
1442
|
colorScheme: theme,
|
|
1337
1443
|
// Inline style has higher specificity than any host-site stylesheet,
|
|
1338
1444
|
// so background-color set here cannot be overridden by host CSS.
|
|
@@ -1355,7 +1461,8 @@ function ChatWidget({
|
|
|
1355
1461
|
"div",
|
|
1356
1462
|
{
|
|
1357
1463
|
className: cn(
|
|
1358
|
-
"wallavi-widget ww-flex ww-flex-col ww-overflow-hidden ww-
|
|
1464
|
+
"wallavi-widget ww-flex ww-flex-col ww-overflow-hidden ww-bg-background ww-h-full ww-relative",
|
|
1465
|
+
!embedded && "ww-rounded-2xl ww-border ww-shadow-xl",
|
|
1359
1466
|
isDragOver && "ww-ring-2 ww-ring-inset ww-ring-primary/60",
|
|
1360
1467
|
className
|
|
1361
1468
|
),
|
|
@@ -1383,6 +1490,20 @@ function ChatWidget({
|
|
|
1383
1490
|
expanded
|
|
1384
1491
|
}
|
|
1385
1492
|
),
|
|
1493
|
+
customBackend?.mode === "human" && /* @__PURE__ */ jsxs(
|
|
1494
|
+
"div",
|
|
1495
|
+
{
|
|
1496
|
+
className: "ww-shrink-0 ww-flex ww-items-center ww-gap-2 ww-px-4 ww-py-1.5 ww-border-b",
|
|
1497
|
+
style: { backgroundColor: `${userMessageColor}0d` },
|
|
1498
|
+
children: [
|
|
1499
|
+
/* @__PURE__ */ jsxs("span", { className: "ww-relative ww-flex ww-h-2 ww-w-2 ww-shrink-0", children: [
|
|
1500
|
+
/* @__PURE__ */ jsx("span", { className: "ww-animate-ping ww-absolute ww-inline-flex ww-h-full ww-w-full ww-rounded-full ww-bg-emerald-400 ww-opacity-75" }),
|
|
1501
|
+
/* @__PURE__ */ jsx("span", { className: "ww-relative ww-inline-flex ww-rounded-full ww-h-2 ww-w-2 ww-bg-emerald-500" })
|
|
1502
|
+
] }),
|
|
1503
|
+
/* @__PURE__ */ jsx("span", { className: "ww-text-xs ww-font-medium ww-text-foreground/60", children: "Hablando con un agente" })
|
|
1504
|
+
]
|
|
1505
|
+
}
|
|
1506
|
+
),
|
|
1386
1507
|
/* @__PURE__ */ jsx(
|
|
1387
1508
|
ChatMessages,
|
|
1388
1509
|
{
|
|
@@ -1398,6 +1519,30 @@ function ChatWidget({
|
|
|
1398
1519
|
onPickerSelect: chat.selectPickerOption
|
|
1399
1520
|
}
|
|
1400
1521
|
),
|
|
1522
|
+
customBackend?.footerAction && /* @__PURE__ */ jsx("div", { className: "ww-shrink-0 ww-px-3 ww-py-1.5 ww-border-t ww-bg-background", children: /* @__PURE__ */ jsxs(
|
|
1523
|
+
"button",
|
|
1524
|
+
{
|
|
1525
|
+
onClick: () => void customBackend.footerAction.onClick(),
|
|
1526
|
+
disabled: customBackend.footerAction.loading,
|
|
1527
|
+
style: customBackend.footerAction.icon === "human" ? { backgroundColor: userMessageColor, color: "#ffffff", boxShadow: `0 2px 12px ${userMessageColor}55` } : { borderColor: `${userMessageColor}35`, backgroundColor: `${userMessageColor}0d`, color: userMessageColor },
|
|
1528
|
+
className: [
|
|
1529
|
+
"ww-w-full ww-flex ww-items-center ww-gap-2 ww-rounded-full ww-px-3.5 ww-py-1.5 ww-text-xs ww-font-semibold ww-transition-all",
|
|
1530
|
+
"hover:ww-opacity-85 active:ww-scale-[0.98] disabled:ww-opacity-50 disabled:ww-pointer-events-none",
|
|
1531
|
+
customBackend.footerAction.icon === "human" ? "" : "ww-border"
|
|
1532
|
+
].join(" "),
|
|
1533
|
+
children: [
|
|
1534
|
+
customBackend.footerAction.loading ? /* @__PURE__ */ jsxs("svg", { className: "ww-animate-spin ww-w-3.5 ww-h-3.5 ww-shrink-0", viewBox: "0 0 24 24", fill: "none", children: [
|
|
1535
|
+
/* @__PURE__ */ jsx("circle", { className: "ww-opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "3" }),
|
|
1536
|
+
/* @__PURE__ */ jsx("path", { className: "ww-opacity-75", fill: "currentColor", d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z" })
|
|
1537
|
+
] }) : customBackend.footerAction.icon === "ai" ? /* @__PURE__ */ jsx("svg", { className: "ww-w-3.5 ww-h-3.5 ww-shrink-0", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsx("path", { d: "m12 3-1.912 5.813a2 2 0 0 1-1.275 1.275L3 12l5.813 1.912a2 2 0 0 1 1.275 1.275L12 21l1.912-5.813a2 2 0 0 1 1.275-1.275L21 12l-5.813-1.912a2 2 0 0 1-1.275-1.275L12 3Z" }) }) : /* @__PURE__ */ jsxs("svg", { className: "ww-w-3.5 ww-h-3.5 ww-shrink-0", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
1538
|
+
/* @__PURE__ */ jsx("path", { d: "M3 18v-6a9 9 0 0 1 18 0v6" }),
|
|
1539
|
+
/* @__PURE__ */ jsx("path", { d: "M21 19a2 2 0 0 1-2 2h-1a2 2 0 0 1-2-2v-3a2 2 0 0 1 2-2h3zM3 19a2 2 0 0 0 2 2h1a2 2 0 0 0 2-2v-3a2 2 0 0 0-2-2H3z" })
|
|
1540
|
+
] }),
|
|
1541
|
+
/* @__PURE__ */ jsx("span", { className: "ww-flex-1 ww-text-left ww-truncate", children: customBackend.footerAction.label }),
|
|
1542
|
+
/* @__PURE__ */ jsx("svg", { className: "ww-shrink-0 ww-w-3 ww-h-3 ww-opacity-60", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsx("path", { d: "M9 18l6-6-6-6" }) })
|
|
1543
|
+
]
|
|
1544
|
+
}
|
|
1545
|
+
) }),
|
|
1401
1546
|
/* @__PURE__ */ jsx(
|
|
1402
1547
|
ChatInput,
|
|
1403
1548
|
{
|
|
@@ -1426,7 +1571,7 @@ function ChatWidget({
|
|
|
1426
1571
|
/* @__PURE__ */ jsxs(
|
|
1427
1572
|
"a",
|
|
1428
1573
|
{
|
|
1429
|
-
href: "https
|
|
1574
|
+
href: "https://wallavi.com",
|
|
1430
1575
|
target: "_blank",
|
|
1431
1576
|
rel: "noopener noreferrer",
|
|
1432
1577
|
className: "ww-flex ww-items-center ww-gap-1 ww-text-[10px] ww-text-muted-foreground hover:ww-text-foreground ww-transition-colors",
|
|
@@ -1505,9 +1650,233 @@ function useAutoConfig(agentId, enabled) {
|
|
|
1505
1650
|
}, [agentId, enabled]);
|
|
1506
1651
|
return result;
|
|
1507
1652
|
}
|
|
1653
|
+
function toWidgetMsg(m) {
|
|
1654
|
+
return {
|
|
1655
|
+
id: m.id,
|
|
1656
|
+
role: m.role === "customer" ? "user" : "assistant",
|
|
1657
|
+
parts: [{ type: "text", text: m.content }],
|
|
1658
|
+
attachments: m.metadata?.attachments ?? void 0
|
|
1659
|
+
};
|
|
1660
|
+
}
|
|
1661
|
+
function useSupportChat({
|
|
1662
|
+
inboxToken,
|
|
1663
|
+
apiBase = "https://app.wallavi.com",
|
|
1664
|
+
requestHumanLabel = "Hablar con un agente",
|
|
1665
|
+
returnToAiLabel
|
|
1666
|
+
}) {
|
|
1667
|
+
const enabled = Boolean(inboxToken) && inboxToken !== "__disabled__";
|
|
1668
|
+
const STORAGE_KEY = `wlv_support_${inboxToken}`;
|
|
1669
|
+
const base = apiBase.replace(/\/$/, "");
|
|
1670
|
+
const [session, setSession] = useState(null);
|
|
1671
|
+
const [rawMessages, setRawMessages] = useState([]);
|
|
1672
|
+
const [sending, setSending] = useState(false);
|
|
1673
|
+
const [isAiMode, setIsAiMode] = useState(false);
|
|
1674
|
+
const [agentTyping, setAgentTyping] = useState(false);
|
|
1675
|
+
const [requestingHuman, setRequestingHuman] = useState(false);
|
|
1676
|
+
const [returningToAi, setReturningToAi] = useState(false);
|
|
1677
|
+
const typingTimerRef = useRef(null);
|
|
1678
|
+
useEffect(() => {
|
|
1679
|
+
if (!enabled) return;
|
|
1680
|
+
try {
|
|
1681
|
+
const saved = localStorage.getItem(STORAGE_KEY);
|
|
1682
|
+
if (saved) {
|
|
1683
|
+
const { session: s, isAiMode: ai } = JSON.parse(saved);
|
|
1684
|
+
setSession(s);
|
|
1685
|
+
setIsAiMode(ai ?? false);
|
|
1686
|
+
}
|
|
1687
|
+
} catch {
|
|
1688
|
+
localStorage.removeItem(STORAGE_KEY);
|
|
1689
|
+
}
|
|
1690
|
+
}, [STORAGE_KEY, enabled]);
|
|
1691
|
+
const loadMessages = useCallback(async (sess) => {
|
|
1692
|
+
try {
|
|
1693
|
+
const res = await fetch(`${base}/api/support-chat/${sess.conversationId}/messages`, {
|
|
1694
|
+
headers: { "x-visitor-token": sess.visitorToken }
|
|
1695
|
+
});
|
|
1696
|
+
const data = await res.json();
|
|
1697
|
+
if (Array.isArray(data.data)) setRawMessages(data.data);
|
|
1698
|
+
} catch {
|
|
1699
|
+
}
|
|
1700
|
+
}, [base]);
|
|
1701
|
+
useEffect(() => {
|
|
1702
|
+
if (!enabled || !session) return;
|
|
1703
|
+
void loadMessages(session);
|
|
1704
|
+
let ablyClient = null;
|
|
1705
|
+
const setupAbly = async () => {
|
|
1706
|
+
try {
|
|
1707
|
+
const res = await fetch(`${base}/api/support-chat/${session.conversationId}/ably-token`, {
|
|
1708
|
+
headers: { "x-visitor-token": session.visitorToken }
|
|
1709
|
+
});
|
|
1710
|
+
if (!res.ok) return;
|
|
1711
|
+
const { tokenRequest, channel: channelName } = await res.json();
|
|
1712
|
+
const AblyLib = (await import('ably')).default;
|
|
1713
|
+
ablyClient = new AblyLib.Realtime({ authCallback: (_, cb) => cb(null, tokenRequest) });
|
|
1714
|
+
const ch = ablyClient.channels.get(channelName);
|
|
1715
|
+
ch.subscribe((msg) => {
|
|
1716
|
+
const event = { type: msg.name, ...msg.data };
|
|
1717
|
+
if (event.type === "message.created" && event.message) {
|
|
1718
|
+
setRawMessages((prev) => {
|
|
1719
|
+
if (prev.some((m) => m.id === event.message.id)) return prev;
|
|
1720
|
+
return [...prev.filter((m) => !m.id.startsWith("tmp_")), event.message];
|
|
1721
|
+
});
|
|
1722
|
+
} else if (event.type === "agent.typing") {
|
|
1723
|
+
setAgentTyping(!!event.isTyping);
|
|
1724
|
+
if (event.isTyping) {
|
|
1725
|
+
if (typingTimerRef.current) clearTimeout(typingTimerRef.current);
|
|
1726
|
+
typingTimerRef.current = setTimeout(() => setAgentTyping(false), 6e3);
|
|
1727
|
+
} else {
|
|
1728
|
+
if (typingTimerRef.current) clearTimeout(typingTimerRef.current);
|
|
1729
|
+
}
|
|
1730
|
+
} else if (event.type === "mode.changed") {
|
|
1731
|
+
const newIsAi = event.mode === "auto";
|
|
1732
|
+
setIsAiMode(newIsAi);
|
|
1733
|
+
setSession((s) => {
|
|
1734
|
+
if (s) localStorage.setItem(STORAGE_KEY, JSON.stringify({ session: s, isAiMode: newIsAi }));
|
|
1735
|
+
return s;
|
|
1736
|
+
});
|
|
1737
|
+
}
|
|
1738
|
+
});
|
|
1739
|
+
} catch {
|
|
1740
|
+
}
|
|
1741
|
+
};
|
|
1742
|
+
void setupAbly();
|
|
1743
|
+
const pollId = setInterval(() => void loadMessages(session), 3e4);
|
|
1744
|
+
return () => {
|
|
1745
|
+
if (ablyClient) try {
|
|
1746
|
+
ablyClient.close();
|
|
1747
|
+
} catch {
|
|
1748
|
+
}
|
|
1749
|
+
clearInterval(pollId);
|
|
1750
|
+
if (typingTimerRef.current) clearTimeout(typingTimerRef.current);
|
|
1751
|
+
};
|
|
1752
|
+
}, [session, STORAGE_KEY, base, loadMessages]);
|
|
1753
|
+
const send = useCallback(async (text, attachments) => {
|
|
1754
|
+
if (!text.trim() && !attachments?.length) return;
|
|
1755
|
+
if (sending) return;
|
|
1756
|
+
setSending(true);
|
|
1757
|
+
if (!session) {
|
|
1758
|
+
try {
|
|
1759
|
+
const res = await fetch(`${base}/api/support-chat/start`, {
|
|
1760
|
+
method: "POST",
|
|
1761
|
+
headers: { "Content-Type": "application/json" },
|
|
1762
|
+
body: JSON.stringify({
|
|
1763
|
+
inboxToken,
|
|
1764
|
+
message: text || `[${attachments.length} archivo(s)]`,
|
|
1765
|
+
attachments
|
|
1766
|
+
})
|
|
1767
|
+
});
|
|
1768
|
+
const data = await res.json();
|
|
1769
|
+
if (data.data) {
|
|
1770
|
+
const sess = {
|
|
1771
|
+
conversationId: data.data.conversationId,
|
|
1772
|
+
visitorToken: data.data.visitorToken
|
|
1773
|
+
};
|
|
1774
|
+
const ai = data.data.isAiMode ?? false;
|
|
1775
|
+
localStorage.setItem(STORAGE_KEY, JSON.stringify({ session: sess, isAiMode: ai }));
|
|
1776
|
+
setSession(sess);
|
|
1777
|
+
setIsAiMode(ai);
|
|
1778
|
+
if (Array.isArray(data.data.messages)) {
|
|
1779
|
+
setRawMessages(data.data.messages);
|
|
1780
|
+
}
|
|
1781
|
+
}
|
|
1782
|
+
} catch {
|
|
1783
|
+
}
|
|
1784
|
+
} else {
|
|
1785
|
+
setRawMessages((prev) => [...prev, {
|
|
1786
|
+
id: `tmp_${Date.now()}`,
|
|
1787
|
+
role: "customer",
|
|
1788
|
+
content: text || `[${attachments.length} archivo(s)]`,
|
|
1789
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1790
|
+
metadata: attachments?.length ? { attachments } : void 0
|
|
1791
|
+
}]);
|
|
1792
|
+
try {
|
|
1793
|
+
const body = { content: text };
|
|
1794
|
+
if (attachments?.length) body.attachments = attachments;
|
|
1795
|
+
const res = await fetch(`${base}/api/support-chat/${session.conversationId}/messages`, {
|
|
1796
|
+
method: "POST",
|
|
1797
|
+
headers: { "Content-Type": "application/json", "x-visitor-token": session.visitorToken },
|
|
1798
|
+
body: JSON.stringify(body)
|
|
1799
|
+
});
|
|
1800
|
+
const data = await res.json();
|
|
1801
|
+
if (data.data?.aiReply) {
|
|
1802
|
+
setRawMessages((prev) => {
|
|
1803
|
+
const withoutTemp = prev.filter((m) => !m.id.startsWith("tmp_"));
|
|
1804
|
+
return [...withoutTemp, data.data.aiReply];
|
|
1805
|
+
});
|
|
1806
|
+
}
|
|
1807
|
+
} catch {
|
|
1808
|
+
}
|
|
1809
|
+
}
|
|
1810
|
+
setSending(false);
|
|
1811
|
+
}, [session, sending, inboxToken, base, STORAGE_KEY]);
|
|
1812
|
+
const requestHuman = useCallback(async () => {
|
|
1813
|
+
if (!session || !isAiMode || requestingHuman) return;
|
|
1814
|
+
setRequestingHuman(true);
|
|
1815
|
+
try {
|
|
1816
|
+
await fetch(`${base}/api/support-chat/${session.conversationId}/mode`, {
|
|
1817
|
+
method: "PATCH",
|
|
1818
|
+
headers: { "Content-Type": "application/json", "x-visitor-token": session.visitorToken },
|
|
1819
|
+
body: JSON.stringify({ mode: "human" })
|
|
1820
|
+
});
|
|
1821
|
+
setIsAiMode(false);
|
|
1822
|
+
localStorage.setItem(STORAGE_KEY, JSON.stringify({ session, isAiMode: false }));
|
|
1823
|
+
} catch {
|
|
1824
|
+
}
|
|
1825
|
+
setRequestingHuman(false);
|
|
1826
|
+
}, [session, isAiMode, requestingHuman, base, STORAGE_KEY]);
|
|
1827
|
+
const returnToAi = useCallback(async () => {
|
|
1828
|
+
if (!session || isAiMode || returningToAi) return;
|
|
1829
|
+
setReturningToAi(true);
|
|
1830
|
+
try {
|
|
1831
|
+
await fetch(`${base}/api/support-chat/${session.conversationId}/mode`, {
|
|
1832
|
+
method: "PATCH",
|
|
1833
|
+
headers: { "Content-Type": "application/json", "x-visitor-token": session.visitorToken },
|
|
1834
|
+
body: JSON.stringify({ mode: "auto" })
|
|
1835
|
+
});
|
|
1836
|
+
setIsAiMode(true);
|
|
1837
|
+
localStorage.setItem(STORAGE_KEY, JSON.stringify({ session, isAiMode: true }));
|
|
1838
|
+
} catch {
|
|
1839
|
+
}
|
|
1840
|
+
setReturningToAi(false);
|
|
1841
|
+
}, [session, isAiMode, returningToAi, base, STORAGE_KEY]);
|
|
1842
|
+
const reset = useCallback(() => {
|
|
1843
|
+
localStorage.removeItem(STORAGE_KEY);
|
|
1844
|
+
setSession(null);
|
|
1845
|
+
setRawMessages([]);
|
|
1846
|
+
setIsAiMode(false);
|
|
1847
|
+
setAgentTyping(false);
|
|
1848
|
+
setRequestingHuman(false);
|
|
1849
|
+
setReturningToAi(false);
|
|
1850
|
+
}, [STORAGE_KEY]);
|
|
1851
|
+
const messages = useMemo(
|
|
1852
|
+
() => rawMessages.filter((m) => m.role !== "system").map(toWidgetMsg),
|
|
1853
|
+
[rawMessages]
|
|
1854
|
+
);
|
|
1855
|
+
const footerAction = useMemo(() => {
|
|
1856
|
+
if (isAiMode) {
|
|
1857
|
+
return { label: requestHumanLabel, sublabel: "Te conectamos con un agente disponible", icon: "human", onClick: requestHuman, loading: requestingHuman };
|
|
1858
|
+
}
|
|
1859
|
+
if (!isAiMode && session && returnToAiLabel) {
|
|
1860
|
+
return { label: returnToAiLabel, sublabel: "Respuesta instant\xE1nea con inteligencia artificial", icon: "ai", onClick: returnToAi, loading: returningToAi };
|
|
1861
|
+
}
|
|
1862
|
+
return void 0;
|
|
1863
|
+
}, [isAiMode, session, requestHumanLabel, requestHuman, requestingHuman, returnToAiLabel, returnToAi, returningToAi]);
|
|
1864
|
+
return useMemo(() => ({
|
|
1865
|
+
messages,
|
|
1866
|
+
streaming: sending || agentTyping,
|
|
1867
|
+
send,
|
|
1868
|
+
reset,
|
|
1869
|
+
mode: isAiMode ? "ai" : "human",
|
|
1870
|
+
...footerAction ? { footerAction } : {}
|
|
1871
|
+
}), [messages, sending, agentTyping, send, reset, isAiMode, footerAction]);
|
|
1872
|
+
}
|
|
1508
1873
|
var KEY_EXPANDED = "wallavi_bubble_expanded";
|
|
1509
1874
|
var KEY_DISMISSED = "wallavi_bubble_dismissed";
|
|
1510
1875
|
function BubbleWidget({
|
|
1876
|
+
inboxToken,
|
|
1877
|
+
supportApiBase,
|
|
1878
|
+
requestHumanLabel,
|
|
1879
|
+
returnToAiLabel,
|
|
1511
1880
|
position: positionProp,
|
|
1512
1881
|
width: widthProp,
|
|
1513
1882
|
height: heightProp,
|
|
@@ -1525,6 +1894,9 @@ function BubbleWidget({
|
|
|
1525
1894
|
onOpenChange,
|
|
1526
1895
|
...chatProps
|
|
1527
1896
|
}) {
|
|
1897
|
+
const supportBackend = useSupportChat(
|
|
1898
|
+
inboxToken ? { inboxToken, apiBase: supportApiBase, requestHumanLabel, returnToAiLabel } : { inboxToken: "__disabled__", apiBase: supportApiBase }
|
|
1899
|
+
);
|
|
1528
1900
|
const isControlled = isOpenProp !== void 0;
|
|
1529
1901
|
const [internalOpen, setInternalOpen] = useState(false);
|
|
1530
1902
|
const open = isControlled ? isOpenProp : internalOpen;
|
|
@@ -1551,7 +1923,7 @@ function BubbleWidget({
|
|
|
1551
1923
|
useEffect(() => {
|
|
1552
1924
|
if (localStorage.getItem(KEY_EXPANDED) === "true") setExpanded(true);
|
|
1553
1925
|
}, []);
|
|
1554
|
-
const remote = useAutoConfig(chatProps.agentId, autoConfig);
|
|
1926
|
+
const remote = useAutoConfig(inboxToken ? "" : chatProps.agentId ?? "", !inboxToken && autoConfig);
|
|
1555
1927
|
const resolvedPosition = positionProp ?? remote.position;
|
|
1556
1928
|
const resolvedBubbleIcon = bubbleIconUrlProp ?? remote.bubbleIconUrl;
|
|
1557
1929
|
const resolvedAutoOpen = autoOpenProp || remote.autoOpen;
|
|
@@ -1565,8 +1937,8 @@ function BubbleWidget({
|
|
|
1565
1937
|
const mergedConfig = {
|
|
1566
1938
|
...remote.remoteConfig,
|
|
1567
1939
|
...definedChatProps,
|
|
1568
|
-
agentId: chatProps.agentId,
|
|
1569
|
-
agentName: chatProps.agentName
|
|
1940
|
+
agentId: chatProps.agentId ?? "",
|
|
1941
|
+
agentName: chatProps.agentName ?? ""
|
|
1570
1942
|
};
|
|
1571
1943
|
const setOpenRef = useRef(setOpen);
|
|
1572
1944
|
useEffect(() => {
|
|
@@ -1642,6 +2014,8 @@ function BubbleWidget({
|
|
|
1642
2014
|
ChatWidget,
|
|
1643
2015
|
{
|
|
1644
2016
|
...mergedConfig,
|
|
2017
|
+
agentId: inboxToken ? "support" : chatProps.agentId ?? "",
|
|
2018
|
+
customBackend: inboxToken ? supportBackend : mergedConfig.customBackend,
|
|
1645
2019
|
onClose: handleClose,
|
|
1646
2020
|
onExpand: toggleExpanded,
|
|
1647
2021
|
expanded,
|
|
@@ -1685,4 +2059,4 @@ function BubbleWidget({
|
|
|
1685
2059
|
);
|
|
1686
2060
|
}
|
|
1687
2061
|
|
|
1688
|
-
export { BubbleWidget, ChatWidget, formatToolName, getContrastColor, useAttachments, useChat, useVoice };
|
|
2062
|
+
export { BubbleWidget, ChatWidget, formatToolName, getContrastColor, useAttachments, useChat, useSupportChat, useVoice };
|